aboutsummaryrefslogtreecommitdiff
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/.gitignore15
-rw-r--r--wpa_supplicant/Android.mk1827
-rw-r--r--wpa_supplicant/ChangeLog2447
-rw-r--r--wpa_supplicant/Makefile2074
-rw-r--r--wpa_supplicant/README1163
-rw-r--r--wpa_supplicant/README-DPP204
-rw-r--r--wpa_supplicant/README-HS20654
-rw-r--r--wpa_supplicant/README-P2P856
-rw-r--r--wpa_supplicant/README-WPS399
-rw-r--r--wpa_supplicant/README-Windows.txt299
-rw-r--r--wpa_supplicant/android.config545
-rw-r--r--wpa_supplicant/ap.c1945
-rw-r--r--wpa_supplicant/ap.h106
-rw-r--r--wpa_supplicant/autoscan.c162
-rw-r--r--wpa_supplicant/autoscan.h59
-rw-r--r--wpa_supplicant/autoscan_exponential.c104
-rw-r--r--wpa_supplicant/autoscan_periodic.c85
-rw-r--r--wpa_supplicant/bgscan.c109
-rw-r--r--wpa_supplicant/bgscan.h82
-rw-r--r--wpa_supplicant/bgscan_learn.c614
-rw-r--r--wpa_supplicant/bgscan_simple.c275
-rw-r--r--wpa_supplicant/binder/.clang-format9
-rw-r--r--wpa_supplicant/binder/binder.cpp104
-rw-r--r--wpa_supplicant/binder/binder.h46
-rw-r--r--wpa_supplicant/binder/binder_constants.cpp18
-rw-r--r--wpa_supplicant/binder/binder_constants.h21
-rw-r--r--wpa_supplicant/binder/binder_i.h28
-rw-r--r--wpa_supplicant/binder/binder_manager.cpp100
-rw-r--r--wpa_supplicant/binder/binder_manager.h58
-rw-r--r--wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl16
-rw-r--r--wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl59
-rw-r--r--wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl20
-rw-r--r--wpa_supplicant/binder/iface.cpp16
-rw-r--r--wpa_supplicant/binder/iface.h42
-rw-r--r--wpa_supplicant/binder/supplicant.cpp127
-rw-r--r--wpa_supplicant/binder/supplicant.h55
-rw-r--r--wpa_supplicant/bss.c1385
-rw-r--r--wpa_supplicant/bss.h200
-rw-r--r--wpa_supplicant/bssid_ignore.c221
-rw-r--r--wpa_supplicant/bssid_ignore.h33
-rw-r--r--wpa_supplicant/config.c5429
-rw-r--r--wpa_supplicant/config.h1797
-rw-r--r--wpa_supplicant/config_file.c1656
-rw-r--r--wpa_supplicant/config_none.c56
-rw-r--r--wpa_supplicant/config_ssid.h1182
-rw-r--r--wpa_supplicant/config_winreg.c1061
-rw-r--r--wpa_supplicant/ctrl_iface.c13103
-rw-r--r--wpa_supplicant/ctrl_iface.h167
-rw-r--r--wpa_supplicant/ctrl_iface_named_pipe.c831
-rw-r--r--wpa_supplicant/ctrl_iface_udp.c831
-rw-r--r--wpa_supplicant/ctrl_iface_unix.c1431
-rw-r--r--wpa_supplicant/dbus/.gitignore1
-rw-r--r--wpa_supplicant/dbus/Makefile69
-rw-r--r--wpa_supplicant/dbus/dbus-wpa_supplicant.conf17
-rw-r--r--wpa_supplicant/dbus/dbus_common.c373
-rw-r--r--wpa_supplicant/dbus/dbus_common.h20
-rw-r--r--wpa_supplicant/dbus/dbus_common_i.h34
-rw-r--r--wpa_supplicant/dbus/dbus_dict_helpers.c1061
-rw-r--r--wpa_supplicant/dbus/dbus_dict_helpers.h152
-rw-r--r--wpa_supplicant/dbus/dbus_new.c5105
-rw-r--r--wpa_supplicant/dbus/dbus_new.h648
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.c5926
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers.h285
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.c3107
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.h152
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_wps.c804
-rw-r--r--wpa_supplicant/dbus/dbus_new_helpers.c1025
-rw-r--r--wpa_supplicant/dbus/dbus_new_helpers.h154
-rw-r--r--wpa_supplicant/dbus/dbus_new_introspect.c286
-rw-r--r--wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in5
-rw-r--r--wpa_supplicant/defconfig635
-rw-r--r--wpa_supplicant/doc/docbook/.gitignore7
-rw-r--r--wpa_supplicant/doc/docbook/Makefile28
-rw-r--r--wpa_supplicant/doc/docbook/eapol_test.sgml209
-rw-r--r--wpa_supplicant/doc/docbook/wpa_background.sgml105
-rw-r--r--wpa_supplicant/doc/docbook/wpa_cli.sgml360
-rw-r--r--wpa_supplicant/doc/docbook/wpa_gui.sgml106
-rw-r--r--wpa_supplicant/doc/docbook/wpa_passphrase.sgml77
-rw-r--r--wpa_supplicant/doc/docbook/wpa_priv.sgml152
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml243
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.sgml764
-rw-r--r--wpa_supplicant/dpp_supplicant.c3995
-rw-r--r--wpa_supplicant/dpp_supplicant.h45
-rw-r--r--wpa_supplicant/driver_i.h1120
-rw-r--r--wpa_supplicant/eap_proxy_dummy.mak0
-rw-r--r--wpa_supplicant/eap_proxy_dummy.mk0
-rw-r--r--wpa_supplicant/eap_register.c271
-rw-r--r--wpa_supplicant/eap_testing.txt392
-rw-r--r--wpa_supplicant/eapol_test.c1555
-rwxr-xr-xwpa_supplicant/eapol_test.py159
-rw-r--r--wpa_supplicant/events.c5783
-rwxr-xr-xwpa_supplicant/examples/60_wpa_supplicant19
-rwxr-xr-xwpa_supplicant/examples/dbus-listen-preq.py66
-rwxr-xr-xwpa_supplicant/examples/dpp-nfc.py1186
-rwxr-xr-xwpa_supplicant/examples/dpp-qrcode.py130
-rw-r--r--wpa_supplicant/examples/ieee8021x.conf13
-rw-r--r--wpa_supplicant/examples/openCryptoki.conf41
-rwxr-xr-xwpa_supplicant/examples/p2p-action-udhcp.sh69
-rwxr-xr-xwpa_supplicant/examples/p2p-action.sh96
-rwxr-xr-xwpa_supplicant/examples/p2p-nfc.py654
-rw-r--r--wpa_supplicant/examples/p2p/p2p_connect.py299
-rw-r--r--wpa_supplicant/examples/p2p/p2p_disconnect.py169
-rw-r--r--wpa_supplicant/examples/p2p/p2p_find.py192
-rw-r--r--wpa_supplicant/examples/p2p/p2p_flush.py168
-rw-r--r--wpa_supplicant/examples/p2p/p2p_group_add.py222
-rw-r--r--wpa_supplicant/examples/p2p/p2p_invite.py201
-rw-r--r--wpa_supplicant/examples/p2p/p2p_listen.py182
-rw-r--r--wpa_supplicant/examples/p2p/p2p_stop_find.py174
-rw-r--r--wpa_supplicant/examples/plaintext.conf8
-rw-r--r--wpa_supplicant/examples/udhcpd-p2p.conf118
-rw-r--r--wpa_supplicant/examples/wep.conf11
-rw-r--r--wpa_supplicant/examples/wpa-psk-tkip.conf12
-rw-r--r--wpa_supplicant/examples/wpa2-eap-ccmp.conf15
-rwxr-xr-xwpa_supplicant/examples/wpas-dbus-new-getall.py58
-rwxr-xr-xwpa_supplicant/examples/wpas-dbus-new-signals.py203
-rwxr-xr-xwpa_supplicant/examples/wpas-dbus-new-wps.py80
-rwxr-xr-xwpa_supplicant/examples/wpas-dbus-new.py149
-rwxr-xr-xwpa_supplicant/examples/wps-ap-cli81
-rwxr-xr-xwpa_supplicant/examples/wps-nfc.py525
-rw-r--r--wpa_supplicant/gas_query.c897
-rw-r--r--wpa_supplicant/gas_query.h59
-rw-r--r--wpa_supplicant/hs20_supplicant.c1357
-rw-r--r--wpa_supplicant/hs20_supplicant.h51
-rw-r--r--wpa_supplicant/ibss_rsn.c954
-rw-r--r--wpa_supplicant/ibss_rsn.h65
-rw-r--r--wpa_supplicant/interworking.c3293
-rw-r--r--wpa_supplicant/interworking.h37
-rw-r--r--wpa_supplicant/libwpa_test.c32
-rw-r--r--wpa_supplicant/main.c409
-rw-r--r--wpa_supplicant/main_none.c40
-rw-r--r--wpa_supplicant/main_winmain.c78
-rw-r--r--wpa_supplicant/main_winsvc.c458
-rw-r--r--wpa_supplicant/mbo.c665
-rw-r--r--wpa_supplicant/mesh.c892
-rw-r--r--wpa_supplicant/mesh.h49
-rw-r--r--wpa_supplicant/mesh_mpm.c1403
-rw-r--r--wpa_supplicant/mesh_mpm.h46
-rw-r--r--wpa_supplicant/mesh_rsn.c795
-rw-r--r--wpa_supplicant/mesh_rsn.h45
-rw-r--r--wpa_supplicant/nfc_pw_token.c83
-rw-r--r--wpa_supplicant/nmake.mak240
-rw-r--r--wpa_supplicant/notify.c975
-rw-r--r--wpa_supplicant/notify.h167
-rw-r--r--wpa_supplicant/offchannel.c488
-rw-r--r--wpa_supplicant/offchannel.h35
-rw-r--r--wpa_supplicant/op_classes.c534
-rw-r--r--wpa_supplicant/p2p_supplicant.c10107
-rw-r--r--wpa_supplicant/p2p_supplicant.h357
-rw-r--r--wpa_supplicant/p2p_supplicant_sd.c1273
-rw-r--r--wpa_supplicant/pasn_supplicant.c1710
-rw-r--r--wpa_supplicant/preauth_test.c371
-rw-r--r--wpa_supplicant/robust_av.c1487
-rw-r--r--wpa_supplicant/rrm.c1594
-rw-r--r--wpa_supplicant/scan.c3360
-rw-r--r--wpa_supplicant/scan.h96
-rw-r--r--wpa_supplicant/sme.c2945
-rw-r--r--wpa_supplicant/sme.h137
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in15
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant-wired.service.arg.in15
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant.service.arg.in15
-rw-r--r--wpa_supplicant/systemd/wpa_supplicant.service.in14
-rw-r--r--wpa_supplicant/todo.txt78
-rw-r--r--wpa_supplicant/twt.c142
-rwxr-xr-xwpa_supplicant/utils/log2pcap.py54
-rwxr-xr-xwpa_supplicant/vs2005/eapol_test/eapol_test.vcproj477
-rwxr-xr-xwpa_supplicant/vs2005/win_if_list/win_if_list.vcproj203
-rwxr-xr-xwpa_supplicant/vs2005/wpa_cli/wpa_cli.vcproj215
-rwxr-xr-xwpa_supplicant/vs2005/wpa_passphrase/wpa_passphrase.vcproj236
-rwxr-xr-xwpa_supplicant/vs2005/wpa_supplicant.sln52
-rwxr-xr-xwpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj465
-rwxr-xr-xwpa_supplicant/vs2005/wpasvc/wpasvc.vcproj465
-rw-r--r--wpa_supplicant/wifi_display.c431
-rw-r--r--wpa_supplicant/wifi_display.h24
-rwxr-xr-xwpa_supplicant/win_example.reg42
-rw-r--r--wpa_supplicant/win_if_list.c173
-rw-r--r--wpa_supplicant/wmm_ac.c987
-rw-r--r--wpa_supplicant/wmm_ac.h176
-rw-r--r--wpa_supplicant/wnm_sta.c1970
-rw-r--r--wpa_supplicant/wnm_sta.h93
-rw-r--r--wpa_supplicant/wpa_cli.c5083
-rw-r--r--wpa_supplicant/wpa_gui-qt4/.gitignore4
-rw-r--r--wpa_supplicant/wpa_gui-qt4/addinterface.cpp239
-rw-r--r--wpa_supplicant/wpa_gui-qt4/addinterface.h39
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.cpp124
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.h57
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.ui61
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons.qrc9
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/.gitignore2
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/Makefile37
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/README74
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/ap.svg832
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/group.svg616
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/invitation.svg374
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/laptop.svg1568
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/wpa_gui.svg256
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons_png.qrc9
-rw-r--r--wpa_supplicant/wpa_gui-qt4/lang/.gitignore1
-rw-r--r--wpa_supplicant/wpa_gui-qt4/lang/wpa_gui_de.ts1262
-rw-r--r--wpa_supplicant/wpa_gui-qt4/main.cpp67
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.cpp853
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.h55
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.ui435
-rw-r--r--wpa_supplicant/wpa_gui-qt4/peers.cpp1885
-rw-r--r--wpa_supplicant/wpa_gui-qt4/peers.h90
-rw-r--r--wpa_supplicant/wpa_gui-qt4/peers.ui40
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.cpp141
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.h40
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.ui94
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresultsitem.cpp18
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresultsitem.h21
-rw-r--r--wpa_supplicant/wpa_gui-qt4/signalbar.cpp58
-rw-r--r--wpa_supplicant/wpa_gui-qt4/signalbar.h28
-rw-r--r--wpa_supplicant/wpa_gui-qt4/stringquery.cpp31
-rw-r--r--wpa_supplicant/wpa_gui-qt4/stringquery.h28
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp94
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.h40
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.ui109
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop10
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpa_gui.pro73
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.cpp1913
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.h180
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.ui524
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpamsg.h35
-rw-r--r--wpa_supplicant/wpa_passphrase.c73
-rw-r--r--wpa_supplicant/wpa_priv.c1292
-rw-r--r--wpa_supplicant/wpa_supplicant.c8658
-rw-r--r--wpa_supplicant/wpa_supplicant.conf2071
-rw-r--r--wpa_supplicant/wpa_supplicant_conf.mk34
-rwxr-xr-xwpa_supplicant/wpa_supplicant_conf.sh16
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1889
-rw-r--r--wpa_supplicant/wpa_supplicant_template.conf7
-rw-r--r--wpa_supplicant/wpas_glue.c1494
-rw-r--r--wpa_supplicant/wpas_glue.h30
-rw-r--r--wpa_supplicant/wpas_kay.c440
-rw-r--r--wpa_supplicant/wpas_kay.h51
-rw-r--r--wpa_supplicant/wpas_module_tests.c114
-rw-r--r--wpa_supplicant/wps_supplicant.c3013
-rw-r--r--wpa_supplicant/wps_supplicant.h164
238 files changed, 0 insertions, 165278 deletions
diff --git a/wpa_supplicant/.gitignore b/wpa_supplicant/.gitignore
deleted file mode 100644
index ff741201e6dd..000000000000
--- a/wpa_supplicant/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-.config
-*.service
-eapol_test
-nfc_pw_token
-preauth_test
-wpa_cli
-wpa_passphrase
-wpa_supplicant
-wpa_priv
-wpa_gui/Makefile
-wpa_gui/wpa_gui
-wpa_gui-qt4/Makefile
-wpa_gui-qt4/wpa_gui
-libwpa_test1
-libwpa_test2
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
deleted file mode 100644
index 7e597f396a07..000000000000
--- a/wpa_supplicant/Android.mk
+++ /dev/null
@@ -1,1827 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-#
-
-LOCAL_PATH := $(call my-dir)
-PKG_CONFIG ?= pkg-config
-
-ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
- CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
-endif
-
-include $(LOCAL_PATH)/android.config
-
-# To ignore possible wrong network configurations
-L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
-
-L_CFLAGS += -DVERSION_STR_POSTFIX=\"-$(PLATFORM_VERSION)\"
-
-# Set Android log name
-L_CFLAGS += -DANDROID_LOG_NAME=\"wpa_supplicant\"
-
-# Disable unused parameter warnings
-L_CFLAGS += -Wno-unused-parameter
-
-# Set Android extended P2P functionality
-L_CFLAGS += -DANDROID_P2P
-
-ifeq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
-L_CFLAGS += -DANDROID_LIB_STUB
-endif
-
-ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB_EVENT),)
-L_CFLAGS += -DANDROID_LIB_EVENT
-endif
-
-# Disable roaming in wpa_supplicant
-ifdef CONFIG_NO_ROAMING
-L_CFLAGS += -DCONFIG_NO_ROAMING
-endif
-
-# Use Android specific directory for control interface sockets
-L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
-L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/misc/wifi/sockets\"
-
-# Use Android specific directory for wpa_cli command completion history
-L_CFLAGS += -DCONFIG_WPA_CLI_HISTORY_DIR=\"/data/misc/wifi\"
-
-# To force sizeof(enum) = 4
-ifeq ($(TARGET_ARCH),arm)
-L_CFLAGS += -mabi=aapcs-linux
-endif
-
-# C++ flags for binder interface
-L_CPPFLAGS := -std=c++11 -Wall -Werror
-# TODO: Remove these allowed warnings later.
-L_CPPFLAGS += -Wno-unused-variable -Wno-unused-parameter
-L_CPPFLAGS += -Wno-unused-private-field
-
-INCLUDES = $(LOCAL_PATH)
-INCLUDES += $(LOCAL_PATH)/src
-INCLUDES += $(LOCAL_PATH)/src/common
-# INCLUDES += $(LOCAL_PATH)/src/crypto # To force proper includes
-INCLUDES += $(LOCAL_PATH)/src/drivers
-INCLUDES += $(LOCAL_PATH)/src/eap_common
-INCLUDES += $(LOCAL_PATH)/src/eapol_supp
-INCLUDES += $(LOCAL_PATH)/src/eap_peer
-INCLUDES += $(LOCAL_PATH)/src/eap_server
-INCLUDES += $(LOCAL_PATH)/src/hlr_auc_gw
-INCLUDES += $(LOCAL_PATH)/src/l2_packet
-INCLUDES += $(LOCAL_PATH)/src/radius
-INCLUDES += $(LOCAL_PATH)/src/rsn_supp
-INCLUDES += $(LOCAL_PATH)/src/tls
-INCLUDES += $(LOCAL_PATH)/src/utils
-INCLUDES += $(LOCAL_PATH)/src/wps
-INCLUDES += system/security/keystore/include
-ifdef CONFIG_DRIVER_NL80211
-ifneq ($(wildcard external/libnl),)
-INCLUDES += external/libnl/include
-else
-INCLUDES += external/libnl-headers
-endif
-endif
-
-ifdef CONFIG_FIPS
-CONFIG_NO_RANDOM_POOL=
-CONFIG_OPENSSL_CMAC=y
-endif
-
-OBJS = config.c
-OBJS += notify.c
-OBJS += bss.c
-OBJS += eap_register.c
-OBJS += src/utils/common.c
-OBJS += src/utils/config.c
-OBJS += src/utils/wpa_debug.c
-OBJS += src/utils/wpabuf.c
-OBJS += src/utils/bitfield.c
-OBJS += src/utils/ip_addr.c
-OBJS += src/utils/crc32.c
-OBJS += wmm_ac.c
-OBJS += op_classes.c
-OBJS += rrm.c
-OBJS += twt.c
-OBJS += robust_av.c
-OBJS_p = wpa_passphrase.c
-OBJS_p += src/utils/common.c
-OBJS_p += src/utils/wpa_debug.c
-OBJS_p += src/utils/wpabuf.c
-OBJS_c = wpa_cli.c src/common/wpa_ctrl.c
-OBJS_c += src/utils/wpa_debug.c
-OBJS_c += src/utils/common.c
-OBJS_c += src/common/cli.c
-OBJS_d =
-OBJS_priv =
-
-ifndef CONFIG_OS
-ifdef CONFIG_NATIVE_WINDOWS
-CONFIG_OS=win32
-else
-CONFIG_OS=unix
-endif
-endif
-
-ifeq ($(CONFIG_OS), internal)
-L_CFLAGS += -DOS_NO_C_LIB_DEFINES
-endif
-
-OBJS += src/utils/os_$(CONFIG_OS).c
-OBJS_p += src/utils/os_$(CONFIG_OS).c
-OBJS_c += src/utils/os_$(CONFIG_OS).c
-
-ifdef CONFIG_WPA_TRACE
-L_CFLAGS += -DWPA_TRACE
-OBJS += src/utils/trace.c
-OBJS_p += src/utils/trace.c
-OBJS_c += src/utils/trace.c
-LDFLAGS += -rdynamic
-L_CFLAGS += -funwind-tables
-ifdef CONFIG_WPA_TRACE_BFD
-L_CFLAGS += -DWPA_TRACE_BFD
-LIBS += -lbfd
-LIBS_p += -lbfd
-LIBS_c += -lbfd
-endif
-endif
-
-ifndef CONFIG_ELOOP
-CONFIG_ELOOP=eloop
-endif
-OBJS += src/utils/$(CONFIG_ELOOP).c
-OBJS_c += src/utils/$(CONFIG_ELOOP).c
-
-ifdef CONFIG_ELOOP_POLL
-L_CFLAGS += -DCONFIG_ELOOP_POLL
-endif
-
-ifdef CONFIG_ELOOP_EPOLL
-L_CFLAGS += -DCONFIG_ELOOP_EPOLL
-endif
-
-ifdef CONFIG_EAPOL_TEST
-L_CFLAGS += -Werror -DEAPOL_TEST
-endif
-
-ifdef CONFIG_HT_OVERRIDES
-L_CFLAGS += -DCONFIG_HT_OVERRIDES
-endif
-
-ifdef CONFIG_VHT_OVERRIDES
-L_CFLAGS += -DCONFIG_VHT_OVERRIDES
-endif
-
-ifdef CONFIG_HE_OVERRIDES
-L_CFLAGS += -DCONFIG_HE_OVERRIDES
-endif
-
-ifndef CONFIG_BACKEND
-CONFIG_BACKEND=file
-endif
-
-ifeq ($(CONFIG_BACKEND), file)
-OBJS += config_file.c
-ifndef CONFIG_NO_CONFIG_BLOBS
-NEED_BASE64=y
-endif
-L_CFLAGS += -DCONFIG_BACKEND_FILE
-endif
-
-ifeq ($(CONFIG_BACKEND), winreg)
-OBJS += config_winreg.c
-endif
-
-ifeq ($(CONFIG_BACKEND), none)
-OBJS += config_none.c
-endif
-
-ifdef CONFIG_NO_CONFIG_WRITE
-L_CFLAGS += -DCONFIG_NO_CONFIG_WRITE
-endif
-
-ifdef CONFIG_NO_CONFIG_BLOBS
-L_CFLAGS += -DCONFIG_NO_CONFIG_BLOBS
-endif
-
-ifdef CONFIG_NO_SCAN_PROCESSING
-L_CFLAGS += -DCONFIG_NO_SCAN_PROCESSING
-endif
-
-ifdef CONFIG_SUITEB
-L_CFLAGS += -DCONFIG_SUITEB
-endif
-
-ifdef CONFIG_SUITEB192
-L_CFLAGS += -DCONFIG_SUITEB192
-NEED_SHA384=y
-endif
-
-ifdef CONFIG_OCV
-L_CFLAGS += -DCONFIG_OCV
-OBJS += src/common/ocv.c
-endif
-
-ifdef CONFIG_IEEE80211R
-L_CFLAGS += -DCONFIG_IEEE80211R
-OBJS += src/rsn_supp/wpa_ft.c
-endif
-
-ifdef CONFIG_MESH
-NEED_80211_COMMON=y
-NEED_AES_SIV=y
-CONFIG_SAE=y
-CONFIG_AP=y
-L_CFLAGS += -DCONFIG_MESH
-OBJS += mesh.c
-OBJS += mesh_mpm.c
-OBJS += mesh_rsn.c
-endif
-
-ifdef CONFIG_SAE
-L_CFLAGS += -DCONFIG_SAE
-OBJS += src/common/sae.c
-ifdef CONFIG_SAE_PK
-L_CFLAGS += -DCONFIG_SAE_PK
-OBJS += src/common/sae_pk.c
-endif
-NEED_ECC=y
-NEED_DH_GROUPS=y
-NEED_HMAC_SHA256_KDF=y
-NEED_DRAGONFLY=y
-ifdef CONFIG_TESTING_OPTIONS
-NEED_DH_GROUPS_ALL=y
-endif
-endif
-
-ifdef CONFIG_DPP
-L_CFLAGS += -DCONFIG_DPP
-OBJS += src/common/dpp.c
-OBJS += src/common/dpp_auth.c
-OBJS += src/common/dpp_backup.c
-OBJS += src/common/dpp_crypto.c
-OBJS += src/common/dpp_pkex.c
-OBJS += src/common/dpp_reconfig.c
-OBJS += src/common/dpp_tcp.c
-OBJS += dpp_supplicant.c
-NEED_AES_SIV=y
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_HMAC_SHA512_KDF=y
-NEED_SHA384=y
-NEED_SHA512=y
-NEED_ECC=y
-NEED_JSON=y
-NEED_GAS_SERVER=y
-NEED_BASE64=y
-NEED_ASN1=y
-ifdef CONFIG_DPP2
-L_CFLAGS += -DCONFIG_DPP2
-endif
-ifdef CONFIG_DPP3
-L_CFLAGS += -DCONFIG_DPP3
-endif
-endif
-
-ifdef CONFIG_OWE
-L_CFLAGS += -DCONFIG_OWE
-NEED_ECC=y
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_HMAC_SHA512_KDF=y
-NEED_SHA384=y
-NEED_SHA512=y
-endif
-
-ifdef CONFIG_FILS
-L_CFLAGS += -DCONFIG_FILS
-NEED_SHA384=y
-NEED_AES_SIV=y
-ifdef CONFIG_FILS_SK_PFS
-L_CFLAGS += -DCONFIG_FILS_SK_PFS
-NEED_ECC=y
-endif
-endif
-
-ifdef CONFIG_MBO
-CONFIG_WNM=y
-endif
-
-ifdef CONFIG_WNM
-L_CFLAGS += -DCONFIG_WNM
-OBJS += wnm_sta.c
-endif
-
-ifdef CONFIG_TDLS
-L_CFLAGS += -DCONFIG_TDLS
-OBJS += src/rsn_supp/tdls.c
-endif
-
-ifdef CONFIG_TDLS_TESTING
-L_CFLAGS += -DCONFIG_TDLS_TESTING
-endif
-
-ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-L_CFLAGS += -DCONFIG_PMKSA_CACHE_EXTERNAL
-endif
-
-ifndef CONFIG_NO_WPA
-OBJS += src/rsn_supp/wpa.c
-OBJS += src/rsn_supp/preauth.c
-OBJS += src/rsn_supp/pmksa_cache.c
-OBJS += src/rsn_supp/wpa_ie.c
-OBJS += src/common/wpa_common.c
-NEED_AES=y
-NEED_SHA1=y
-NEED_MD5=y
-NEED_RC4=y
-else
-L_CFLAGS += -DCONFIG_NO_WPA
-endif
-
-ifdef CONFIG_IBSS_RSN
-NEED_RSN_AUTHENTICATOR=y
-L_CFLAGS += -DCONFIG_IBSS_RSN
-L_CFLAGS += -DCONFIG_NO_VLAN
-OBJS += ibss_rsn.c
-endif
-
-ifdef CONFIG_P2P
-OBJS += p2p_supplicant.c
-OBJS += p2p_supplicant_sd.c
-OBJS += src/p2p/p2p.c
-OBJS += src/p2p/p2p_utils.c
-OBJS += src/p2p/p2p_parse.c
-OBJS += src/p2p/p2p_build.c
-OBJS += src/p2p/p2p_go_neg.c
-OBJS += src/p2p/p2p_sd.c
-OBJS += src/p2p/p2p_pd.c
-OBJS += src/p2p/p2p_invitation.c
-OBJS += src/p2p/p2p_dev_disc.c
-OBJS += src/p2p/p2p_group.c
-OBJS += src/ap/p2p_hostapd.c
-L_CFLAGS += -DCONFIG_P2P
-NEED_GAS=y
-NEED_OFFCHANNEL=y
-CONFIG_WPS=y
-CONFIG_AP=y
-ifdef CONFIG_P2P_STRICT
-L_CFLAGS += -DCONFIG_P2P_STRICT
-endif
-ifdef CONFIG_WIFI_DISPLAY
-L_CFLAGS += -DCONFIG_WIFI_DISPLAY
-OBJS += wifi_display.c
-endif
-endif
-
-ifdef CONFIG_PASN
-L_CFLAGS += -DCONFIG_PASN
-L_CFLAGS += -DCONFIG_PTKSA_CACHE
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_SHA256=y
-NEED_SHA384=y
-OBJS += src/common/ptksa_cache.c
-OBJS += pasn_supplicant.c
-endif
-
-ifdef CONFIG_HS20
-OBJS += hs20_supplicant.c
-L_CFLAGS += -DCONFIG_HS20
-CONFIG_INTERWORKING=y
-endif
-
-ifdef CONFIG_INTERWORKING
-OBJS += interworking.c
-L_CFLAGS += -DCONFIG_INTERWORKING
-NEED_GAS=y
-endif
-
-ifdef CONFIG_FST
-L_CFLAGS += -DCONFIG_FST
-OBJS += src/fst/fst.c
-OBJS += src/fst/fst_session.c
-OBJS += src/fst/fst_iface.c
-OBJS += src/fst/fst_group.c
-OBJS += src/fst/fst_ctrl_aux.c
-ifdef CONFIG_FST_TEST
-L_CFLAGS += -DCONFIG_FST_TEST
-endif
-ifdef CONFIG_CTRL_IFACE
-OBJS += src/fst/fst_ctrl_iface.c
-endif
-endif
-
-ifdef CONFIG_WEP
-L_CFLAGS += -DCONFIG_WEP
-endif
-
-ifdef CONFIG_NO_TKIP
-L_CFLAGS += -DCONFIG_NO_TKIP
-endif
-
-
-include $(LOCAL_PATH)/src/drivers/drivers.mk
-
-ifdef CONFIG_AP
-OBJS_d += $(DRV_BOTH_OBJS)
-L_CFLAGS += $(DRV_BOTH_CFLAGS)
-LDFLAGS += $(DRV_BOTH_LDFLAGS)
-LIBS += $(DRV_BOTH_LIBS)
-else
-NEED_AP_MLME=
-OBJS_d += $(DRV_WPA_OBJS)
-L_CFLAGS += $(DRV_WPA_CFLAGS)
-LDFLAGS += $(DRV_WPA_LDFLAGS)
-LIBS += $(DRV_WPA_LIBS)
-endif
-
-ifndef CONFIG_L2_PACKET
-CONFIG_L2_PACKET=linux
-endif
-
-OBJS_l2 += src/l2_packet/l2_packet_$(CONFIG_L2_PACKET).c
-
-ifeq ($(CONFIG_L2_PACKET), pcap)
-ifdef CONFIG_WINPCAP
-L_CFLAGS += -DCONFIG_WINPCAP
-LIBS += -lwpcap -lpacket
-LIBS_w += -lwpcap
-else
-LIBS += -ldnet -lpcap
-endif
-endif
-
-ifeq ($(CONFIG_L2_PACKET), winpcap)
-LIBS += -lwpcap -lpacket
-LIBS_w += -lwpcap
-endif
-
-ifeq ($(CONFIG_L2_PACKET), freebsd)
-LIBS += -lpcap
-endif
-
-ifdef CONFIG_ERP
-L_CFLAGS += -DCONFIG_ERP
-NEED_HMAC_SHA256_KDF=y
-endif
-
-ifdef CONFIG_EAP_TLS
-# EAP-TLS
-ifeq ($(CONFIG_EAP_TLS), dyn)
-L_CFLAGS += -DEAP_TLS_DYNAMIC
-EAPDYN += src/eap_peer/eap_tls.so
-else
-L_CFLAGS += -DEAP_TLS
-OBJS += src/eap_peer/eap_tls.c
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_UNAUTH_TLS
-# EAP-UNAUTH-TLS
-L_CFLAGS += -DEAP_UNAUTH_TLS
-ifndef CONFIG_EAP_TLS
-OBJS += src/eap_peer/eap_tls.c
-TLS_FUNCS=y
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_PEAP
-# EAP-PEAP
-ifeq ($(CONFIG_EAP_PEAP), dyn)
-L_CFLAGS += -DEAP_PEAP_DYNAMIC
-EAPDYN += src/eap_peer/eap_peap.so
-else
-L_CFLAGS += -DEAP_PEAP
-OBJS += src/eap_peer/eap_peap.c
-OBJS += src/eap_common/eap_peap_common.c
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_TTLS
-# EAP-TTLS
-ifeq ($(CONFIG_EAP_TTLS), dyn)
-L_CFLAGS += -DEAP_TTLS_DYNAMIC
-EAPDYN += src/eap_peer/eap_ttls.so
-else
-L_CFLAGS += -DEAP_TTLS
-OBJS += src/eap_peer/eap_ttls.c
-endif
-TLS_FUNCS=y
-ifndef CONFIG_FIPS
-MS_FUNCS=y
-CHAP=y
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_MD5
-# EAP-MD5
-ifeq ($(CONFIG_EAP_MD5), dyn)
-L_CFLAGS += -DEAP_MD5_DYNAMIC
-EAPDYN += src/eap_peer/eap_md5.so
-else
-L_CFLAGS += -DEAP_MD5
-OBJS += src/eap_peer/eap_md5.c
-endif
-CHAP=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-# backwards compatibility for old spelling
-ifdef CONFIG_MSCHAPV2
-ifndef CONFIG_EAP_MSCHAPV2
-CONFIG_EAP_MSCHAPV2=y
-endif
-endif
-
-ifdef CONFIG_EAP_MSCHAPV2
-# EAP-MSCHAPv2
-ifeq ($(CONFIG_EAP_MSCHAPV2), dyn)
-L_CFLAGS += -DEAP_MSCHAPv2_DYNAMIC
-EAPDYN += src/eap_peer/eap_mschapv2.so
-EAPDYN += src/eap_peer/mschapv2.so
-else
-L_CFLAGS += -DEAP_MSCHAPv2
-OBJS += src/eap_peer/eap_mschapv2.c
-OBJS += src/eap_peer/mschapv2.c
-endif
-MS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_GTC
-# EAP-GTC
-ifeq ($(CONFIG_EAP_GTC), dyn)
-L_CFLAGS += -DEAP_GTC_DYNAMIC
-EAPDYN += src/eap_peer/eap_gtc.so
-else
-L_CFLAGS += -DEAP_GTC
-OBJS += src/eap_peer/eap_gtc.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_OTP
-# EAP-OTP
-ifeq ($(CONFIG_EAP_OTP), dyn)
-L_CFLAGS += -DEAP_OTP_DYNAMIC
-EAPDYN += src/eap_peer/eap_otp.so
-else
-L_CFLAGS += -DEAP_OTP
-OBJS += src/eap_peer/eap_otp.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_SIM
-# EAP-SIM
-ifeq ($(CONFIG_EAP_SIM), dyn)
-L_CFLAGS += -DEAP_SIM_DYNAMIC
-EAPDYN += src/eap_peer/eap_sim.so
-else
-L_CFLAGS += -DEAP_SIM
-OBJS += src/eap_peer/eap_sim.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_SIM_COMMON=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_EAP_LEAP
-# EAP-LEAP
-ifeq ($(CONFIG_EAP_LEAP), dyn)
-L_CFLAGS += -DEAP_LEAP_DYNAMIC
-EAPDYN += src/eap_peer/eap_leap.so
-else
-L_CFLAGS += -DEAP_LEAP
-OBJS += src/eap_peer/eap_leap.c
-endif
-MS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_PSK
-# EAP-PSK
-ifeq ($(CONFIG_EAP_PSK), dyn)
-L_CFLAGS += -DEAP_PSK_DYNAMIC
-EAPDYN += src/eap_peer/eap_psk.so
-else
-L_CFLAGS += -DEAP_PSK
-OBJS += src/eap_peer/eap_psk.c src/eap_common/eap_psk_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_AES=y
-NEED_AES_ENCBLOCK=y
-NEED_AES_EAX=y
-endif
-
-ifdef CONFIG_EAP_AKA
-# EAP-AKA
-ifeq ($(CONFIG_EAP_AKA), dyn)
-L_CFLAGS += -DEAP_AKA_DYNAMIC
-EAPDYN += src/eap_peer/eap_aka.so
-else
-L_CFLAGS += -DEAP_AKA
-OBJS += src/eap_peer/eap_aka.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_SIM_COMMON=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_EAP_PROXY
-L_CFLAGS += -DCONFIG_EAP_PROXY
-OBJS += src/eap_peer/eap_proxy_$(CONFIG_EAP_PROXY).c
-include $(LOCAL_PATH)/eap_proxy_$(CONFIG_EAP_PROXY).mk
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_AKA_PRIME
-# EAP-AKA'
-ifeq ($(CONFIG_EAP_AKA_PRIME), dyn)
-L_CFLAGS += -DEAP_AKA_PRIME_DYNAMIC
-else
-L_CFLAGS += -DEAP_AKA_PRIME
-endif
-endif
-
-ifdef CONFIG_EAP_SIM_COMMON
-OBJS += src/eap_common/eap_sim_common.c
-NEED_AES=y
-NEED_FIPS186_2_PRF=y
-endif
-
-ifdef CONFIG_EAP_FAST
-# EAP-FAST
-ifeq ($(CONFIG_EAP_FAST), dyn)
-L_CFLAGS += -DEAP_FAST_DYNAMIC
-EAPDYN += src/eap_peer/eap_fast.so
-EAPDYN += src/eap_common/eap_fast_common.c
-else
-L_CFLAGS += -DEAP_FAST
-OBJS += src/eap_peer/eap_fast.c src/eap_peer/eap_fast_pac.c
-OBJS += src/eap_common/eap_fast_common.c
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-NEED_T_PRF=y
-endif
-
-ifdef CONFIG_EAP_TEAP
-# EAP-TEAP
-ifeq ($(CONFIG_EAP_TEAP), dyn)
-L_CFLAGS += -DEAP_YEAP_DYNAMIC
-EAPDYN += src/eap_peer/eap_teap.so
-EAPDYN += src/eap_common/eap_teap_common.c
-else
-L_CFLAGS += -DEAP_TEAP
-OBJS += src/eap_peer/eap_teap.c src/eap_peer/eap_teap_pac.c
-OBJS += src/eap_common/eap_teap_common.c
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-NEED_T_PRF=y
-NEED_SHA384=y
-NEED_TLS_PRF_SHA256=y
-NEED_TLS_PRF_SHA384=y
-endif
-
-ifdef CONFIG_EAP_PAX
-# EAP-PAX
-ifeq ($(CONFIG_EAP_PAX), dyn)
-L_CFLAGS += -DEAP_PAX_DYNAMIC
-EAPDYN += src/eap_peer/eap_pax.so
-else
-L_CFLAGS += -DEAP_PAX
-OBJS += src/eap_peer/eap_pax.c src/eap_common/eap_pax_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_SAKE
-# EAP-SAKE
-ifeq ($(CONFIG_EAP_SAKE), dyn)
-L_CFLAGS += -DEAP_SAKE_DYNAMIC
-EAPDYN += src/eap_peer/eap_sake.so
-else
-L_CFLAGS += -DEAP_SAKE
-OBJS += src/eap_peer/eap_sake.c src/eap_common/eap_sake_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_GPSK
-# EAP-GPSK
-ifeq ($(CONFIG_EAP_GPSK), dyn)
-L_CFLAGS += -DEAP_GPSK_DYNAMIC
-EAPDYN += src/eap_peer/eap_gpsk.so
-else
-L_CFLAGS += -DEAP_GPSK
-OBJS += src/eap_peer/eap_gpsk.c src/eap_common/eap_gpsk_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-ifdef CONFIG_EAP_GPSK_SHA256
-L_CFLAGS += -DEAP_GPSK_SHA256
-endif
-endif
-
-ifdef CONFIG_EAP_PWD
-L_CFLAGS += -DEAP_PWD
-OBJS += src/eap_peer/eap_pwd.c src/eap_common/eap_pwd_common.c
-CONFIG_IEEE8021X_EAPOL=y
-NEED_ECC=y
-NEED_DRAGONFLY=y
-endif
-
-ifdef CONFIG_EAP_EKE
-# EAP-EKE
-ifeq ($(CONFIG_EAP_EKE), dyn)
-L_CFLAGS += -DEAP_EKE_DYNAMIC
-EAPDYN += src/eap_peer/eap_eke.so
-else
-L_CFLAGS += -DEAP_EKE
-OBJS += src/eap_peer/eap_eke.c src/eap_common/eap_eke_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_DH_GROUPS_ALL=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_WPS
-# EAP-WSC
-L_CFLAGS += -DCONFIG_WPS -DEAP_WSC
-OBJS += wps_supplicant.c
-OBJS += src/utils/uuid.c
-OBJS += src/eap_peer/eap_wsc.c src/eap_common/eap_wsc_common.c
-OBJS += src/wps/wps.c
-OBJS += src/wps/wps_common.c
-OBJS += src/wps/wps_attr_parse.c
-OBJS += src/wps/wps_attr_build.c
-OBJS += src/wps/wps_attr_process.c
-OBJS += src/wps/wps_dev_attr.c
-OBJS += src/wps/wps_enrollee.c
-OBJS += src/wps/wps_registrar.c
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_BASE64=y
-NEED_AES_CBC=y
-NEED_MODEXP=y
-
-ifdef CONFIG_WPS_NFC
-L_CFLAGS += -DCONFIG_WPS_NFC
-OBJS += src/wps/ndef.c
-NEED_WPS_OOB=y
-endif
-
-ifdef NEED_WPS_OOB
-L_CFLAGS += -DCONFIG_WPS_OOB
-endif
-
-ifdef CONFIG_WPS_ER
-CONFIG_WPS_UPNP=y
-L_CFLAGS += -DCONFIG_WPS_ER
-OBJS += src/wps/wps_er.c
-OBJS += src/wps/wps_er_ssdp.c
-endif
-
-ifdef CONFIG_WPS_UPNP
-L_CFLAGS += -DCONFIG_WPS_UPNP
-OBJS += src/wps/wps_upnp.c
-OBJS += src/wps/wps_upnp_ssdp.c
-OBJS += src/wps/wps_upnp_web.c
-OBJS += src/wps/wps_upnp_event.c
-OBJS += src/wps/wps_upnp_ap.c
-OBJS += src/wps/upnp_xml.c
-OBJS += src/wps/httpread.c
-OBJS += src/wps/http_client.c
-OBJS += src/wps/http_server.c
-endif
-
-ifdef CONFIG_WPS_STRICT
-L_CFLAGS += -DCONFIG_WPS_STRICT
-OBJS += src/wps/wps_validate.c
-endif
-
-ifdef CONFIG_WPS_TESTING
-L_CFLAGS += -DCONFIG_WPS_TESTING
-endif
-
-ifdef CONFIG_WPS_REG_DISABLE_OPEN
-L_CFLAGS += -DCONFIG_WPS_REG_DISABLE_OPEN
-endif
-
-endif
-
-ifdef CONFIG_EAP_IKEV2
-# EAP-IKEv2
-ifeq ($(CONFIG_EAP_IKEV2), dyn)
-L_CFLAGS += -DEAP_IKEV2_DYNAMIC
-EAPDYN += src/eap_peer/eap_ikev2.so src/eap_peer/ikev2.c
-EAPDYN += src/eap_common/eap_ikev2_common.c src/eap_common/ikev2_common.c
-else
-L_CFLAGS += -DEAP_IKEV2
-OBJS += src/eap_peer/eap_ikev2.c src/eap_peer/ikev2.c
-OBJS += src/eap_common/eap_ikev2_common.c src/eap_common/ikev2_common.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_DH_GROUPS_ALL=y
-NEED_MODEXP=y
-NEED_CIPHER=y
-endif
-
-ifdef CONFIG_EAP_VENDOR_TEST
-ifeq ($(CONFIG_EAP_VENDOR_TEST), dyn)
-L_CFLAGS += -DEAP_VENDOR_TEST_DYNAMIC
-EAPDYN += src/eap_peer/eap_vendor_test.so
-else
-L_CFLAGS += -DEAP_VENDOR_TEST
-OBJS += src/eap_peer/eap_vendor_test.c
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_TNC
-# EAP-TNC
-L_CFLAGS += -DEAP_TNC
-OBJS += src/eap_peer/eap_tnc.c
-OBJS += src/eap_peer/tncc.c
-NEED_BASE64=y
-ifndef CONFIG_NATIVE_WINDOWS
-ifndef CONFIG_DRIVER_BSD
-LIBS += -ldl
-endif
-endif
-endif
-
-ifdef CONFIG_IEEE8021X_EAPOL
-# IEEE 802.1X/EAPOL state machines (e.g., for RADIUS authentication)
-L_CFLAGS += -DIEEE8021X_EAPOL
-OBJS += src/eapol_supp/eapol_supp_sm.c
-OBJS += src/eap_peer/eap.c src/eap_peer/eap_methods.c
-NEED_EAP_COMMON=y
-ifdef CONFIG_DYNAMIC_EAP_METHODS
-L_CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
-LIBS += -ldl -rdynamic
-endif
-endif
-
-ifdef CONFIG_AP
-NEED_EAP_COMMON=y
-NEED_RSN_AUTHENTICATOR=y
-L_CFLAGS += -DCONFIG_AP
-OBJS += ap.c
-L_CFLAGS += -DCONFIG_NO_RADIUS
-L_CFLAGS += -DCONFIG_NO_ACCOUNTING
-L_CFLAGS += -DCONFIG_NO_VLAN
-OBJS += src/ap/hostapd.c
-OBJS += src/ap/wpa_auth_glue.c
-OBJS += src/ap/utils.c
-OBJS += src/ap/authsrv.c
-OBJS += src/ap/ap_config.c
-OBJS += src/ap/sta_info.c
-OBJS += src/ap/tkip_countermeasures.c
-OBJS += src/ap/ap_mlme.c
-OBJS += src/ap/ieee802_1x.c
-OBJS += src/eapol_auth/eapol_auth_sm.c
-OBJS += src/ap/ieee802_11_auth.c
-OBJS += src/ap/ieee802_11_shared.c
-OBJS += src/ap/drv_callbacks.c
-OBJS += src/ap/ap_drv_ops.c
-OBJS += src/ap/beacon.c
-OBJS += src/ap/bss_load.c
-OBJS += src/ap/eap_user_db.c
-OBJS += src/ap/neighbor_db.c
-OBJS += src/ap/rrm.c
-OBJS += src/ap/ieee802_11_ht.c
-ifdef CONFIG_IEEE80211AC
-OBJS += src/ap/ieee802_11_vht.c
-endif
-ifdef CONFIG_IEEE80211AX
-OBJS += src/ap/ieee802_11_he.c
-endif
-ifdef CONFIG_WNM_AP
-L_CFLAGS += -DCONFIG_WNM_AP
-OBJS += src/ap/wnm_ap.c
-endif
-ifdef CONFIG_MBO
-OBJS += src/ap/mbo_ap.c
-endif
-ifdef CONFIG_FILS
-OBJS += src/ap/fils_hlp.c
-endif
-ifdef CONFIG_CTRL_IFACE
-OBJS += src/ap/ctrl_iface_ap.c
-endif
-
-L_CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
-OBJS += src/eap_server/eap_server.c
-OBJS += src/eap_server/eap_server_identity.c
-OBJS += src/eap_server/eap_server_methods.c
-
-ifdef CONFIG_IEEE80211AC
-L_CFLAGS += -DCONFIG_IEEE80211AC
-endif
-ifdef CONFIG_IEEE80211AX
-L_CFLAGS += -DCONFIG_IEEE80211AX
-endif
-
-ifdef NEED_AP_MLME
-OBJS += src/ap/wmm.c
-OBJS += src/ap/ap_list.c
-OBJS += src/ap/ieee802_11.c
-OBJS += src/ap/hw_features.c
-OBJS += src/ap/dfs.c
-L_CFLAGS += -DNEED_AP_MLME
-endif
-ifdef CONFIG_WPS
-L_CFLAGS += -DEAP_SERVER_WSC
-OBJS += src/ap/wps_hostapd.c
-OBJS += src/eap_server/eap_server_wsc.c
-endif
-ifdef CONFIG_DPP
-OBJS += src/ap/dpp_hostapd.c
-OBJS += src/ap/gas_query_ap.c
-NEED_AP_GAS_SERV=y
-endif
-ifdef CONFIG_INTERWORKING
-NEED_AP_GAS_SERV=y
-endif
-ifdef NEED_AP_GAS_SERV
-OBJS += src/ap/gas_serv.c
-endif
-ifdef CONFIG_HS20
-OBJS += src/ap/hs20.c
-endif
-endif
-
-ifdef CONFIG_MBO
-OBJS += mbo.c
-L_CFLAGS += -DCONFIG_MBO
-endif
-
-ifdef CONFIG_TESTING_OPTIONS
-L_CFLAGS += -DCONFIG_TESTING_OPTIONS
-endif
-
-ifdef NEED_RSN_AUTHENTICATOR
-L_CFLAGS += -DCONFIG_NO_RADIUS
-NEED_AES_WRAP=y
-OBJS += src/ap/wpa_auth.c
-OBJS += src/ap/wpa_auth_ie.c
-OBJS += src/ap/pmksa_cache_auth.c
-endif
-
-ifdef CONFIG_ACS
-L_CFLAGS += -DCONFIG_ACS
-OBJS += src/ap/acs.c
-LIBS += -lm
-endif
-
-ifdef CONFIG_PCSC
-# PC/SC interface for smartcards (USIM, GSM SIM)
-L_CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
-OBJS += src/utils/pcsc_funcs.c
-# -lpthread may not be needed depending on how pcsc-lite was configured
-ifdef CONFIG_NATIVE_WINDOWS
-#Once MinGW gets support for WinScard, -lwinscard could be used instead of the
-#dynamic symbol loading that is now used in pcsc_funcs.c
-#LIBS += -lwinscard
-else
-LIBS += -lpcsclite -lpthread
-endif
-endif
-
-ifdef CONFIG_SIM_SIMULATOR
-L_CFLAGS += -DCONFIG_SIM_SIMULATOR
-NEED_MILENAGE=y
-endif
-
-ifdef CONFIG_USIM_SIMULATOR
-L_CFLAGS += -DCONFIG_USIM_SIMULATOR
-NEED_MILENAGE=y
-endif
-
-ifdef NEED_MILENAGE
-OBJS += src/crypto/milenage.c
-NEED_AES_ENCBLOCK=y
-endif
-
-ifdef CONFIG_PKCS12
-L_CFLAGS += -DPKCS12_FUNCS
-endif
-
-ifdef CONFIG_SMARTCARD
-L_CFLAGS += -DCONFIG_SMARTCARD
-endif
-
-ifdef NEED_DRAGONFLY
-OBJS += src/common/dragonfly.c
-endif
-
-ifdef MS_FUNCS
-OBJS += src/crypto/ms_funcs.c
-NEED_DES=y
-NEED_MD4=y
-endif
-
-ifdef CHAP
-OBJS += src/eap_common/chap.c
-endif
-
-ifdef TLS_FUNCS
-NEED_DES=y
-# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, EAP_TTLS, and EAP_FAST)
-OBJS += src/eap_peer/eap_tls_common.c
-ifndef CONFIG_FIPS
-NEED_TLS_PRF=y
-NEED_SHA1=y
-NEED_MD5=y
-endif
-endif
-
-ifndef CONFIG_TLS
-CONFIG_TLS=openssl
-endif
-
-ifdef CONFIG_TLSV11
-L_CFLAGS += -DCONFIG_TLSV11
-endif
-
-ifdef CONFIG_TLSV12
-L_CFLAGS += -DCONFIG_TLSV12
-endif
-
-ifeq ($(CONFIG_TLS), openssl)
-ifdef TLS_FUNCS
-L_CFLAGS += -DEAP_TLS_OPENSSL
-OBJS += src/crypto/tls_openssl.c
-OBJS += src/crypto/tls_openssl_ocsp.c
-LIBS += -lssl
-endif
-OBJS += src/crypto/crypto_openssl.c
-OBJS_p += src/crypto/crypto_openssl.c
-ifdef NEED_FIPS186_2_PRF
-OBJS += src/crypto/fips_prf_openssl.c
-endif
-NEED_TLS_PRF_SHA256=y
-LIBS += -lcrypto
-LIBS_p += -lcrypto
-ifdef CONFIG_TLS_ADD_DL
-LIBS += -ldl
-LIBS_p += -ldl
-endif
-ifndef CONFIG_TLS_DEFAULT_CIPHERS
-CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW"
-endif
-L_CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\"
-endif
-
-ifeq ($(CONFIG_TLS), gnutls)
-ifndef CONFIG_CRYPTO
-# default to libgcrypt
-CONFIG_CRYPTO=gnutls
-endif
-ifdef TLS_FUNCS
-OBJS += src/crypto/tls_gnutls.c
-LIBS += -lgnutls -lgpg-error
-endif
-OBJS += src/crypto/crypto_$(CONFIG_CRYPTO).c
-OBJS_p += src/crypto/crypto_$(CONFIG_CRYPTO).c
-ifdef NEED_FIPS186_2_PRF
-OBJS += src/crypto/fips_prf_internal.c
-OBJS += src/crypto/sha1-internal.c
-endif
-ifeq ($(CONFIG_CRYPTO), gnutls)
-LIBS += -lgcrypt
-LIBS_p += -lgcrypt
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), nettle)
-LIBS += -lnettle -lgmp
-LIBS_p += -lnettle -lgmp
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-endif
-
-ifeq ($(CONFIG_TLS), internal)
-ifndef CONFIG_CRYPTO
-CONFIG_CRYPTO=internal
-endif
-ifdef TLS_FUNCS
-OBJS += src/crypto/crypto_internal-rsa.c
-OBJS += src/crypto/tls_internal.c
-OBJS += src/tls/tlsv1_common.c
-OBJS += src/tls/tlsv1_record.c
-OBJS += src/tls/tlsv1_cred.c
-OBJS += src/tls/tlsv1_client.c
-OBJS += src/tls/tlsv1_client_write.c
-OBJS += src/tls/tlsv1_client_read.c
-OBJS += src/tls/tlsv1_client_ocsp.c
-NEED_ASN1=y
-OBJS += src/tls/rsa.c
-OBJS += src/tls/x509v3.c
-OBJS += src/tls/pkcs1.c
-OBJS += src/tls/pkcs5.c
-OBJS += src/tls/pkcs8.c
-NEED_BASE64=y
-NEED_TLS_PRF=y
-ifdef CONFIG_TLSV12
-NEED_TLS_PRF_SHA256=y
-endif
-NEED_MODEXP=y
-NEED_CIPHER=y
-L_CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
-endif
-ifdef NEED_CIPHER
-NEED_DES=y
-OBJS += src/crypto/crypto_internal-cipher.c
-endif
-ifdef NEED_MODEXP
-OBJS += src/crypto/crypto_internal-modexp.c
-OBJS += src/tls/bignum.c
-endif
-ifeq ($(CONFIG_CRYPTO), libtomcrypt)
-OBJS += src/crypto/crypto_libtomcrypt.c
-OBJS_p += src/crypto/crypto_libtomcrypt.c
-LIBS += -ltomcrypt -ltfm
-LIBS_p += -ltomcrypt -ltfm
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), internal)
-OBJS += src/crypto/crypto_internal.c
-OBJS_p += src/crypto/crypto_internal.c
-NEED_AES_ENC=y
-L_CFLAGS += -DCONFIG_CRYPTO_INTERNAL
-ifdef CONFIG_INTERNAL_LIBTOMMATH
-L_CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
-ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
-L_CFLAGS += -DLTM_FAST
-endif
-else
-LIBS += -ltommath
-LIBS_p += -ltommath
-endif
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_DES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_MD5=y
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_SHA384=y
-CONFIG_INTERNAL_SHA512=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), cryptoapi)
-OBJS += src/crypto/crypto_cryptoapi.c
-OBJS_p += src/crypto/crypto_cryptoapi.c
-L_CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-endif
-endif
-
-ifeq ($(CONFIG_TLS), none)
-ifdef TLS_FUNCS
-OBJS += src/crypto/tls_none.c
-L_CFLAGS += -DEAP_TLS_NONE
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD5=y
-endif
-OBJS += src/crypto/crypto_none.c
-OBJS_p += src/crypto/crypto_none.c
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-endif
-
-ifdef TLS_FUNCS
-ifdef CONFIG_SMARTCARD
-ifndef CONFIG_NATIVE_WINDOWS
-ifneq ($(CONFIG_L2_PACKET), freebsd)
-LIBS += -ldl
-endif
-endif
-endif
-endif
-
-ifndef TLS_FUNCS
-OBJS += src/crypto/tls_none.c
-ifeq ($(CONFIG_TLS), internal)
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD5=y
-CONFIG_INTERNAL_RC4=y
-endif
-endif
-
-AESOBJS = # none so far (see below)
-ifdef CONFIG_INTERNAL_AES
-AESOBJS += src/crypto/aes-internal.c src/crypto/aes-internal-dec.c
-endif
-
-ifneq ($(CONFIG_TLS), openssl)
-NEED_INTERNAL_AES_WRAP=y
-endif
-ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP
-# Seems to be needed at least with BoringSSL
-NEED_INTERNAL_AES_WRAP=y
-L_CFLAGS += -DCONFIG_OPENSSL_INTERNAL_AES_WRAP
-endif
-ifdef CONFIG_FIPS
-# Have to use internal AES key wrap routines to use OpenSSL EVP since the
-# OpenSSL AES_wrap_key()/AES_unwrap_key() API is not available in FIPS mode.
-NEED_INTERNAL_AES_WRAP=y
-endif
-
-ifdef NEED_INTERNAL_AES_WRAP
-AESOBJS += src/crypto/aes-unwrap.c
-endif
-ifdef NEED_AES_EAX
-AESOBJS += src/crypto/aes-eax.c
-NEED_AES_CTR=y
-endif
-ifdef NEED_AES_SIV
-AESOBJS += src/crypto/aes-siv.c
-NEED_AES_CTR=y
-endif
-ifdef NEED_AES_CTR
-AESOBJS += src/crypto/aes-ctr.c
-endif
-ifdef NEED_AES_ENCBLOCK
-AESOBJS += src/crypto/aes-encblock.c
-endif
-NEED_AES_ENC=y
-ifdef CONFIG_OPENSSL_CMAC
-L_CFLAGS += -DCONFIG_OPENSSL_CMAC
-else
-AESOBJS += src/crypto/aes-omac1.c
-endif
-ifdef NEED_AES_WRAP
-NEED_AES_ENC=y
-ifdef NEED_INTERNAL_AES_WRAP
-AESOBJS += src/crypto/aes-wrap.c
-endif
-endif
-ifdef NEED_AES_CBC
-NEED_AES_ENC=y
-ifneq ($(CONFIG_TLS), openssl)
-AESOBJS += src/crypto/aes-cbc.c
-endif
-endif
-ifdef NEED_AES_ENC
-ifdef CONFIG_INTERNAL_AES
-AESOBJS += src/crypto/aes-internal-enc.c
-endif
-endif
-ifdef NEED_AES
-OBJS += $(AESOBJS)
-endif
-
-SHA1OBJS =
-ifdef NEED_SHA1
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), gnutls)
-SHA1OBJS += src/crypto/sha1.c
-endif
-endif
-SHA1OBJS += src/crypto/sha1-prf.c
-ifdef CONFIG_INTERNAL_SHA1
-SHA1OBJS += src/crypto/sha1-internal.c
-ifdef NEED_FIPS186_2_PRF
-SHA1OBJS += src/crypto/fips_prf_internal.c
-endif
-endif
-ifdef CONFIG_NO_WPA_PASSPHRASE
-L_CFLAGS += -DCONFIG_NO_PBKDF2
-else
-ifneq ($(CONFIG_TLS), openssl)
-SHA1OBJS += src/crypto/sha1-pbkdf2.c
-endif
-endif
-ifdef NEED_T_PRF
-SHA1OBJS += src/crypto/sha1-tprf.c
-endif
-ifdef NEED_TLS_PRF
-SHA1OBJS += src/crypto/sha1-tlsprf.c
-endif
-endif
-
-MD5OBJS =
-ifndef CONFIG_FIPS
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), gnutls)
-MD5OBJS += src/crypto/md5.c
-endif
-endif
-endif
-ifdef NEED_MD5
-ifdef CONFIG_INTERNAL_MD5
-MD5OBJS += src/crypto/md5-internal.c
-endif
-OBJS += $(MD5OBJS)
-OBJS_p += $(MD5OBJS)
-endif
-
-ifdef NEED_MD4
-ifdef CONFIG_INTERNAL_MD4
-OBJS += src/crypto/md4-internal.c
-endif
-endif
-
-DESOBJS = # none needed when not internal
-ifdef NEED_DES
-ifdef CONFIG_INTERNAL_DES
-DESOBJS += src/crypto/des-internal.c
-endif
-endif
-
-ifdef CONFIG_NO_RC4
-L_CFLAGS += -DCONFIG_NO_RC4
-endif
-
-ifdef NEED_RC4
-ifdef CONFIG_INTERNAL_RC4
-ifndef CONFIG_NO_RC4
-OBJS += src/crypto/rc4.c
-endif
-endif
-endif
-
-SHA256OBJS = # none by default
-L_CFLAGS += -DCONFIG_SHA256
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), gnutls)
-SHA256OBJS += src/crypto/sha256.c
-endif
-endif
-SHA256OBJS += src/crypto/sha256-prf.c
-ifdef CONFIG_INTERNAL_SHA256
-SHA256OBJS += src/crypto/sha256-internal.c
-endif
-ifdef CONFIG_INTERNAL_SHA384
-L_CFLAGS += -DCONFIG_INTERNAL_SHA384
-SHA256OBJS += src/crypto/sha384-internal.c
-endif
-ifdef CONFIG_INTERNAL_SHA512
-L_CFLAGS += -DCONFIG_INTERNAL_SHA512
-SHA256OBJS += src/crypto/sha512-internal.c
-endif
-ifdef NEED_TLS_PRF_SHA256
-SHA256OBJS += src/crypto/sha256-tlsprf.c
-endif
-ifdef NEED_TLS_PRF_SHA384
-SHA256OBJS += src/crypto/sha384-tlsprf.c
-endif
-ifdef NEED_HMAC_SHA256_KDF
-L_CFLAGS += -DCONFIG_HMAC_SHA256_KDF
-SHA256OBJS += src/crypto/sha256-kdf.c
-endif
-ifdef NEED_HMAC_SHA384_KDF
-L_CFLAGS += -DCONFIG_HMAC_SHA384_KDF
-SHA256OBJS += src/crypto/sha384-kdf.c
-endif
-ifdef NEED_HMAC_SHA512_KDF
-L_CFLAGS += -DCONFIG_HMAC_SHA512_KDF
-SHA256OBJS += src/crypto/sha512-kdf.c
-endif
-OBJS += $(SHA256OBJS)
-ifdef NEED_SHA384
-L_CFLAGS += -DCONFIG_SHA384
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), gnutls)
-OBJS += src/crypto/sha384.c
-endif
-endif
-OBJS += src/crypto/sha384-prf.c
-endif
-ifdef NEED_SHA512
-L_CFLAGS += -DCONFIG_SHA512
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), gnutls)
-OBJS += src/crypto/sha512.c
-endif
-endif
-OBJS += src/crypto/sha512-prf.c
-endif
-
-ifdef NEED_ASN1
-OBJS += src/tls/asn1.c
-endif
-
-ifdef NEED_DH_GROUPS
-OBJS += src/crypto/dh_groups.c
-endif
-ifdef NEED_DH_GROUPS_ALL
-L_CFLAGS += -DALL_DH_GROUPS
-endif
-ifdef CONFIG_INTERNAL_DH_GROUP5
-ifdef NEED_DH_GROUPS
-OBJS += src/crypto/dh_group5.c
-endif
-endif
-
-ifdef NEED_ECC
-L_CFLAGS += -DCONFIG_ECC
-endif
-
-ifdef CONFIG_NO_RANDOM_POOL
-L_CFLAGS += -DCONFIG_NO_RANDOM_POOL
-else
-OBJS += src/crypto/random.c
-endif
-
-ifdef CONFIG_CTRL_IFACE
-ifeq ($(CONFIG_CTRL_IFACE), y)
-ifdef CONFIG_NATIVE_WINDOWS
-CONFIG_CTRL_IFACE=named_pipe
-else
-CONFIG_CTRL_IFACE=unix
-endif
-endif
-L_CFLAGS += -DCONFIG_CTRL_IFACE
-ifeq ($(CONFIG_CTRL_IFACE), unix)
-L_CFLAGS += -DCONFIG_CTRL_IFACE_UNIX
-OBJS += src/common/ctrl_iface_common.c
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp)
-L_CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-endif
-ifeq ($(CONFIG_CTRL_IFACE), named_pipe)
-L_CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp-remote)
-CONFIG_CTRL_IFACE=udp
-L_CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-L_CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
-endif
-OBJS += ctrl_iface.c ctrl_iface_$(CONFIG_CTRL_IFACE).c
-endif
-
-ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-OBJS += dbus/dbus_dict_helpers.c
-OBJS += dbus/dbus_new_helpers.c
-OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
-OBJS += dbus/dbus_common.c
-ifdef CONFIG_WPS
-OBJS += dbus/dbus_new_handlers_wps.c
-endif
-ifdef CONFIG_P2P
-OBJS += dbus/dbus_new_handlers_p2p.c
-endif
-ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-OBJS += dbus/dbus_new_introspect.c
-L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
-endif
-L_CFLAGS += $(DBUS_INCLUDE)
-endif
-
-ifdef CONFIG_CTRL_IFACE_BINDER
-WPA_SUPPLICANT_USE_BINDER=y
-L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
-endif
-
-ifdef CONFIG_READLINE
-OBJS_c += src/utils/edit_readline.c
-LIBS_c += -lncurses -lreadline
-else
-ifdef CONFIG_WPA_CLI_EDIT
-OBJS_c += src/utils/edit.c
-else
-OBJS_c += src/utils/edit_simple.c
-endif
-endif
-
-ifdef CONFIG_NATIVE_WINDOWS
-L_CFLAGS += -DCONFIG_NATIVE_WINDOWS
-LIBS += -lws2_32 -lgdi32 -lcrypt32
-LIBS_c += -lws2_32
-LIBS_p += -lws2_32 -lgdi32
-ifeq ($(CONFIG_CRYPTO), cryptoapi)
-LIBS_p += -lcrypt32
-endif
-endif
-
-ifdef CONFIG_NO_STDOUT_DEBUG
-L_CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
-ifndef CONFIG_CTRL_IFACE
-L_CFLAGS += -DCONFIG_NO_WPA_MSG
-endif
-endif
-
-ifdef CONFIG_ANDROID_LOG
-L_CFLAGS += -DCONFIG_ANDROID_LOG
-endif
-
-ifdef CONFIG_IPV6
-# for eapol_test only
-L_CFLAGS += -DCONFIG_IPV6
-endif
-
-ifdef NEED_BASE64
-OBJS += src/utils/base64.c
-endif
-
-ifdef NEED_SME
-OBJS += sme.c
-L_CFLAGS += -DCONFIG_SME
-endif
-
-OBJS += src/common/ieee802_11_common.c
-OBJS += src/common/hw_features_common.c
-
-ifdef NEED_EAP_COMMON
-OBJS += src/eap_common/eap_common.c
-endif
-
-ifndef CONFIG_MAIN
-CONFIG_MAIN=main
-endif
-
-ifdef CONFIG_DEBUG_SYSLOG
-L_CFLAGS += -DCONFIG_DEBUG_SYSLOG
-ifdef CONFIG_DEBUG_SYSLOG_FACILITY
-L_CFLAGS += -DLOG_HOSTAPD="$(CONFIG_DEBUG_SYSLOG_FACILITY)"
-endif
-endif
-
-ifdef CONFIG_DEBUG_LINUX_TRACING
-L_CFLAGS += -DCONFIG_DEBUG_LINUX_TRACING
-endif
-
-ifdef CONFIG_DEBUG_FILE
-L_CFLAGS += -DCONFIG_DEBUG_FILE
-endif
-
-ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
-L_CFLAGS += -DCONFIG_DELAYED_MIC_ERROR_REPORT
-endif
-
-ifdef CONFIG_FIPS
-L_CFLAGS += -DCONFIG_FIPS
-endif
-
-OBJS += $(SHA1OBJS) $(DESOBJS)
-
-OBJS_p += $(SHA1OBJS)
-OBJS_p += $(SHA256OBJS)
-
-ifdef CONFIG_BGSCAN_SIMPLE
-L_CFLAGS += -DCONFIG_BGSCAN_SIMPLE
-OBJS += bgscan_simple.c
-NEED_BGSCAN=y
-endif
-
-ifdef CONFIG_BGSCAN_LEARN
-L_CFLAGS += -DCONFIG_BGSCAN_LEARN
-OBJS += bgscan_learn.c
-NEED_BGSCAN=y
-endif
-
-ifdef NEED_BGSCAN
-L_CFLAGS += -DCONFIG_BGSCAN
-OBJS += bgscan.c
-endif
-
-ifdef CONFIG_AUTOSCAN_EXPONENTIAL
-L_CFLAGS += -DCONFIG_AUTOSCAN_EXPONENTIAL
-OBJS += autoscan_exponential.c
-NEED_AUTOSCAN=y
-endif
-
-ifdef CONFIG_AUTOSCAN_PERIODIC
-L_CFLAGS += -DCONFIG_AUTOSCAN_PERIODIC
-OBJS += autoscan_periodic.c
-NEED_AUTOSCAN=y
-endif
-
-ifdef NEED_AUTOSCAN
-L_CFLAGS += -DCONFIG_AUTOSCAN
-OBJS += autoscan.c
-endif
-
-ifdef CONFIG_EXT_PASSWORD_TEST
-OBJS += src/utils/ext_password_test.c
-L_CFLAGS += -DCONFIG_EXT_PASSWORD_TEST
-NEED_EXT_PASSWORD=y
-endif
-
-ifdef CONFIG_EXT_PASSWORD_FILE
-OBJS += src/utils/ext_password_file.c
-L_CFLAGS += -DCONFIG_EXT_PASSWORD_FILE
-NEED_EXT_PASSWORD=y
-endif
-
-ifdef NEED_EXT_PASSWORD
-OBJS += src/utils/ext_password.c
-L_CFLAGS += -DCONFIG_EXT_PASSWORD
-endif
-
-ifdef NEED_GAS_SERVER
-OBJS += src/common/gas_server.c
-L_CFLAGS += -DCONFIG_GAS_SERVER
-NEED_GAS=y
-endif
-
-ifdef NEED_GAS
-OBJS += src/common/gas.c
-OBJS += gas_query.c
-L_CFLAGS += -DCONFIG_GAS
-NEED_OFFCHANNEL=y
-endif
-
-ifdef NEED_OFFCHANNEL
-OBJS += offchannel.c
-L_CFLAGS += -DCONFIG_OFFCHANNEL
-endif
-
-ifdef NEED_JSON
-OBJS += src/utils/json.c
-L_CFLAGS += -DCONFIG_JSON
-endif
-
-OBJS += src/drivers/driver_common.c
-
-OBJS += wpa_supplicant.c events.c bssid_ignore.c wpas_glue.c scan.c
-OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.c
-OBJS_t += src/radius/radius_client.c
-OBJS_t += src/radius/radius.c
-OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.c
-OBJS += $(CONFIG_MAIN).c
-
-ifdef CONFIG_PRIVSEP
-OBJS_priv += $(OBJS_d) src/drivers/drivers.c
-OBJS_priv += $(OBJS_l2)
-OBJS_priv += src/utils/os_$(CONFIG_OS).c
-OBJS_priv += src/utils/$(CONFIG_ELOOP).c
-OBJS_priv += src/utils/common.c
-OBJS_priv += src/utils/wpa_debug.c
-OBJS_priv += src/utils/wpabuf.c
-OBJS_priv += wpa_priv.c
-ifdef CONFIG_DRIVER_NL80211
-OBJS_priv += src/common/ieee802_11_common.c
-endif
-OBJS += src/l2_packet/l2_packet_privsep.c
-OBJS += src/drivers/driver_privsep.c
-EXTRA_progs += wpa_priv
-else
-OBJS += $(OBJS_d) src/drivers/drivers.c
-OBJS += $(OBJS_l2)
-endif
-
-ifdef CONFIG_NDIS_EVENTS_INTEGRATED
-L_CFLAGS += -DCONFIG_NDIS_EVENTS_INTEGRATED
-OBJS += src/drivers/ndis_events.c
-EXTRALIBS += -loleaut32 -lole32 -luuid
-ifdef PLATFORMSDKLIB
-EXTRALIBS += $(PLATFORMSDKLIB)/WbemUuid.Lib
-else
-EXTRALIBS += WbemUuid.Lib
-endif
-endif
-
-ifndef LDO
-LDO=$(CC)
-endif
-
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := wpa_cli
-LOCAL_MODULE_TAGS := debug
-LOCAL_SHARED_LIBRARIES := libc libcutils liblog
-LOCAL_CFLAGS := $(L_CFLAGS)
-LOCAL_SRC_FILES := $(OBJS_c)
-LOCAL_C_INCLUDES := $(INCLUDES)
-include $(BUILD_EXECUTABLE)
-
-########################
-include $(CLEAR_VARS)
-LOCAL_MODULE := wpa_supplicant
-ifdef CONFIG_DRIVER_CUSTOM
-LOCAL_STATIC_LIBRARIES := libCustomWifi
-endif
-ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
-LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
-endif
-LOCAL_SHARED_LIBRARIES := libc libcutils liblog
-ifdef CONFIG_EAP_PROXY
-LOCAL_STATIC_LIBRARIES += $(LIB_STATIC_EAP_PROXY)
-LOCAL_SHARED_LIBRARIES += $(LIB_SHARED_EAP_PROXY)
-endif
-ifeq ($(CONFIG_TLS), openssl)
-LOCAL_SHARED_LIBRARIES += libcrypto libssl libkeystore_binder
-endif
-
-# With BoringSSL we need libkeystore-engine in order to provide access to
-# keystore keys.
-LOCAL_SHARED_LIBRARIES += libkeystore-engine
-
-ifdef CONFIG_DRIVER_NL80211
-ifneq ($(wildcard external/libnl),)
-LOCAL_SHARED_LIBRARIES += libnl
-else
-LOCAL_STATIC_LIBRARIES += libnl_2
-endif
-endif
-LOCAL_CFLAGS := $(L_CFLAGS)
-LOCAL_SRC_FILES := $(OBJS)
-LOCAL_C_INCLUDES := $(INCLUDES)
-ifeq ($(DBUS), y)
-LOCAL_SHARED_LIBRARIES += libdbus
-endif
-ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
-LOCAL_SHARED_LIBRARIES += libbinder libutils
-LOCAL_STATIC_LIBRARIES += libwpa_binder libwpa_binder_interface
-endif
-include $(BUILD_EXECUTABLE)
-
-########################
-#
-#include $(CLEAR_VARS)
-#LOCAL_MODULE := eapol_test
-#ifdef CONFIG_DRIVER_CUSTOM
-#LOCAL_STATIC_LIBRARIES := libCustomWifi
-#endif
-#LOCAL_SHARED_LIBRARIES := libc libcrypto libssl
-#LOCAL_CFLAGS := $(L_CFLAGS)
-#LOCAL_SRC_FILES := $(OBJS_t)
-#LOCAL_C_INCLUDES := $(INCLUDES)
-#include $(BUILD_EXECUTABLE)
-#
-########################
-#
-#local_target_dir := $(TARGET_OUT)/etc/wifi
-#
-#include $(CLEAR_VARS)
-#LOCAL_MODULE := wpa_supplicant.conf
-#LOCAL_MODULE_CLASS := ETC
-#LOCAL_MODULE_PATH := $(local_target_dir)
-#LOCAL_SRC_FILES := $(LOCAL_MODULE)
-#include $(BUILD_PREBUILT)
-#
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE = libwpa_client
-LOCAL_CFLAGS = $(L_CFLAGS)
-LOCAL_SRC_FILES = src/common/wpa_ctrl.c src/utils/os_$(CONFIG_OS).c
-LOCAL_C_INCLUDES = $(INCLUDES)
-LOCAL_SHARED_LIBRARIES := libcutils liblog
-LOCAL_COPY_HEADERS_TO := libwpa_client
-LOCAL_COPY_HEADERS := src/common/wpa_ctrl.h
-LOCAL_COPY_HEADERS += src/common/qca-vendor.h
-include $(BUILD_SHARED_LIBRARY)
-
-ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
-### Binder interface library ###
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libwpa_binder_interface
-LOCAL_AIDL_INCLUDES := \
- $(LOCAL_PATH)/binder \
- frameworks/native/aidl/binder
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
- $(LOCAL_PATH)/binder
-LOCAL_CPPFLAGS := $(L_CPPFLAGS)
-LOCAL_SRC_FILES := \
- binder/binder_constants.cpp \
- binder/fi/w1/wpa_supplicant/ISupplicant.aidl \
- binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl \
- binder/fi/w1/wpa_supplicant/IIface.aidl
-LOCAL_SHARED_LIBRARIES := libbinder
-include $(BUILD_STATIC_LIBRARY)
-
-### Binder service library ###
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libwpa_binder
-LOCAL_CPPFLAGS := $(L_CPPFLAGS)
-LOCAL_CFLAGS := $(L_CFLAGS)
-LOCAL_C_INCLUDES := $(INCLUDES)
-LOCAL_SRC_FILES := \
- binder/binder.cpp binder/binder_manager.cpp \
- binder/supplicant.cpp binder/iface.cpp
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libutils
-LOCAL_STATIC_LIBRARIES := libwpa_binder_interface
-include $(BUILD_STATIC_LIBRARY)
-
-endif # BINDER == y
diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog
deleted file mode 100644
index 5ca82457ad1b..000000000000
--- a/wpa_supplicant/ChangeLog
+++ /dev/null
@@ -1,2447 +0,0 @@
-ChangeLog for wpa_supplicant
-
-2019-08-07 - v2.9
- * SAE changes
- - disable use of groups using Brainpool curves
- - improved protection against side channel attacks
- [https://w1.fi/security/2019-6/]
- * EAP-pwd changes
- - disable use of groups using Brainpool curves
- - allow the set of groups to be configured (eap_pwd_groups)
- - improved protection against side channel attacks
- [https://w1.fi/security/2019-6/]
- * fixed FT-EAP initial mobility domain association using PMKSA caching
- (disabled by default for backwards compatibility; can be enabled
- with ft_eap_pmksa_caching=1)
- * fixed a regression in OpenSSL 1.1+ engine loading
- * added validation of RSNE in (Re)Association Response frames
- * fixed DPP bootstrapping URI parser of channel list
- * extended EAP-SIM/AKA fast re-authentication to allow use with FILS
- * extended ca_cert_blob to support PEM format
- * improved robustness of P2P Action frame scheduling
- * added support for EAP-SIM/AKA using anonymous@realm identity
- * fixed Hotspot 2.0 credential selection based on roaming consortium
- to ignore credentials without a specific EAP method
- * added experimental support for EAP-TEAP peer (RFC 7170)
- * added experimental support for EAP-TLS peer with TLS v1.3
- * fixed a regression in WMM parameter configuration for a TDLS peer
- * fixed a regression in operation with drivers that offload 802.1X
- 4-way handshake
- * fixed an ECDH operation corner case with OpenSSL
-
-2019-04-21 - v2.8
- * SAE changes
- - added support for SAE Password Identifier
- - changed default configuration to enable only groups 19, 20, 21
- (i.e., disable groups 25 and 26) and disable all unsuitable groups
- completely based on REVmd changes
- - do not regenerate PWE unnecessarily when the AP uses the
- anti-clogging token mechanisms
- - fixed some association cases where both SAE and FT-SAE were enabled
- on both the station and the selected AP
- - started to prefer FT-SAE over SAE AKM if both are enabled
- - started to prefer FT-SAE over FT-PSK if both are enabled
- - fixed FT-SAE when SAE PMKSA caching is used
- - reject use of unsuitable groups based on new implementation guidance
- in REVmd (allow only FFC groups with prime >= 3072 bits and ECC
- groups with prime >= 256)
- - minimize timing and memory use differences in PWE derivation
- [https://w1.fi/security/2019-1/] (CVE-2019-9494)
- * EAP-pwd changes
- - minimize timing and memory use differences in PWE derivation
- [https://w1.fi/security/2019-2/] (CVE-2019-9495)
- - verify server scalar/element
- [https://w1.fi/security/2019-4/] (CVE-2019-9499)
- - fix message reassembly issue with unexpected fragment
- [https://w1.fi/security/2019-5/]
- - enforce rand,mask generation rules more strictly
- - fix a memory leak in PWE derivation
- - disallow ECC groups with a prime under 256 bits (groups 25, 26, and
- 27)
- * fixed CONFIG_IEEE80211R=y (FT) build without CONFIG_FILS=y
- * Hotspot 2.0 changes
- - do not indicate release number that is higher than the one
- AP supports
- - added support for release number 3
- - enable PMF automatically for network profiles created from
- credentials
- * fixed OWE network profile saving
- * fixed DPP network profile saving
- * added support for RSN operating channel validation
- (CONFIG_OCV=y and network profile parameter ocv=1)
- * added Multi-AP backhaul STA support
- * fixed build with LibreSSL
- * number of MKA/MACsec fixes and extensions
- * extended domain_match and domain_suffix_match to allow list of values
- * fixed dNSName matching in domain_match and domain_suffix_match when
- using wolfSSL
- * started to prefer FT-EAP-SHA384 over WPA-EAP-SUITE-B-192 AKM if both
- are enabled
- * extended nl80211 Connect and external authentication to support
- SAE, FT-SAE, FT-EAP-SHA384
- * fixed KEK2 derivation for FILS+FT
- * extended client_cert file to allow loading of a chain of PEM
- encoded certificates
- * extended beacon reporting functionality
- * extended D-Bus interface with number of new properties
- * fixed a regression in FT-over-DS with mac80211-based drivers
- * OpenSSL: allow systemwide policies to be overridden
- * extended driver flags indication for separate 802.1X and PSK
- 4-way handshake offload capability
- * added support for random P2P Device/Interface Address use
- * extended PEAP to derive EMSK to enable use with ERP/FILS
- * extended WPS to allow SAE configuration to be added automatically
- for PSK (wps_cred_add_sae=1)
- * removed support for the old D-Bus interface (CONFIG_CTRL_IFACE_DBUS)
- * extended domain_match and domain_suffix_match to allow list of values
- * added a RSN workaround for misbehaving PMF APs that advertise
- IGTK/BIP KeyID using incorrect byte order
- * fixed PTK rekeying with FILS and FT
-
-2018-12-02 - v2.7
- * fixed WPA packet number reuse with replayed messages and key
- reinstallation
- [https://w1.fi/security/2017-1/] (CVE-2017-13077, CVE-2017-13078,
- CVE-2017-13079, CVE-2017-13080, CVE-2017-13081, CVE-2017-13082,
- CVE-2017-13086, CVE-2017-13087, CVE-2017-13088)
- * fixed unauthenticated EAPOL-Key decryption in wpa_supplicant
- [https://w1.fi/security/2018-1/] (CVE-2018-14526)
- * added support for FILS (IEEE 802.11ai) shared key authentication
- * added support for OWE (Opportunistic Wireless Encryption, RFC 8110;
- and transition mode defined by WFA)
- * added support for DPP (Wi-Fi Device Provisioning Protocol)
- * added support for RSA 3k key case with Suite B 192-bit level
- * fixed Suite B PMKSA caching not to update PMKID during each 4-way
- handshake
- * fixed EAP-pwd pre-processing with PasswordHashHash
- * added EAP-pwd client support for salted passwords
- * fixed a regression in TDLS prohibited bit validation
- * started to use estimated throughput to avoid undesired signal
- strength based roaming decision
- * MACsec/MKA:
- - new macsec_linux driver interface support for the Linux
- kernel macsec module
- - number of fixes and extensions
- * added support for external persistent storage of PMKSA cache
- (PMKSA_GET/PMKSA_ADD control interface commands; and
- MESH_PMKSA_GET/MESH_PMKSA_SET for the mesh case)
- * fixed mesh channel configuration pri/sec switch case
- * added support for beacon report
- * large number of other fixes, cleanup, and extensions
- * added support for randomizing local address for GAS queries
- (gas_rand_mac_addr parameter)
- * fixed EAP-SIM/AKA/AKA' ext auth cases within TLS tunnel
- * added option for using random WPS UUID (auto_uuid=1)
- * added SHA256-hash support for OCSP certificate matching
- * fixed EAP-AKA' to add AT_KDF into Synchronization-Failure
- * fixed a regression in RSN pre-authentication candidate selection
- * added option to configure allowed group management cipher suites
- (group_mgmt network profile parameter)
- * removed all PeerKey functionality
- * fixed nl80211 AP and mesh mode configuration regression with
- Linux 4.15 and newer
- * added ap_isolate configuration option for AP mode
- * added support for nl80211 to offload 4-way handshake into the driver
- * added support for using wolfSSL cryptographic library
- * SAE
- - added support for configuring SAE password separately of the
- WPA2 PSK/passphrase
- - fixed PTK and EAPOL-Key integrity and key-wrap algorithm selection
- for SAE;
- note: this is not backwards compatible, i.e., both the AP and
- station side implementations will need to be update at the same
- time to maintain interoperability
- - added support for Password Identifier
- - fixed FT-SAE PMKID matching
- * Hotspot 2.0
- - added support for fetching of Operator Icon Metadata ANQP-element
- - added support for Roaming Consortium Selection element
- - added support for Terms and Conditions
- - added support for OSEN connection in a shared RSN BSS
- - added support for fetching Venue URL information
- * added support for using OpenSSL 1.1.1
- * FT
- - disabled PMKSA caching with FT since it is not fully functional
- - added support for SHA384 based AKM
- - added support for BIP ciphers BIP-CMAC-256, BIP-GMAC-128,
- BIP-GMAC-256 in addition to previously supported BIP-CMAC-128
- - fixed additional IE inclusion in Reassociation Request frame when
- using FT protocol
-
-2016-10-02 - v2.6
- * fixed WNM Sleep Mode processing when PMF is not enabled
- [http://w1.fi/security/2015-6/] (CVE-2015-5310)
- * fixed EAP-pwd last fragment validation
- [http://w1.fi/security/2015-7/] (CVE-2015-5315)
- * fixed EAP-pwd unexpected Confirm message processing
- [http://w1.fi/security/2015-8/] (CVE-2015-5316)
- * fixed WPS configuration update vulnerability with malformed passphrase
- [http://w1.fi/security/2016-1/] (CVE-2016-4476)
- * fixed configuration update vulnerability with malformed parameters set
- over the local control interface
- [http://w1.fi/security/2016-1/] (CVE-2016-4477)
- * fixed TK configuration to the driver in EAPOL-Key 3/4 retry case
- * extended channel switch support for P2P GO
- * started to throttle control interface event message bursts to avoid
- issues with monitor sockets running out of buffer space
- * mesh mode fixes/improvements
- - generate proper AID for peer
- - enable WMM by default
- - add VHT support
- - fix PMKID derivation
- - improve robustness on various exchanges
- - fix peer link counting in reconnect case
- - improve mesh joining behavior
- - allow DTIM period to be configured
- - allow HT to be disabled (disable_ht=1)
- - add MESH_PEER_ADD and MESH_PEER_REMOVE commands
- - add support for PMKSA caching
- - add minimal support for SAE group negotiation
- - allow pairwise/group cipher to be configured in the network profile
- - use ieee80211w profile parameter to enable/disable PMF and derive
- a separate TX IGTK if PMF is enabled instead of using MGTK
- incorrectly
- - fix AEK and MTK derivation
- - remove GTKdata and IGTKdata from Mesh Peering Confirm/Close
- - note: these changes are not fully backwards compatible for secure
- (RSN) mesh network
- * fixed PMKID derivation with SAE
- * added support for requesting and fetching arbitrary ANQP-elements
- without internal support in wpa_supplicant for the specific element
- (anqp[265]=<hexdump> in "BSS <BSSID>" command output)
- * P2P
- - filter control characters in group client device names to be
- consistent with other P2P peer cases
- - support VHT 80+80 MHz and 160 MHz
- - indicate group completion in P2P Client role after data association
- instead of already after the WPS provisioning step
- - improve group-join operation to use SSID, if known, to filter BSS
- entries
- - added optional ssid=<hexdump> argument to P2P_CONNECT for join case
- - added P2P_GROUP_MEMBER command to fetch client interface address
- * P2PS
- - fix follow-on PD Response behavior
- - fix PD Response generation for unknown peer
- - fix persistent group reporting
- - add channel policy to PD Request
- - add group SSID to the P2PS-PROV-DONE event
- - allow "P2P_CONNECT <addr> p2ps" to be used without specifying the
- default PIN
- * BoringSSL
- - support for OCSP stapling
- - support building of h20-osu-client
- * D-Bus
- - add ExpectDisconnect()
- - add global config parameters as properties
- - add SaveConfig()
- - add VendorElemAdd(), VendorElemGet(), VendorElemRem()
- * fixed Suite B 192-bit AKM to use proper PMK length
- (note: this makes old releases incompatible with the fixed behavior)
- * improved PMF behavior for cases where the AP and STA has different
- configuration by not trying to connect in some corner cases where the
- connection cannot succeed
- * added option to reopen debug log (e.g., to rotate the file) upon
- receipt of SIGHUP signal
- * EAP-pwd: added support for Brainpool Elliptic Curves
- (with OpenSSL 1.0.2 and newer)
- * fixed EAPOL reauthentication after FT protocol run
- * fixed FTIE generation for 4-way handshake after FT protocol run
- * extended INTERFACE_ADD command to allow certain type (sta/ap)
- interface to be created
- * fixed and improved various FST operations
- * added 80+80 MHz and 160 MHz VHT support for IBSS/mesh
- * fixed SIGNAL_POLL in IBSS and mesh cases
- * added an option to abort an ongoing scan (used to speed up connection
- and can also be done with the new ABORT_SCAN command)
- * TLS client
- - do not verify CA certificates when ca_cert is not specified
- - support validating server certificate hash
- - support SHA384 and SHA512 hashes
- - add signature_algorithms extension into ClientHello
- - support TLS v1.2 signature algorithm with SHA384 and SHA512
- - support server certificate probing
- - allow specific TLS versions to be disabled with phase2 parameter
- - support extKeyUsage
- - support PKCS #5 v2.0 PBES2
- - support PKCS #5 with PKCS #12 style key decryption
- - minimal support for PKCS #12
- - support OCSP stapling (including ocsp_multi)
- * OpenSSL
- - support OpenSSL 1.1 API changes
- - drop support for OpenSSL 0.9.8
- - drop support for OpenSSL 1.0.0
- * added support for multiple schedule scan plans (sched_scan_plans)
- * added support for external server certificate chain validation
- (tls_ext_cert_check=1 in the network profile phase1 parameter)
- * made phase2 parser more strict about correct use of auth=<val> and
- autheap=<val> values
- * improved GAS offchannel operations with comeback request
- * added SIGNAL_MONITOR command to request signal strength monitoring
- events
- * added command for retrieving HS 2.0 icons with in-memory storage
- (REQ_HS20_ICON, GET_HS20_ICON, DEL_HS20_ICON commands and
- RX-HS20-ICON event)
- * enabled ACS support for AP mode operations with wpa_supplicant
- * EAP-PEAP: fixed interoperability issue with Windows 2012r2 server
- ("Invalid Compound_MAC in cryptobinding TLV")
- * EAP-TTLS: fixed success after fragmented final Phase 2 message
- * VHT: added interoperability workaround for 80+80 and 160 MHz channels
- * WNM: workaround for broken AP operating class behavior
- * added kqueue(2) support for eloop (CONFIG_ELOOP_KQUEUE)
- * nl80211:
- - add support for full station state operations
- - do not add NL80211_ATTR_SMPS_MODE attribute if HT is disabled
- - add NL80211_ATTR_PREV_BSSID with Connect command
- - fix IEEE 802.1X/WEP EAP reauthentication and rekeying to use
- unencrypted EAPOL frames
- * added initial MBO support; number of extensions to WNM BSS Transition
- Management
- * added support for PBSS/PCP and P2P on 60 GHz
- * Interworking: add credential realm to EAP-TLS identity
- * fixed EAPOL-Key Request Secure bit to be 1 if PTK is set
- * HS 2.0: add support for configuring frame filters
- * added POLL_STA command to check connectivity in AP mode
- * added initial functionality for location related operations
- * started to ignore pmf=1/2 parameter for non-RSN networks
- * added wps_disabled=1 network profile parameter to allow AP mode to
- be started without enabling WPS
- * wpa_cli: added action script support for AP-ENABLED and AP-DISABLED
- events
- * improved Public Action frame addressing
- - add gas_address3 configuration parameter to control Address 3
- behavior
- * number of small fixes
-
-2015-09-27 - v2.5
- * fixed P2P validation of SSID element length before copying it
- [http://w1.fi/security/2015-1/] (CVE-2015-1863)
- * fixed WPS UPnP vulnerability with HTTP chunked transfer encoding
- [http://w1.fi/security/2015-2/] (CVE-2015-4141)
- * fixed WMM Action frame parser (AP mode)
- [http://w1.fi/security/2015-3/] (CVE-2015-4142)
- * fixed EAP-pwd peer missing payload length validation
- [http://w1.fi/security/2015-4/]
- (CVE-2015-4143, CVE-2015-4144, CVE-2015-4145, CVE-2015-4146)
- * fixed validation of WPS and P2P NFC NDEF record payload length
- [http://w1.fi/security/2015-5/]
- * nl80211:
- - added VHT configuration for IBSS
- - fixed vendor command handling to check OUI properly
- - allow driver-based roaming to change ESS
- * added AVG_BEACON_RSSI to SIGNAL_POLL output
- * wpa_cli: added tab completion for number of commands
- * removed unmaintained and not yet completed SChannel/CryptoAPI support
- * modified Extended Capabilities element use in Probe Request frames to
- include all cases if any of the values are non-zero
- * added support for dynamically creating/removing a virtual interface
- with interface_add/interface_remove
- * added support for hashed password (NtHash) in EAP-pwd peer
- * added support for memory-only PSK/passphrase (mem_only_psk=1 and
- CTRL-REQ/RSP-PSK_PASSPHRASE)
- * P2P
- - optimize scan frequencies list when re-joining a persistent group
- - fixed number of sequences with nl80211 P2P Device interface
- - added operating class 125 for P2P use cases (this allows 5 GHz
- channels 161 and 169 to be used if they are enabled in the current
- regulatory domain)
- - number of fixes to P2PS functionality
- - do not allow 40 MHz co-ex PRI/SEC switch to force MCC
- - extended support for preferred channel listing
- * D-Bus:
- - fixed WPS property of fi.w1.wpa_supplicant1.BSS interface
- - fixed PresenceRequest to use group interface
- - added new signals: FindStopped, WPS pbc-overlap,
- GroupFormationFailure, WPS timeout, InvitationReceived
- - added new methods: WPS Cancel, P2P Cancel, Reconnect, RemoveClient
- - added manufacturer info
- * added EAP-EKE peer support for deriving Session-Id
- * added wps_priority configuration parameter to set the default priority
- for all network profiles added by WPS
- * added support to request a scan with specific SSIDs with the SCAN
- command (optional "ssid <hexdump>" arguments)
- * removed support for WEP40/WEP104 as a group cipher with WPA/WPA2
- * fixed SAE group selection in an error case
- * modified SAE routines to be more robust and PWE generation to be
- stronger against timing attacks
- * added support for Brainpool Elliptic Curves with SAE
- * added support for CCMP-256 and GCMP-256 as group ciphers with FT
- * fixed BSS selection based on estimated throughput
- * added option to disable TLSv1.0 with OpenSSL
- (phase1="tls_disable_tlsv1_0=1")
- * added Fast Session Transfer (FST) module
- * fixed OpenSSL PKCS#12 extra certificate handling
- * fixed key derivation for Suite B 192-bit AKM (this breaks
- compatibility with the earlier version)
- * added RSN IE to Mesh Peering Open/Confirm frames
- * number of small fixes
-
-2015-03-15 - v2.4
- * allow OpenSSL cipher configuration to be set for internal EAP server
- (openssl_ciphers parameter)
- * fixed number of small issues based on hwsim test case failures and
- static analyzer reports
- * P2P:
- - add new=<0/1> flag to P2P-DEVICE-FOUND events
- - add passive channels in invitation response from P2P Client
- - enable nl80211 P2P_DEVICE support by default
- - fix regresssion in disallow_freq preventing search on social
- channels
- - fix regressions in P2P SD query processing
- - try to re-invite with social operating channel if no common channels
- in invitation
- - allow cross connection on parent interface (this fixes number of
- use cases with nl80211)
- - add support for P2P services (P2PS)
- - add p2p_go_ctwindow configuration parameter to allow GO CTWindow to
- be configured
- * increase postponing of EAPOL-Start by one second with AP/GO that
- supports WPS 2.0 (this makes it less likely to trigger extra roundtrip
- of identity frames)
- * add support for PMKSA caching with SAE
- * add support for control mesh BSS (IEEE 802.11s) operations
- * fixed number of issues with D-Bus P2P commands
- * fixed regression in ap_scan=2 special case for WPS
- * fixed macsec_validate configuration
- * add a workaround for incorrectly behaving APs that try to use
- EAPOL-Key descriptor version 3 when the station supports PMF even if
- PMF is not enabled on the AP
- * allow TLS v1.1 and v1.2 to be negotiated by default; previous behavior
- of disabling these can be configured to work around issues with broken
- servers with phase1="tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1"
- * add support for Suite B (128-bit and 192-bit level) key management and
- cipher suites
- * add WMM-AC support (WMM_AC_ADDTS/WMM_AC_DELTS)
- * improved BSS Transition Management processing
- * add support for neighbor report
- * add support for link measurement
- * fixed expiration of BSS entry with all-zeros BSSID
- * add optional LAST_ID=x argument to LIST_NETWORK to allow all
- configured networks to be listed even with huge number of network
- profiles
- * add support for EAP Re-Authentication Protocol (ERP)
- * fixed EAP-IKEv2 fragmentation reassembly
- * improved PKCS#11 configuration for OpenSSL
- * set stdout to be line-buffered
- * add TDLS channel switch configuration
- * add support for MAC address randomization in scans with nl80211
- * enable HT for IBSS if supported by the driver
- * add BSSID black and white lists (bssid_blacklist, bssid_whitelist)
- * add support for domain_suffix_match with GnuTLS
- * add OCSP stapling client support with GnuTLS
- * include peer certificate in EAP events even without a separate probe
- operation; old behavior can be restored with cert_in_cb=0
- * add peer ceritficate alt subject name to EAP events
- (CTRL-EVENT-EAP-PEER-ALT)
- * add domain_match network profile parameter (similar to
- domain_suffix_match, but full match is required)
- * enable AP/GO mode HT Tx STBC automatically based on driver support
- * add ANQP-QUERY-DONE event to provide information on ANQP parsing
- status
- * allow passive scanning to be forced with passive_scan=1
- * add a workaround for Linux packet socket behavior when interface is in
- bridge
- * increase 5 GHz band preference in BSS selection (estimate SNR, if info
- not available from driver; estimate maximum throughput based on common
- HT/VHT/specific TX rate support)
- * add INTERWORKING_ADD_NETWORK ctrl_iface command; this can be used to
- implement Interworking network selection behavior in upper layers
- software components
- * add optional reassoc_same_bss_optim=1 (disabled by default)
- optimization to avoid unnecessary Authentication frame exchange
- * extend TDLS frame padding workaround to cover all packets
- * allow wpa_supplicant to recover nl80211 functionality if the cfg80211
- module gets removed and reloaded without restarting wpa_supplicant
- * allow hostapd DFS implementation to be used in wpa_supplicant AP mode
-
-2014-10-09 - v2.3
- * fixed number of minor issues identified in static analyzer warnings
- * fixed wfd_dev_info to be more careful and not read beyond the buffer
- when parsing invalid information for P2P-DEVICE-FOUND
- * extended P2P and GAS query operations to support drivers that have
- maximum remain-on-channel time below 1000 ms (500 ms is the current
- minimum supported value)
- * added p2p_search_delay parameter to make the default p2p_find delay
- configurable
- * improved P2P operating channel selection for various multi-channel
- concurrency cases
- * fixed some TDLS failure cases to clean up driver state
- * fixed dynamic interface addition cases with nl80211 to avoid adding
- ifindex values to incorrect interface to skip foreign interface events
- properly
- * added TDLS workaround for some APs that may add extra data to the
- end of a short frame
- * fixed EAP-AKA' message parser with multiple AT_KDF attributes
- * added configuration option (p2p_passphrase_len) to allow longer
- passphrases to be generated for P2P groups
- * fixed IBSS channel configuration in some corner cases
- * improved HT/VHT/QoS parameter setup for TDLS
- * modified D-Bus interface for P2P peers/groups
- * started to use constant time comparison for various password and hash
- values to reduce possibility of any externally measurable timing
- differences
- * extended explicit clearing of freed memory and expired keys to avoid
- keeping private data in memory longer than necessary
- * added optional scan_id parameter to the SCAN command to allow manual
- scan requests for active scans for specific configured SSIDs
- * fixed CTRL-EVENT-REGDOM-CHANGE event init parameter value
- * added option to set Hotspot 2.0 Rel 2 update_identifier in network
- configuration to support external configuration
- * modified Android PNO functionality to send Probe Request frames only
- for hidden SSIDs (based on scan_ssid=1)
- * added generic mechanism for adding vendor elements into frames at
- runtime (VENDOR_ELEM_ADD, VENDOR_ELEM_GET, VENDOR_ELEM_REMOVE)
- * added fields to show unrecognized vendor elements in P2P_PEER
- * removed EAP-TTLS/MSCHAPv2 interoperability workaround so that
- MS-CHAP2-Success is required to be present regardless of
- eap_workaround configuration
- * modified EAP fast session resumption to allow results to be used only
- with the same network block that generated them
- * extended freq_list configuration to apply for sched_scan as well as
- normal scan
- * modified WPS to merge mixed-WPA/WPA2 credentials from a single session
- * fixed nl80211/RTM_DELLINK processing when a P2P GO interface is
- removed from a bridge
- * fixed number of small P2P issues to make negotiations more robust in
- corner cases
- * added experimental support for using temporary, random local MAC
- address (mac_addr and preassoc_mac_addr parameters); this is disabled
- by default (i.e., previous behavior of using permanent address is
- maintained if configuration is not changed)
- * added D-Bus interface for setting/clearing WFD IEs
- * fixed TDLS AID configuration for VHT
- * modified -m<conf> configuration file to be used only for the P2P
- non-netdev management device and do not load this for the default
- station interface or load the station interface configuration for
- the P2P management interface
- * fixed external MAC address changes while wpa_supplicant is running
- * started to enable HT (if supported by the driver) for IBSS
- * fixed wpa_cli action script execution to use more robust mechanism
- (CVE-2014-3686)
-
-2014-06-04 - v2.2
- * added DFS indicator to get_capability freq
- * added/fixed nl80211 functionality
- - BSSID/frequency hint for driver-based BSS selection
- - fix tearing down WDS STA interfaces
- - support vendor specific driver command
- (VENDOR <vendor id> <sub command id> [<hex formatted data>])
- - GO interface teardown optimization
- - allow beacon interval to be configured for IBSS
- - add SHA256-based AKM suites to CONNECT/ASSOCIATE commands
- * removed unused NFC_RX_HANDOVER_REQ and NFC_RX_HANDOVER_SEL control
- interface commands (the more generic NFC_REPORT_HANDOVER is now used)
- * fixed MSCHAP UTF-8 to UCS-2 conversion for three-byte encoding;
- this fixes password with include UTF-8 characters that use
- three-byte encoding EAP methods that use NtPasswordHash
- * fixed couple of sequences where radio work items could get stuck,
- e.g., when rfkill blocking happens during scanning or when
- scan-for-auth workaround is used
- * P2P enhancements/fixes
- - enable enable U-APSD on GO automatically if the driver indicates
- support for this
- - fixed some service discovery cases with broadcast queries not being
- sent to all stations
- - fixed Probe Request frame triggering invitation to trigger only a
- single invitation instance even if multiple Probe Request frames are
- received
- - fixed a potential NULL pointer dereference crash when processing an
- invalid Invitation Request frame
- - add optional configuration file for the P2P_DEVICE parameters
- - optimize scan for GO during persistent group invocation
- - fix possible segmentation fault when PBC overlap is detected while
- using a separate P2P group interface
- - improve GO Negotiation robustness by allowing GO Negotiation
- Confirmation to be retransmitted
- - do use freed memory on device found event when P2P NFC
- * added phase1 network parameter options for disabling TLS v1.1 and v1.2
- to allow workarounds with misbehaving AAA servers
- (tls_disable_tlsv1_1=1 and tls_disable_tlsv1_2=1)
- * added support for OCSP stapling to validate AAA server certificate
- during TLS exchange
- * Interworking/Hotspot 2.0 enhancements
- - prefer the last added network in Interworking connection to make the
- behavior more consistent with likely user expectation
- - roaming partner configuration (roaming_partner within a cred block)
- - support Hotspot 2.0 Release 2
- * "hs20_anqp_get <BSSID> 8" to request OSU Providers list
- * "hs20_icon_request <BSSID> <icon filename>" to request icon files
- * "fetch_osu" and "cancel_osu_fetch" to start/stop full OSU provider
- search (all suitable APs in scan results)
- * OSEN network for online signup connection
- * min_{dl,ul}_bandwidth_{home,roaming} cred parameters
- * max_bss_load cred parameter
- * req_conn_capab cred parameter
- * sp_priority cred parameter
- * ocsp cred parameter
- * slow down automatic connection attempts on EAP failure to meet
- required behavior (no more than 10 retries within a 10-minute
- interval)
- * sample implementation of online signup client (both SPP and
- OMA-DM protocols) (hs20/client/*)
- - fixed GAS indication for additional comeback delay with status
- code 95
- - extend ANQP_GET to accept Hotspot 2.0 subtypes
- ANQP_GET <addr> <info id>[,<info id>]...
- [,hs20:<subtype>][...,hs20:<subtype>]
- - add control interface events CRED-ADDED <id>,
- CRED-MODIFIED <id> <field>, CRED-REMOVED <id>
- - add "GET_CRED <id> <field>" command
- - enable FT for the connection automatically if the AP advertises
- support for this
- - fix a case where auto_interworking=1 could end up stopping scanning
- * fixed TDLS interoperability issues with supported operating class in
- some deployed stations
- * internal TLS implementation enhancements/fixes
- - add SHA256-based cipher suites
- - add DHE-RSA cipher suites
- - fix X.509 validation of PKCS#1 signature to check for extra data
- * fixed PTK derivation for CCMP-256 and GCMP-256
- * added "reattach" command for fast reassociate-back-to-same-BSS
- * allow PMF to be enabled for AP mode operation with the ieee80211w
- parameter
- * added "get_capability tdls" command
- * added option to set config blobs through control interface with
- "SET blob <name> <hexdump>"
- * D-Bus interface extensions/fixes
- - make p2p_no_group_iface configurable
- - declare ServiceDiscoveryRequest method properly
- - export peer's device address as a property
- - make reassociate command behave like the control interface one,
- i.e., to allow connection from disconnected state
- * added optional "freq=<channel ranges>" parameter to SET pno
- * added optional "freq=<channel ranges>" parameter to SELECT_NETWORK
- * fixed OBSS scan result processing for 20/40 MHz co-ex report
- * remove WPS 1.0 only support, i.e., WSC 2.0 support is now enabled
- whenever CONFIG_WPS=y is set
- * fixed regression in parsing of WNM Sleep Mode exit key data
- * fixed potential segmentation fault and memory leaks in WNM neighbor
- report processing
- * EAP-pwd fixes
- - fragmentation of PWD-Confirm-Resp
- - fix memory leak when fragmentation is used
- - fix possible segmentation fault on EAP method deinit if an invalid
- group is negotiated
- * added MACsec/IEEE Std 802.1X-2010 PAE implementation (currently
- available only with the macsec_qca driver wrapper)
- * fixed EAP-SIM counter-too-small message
- * added 'dup_network <id_s> <id_d> <name>' command; this can be used to
- clone the psk field without having toextract it from wpa_supplicant
- * fixed GSM authentication on USIM
- * added support for using epoll in eloop (CONFIG_ELOOP_EPOLL=y)
- * fixed some concurrent virtual interface cases with dedicated P2P
- management interface to not catch events from removed interface (this
- could result in the management interface getting disabled)
- * fixed a memory leak in SAE random number generation
- * fixed off-by-one bounds checking in printf_encode()
- - this could result in some control interface ATTACH command cases
- terminating wpa_supplicant
- * fixed EAPOL-Key exchange when GCMP is used with SHA256-based AKM
- * various bug fixes
-
-2014-02-04 - v2.1
- * added support for simultaneous authentication of equals (SAE) for
- stronger password-based authentication with WPA2-Personal
- * improved P2P negotiation and group formation robustness
- - avoid unnecessary Dialog Token value changes during retries
- - avoid more concurrent scanning cases during full group formation
- sequence
- - do not use potentially obsolete scan result data from driver
- cache for peer discovery/updates
- - avoid undesired re-starting of GO negotiation based on Probe
- Request frames
- - increase GO Negotiation and Invitation timeouts to address busy
- environments and peers that take long time to react to messages,
- e.g., due to power saving
- - P2P Device interface type
- * improved P2P channel selection (use more peer information and allow
- more local options)
- * added support for optional per-device PSK assignment by P2P GO
- (wpa_cli p2p_set per_sta_psk <0/1>)
- * added P2P_REMOVE_CLIENT for removing a client from P2P groups
- (including persistent groups); this can be used to securely remove
- a client from a group if per-device PSKs are used
- * added more configuration flexibility for allowed P2P GO/client
- channels (p2p_no_go_freq list and p2p_add_cli_chan=0/1)
- * added nl80211 functionality
- - VHT configuration for nl80211
- - MFP (IEEE 802.11w) information for nl80211 command API
- - support split wiphy dump
- - FT (IEEE 802.11r) with driver-based SME
- - use advertised number of supported concurrent channels
- - QoS Mapping configuration
- * improved TDLS negotiation robustness
- * added more TDLS peer parameters to be configured to the driver
- * optimized connection time by allowing recently received scan results
- to be used instead of having to run through a new scan
- * fixed ctrl_iface BSS command iteration with RANGE argument and no
- exact matches; also fixed argument parsing for some cases with
- multiple arguments
- * added 'SCAN TYPE=ONLY' ctrl_iface command to request manual scan
- without executing roaming/network re-selection on scan results
- * added Session-Id derivation for EAP peer methods
- * added fully automated regression testing with mac80211_hwsim
- * changed configuration parser to reject invalid integer values
- * allow AP/Enrollee to be specified with BSSID instead of UUID for
- WPS ER operations
- * disable network block temporarily on repeated connection failures
- * changed the default driver interface from wext to nl80211 if both are
- included in the build
- * remove duplicate networks if WPS provisioning is run multiple times
- * remove duplicate networks when Interworking network selection uses the
- same network
- * added global freq_list configuration to allow scan frequencies to be
- limited for all cases instead of just for a specific network block
- * added support for BSS Transition Management
- * added option to use "IFNAME=<ifname> " prefix to use the global
- control interface connection to perform per-interface commands;
- similarly, allow global control interface to be used as a monitor
- interface to receive events from all interfaces
- * fixed OKC-based PMKSA cache entry clearing
- * fixed TKIP group key configuration with FT
- * added support for using OCSP stapling to validate server certificate
- (ocsp=1 as optional and ocsp=2 as mandatory)
- * added EAP-EKE peer
- * added peer restart detection for IBSS RSN
- * added domain_suffix_match (and domain_suffix_match2 for Phase 2
- EAP-TLS) to specify additional constraint for the server certificate
- domain name
- * added support for external SIM/USIM processing in EAP-SIM, EAP-AKA,
- and EAP-AKA' (CTRL-REQ-SIM and CTRL-RSP-SIM commands over control
- interface)
- * added global bgscan configuration option as a default for all network
- blocks that do not specify their own bgscan parameters
- * added D-Bus methods for TDLS
- * added more control to scan requests
- - "SCAN freq=<freq list>" can be used to specify which channels are
- scanned (comma-separated frequency ranges in MHz)
- - "SCAN passive=1" can be used to request a passive scan (no Probe
- Request frames are sent)
- - "SCAN use_id" can be used to request a scan id to be returned and
- included in event messages related to this specific scan operation
- - "SCAN only_new=1" can be used to request the driver/cfg80211 to
- report only BSS entries that have been updated during this scan
- round
- - these optional arguments to the SCAN command can be combined with
- each other
- * modified behavior on externally triggered scans
- - avoid concurrent operations requiring full control of the radio when
- an externally triggered scan is detected
- - do not use results for internal roaming decision
- * added a new cred block parameter 'temporary' to allow credential
- blocks to be stored separately even if wpa_supplicant configuration
- file is used to maintain other network information
- * added "radio work" framework to schedule exclusive radio operations
- for off-channel functionality
- - reduce issues with concurrent operations that try to control which
- channel is used
- - allow external programs to request exclusive radio control in a way
- that avoids conflicts with wpa_supplicant
- * added support for using Protected Dual of Public Action frames for
- GAS/ANQP exchanges when associated with PMF
- * added support for WPS+NFC updates and P2P+NFC
- - improved protocol for WPS
- - P2P group formation/join based on NFC connection handover
- - new IPv4 address assignment for P2P groups (ip_addr_* configuration
- parameters on the GO) to replace DHCP
- - option to fetch and report alternative carrier records for external
- NFC operations
- * various bug fixes
-
-2013-01-12 - v2.0
- * removed Qt3-based wpa_gui (obsoleted by wpa_qui-qt4)
- * removed unmaintained driver wrappers broadcom, iphone, osx, ralink,
- hostap, madwifi (hostap and madwifi remain available for hostapd;
- their wpa_supplicant functionality is obsoleted by wext)
- * improved debug logging (human readable event names, interface name
- included in more entries)
- * changed AP mode behavior to enable WPS only for open and
- WPA/WPA2-Personal configuration
- * improved P2P concurrency operations
- - better coordination of concurrent scan and P2P search operations
- - avoid concurrent remain-on-channel operation requests by canceling
- previous operations prior to starting a new one
- - reject operations that would require multi-channel concurrency if
- the driver does not support it
- - add parameter to select whether STA or P2P connection is preferred
- if the driver cannot support both at the same time
- - allow driver to indicate channel changes
- - added optional delay=<search delay in milliseconds> parameter for
- p2p_find to avoid taking all radio resources
- - use 500 ms p2p_find search delay by default during concurrent
- operations
- - allow all channels in GO Negotiation if the driver supports
- multi-channel concurrency
- * added number of small changes to make it easier for static analyzers
- to understand the implementation
- * fixed number of small bugs (see git logs for more details)
- * nl80211: number of updates to use new cfg80211/nl80211 functionality
- - replace monitor interface with nl80211 commands for AP mode
- - additional information for driver-based AP SME
- - STA entry authorization in RSN IBSS
- * EAP-pwd:
- - fixed KDF for group 21 and zero-padding
- - added support for fragmentation
- - increased maximum number of hunting-and-pecking iterations
- * avoid excessive Probe Response retries for broadcast Probe Request
- frames (only with drivers using wpa_supplicant AP mode SME/MLME)
- * added "GET country" ctrl_iface command
- * do not save an invalid network block in wpa_supplicant.conf to avoid
- problems reading the file on next start
- * send STA connected/disconnected ctrl_iface events to both the P2P
- group and parent interfaces
- * added preliminary support for using TLS v1.2 (CONFIG_TLSV12=y)
- * added "SET pno <1/0>" ctrl_iface command to start/stop preferred
- network offload with sched_scan driver command
- * merged in number of changes from Android repository for P2P, nl80211,
- and build parameters
- * changed P2P GO mode configuration to use driver capabilities to
- automatically enable HT operations when supported
- * added "wpa_cli status wps" command to fetch WPA2-Personal passhrase
- for WPS use cases in AP mode
- * EAP-AKA: keep pseudonym identity across EAP exchanges to match EAP-SIM
- behavior
- * improved reassociation behavior in cases where association is rejected
- or when an AP disconnects us to handle common load balancing
- mechanisms
- - try to avoid extra scans when the needed information is available
- * added optional "join" argument for p2p_prov_disc ctrl_iface command
- * added group ifname to P2P-PROV-DISC-* events
- * added P2P Device Address to AP-STA-DISCONNECTED event and use
- p2p_dev_addr parameter name with AP-STA-CONNECTED
- * added workarounds for WPS PBC overlap detection for some P2P use cases
- where deployed stations work incorrectly
- * optimize WPS connection speed by disconnecting prior to WPS scan and
- by using single channel scans when AP channel is known
- * PCSC and SIM/USIM improvements:
- - accept 0x67 (Wrong length) as a response to READ RECORD to fix
- issues with some USIM cards
- - try to read MNC length from SIM/USIM
- - build realm according to 3GPP TS 23.003 with identity from the SIM
- - allow T1 protocol to be enabled
- * added more WPS and P2P information available through D-Bus
- * improve P2P negotiation robustness
- - extra waits to get ACK frames through
- - longer timeouts for cases where deployed devices have been
- identified have issues meeting the specification requirements
- - more retries for some P2P frames
- - handle race conditions in GO Negotiation start by both devices
- - ignore unexpected GO Negotiation Response frame
- * added support for libnl 3.2 and newer
- * added P2P persistent group info to P2P_PEER data
- * maintain a list of P2P Clients for persistent group on GO
- * AP: increased initial group key handshake retransmit timeout to 500 ms
- * added optional dev_id parameter for p2p_find
- * added P2P-FIND-STOPPED ctrl_iface event
- * fixed issues in WPA/RSN element validation when roaming with ap_scan=1
- and driver-based BSS selection
- * do not expire P2P peer entries while connected with the peer in a
- group
- * fixed WSC element inclusion in cases where P2P is disabled
- * AP: added a WPS workaround for mixed mode AP Settings with Windows 7
- * EAP-SIM: fixed AT_COUNTER_TOO_SMALL use
- * EAP-SIM/AKA: append realm to pseudonym identity
- * EAP-SIM/AKA: store pseudonym identity in network configuration to
- allow it to persist over multiple EAP sessions and wpa_supplicant
- restarts
- * EAP-AKA': updated to RFC 5448 (username prefixes changed); note: this
- breaks interoperability with older versions
- * added support for WFA Hotspot 2.0
- - GAS/ANQP to fetch network information
- - credential configuration and automatic network selections based on
- credential match with ANQP information
- * limited PMKSA cache entries to be used only with the network context
- that was used to create them
- * improved PMKSA cache expiration to avoid unnecessary disconnections
- * adjusted bgscan_simple fast-scan backoff to avoid too frequent
- background scans
- * removed ctrl_iface event on P2P PD Response in join-group case
- * added option to fetch BSS table entry based on P2P Device Address
- ("BSS p2p_dev_addr=<P2P Device Address>")
- * added BSS entry age to ctrl_iface BSS command output
- * added optional MASK=0xH option for ctrl_iface BSS command to select
- which fields are included in the response
- * added optional RANGE=ALL|N1-N2 option for ctrl_iface BSS command to
- fetch information about several BSSes in one call
- * simplified licensing terms by selecting the BSD license as the only
- alternative
- * added "P2P_SET disallow_freq <freq list>" ctrl_iface command to
- disable channels from P2P use
- * added p2p_pref_chan configuration parameter to allow preferred P2P
- channels to be specified
- * added support for advertising immediate availability of a WPS
- credential for P2P use cases
- * optimized scan operations for P2P use cases (use single channel scan
- for a specific SSID when possible)
- * EAP-TTLS: fixed peer challenge generation for MSCHAPv2
- * SME: do not use reassociation after explicit disconnection request
- (local or a notification from an AP)
- * added support for sending debug info to Linux tracing (-T on command
- line)
- * added support for using Deauthentication reason code 3 as an
- indication of P2P group termination
- * added wps_vendor_ext_m1 configuration parameter to allow vendor
- specific attributes to be added to WPS M1
- * started using separate TLS library context for tunneled TLS
- (EAP-PEAP/TLS, EAP-TTLS/TLS, EAP-FAST/TLS) to support different CA
- certificate configuration between Phase 1 and Phase 2
- * added optional "auto" parameter for p2p_connect to request automatic
- GO Negotiation vs. join-a-group selection
- * added disabled_scan_offload parameter to disable automatic scan
- offloading (sched_scan)
- * added optional persistent=<network id> parameter for p2p_connect to
- allow forcing of a specific SSID/passphrase for GO Negotiation
- * added support for OBSS scan requests and 20/40 BSS coexistence reports
- * reject PD Request for unknown group
- * removed scripts and notes related to Windows binary releases (which
- have not been used starting from 1.x)
- * added initial support for WNM operations
- - Keep-alive based on BSS max idle period
- - WNM-Sleep Mode
- - minimal BSS Transition Management processing
- * added autoscan module to control scanning behavior while not connected
- - autoscan_periodic and autoscan_exponential modules
- * added new WPS NFC ctrl_iface mechanism
- - added initial support NFC connection handover
- - removed obsoleted WPS_OOB command (including support for deprecated
- UFD config_method)
- * added optional framework for external password storage ("ext:<name>")
- * wpa_cli: added optional support for controlling wpa_supplicant
- remotely over UDP (CONFIG_CTRL_IFACE=udp-remote) for testing purposes
- * wpa_cli: extended tab completion to more commands
- * changed SSID output to use printf-escaped strings instead of masking
- of non-ASCII characters
- - SSID can now be configured in the same format: ssid=P"abc\x00test"
- * removed default ACM=1 from AC_VO and AC_VI
- * added optional "ht40" argument for P2P ctrl_iface commands to allow
- 40 MHz channels to be requested on the 5 GHz band
- * added optional parameters for p2p_invite command to specify channel
- when reinvoking a persistent group as the GO
- * improved FIPS mode builds with OpenSSL
- - "make fips" with CONFIG_FIPS=y to build wpa_supplicant with the
- OpenSSL FIPS object module
- - replace low level OpenSSL AES API calls to use EVP
- - use OpenSSL keying material exporter when possible
- - do not export TLS keys in FIPS mode
- - remove MD5 from CONFIG_FIPS=y builds
- - use OpenSSL function for PKBDF2 passphrase-to-PSK
- - use OpenSSL HMAC implementation
- - mix RAND_bytes() output into random_get_bytes() to force OpenSSL
- DRBG to be used in FIPS mode
- - use OpenSSL CMAC implementation
- * added mechanism to disable TLS Session Ticket extension
- - a workaround for servers that do not support TLS extensions that
- was enabled by default in recent OpenSSL versions
- - tls_disable_session_ticket=1
- - automatically disable TLS Session Ticket extension by default when
- using EAP-TLS/PEAP/TTLS (i.e., only use it with EAP-FAST)
- * changed VENDOR-TEST EAP method to use proper private enterprise number
- (this will not interoperate with older versions)
- * disable network block temporarily on authentication failures
- * improved WPS AP selection during WPS PIN iteration
- * added support for configuring GCMP cipher for IEEE 802.11ad
- * added support for Wi-Fi Display extensions
- - WFD_SUBELEMENT_SET ctrl_iface command to configure WFD subelements
- - SET wifi_display <0/1> to disable/enable WFD support
- - WFD service discovery
- - an external program is needed to manage the audio/video streaming
- and codecs
- * optimized scan result use for network selection
- - use the internal BSS table instead of raw scan results
- - allow unnecessary scans to be skipped if fresh information is
- available (e.g., after GAS/ANQP round for Interworking)
- * added support for 256-bit AES with internal TLS implementation
- * allow peer to propose channel in P2P invitation process for a
- persistent group
- * added disallow_aps parameter to allow BSSIDs/SSIDs to be disallowed
- from network selection
- * re-enable the networks disabled during WPS operations
- * allow P2P functionality to be disabled per interface (p2p_disabled=1)
- * added secondary device types into P2P_PEER output
- * added an option to disable use of a separate P2P group interface
- (p2p_no_group_iface=1)
- * fixed P2P Bonjour SD to match entries with both compressed and not
- compressed domain name format and support multiple Bonjour PTR matches
- for the same key
- * use deauthentication instead of disassociation for all disconnection
- operations; this removes the now unused disassociate() wpa_driver_ops
- callback
- * optimized PSK generation on P2P GO by caching results to avoid
- multiple PBKDF2 operations
- * added okc=1 global configuration parameter to allow OKC to be enabled
- by default for all network blocks
- * added a workaround for WPS PBC session overlap detection to avoid
- interop issues with deployed station implementations that do not
- remove active PBC indication from Probe Request frames properly
- * added basic support for 60 GHz band
- * extend EAPOL frames processing workaround for roaming cases
- (postpone processing of unexpected EAPOL frame until association
- event to handle reordered events)
-
-2012-05-10 - v1.0
- * bsd: Add support for setting HT values in IFM_MMASK.
- * Delay STA entry removal until Deauth/Disassoc TX status in AP mode.
- This allows the driver to use PS buffering of Deauthentication and
- Disassociation frames when the STA is in power save sleep. Only
- available with drivers that provide TX status events for Deauth/
- Disassoc frames (nl80211).
- * Drop oldest unknown BSS table entries first. This makes it less
- likely to hit connection issues in environments with huge number
- of visible APs.
- * Add systemd support.
- * Add support for setting the syslog facility from the config file
- at build time.
- * atheros: Add support for IEEE 802.11w configuration.
- * AP mode: Allow enable HT20 if driver supports it, by setting the
- config parameter ieee80211n.
- * Allow AP mode to disconnect STAs based on low ACK condition (when
- the data connection is not working properly, e.g., due to the STA
- going outside the range of the AP). Disabled by default, enable by
- config option disassoc_low_ack.
- * nl80211:
- - Support GTK rekey offload.
- - Support PMKSA candidate events. This adds support for RSN
- pre-authentication with nl80211 interface and drivers that handle
- roaming internally.
- * dbus:
- - Add a DBus signal for EAP SM requests, emitted on the Interface
- object.
- - Export max scan ssids supported by the driver as MaxScanSSID.
- - Add signal Certification for information about server certification.
- - Add BSSExpireAge and BSSExpireCount interface properties and
- support set/get, which allows for setting BSS cache expiration age
- and expiration scan count.
- - Add ConfigFile to AddInterface properties.
- - Add Interface.Country property and support to get/set the value.
- - Add DBus property CurrentAuthMode.
- - P2P DBus API added.
- - Emit property changed events (for property BSSs) when adding/
- removing BSSs.
- - Treat '' in SSIDs of Interface.Scan as a request for broadcast
- scan, instead of ignoring it.
- - Add DBus getter/setter for FastReauth.
- - Raise PropertiesChanged on org.freedesktop.DBus.Properties.
- * wpa_cli:
- - Send AP-STA-DISCONNECTED event when an AP disconnects a station
- due to inactivity.
- - Make second argument to set command optional. This can be used to
- indicate a zero length value.
- - Add signal_poll command.
- - Add bss_expire_age and bss_expire_count commands to set/get BSS
- cache expiration age and expiration scan count.
- - Add ability to set scan interval (the time in seconds wpa_s waits
- before requesting a new scan after failing to find a suitable
- network in scan results) using scan_interval command.
- - Add event CTRL-EVENT-ASSOC-REJECT for association rejected.
- - Add command get version, that returns wpa_supplicant version string.
- - Add command sta_autoconnect for disabling automatic reconnection
- on receiving disconnection event.
- - Setting bssid parameter to an empty string "" or any can now be
- used to clear the bssid_set flag in a network block, i.e., to remove
- bssid filtering.
- - Add tdls_testing command to add a special testing feature for
- changing TDLS behavior. Build param CONFIG_TDLS_TESTING must be
- enabled as well.
- - For interworking, add wpa_cli commands interworking_select,
- interworking_connect, anqp_get, fetch_anqp, and stop_fetch_anqp.
- - Many P2P commands were added. See README-P2P.
- - Many WPS/WPS ER commands - see WPS/WPS ER sections for details.
- - Allow set command to change global config parameters.
- - Add log_level command, which can be used to display the current
- debugging level and to change the log level during run time.
- - Add note command, which can be used to insert notes to the debug
- log.
- - Add internal line edit implementation. CONFIG_WPA_CLI_EDIT=y
- can now be used to build wpa_cli with internal implementation of
- line editing and history support. This can be used as a replacement
- for CONFIG_READLINE=y.
- * AP mode: Add max_num_sta config option, which can be used to limit
- the number of stations allowed to connect to the AP.
- * Add WPA_IGNORE_CONFIG_ERRORS build option to continue in case of bad
- config file.
- * wext: Increase scan timeout from 5 to 10 seconds.
- * Add blacklist command, allowing an external program to
- manage the BSS blacklist and display its current contents.
- * WPS:
- - Add wpa_cli wps_pin get command for generating random PINs. This can
- be used in a UI to generate a PIN without starting WPS (or P2P)
- operation.
- - Set RF bands based on driver capabilities, instead of hardcoding
- them.
- - Add mechanism for indicating non-standard WPS errors.
- - Add CONFIG_WPS_REG_DISABLE_OPEN=y option to disable open networks
- by default.
- - Add wps_ap_pin cli command for wpa_supplicant AP mode.
- - Add wps_check_pin cli command for processing PIN from user input.
- UIs can use this command to process a PIN entered by a user and to
- validate the checksum digit (if present).
- - Cancel WPS operation on PBC session overlap detection.
- - New wps_cancel command in wpa_cli will cancel a pending WPS
- operation.
- - wpa_cli action: Add WPS_EVENT_SUCCESS and WPS_EVENT_FAIL handlers.
- - Trigger WPS config update on Manufacturer, Model Name, Model
- Number, and Serial Number changes.
- - Fragment size is now configurable for EAP-WSC peer. Use
- wpa_cli set wps_fragment_size <val>.
- - Disable AP PIN after 10 consecutive failures. Slow down attacks on
- failures up to 10.
- - Allow AP to start in Enrollee mode without AP PIN for probing, to
- be compatible with Windows 7.
- - Add Config Error into WPS-FAIL events to provide more info to the
- user on how to resolve the issue.
- - Label and Display config methods are not allowed to be enabled
- at the same time, since it is unclear which PIN to use if both
- methods are advertised.
- - When controlling multiple interfaces:
- - apply WPS commands to all interfaces configured to use WPS
- - apply WPS config changes to all interfaces that use WPS
- - when an attack is detected on any interface, disable AP PIN on
- all interfaces
- * WPS ER:
- - Add special AP Setup Locked mode to allow read only ER.
- ap_setup_locked=2 can now be used to enable a special mode where
- WPS ER can learn the current AP settings, but cannot change them.
- - Show SetSelectedRegistrar events as ctrl_iface events
- - Add wps_er_set_config to enroll a network based on a local
- network configuration block instead of having to (re-)learn the
- current AP settings with wps_er_learn.
- - Allow AP filtering based on IP address, add ctrl_iface event for
- learned AP settings, add wps_er_config command to configure an AP.
- * WPS 2.0: Add support for WPS 2.0 (CONFIG_WPS2)
- - Add build option CONFIG_WPS_EXTENSIBILITY_TESTING to enable tool
- for testing protocol extensibility.
- - Add build option CONFIG_WPS_STRICT to allow disabling of WPS
- workarounds.
- - Add support for AuthorizedMACs attribute.
- * TDLS:
- - Propagate TDLS related nl80211 capability flags from kernel and
- add them as driver capability flags. If the driver doesn't support
- capabilities, assume TDLS is supported internally. When TDLS is
- explicitly not supported, disable all user facing TDLS operations.
- - Allow TDLS to be disabled at runtime (mostly for testing).
- Use set tdls_disabled.
- - Honor AP TDLS settings that prohibit/allow TDLS.
- - Add a special testing feature for changing TDLS behavior. Use
- CONFIG_TDLS_TESTING build param to enable. Configure at runtime
- with tdls_testing cli command.
- - Add support for TDLS 802.11z.
- * wlantest: Add a tool wlantest for IEEE802.11 protocol testing.
- wlantest can be used to capture frames from a monitor interface
- for realtime capturing or from pcap files for offline analysis.
- * Interworking: Support added for 802.11u. Enable in .config with
- CONFIG_INTERWORKING. See wpa_supplicant.conf for config parameters
- for interworking. wpa_cli commands added to support this are
- interworking_select, interworking_connect, anqp_get, fetch_anqp,
- and stop_fetch_anqp.
- * Android: Add build and runtime support for Android wpa_supplicant.
- * bgscan learn: Add new bgscan that learns BSS information based on
- previous scans, and uses that information to dynamically generate
- the list of channels for background scans.
- * Add a new debug message level for excessive information. Use
- -ddd to enable.
- * TLS: Add support for tls_disable_time_checks=1 in client mode.
- * Internal TLS:
- - Add support for TLS v1.1 (RFC 4346). Enable with build parameter
- CONFIG_TLSV11.
- - Add domainComponent parser for X.509 names.
- * Linux: Add RFKill support by adding an interface state "disabled".
- * Reorder some IEs to get closer to IEEE 802.11 standard. Move
- WMM into end of Beacon, Probe Resp and (Re)Assoc Resp frames.
- Move HT IEs to be later in (Re)Assoc Resp.
- * Solaris: Add support for wired 802.1X client.
- * Wi-Fi Direct support. See README-P2P for more information.
- * Many bugfixes.
-
-2010-04-18 - v0.7.2
- * nl80211: fixed number of issues with roaming
- * avoid unnecessary roaming if multiple APs with similar signal
- strength are present in scan results
- * add TLS client events and server probing to ease design of
- automatic detection of EAP parameters
- * add option for server certificate matching (SHA256 hash of the
- certificate) instead of trusted CA certificate configuration
- * bsd: Cleaned up driver wrapper and added various low-level
- configuration options
- * wpa_gui-qt4: do not show too frequent WPS AP available events as
- tray messages
- * TNC: fixed issues with fragmentation
- * EAP-TNC: add Flags field into fragment acknowledgement (needed to
- interoperate with other implementations; may potentially breaks
- compatibility with older wpa_supplicant/hostapd versions)
- * wpa_cli: added option for using a separate process to receive event
- messages to reduce latency in showing these
- (CFLAGS += -DCONFIG_WPA_CLI_FORK=y in .config to enable this)
- * maximum BSS table size can now be configured (bss_max_count)
- * BSSes to be included in the BSS table can be filtered based on
- configured SSIDs to save memory (filter_ssids)
- * fix number of issues with IEEE 802.11r/FT; this version is not
- backwards compatible with old versions
- * nl80211: add support for IEEE 802.11r/FT protocol (both over-the-air
- and over-the-DS)
- * add freq_list network configuration parameter to allow the AP
- selection to filter out entries based on the operating channel
- * add signal strength change events for bgscan; this allows more
- dynamic changes to background scanning interval based on changes in
- the signal strength with the current AP; this improves roaming within
- ESS quite a bit, e.g., with bgscan="simple:30:-45:300" in the network
- configuration block to request background scans less frequently when
- signal strength remains good and to automatically trigger background
- scans whenever signal strength drops noticeably
- (this is currently only available with nl80211)
- * add BSSID and reason code (if available) to disconnect event messages
- * wpa_gui-qt4: more complete support for translating the GUI with
- linguist and add German translation
- * fix DH padding with internal crypto code (mainly, for WPS)
- * do not trigger initial scan automatically anymore if there are no
- enabled networks
-
-2010-01-16 - v0.7.1
- * cleaned up driver wrapper API (struct wpa_driver_ops); the new API
- is not fully backwards compatible, so out-of-tree driver wrappers
- will need modifications
- * cleaned up various module interfaces
- * merge hostapd and wpa_supplicant developers' documentation into a
- single document
- * nl80211: use explicit deauthentication to clear cfg80211 state to
- avoid issues when roaming between APs
- * dbus: major design changes in the new D-Bus API
- (fi.w1.wpa_supplicant1)
- * nl80211: added support for IBSS networks
- * added internal debugging mechanism with backtrace support and memory
- allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y)
- * added WPS ER unsubscription command to more cleanly unregister from
- receiving UPnP events when ER is terminated
- * cleaned up AP mode operations to avoid need for virtual driver_ops
- wrapper
- * added BSS table to maintain more complete scan result information
- over multiple scans (that may include only partial results)
- * wpa_gui-qt4: update Peers dialog information more dynamically while
- the dialog is kept open
- * fixed PKCS#12 use with OpenSSL 1.0.0
- * driver_wext: Added cfg80211-specific optimization to avoid some
- unnecessary scans and to speed up association
-
-2009-11-21 - v0.7.0
- * increased wpa_cli ping interval to 5 seconds and made this
- configurable with a new command line options (-G<seconds>)
- * fixed scan buffer processing with WEXT to handle up to 65535
- byte result buffer (previously, limited to 32768 bytes)
- * allow multiple driver wrappers to be specified on command line
- (e.g., -Dnl80211,wext); the first one that is able to initialize the
- interface will be used
- * added support for multiple SSIDs per scan request to optimize
- scan_ssid=1 operations in ap_scan=1 mode (i.e., search for hidden
- SSIDs); this requires driver support and can currently be used only
- with nl80211
- * added support for WPS USBA out-of-band mechanism with USB Flash
- Drives (UFD) (CONFIG_WPS_UFD=y)
- * driver_ndis: add PAE group address to the multicast address list to
- fix wired IEEE 802.1X authentication
- * fixed IEEE 802.11r key derivation function to match with the standard
- (note: this breaks interoperability with previous version) [Bug 303]
- * added better support for drivers that allow separate authentication
- and association commands (e.g., mac80211-based Linux drivers with
- nl80211; SME in wpa_supplicant); this allows over-the-air FT protocol
- to be used (IEEE 802.11r)
- * fixed SHA-256 based key derivation function to match with the
- standard when using CCMP (for IEEE 802.11r and IEEE 802.11w)
- (note: this breaks interoperability with previous version) [Bug 307]
- * use shared driver wrapper files with hostapd
- * added AP mode functionality (CONFIG_AP=y) with mode=2 in the network
- block; this can be used for open and WPA2-Personal networks
- (optionally, with WPS); this links in parts of hostapd functionality
- into wpa_supplicant
- * wpa_gui-qt4: added new Peers dialog to show information about peers
- (other devices, including APs and stations, etc. in the neighborhood)
- * added support for WPS External Registrar functionality (configure APs
- and enroll new devices); can be used with wpa_gui-qt4 Peers dialog
- and wpa_cli commands wps_er_start, wps_er_stop, wps_er_pin,
- wps_er_pbc, wps_er_learn
- (this can also be used with a new 'none' driver wrapper if no
- wireless device or IEEE 802.1X on wired is needed)
- * driver_nl80211: multiple updates to provide support for new Linux
- nl80211/mac80211 functionality
- * updated management frame protection to use IEEE Std 802.11w-2009
- * fixed number of small WPS issues and added workarounds to
- interoperate with common deployed broken implementations
- * added support for NFC out-of-band mechanism with WPS
- * driver_ndis: fixed wired IEEE 802.1X authentication with PAE group
- address frames
- * added preliminary support for IEEE 802.11r RIC processing
- * added support for specifying subset of enabled frequencies to scan
- (scan_freq option in the network configuration block); this can speed
- up scanning process considerably if it is known that only a small
- subset of channels is actually used in the network (this is currently
- supported only with -Dnl80211)
- * added a workaround for race condition between receiving the
- association event and the following EAPOL-Key
- * added background scan and roaming infrastructure to allow
- network-specific optimizations to be used to improve roaming within
- an ESS (same SSID)
- * added new DBus interface (fi.w1.wpa_supplicant1)
-
-2009-01-06 - v0.6.7
- * added support for Wi-Fi Protected Setup (WPS)
- (wpa_supplicant can now be configured to act as a WPS Enrollee to
- enroll credentials for a network using PIN and PBC methods; in
- addition, wpa_supplicant can act as a wireless WPS Registrar to
- configure an AP); WPS support can be enabled by adding CONFIG_WPS=y
- into .config and setting the runtime configuration variables in
- wpa_supplicant.conf (see WPS section in the example configuration
- file); new wpa_cli commands wps_pin, wps_pbc, and wps_reg are used to
- manage WPS negotiation; see README-WPS for more details
- * added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
- * added support for using driver_test over UDP socket
- * fixed PEAPv0 Cryptobinding interoperability issue with Windows Server
- 2008 NPS; optional cryptobinding is now enabled (again) by default
- * fixed PSK editing in wpa_gui
- * changed EAP-GPSK to use the IANA assigned EAP method type 51
- * added a Windows installer that includes WinPcap and all the needed
- DLLs; in addition, it set up the registry automatically so that user
- will only need start wpa_gui to get prompted to start the wpasvc
- servide and add a new interface if needed through wpa_gui dialog
- * updated management frame protection to use IEEE 802.11w/D7.0
-
-2008-11-23 - v0.6.6
- * added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA
- (can be used to simulate test SIM/USIM card with a known private key;
- enable with CONFIG_SIM_SIMULATOR=y/CONFIG_USIM_SIMULATOR=y in .config
- and password="Ki:OPc"/password="Ki:OPc:SQN" in network configuration)
- * added a new network configuration option, wpa_ptk_rekey, that can be
- used to enforce frequent PTK rekeying, e.g., to mitigate some attacks
- against TKIP deficiencies
- * added an optional mitigation mechanism for certain attacks against
- TKIP by delaying Michael MIC error reports by a random amount of time
- between 0 and 60 seconds; this can be enabled with a build option
- CONFIG_DELAYED_MIC_ERROR_REPORT=y in .config
- * fixed EAP-AKA to use RES Length field in AT_RES as length in bits,
- not bytes
- * updated OpenSSL code for EAP-FAST to use an updated version of the
- session ticket overriding API that was included into the upstream
- OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is
- needed with that version anymore)
- * updated userspace MLME instructions to match with the current Linux
- mac80211 implementation; please also note that this can only be used
- with driver_nl80211.c (the old code from driver_wext.c was removed)
- * added support (Linux only) for RoboSwitch chipsets (often found in
- consumer grade routers); driver interface 'roboswitch'
- * fixed canceling of PMKSA caching when using drivers that generate
- RSN IE and refuse to drop PMKIDs that wpa_supplicant does not know
- about
-
-2008-11-01 - v0.6.5
- * added support for SHA-256 as X.509 certificate digest when using the
- internal X.509/TLSv1 implementation
- * updated management frame protection to use IEEE 802.11w/D6.0
- * added support for using SHA256-based stronger key derivation for WPA2
- (IEEE 802.11w)
- * fixed FT (IEEE 802.11r) authentication after a failed association to
- use correct FTIE
- * added support for configuring Phase 2 (inner/tunneled) authentication
- method with wpa_gui-qt4
-
-2008-08-10 - v0.6.4
- * added support for EAP Sequences in EAP-FAST Phase 2
- * added support for using TNC with EAP-FAST
- * added driver_ps3 for the PS3 Linux wireless driver
- * added support for optional cryptobinding with PEAPv0
- * fixed the OpenSSL patches (0.9.8g and 0.9.9) for EAP-FAST to
- allow fallback to full handshake if server rejects PAC-Opaque
- * added fragmentation support for EAP-TNC
- * added support for parsing PKCS #8 formatted private keys into the
- internal TLS implementation (both PKCS #1 RSA key and PKCS #8
- encapsulated RSA key can now be used)
- * added option of using faster, but larger, routines in the internal
- LibTomMath (for internal TLS implementation) to speed up DH and RSA
- calculations (CONFIG_INTERNAL_LIBTOMMATH_FAST=y)
- * fixed race condition between disassociation event and group key
- handshake to avoid getting stuck in incorrect state [Bug 261]
- * fixed opportunistic key caching (proactive_key_caching)
-
-2008-02-22 - v0.6.3
- * removed 'nai' and 'eappsk' network configuration variables that were
- previously used for configuring user identity and key for EAP-PSK,
- EAP-PAX, EAP-SAKE, and EAP-GPSK. 'identity' field is now used as the
- replacement for 'nai' (if old configuration used a separate
- 'identity' value, that would now be configured as
- 'anonymous_identity'). 'password' field is now used as the
- replacement for 'eappsk' (it can also be set using hexstring to
- present random binary data)
- * removed '-w' command line parameter (wait for interface to be added,
- if needed); cleaner way of handling this functionality is to use an
- external mechanism (e.g., hotplug scripts) that start wpa_supplicant
- when an interface is added
- * updated FT support to use the latest draft, IEEE 802.11r/D9.0
- * added ctrl_iface monitor event (CTRL-EVENT-SCAN-RESULTS) for
- indicating when new scan results become available
- * added new ctrl_iface command, BSS, to allow scan results to be
- fetched without hitting the message size limits (this command
- can be used to iterate through the scan results one BSS at the time)
- * fixed EAP-SIM not to include AT_NONCE_MT and AT_SELECTED_VERSION
- attributes in EAP-SIM Start/Response when using fast reauthentication
- * fixed EAPOL not to end up in infinite loop when processing dynamic
- WEP keys with IEEE 802.1X
- * fixed problems in getting NDIS events from WMI on Windows 2000
-
-2008-01-01 - v0.6.2
- * added support for Makefile builds to include debug-log-to-a-file
- functionality (CONFIG_DEBUG_FILE=y and -f<path> on command line)
- * fixed EAP-SIM and EAP-AKA message parser to validate attribute
- lengths properly to avoid potential crash caused by invalid messages
- * added data structure for storing allocated buffers (struct wpabuf);
- this does not affect wpa_supplicant usage, but many of the APIs
- changed and various interfaces (e.g., EAP) is not compatible with old
- versions
- * added support for protecting EAP-AKA/Identity messages with
- AT_CHECKCODE (optional feature in RFC 4187)
- * added support for protected result indication with AT_RESULT_IND for
- EAP-SIM and EAP-AKA (phase1="result_ind=1")
- * added driver_wext workaround for race condition between scanning and
- association with drivers that take very long time to scan all
- channels (e.g., madwifi with dual-band cards); wpa_supplicant is now
- using a longer hardcoded timeout for the scan if the driver supports
- notifications for scan completion (SIOCGIWSCAN event); this helps,
- e.g., in cases where wpa_supplicant and madwifi driver ended up in
- loop where the driver did not even try to associate
- * stop EAPOL timer tick when no timers are in use in order to reduce
- power consumption (no need to wake up the process once per second)
- [Bug 237]
- * added support for privilege separation (run only minimal part of
- wpa_supplicant functionality as root and rest as unprivileged,
- non-root process); see 'Privilege separation' in README for details;
- this is disabled by default and can be enabled with CONFIG_PRIVSEP=y
- in .config
- * changed scan results data structure to include all information
- elements to make it easier to support new IEs; old get_scan_result()
- driver_ops is still supported for backwards compatibility (results
- are converted internally to the new format), but all drivers should
- start using the new get_scan_results2() to make them more likely to
- work with new features
- * Qt4 version of wpa_gui (wpa_gui-qt4 subdirectory) is now native Qt4
- application, i.e., it does not require Qt3Support anymore; Windows
- binary of wpa_gui.exe is now from this directory and only requires
- QtCore4.dll and QtGui4.dll libraries
- * updated Windows binary build to use Qt 4.3.3 and made Qt DLLs
- available as a separate package to make wpa_gui installation easier:
- http://w1.fi/wpa_supplicant/qt4/wpa_gui-qt433-windows-dll.zip
- * added support for EAP-IKEv2 (draft-tschofenig-eap-ikev2-15.txt);
- only shared key/password authentication is supported in this version
-
-2007-11-24 - v0.6.1
- * added support for configuring password as NtPasswordHash
- (16-byte MD4 hash of password) in hash:<32 hex digits> format
- * added support for fallback from abbreviated TLS handshake to
- full handshake when using EAP-FAST (e.g., due to an expired
- PAC-Opaque)
- * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
- draft (draft-ietf-emu-eap-gpsk-07.txt)
- * added support for drivers that take care of RSN 4-way handshake
- internally (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE in get_capa flags and
- WPA_ALG_PMK in set_key)
- * added an experimental port for Mac OS X (CONFIG_DRIVER_OSX=y in
- .config); this version supports only ap_scan=2 mode and allow the
- driver to take care of the 4-way handshake
- * fixed a buffer overflow in parsing TSF from scan results when using
- driver_wext.c with a driver that includes the TSF (e.g., iwl4965)
- [Bug 232]
- * updated FT support to use the latest draft, IEEE 802.11r/D8.0
- * fixed an integer overflow issue in the ASN.1 parser used by the
- (experimental) internal TLS implementation to avoid a potential
- buffer read overflow
- * fixed a race condition with -W option (wait for a control interface
- monitor before starting) that could have caused the first messages to
- be lost
- * added support for processing TNCC-TNCS-Messages to report
- recommendation (allow/none/isolate) when using TNC [Bug 243]
-
-2007-05-28 - v0.6.0
- * added network configuration parameter 'frequency' for setting
- initial channel for IBSS (adhoc) networks
- * added experimental IEEE 802.11r/D6.0 support
- * updated EAP-SAKE to RFC 4763 and the IANA-allocated EAP type 48
- * updated EAP-PSK to use the IANA-allocated EAP type 47
- * fixed EAP-PAX key derivation
- * fixed EAP-PSK bit ordering of the Flags field
- * fixed EAP-PEAP/TTLS/FAST to use the correct EAP identifier in
- tunnelled identity request (previously, the identifier from the outer
- method was used, not the tunnelled identifier which could be
- different)
- * added support for fragmentation of outer TLS packets during Phase 2
- of EAP-PEAP/TTLS/FAST
- * fixed EAP-TTLS AVP parser processing for too short AVP lengths
- * added support for EAP-FAST authentication with inner methods that
- generate MSK (e.g., EAP-MSCHAPv2 that was previously only supported
- for PAC provisioning)
- * added support for authenticated EAP-FAST provisioning
- * added support for configuring maximum number of EAP-FAST PACs to
- store in a PAC list (fast_max_pac_list_len=<max> in phase1 string)
- * added support for storing EAP-FAST PACs in binary format
- (fast_pac_format=binary in phase1 string)
- * fixed dbus ctrl_iface to validate message interface before
- dispatching to avoid a possible segfault [Bug 190]
- * fixed PeerKey key derivation to use the correct PRF label
- * updated Windows binary build to link against OpenSSL 0.9.8d and
- added support for EAP-FAST
- * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
- draft (draft-ietf-emu-eap-gpsk-04.txt)
- * fixed EAP-AKA Notification processing to allow Notification to be
- processed after AKA Challenge response has been sent
- * updated to use IEEE 802.11w/D2.0 for management frame protection
- (still experimental)
- * fixed EAP-TTLS implementation not to crash on use of freed memory
- if TLS library initialization fails
- * added support for EAP-TNC (Trusted Network Connect)
- (this version implements the EAP-TNC method and EAP-TTLS changes
- needed to run two methods in sequence (IF-T) and the IF-IMC and
- IF-TNCCS interfaces from TNCC)
-
-2006-11-24 - v0.5.6
- * added experimental, integrated TLSv1 client implementation with the
- needed X.509/ASN.1/RSA/bignum processing (this can be enabled by
- setting CONFIG_TLS=internal and CONFIG_INTERNAL_LIBTOMMATH=y in
- .config); this can be useful, e.g., if the target system does not
- have a suitable TLS library and a minimal code size is required
- (total size of this internal TLS/crypto code is bit under 50 kB on
- x86 and the crypto code is shared by rest of the supplicant so some
- of it was already required; TLSv1/X.509/ASN.1/RSA added about 25 kB)
- * removed STAKey handshake since PeerKey handshake has replaced it in
- IEEE 802.11ma and there are no known deployments of STAKey
- * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
- draft (draft-ietf-emu-eap-gpsk-01.txt)
- * added preliminary implementation of IEEE 802.11w/D1.0 (management
- frame protection)
- (Note: this requires driver support to work properly.)
- (Note2: IEEE 802.11w is an unapproved draft and subject to change.)
- * fixed Windows named pipes ctrl_iface to not stop listening for
- commands if client program opens a named pipe and closes it
- immediately without sending a command
- * fixed USIM PIN status determination for the case that PIN is not
- needed (this allows EAP-AKA to be used with USIM cards that do not
- use PIN)
- * added support for reading 3G USIM AID from EF_DIR to allow EAP-AKA to
- be used with cards that do not support file selection based on
- partial AID
- * added support for matching the subjectAltName of the authentication
- server certificate against multiple name components (e.g.,
- altsubject_match="DNS:server.example.com;DNS:server2.example.com")
- * fixed EAP-SIM/AKA key derivation for re-authentication case (only
- affects IEEE 802.1X with dynamic WEP keys)
- * changed ctrl_iface network configuration 'get' operations to not
- return password/key material; if these fields are requested, "*"
- will be returned if the password/key is set, but the value of the
- parameter is not exposed
-
-2006-08-27 - v0.5.5
- * added support for building Windows version with UNICODE defined
- (wide-char functions)
- * driver_ndis: fixed static WEP configuration to avoid race condition
- issues with some NDIS drivers between association and setting WEP
- keys
- * driver_ndis: added validation for IELength value in scan results to
- avoid crashes when using buggy NDIS drivers [Bug 165]
- * fixed Release|Win32 target in the Visual Studio project files
- (previously, only Debug|Win32 target was set properly)
- * changed control interface API call wpa_ctrl_pending() to allow it to
- return -1 on error (e.g., connection lost); control interface clients
- will need to make sure that they verify that the value is indeed >0
- when determining whether there are pending messages
- * added an alternative control interface backend for Windows targets:
- Named Pipe (CONFIG_CTRL_IFACE=named_pipe); this is now the default
- control interface mechanism for Windows builds (previously, UDP to
- localhost was used)
- * changed ctrl_interface configuration for UNIX domain sockets:
- - deprecated ctrl_interface_group variable (it may be removed in
- future versions)
- - allow both directory and group be configured with ctrl_interface
- in following format: DIR=/var/run/wpa_supplicant GROUP=wheel
- - ctrl_interface=/var/run/wpa_supplicant is still supported for the
- case when group is not changed
- * added support for controlling more than one interface per process in
- Windows version
- * added a workaround for a case where the AP is using unknown address
- (e.g., MAC address of the wired interface) as the source address for
- EAPOL-Key frames; previously, that source address was used as the
- destination for EAPOL-Key frames and in key derivation; now, BSSID is
- used even if the source address does not match with it
- (this resolves an interoperability issue with Thomson SpeedTouch 580)
- * added a workaround for UDP-based control interface (which was used in
- Windows builds before this release) to prevent packets with forged
- addresses from being accepted as local control requests
- * removed ndis_events.cpp and possibility of using external
- ndis_events.exe; C version (ndis_events.c) is fully functional and
- there is no desire to maintain two separate versions of this
- implementation
- * ndis_events: Changed NDIS event notification design to use WMI to
- learn the adapter description through Win32_PnPEntity class; this
- should fix some cases where the adapter name was not recognized
- correctly (e.g., with some USB WLAN adapters, e.g., Ralink RT2500
- USB) [Bug 113]
- * fixed selection of the first network in ap_scan=2 mode; previously,
- wpa_supplicant could get stuck in SCANNING state when only the first
- network for enabled (e.g., after 'wpa_cli select_network 0')
- * winsvc: added support for configuring ctrl_interface parameters in
- registry (ctrl_interface string value in
- HKLM\SOFTWARE\wpa_supplicant\interfaces\0000 key); this new value is
- required to enable control interface (previously, this was hardcoded
- to be enabled)
- * allow wpa_gui subdirectory to be built with both Qt3 and Qt4
- * converted wpa_gui-qt4 subdirectory to use Qt4 specific project format
-
-2006-06-20 - v0.5.4
- * fixed build with CONFIG_STAKEY=y [Bug 143]
- * added support for doing MLME (IEEE 802.11 management frame
- processing) in wpa_supplicant when using Devicescape IEEE 802.11
- stack (wireless-dev.git tree)
- * added a new network block configuration option, fragment_size, to
- configure the maximum EAP fragment size
- * driver_ndis: Disable WZC automatically for the selected interface to
- avoid conflicts with two programs trying to control the radio; WZC
- will be re-enabled (if it was enabled originally) when wpa_supplicant
- is terminated
- * added an experimental TLSv1 client implementation
- (CONFIG_TLS=internal) that can be used instead of an external TLS
- library, e.g., to reduce total size requirement on systems that do
- not include any TLS library by default (this is not yet complete;
- basic functionality is there, but certificate validation is not yet
- included)
- * added PeerKey handshake implementation for IEEE 802.11e
- direct link setup (DLS) to replace STAKey handshake
- * fixed WPA PSK update through ctrl_iface for the case where the old
- PSK was derived from an ASCII passphrase and the new PSK is set as
- a raw PSK (hex string)
- * added new configuration option for identifying which network block
- was used (id_str in wpa_supplicant.conf; included on
- WPA_EVENT_CONNECT monitor event and as WPA_ID_STR environmental
- variable in wpa_cli action scripts; in addition WPA_ID variable is
- set to the current unique identifier that wpa_supplicant assigned
- automatically for the network and that can be used with
- GET_NETWORK/SET_NETWORK ctrl_iface commands)
- * wpa_cli action script is now called only when the connect/disconnect
- status changes or when associating with a different network
- * fixed configuration parser not to remove CCMP from group cipher list
- if WPA-None (adhoc) is used (pairwise=NONE in that case)
- * fixed integrated NDIS events processing not to hang the process due
- to a missed change in eloop_win.c API in v0.5.3 [Bug 155]
- * added support for EAP Generalized Pre-Shared Key (EAP-GPSK,
- draft-clancy-emu-eap-shared-secret-00.txt)
- * added Microsoft Visual Studio 2005 solution and project files for
- build wpa_supplicant for Windows (see vs2005 subdirectory)
- * eloop_win: fixed unregistration of Windows events
- * l2_packet_winpcap: fixed a deadlock in deinitializing l2_packet
- at the end of RSN pre-authentication and added unregistration of
- a Windows event to avoid getting eloop_win stuck with an invalid
- handle
- * driver_ndis: added support for selecting AP based on BSSID
- * added new environmental variable for wpa_cli action scripts:
- WPA_CTRL_DIR is the current control interface directory
- * driver_ndis: added support for using NDISUIO instead of WinPcap for
- OID set/query operations (CONFIG_USE_NDISUIO=y in .config); with new
- l2_packet_ndis (CONFIG_L2_PACKET=ndis), this can be used to build
- wpa_supplicant without requiring WinPcap; note that using NDISUIO
- requires that WZC is disabled (net stop wzcsvc) since NDISUIO allows
- only one application to open the device
- * changed NDIS driver naming to only include device GUID, e.g.,
- {7EE3EFE5-C165-472F-986D-F6FBEDFE8C8D}, instead of including WinPcap
- specific \Device\NPF_ prefix before the GUID; the prefix is still
- allowed for backwards compatibility, but it is not required anymore
- when specifying the interface
- * driver_ndis: re-initialize driver interface is the adapter is removed
- and re-inserted [Bug 159]
- * driver_madwifi: fixed TKIP and CCMP sequence number configuration on
- big endian hosts [Bug 146]
-
-2006-04-27 - v0.5.3
- * fixed EAP-GTC response to include correct user identity when run as
- phase 2 method of EAP-FAST (i.e., EAP-FAST did not work in v0.5.2)
- * driver_ndis: Fixed encryption mode configuration for unencrypted
- networks (some NDIS drivers ignored this, but others, e.g., Broadcom,
- refused to associate with open networks) [Bug 106]
- * driver_ndis: use BSSID OID polling to detect when IBSS network is
- formed even when ndis_events code is included since some NDIS drivers
- do not generate media connect events in IBSS mode
- * config_winreg: allow global ctrl_interface parameter to be configured
- in Windows registry
- * config_winreg: added support for saving configuration data into
- Windows registry
- * added support for controlling network device operational state
- (dormant/up) for Linux 2.6.17 to improve DHCP processing (see
- http://www.flamewarmaster.de/software/dhcpclient/ for a DHCP client
- that can use this information)
- * driver_wext: added support for WE-21 change to SSID configuration
- * driver_wext: fixed privacy configuration for static WEP keys mode
- [Bug 140]
- * added an optional driver_ops callback for MLME-SETPROTECTION.request
- primitive
- * added support for EAP-SAKE (no EAP method number allocated yet, so
- this is using the same experimental type 255 as EAP-PSK)
- * added support for dynamically loading EAP methods (.so files) instead
- of requiring them to be statically linked in; this is disabled by
- default (see CONFIG_DYNAMIC_EAP_METHODS in defconfig for information
- on how to use this)
-
-2006-03-19 - v0.5.2
- * do not try to use USIM APDUs when initializing PC/SC for SIM card
- access for a network that has not enabled EAP-AKA
- * fixed EAP phase 2 Nak for EAP-{PEAP,TTLS,FAST} (this was broken in
- v0.5.1 due to the new support for expanded EAP types)
- * added support for generating EAP Expanded Nak
- * try to fetch scan results once before requesting new scan when
- starting up in ap_scan=1 mode (this can speed up initial association
- a lot with, e.g., madwifi-ng driver)
- * added support for receiving EAPOL frames from a Linux bridge
- interface (-bbr0 on command line)
- * fixed EAPOL re-authentication for sessions that used PMKSA caching
- * changed EAP method registration to use a dynamic list of methods
- instead of a static list generated at build time
- * fixed PMKSA cache deinitialization not to use freed memory when
- removing PMKSA entries
- * fixed a memory leak in EAP-TTLS re-authentication
- * reject WPA/WPA2 message 3/4 if it does not include any valid
- WPA/RSN IE
- * driver_wext: added fallback to use SIOCSIWENCODE for setting auth_alg
- if the driver does not support SIOCSIWAUTH
-
-2006-01-29 - v0.5.1
- * driver_test: added better support for multiple APs and STAs by using
- a directory with sockets that include MAC address for each device in
- the name (driver_param=test_dir=/tmp/test)
- * added support for EAP expanded type (vendor specific EAP methods)
- * added AP_SCAN command into ctrl_iface so that ap_scan configuration
- option can be changed if needed
- * wpa_cli/wpa_gui: skip non-socket files in control directory when
- using UNIX domain sockets; this avoids selecting an incorrect
- interface (e.g., a PID file could be in this directory, even though
- use of this directory for something else than socket files is not
- recommended)
- * fixed TLS library deinitialization after RSN pre-authentication not
- to disable TLS library for normal authentication
- * driver_wext: Remove null-termination from SSID length if the driver
- used it; some Linux drivers do this and they were causing problems in
- wpa_supplicant not finding matching configuration block. This change
- would break a case where the SSID actually ends in '\0', but that is
- not likely to happen in real use.
- * fixed PMKSA cache processing not to trigger deauthentication if the
- current PMKSA cache entry is replaced with a valid new entry
- * fixed PC/SC initialization for ap_scan != 1 modes (this fixes
- EAP-SIM and EAP-AKA with real SIM/USIM card when using ap_scan=0 or
- ap_scan=2)
-
-2005-12-18 - v0.5.0 (beginning of 0.5.x development releases)
- * added experimental STAKey handshake implementation for IEEE 802.11e
- direct link setup (DLS); note: this is disabled by default in both
- build and runtime configuration (can be enabled with CONFIG_STAKEY=y
- and stakey=1)
- * fixed EAP-SIM and EAP-AKA pseudonym and fast re-authentication to
- decrypt AT_ENCR_DATA attributes correctly
- * fixed EAP-AKA to allow resynchronization within the same session
- * made code closer to ANSI C89 standard to make it easier to port to
- other C libraries and compilers
- * started moving operating system or C library specific functions into
- wrapper functions defined in os.h and implemented in os_*.c to make
- code more portable
- * wpa_supplicant can now be built with Microsoft Visual C++
- (e.g., with the freely available Toolkit 2003 version or Visual
- C++ 2005 Express Edition and Platform SDK); see nmake.mak for an
- example makefile for nmake
- * added support for using Windows registry for command line parameters
- (CONFIG_MAIN=main_winsvc) and configuration data
- (CONFIG_BACKEND=winreg); see win_example.reg for an example registry
- contents; this version can be run both as a Windows service and as a
- normal application; 'wpasvc.exe app' to start as applicant,
- 'wpasvc.exe reg <full path to wpasvc.exe>' to register a service,
- 'net start wpasvc' to start the service, 'wpasvc.exe unreg' to
- unregister a service
- * made it possible to link ndis_events.exe functionality into
- wpa_supplicant.exe by defining CONFIG_NDIS_EVENTS_INTEGRATED
- * added better support for multiple control interface backends
- (CONFIG_CTRL_IFACE option); currently, 'unix' and 'udp' are supported
- * fixed PC/SC code to use correct length for GSM AUTH command buffer
- and to not use pioRecvPci with SCardTransmit() calls; these were not
- causing visible problems with pcsc-lite, but Windows Winscard.dll
- refused the previously used parameters; this fixes EAP-SIM and
- EAP-AKA authentication using SIM/USIM card under Windows
- * added new event loop implementation for Windows using
- WaitForMultipleObject() instead of select() in order to allow waiting
- for non-socket objects; this can be selected with
- CONFIG_ELOOP=eloop_win in .config
- * added support for selecting l2_packet implementation in .config
- (CONFIG_L2_PACKET; following options are available now: linux, pcap,
- winpcap, freebsd, none)
- * added new l2_packet implementation for WinPcap
- (CONFIG_L2_PACKET=winpcap) that uses a separate receive thread to
- reduce latency in EAPOL receive processing from about 100 ms to about
- 3 ms
- * added support for EAP-FAST key derivation using other ciphers than
- RC4-128-SHA for authentication and AES128-SHA for provisioning
- * added support for configuring CA certificate as DER file and as a
- configuration blob
- * fixed private key configuration as configuration blob and added
- support for using PKCS#12 as a blob
- * tls_gnutls: added support for using PKCS#12 files; added support for
- session resumption
- * added support for loading trusted CA certificates from Windows
- certificate store: ca_cert="cert_store://<name>", where <name> is
- likely CA (Intermediate CA certificates) or ROOT (root certificates)
- * added C version of ndis_events.cpp and made it possible to build this
- with MinGW so that CONFIG_NDIS_EVENTS_INTEGRATED can be used more
- easily on cross-compilation builds
- * added wpasvc.exe into Windows binary release; this is an alternative
- version of wpa_supplicant.exe with configuration backend using
- Windows registry and with the entry point designed to run as a
- Windows service
- * integrated ndis_events.exe functionality into wpa_supplicant.exe and
- wpasvc.exe and removed this additional tool from the Windows binary
- release since it is not needed anymore
- * load winscard.dll functions dynamically when building with MinGW
- since MinGW does not yet include winscard library
-
-2005-11-20 - v0.4.7 (beginning of 0.4.x stable releases)
- * l2_packet_pcap: fixed wired IEEE 802.1X authentication with libpcap
- and WinPcap to receive frames sent to PAE group address
- * disable EAP state machine when IEEE 802.1X authentication is not used
- in order to get rid of bogus "EAP failed" messages
- * fixed OpenSSL error reporting to go through all pending errors to
- avoid confusing reports of old errors being reported at later point
- during handshake
- * fixed configuration file updating to not write empty variables
- (e.g., proto or key_mgmt) that the file parser would not accept
- * fixed ADD_NETWORK ctrl_iface command to use the same default values
- for variables as empty network definitions read from config file
- would get
- * fixed EAP state machine to not discard EAP-Failure messages in many
- cases (e.g., during TLS handshake)
- * fixed a infinite loop in private key reading if the configured file
- cannot be parsed successfully
- * driver_madwifi: added support for madwifi-ng
- * wpa_gui: do not display password/PSK field contents
- * wpa_gui: added CA certificate configuration
- * driver_ndis: fixed scan request in ap_scan=2 mode not to change SSID
- * driver_ndis: include Beacon IEs in AssocInfo in order to notice if
- the new AP is using different WPA/RSN IE
- * use longer timeout for IEEE 802.11 association to avoid problems with
- drivers that may take more than five second to associate
-
-2005-10-27 - v0.4.6
- * allow fallback to WPA, if mixed WPA+WPA2 networks have mismatch in
- RSN IE, but WPA IE would match with wpa_supplicant configuration
- * added support for named configuration blobs in order to avoid having
- to use file system for external files (e.g., certificates);
- variables can be set to "blob://<blob name>" instead of file path to
- use a named blob; supported fields: pac_file, client_cert,
- private_key
- * fixed RSN pre-authentication (it was broken in the clean up of WPA
- state machine interface in v0.4.5)
- * driver_madwifi: set IEEE80211_KEY_GROUP flag for group keys to make
- sure the driver configures broadcast decryption correctly
- * added ca_path (and ca_path2) configuration variables that can be used
- to configure OpenSSL CA path, e.g., /etc/ssl/certs, for using the
- system-wide trusted CA list
- * added support for starting wpa_supplicant without a configuration
- file (-C argument must be used to set ctrl_interface parameter for
- this case; in addition, -p argument can be used to provide
- driver_param; these new arguments can also be used with a
- configuration to override the values from the configuration)
- * added global control interface that can be optionally used for adding
- and removing network interfaces dynamically (-g command line argument
- for both wpa_supplicant and wpa_cli) without having to restart
- wpa_supplicant process
- * wpa_gui:
- - try to save configuration whenever something is modified
- - added WEP key configuration
- - added possibility to edit the current network configuration
- * driver_ndis: fixed driver polling not to increase frequency on each
- received EAPOL frame due to incorrectly cancelled timeout
- * added simple configuration file examples (in examples subdirectory)
- * fixed driver_wext.c to filter wireless events based on ifindex to
- avoid interfaces receiving events from other interfaces
- * delay sending initial EAPOL-Start couple of seconds to speed up
- authentication for the most common case of Authenticator starting
- EAP authentication immediately after association
-
-2005-09-25 - v0.4.5
- * added a workaround for clearing keys with ndiswrapper to allow
- roaming from WPA enabled AP to plaintext one
- * added docbook documentation (doc/docbook) that can be used to
- generate, e.g., man pages
- * l2_packet_linux: use socket type SOCK_DGRAM instead of SOCK_RAW for
- PF_PACKET in order to prepare for network devices that do not use
- Ethernet headers (e.g., network stack that includes IEEE 802.11
- header in the frames)
- * use receipt of EAPOL-Key frame as a lower layer success indication
- for EAP state machine to allow recovery from dropped EAP-Success
- frame
- * cleaned up internal EAPOL frame processing by not including link
- layer (Ethernet) header during WPA and EAPOL/EAP processing; this
- header is added only when transmitted the frame; this makes it easier
- to use wpa_supplicant on link layers that use different header than
- Ethernet
- * updated EAP-PSK to use draft 9 by default since this can now be
- tested with hostapd; removed support for draft 3, including
- server_nai configuration option from network blocks
- * driver_wired: add PAE address to the multicast address list in order
- to be able to receive EAPOL frames with drivers that do not include
- these multicast addresses by default
- * driver_wext: add support for WE-19
- * added support for multiple configuration backends (CONFIG_BACKEND
- option); currently, only 'file' is supported (i.e., the format used
- in wpa_supplicant.conf)
- * added support for updating configuration ('wpa_cli save_config');
- this is disabled by default and can be enabled with global
- update_config=1 variable in wpa_supplicant.conf; this allows wpa_cli
- and wpa_gui to store the configuration changes in a permanent store
- * added GET_NETWORK ctrl_iface command
- (e.g., 'wpa_cli get_network 0 ssid')
-
-2005-08-21 - v0.4.4
- * replaced OpenSSL patch for EAP-FAST support
- (openssl-tls-extensions.patch) with a more generic and correct
- patch (the new patch is not compatible with the previous one, so the
- OpenSSL library will need to be patched with the new patch in order
- to be able to build wpa_supplicant with EAP-FAST support)
- * added support for using Windows certificate store (through CryptoAPI)
- for client certificate and private key operations (EAP-TLS)
- (see wpa_supplicant.conf for more information on how to configure
- this with private_key)
- * ported wpa_gui to Windows
- * added Qt4 version of wpa_gui (wpa_gui-qt4 directory); this can be
- built with the open source version of the Qt4 for Windows
- * allow non-WPA modes (e.g., IEEE 802.1X with dynamic WEP) to be used
- with drivers that do not support WPA
- * ndis_events: fixed Windows 2000 support
- * added support for enabling/disabling networks from the list of all
- configured networks ('wpa_cli enable_network <network id>' and
- 'wpa_cli disable_network <network id>')
- * added support for adding and removing network from the current
- configuration ('wpa_cli add_network' and 'wpa_cli remove_network
- <network id>'); added networks are disabled by default and they can
- be enabled with enable_network command once the configuration is done
- for the new network; note: configuration file is not yet updated, so
- these new networks are lost when wpa_supplicant is restarted
- * added support for setting network configuration parameters through
- the control interface, for example:
- wpa_cli set_network 0 ssid "\"my network\""
- * fixed parsing of strings that include both " and # within double
- quoted area (e.g., "start"#end")
- * added EAP workaround for PEAP session resumption: allow outer,
- i.e., not tunneled, EAP-Success to terminate session since; this can
- be disabled with eap_workaround=0
- (this was allowed for PEAPv1 before, but now it is also allowed for
- PEAPv0 since at least one RADIUS authentication server seems to be
- doing this for PEAPv0, too)
- * wpa_gui: added preliminary support for adding new networks to the
- wpa_supplicant configuration (double click on the scan results to
- open network configuration)
-
-2005-06-26 - v0.4.3
- * removed interface for external EAPOL/EAP supplicant (e.g.,
- Xsupplicant), (CONFIG_XSUPPLICANT_IFACE) since it is not required
- anymore and is unlikely to be used by anyone
- * driver_ndis: fixed WinPcap 3.0 support
- * fixed build with CONFIG_DNET_PCAP=y on Linux
- * l2_packet: moved different implementations into separate files
- (l2_packet_*.c)
-
-2005-06-12 - v0.4.2
- * driver_ipw: updated driver structures to match with ipw2200-1.0.4
- (note: ipw2100-1.1.0 is likely to require an update to work with
- this)
- * added support for using ap_scan=2 mode with multiple network blocks;
- wpa_supplicant will go through the networks one by one until the
- driver reports a successful association; this uses the same order for
- networks as scan_ssid=1 scans, i.e., the priority field is ignored
- and the network block order in the file is used instead
- * fixed a potential issue in RSN pre-authentication ending up using
- freed memory if pre-authentication times out
- * added support for matching alternative subject name extensions of the
- authentication server certificate; new configuration variables
- altsubject_match and altsubject_match2
- * driver_ndis: added support for IEEE 802.1X authentication with wired
- NDIS drivers
- * added support for querying private key password (EAP-TLS) through the
- control interface (wpa_cli/wpa_gui) if one is not included in the
- configuration file
- * driver_broadcom: fixed couple of memory leaks in scan result
- processing
- * EAP-PAX is now registered as EAP type 46
- * fixed EAP-PAX MAC calculation
- * fixed EAP-PAX CK and ICK key derivation
- * added support for using password with EAP-PAX (as an alternative to
- entering key with eappsk); SHA-1 hash of the password will be used as
- the key in this case
- * added support for arbitrary driver interface parameters through the
- configuration file with a new driver_param field; this adds a new
- driver_ops function set_param()
- * added possibility to override l2_packet module with driver interface
- API (new send_eapol handler); this can be used to implement driver
- specific TX/RX functions for EAPOL frames
- * fixed ctrl_interface_group processing for the case where gid is
- entered as a number, not group name
- * driver_test: added support for testing hostapd with wpa_supplicant
- by using test driver interface without any kernel drivers or network
- cards
-
-2005-05-22 - v0.4.1
- * driver_madwifi: fixed WPA/WPA2 mode configuration to allow EAPOL
- packets to be encrypted; this was apparently broken by the changed
- ioctl order in v0.4.0
- * driver_madwifi: added preliminary support for compiling against 'BSD'
- branch of madwifi CVS tree
- * added support for EAP-MSCHAPv2 password retries within the same EAP
- authentication session
- * added support for password changes with EAP-MSCHAPv2 (used when the
- password has expired)
- * added support for reading additional certificates from PKCS#12 files
- and adding them to the certificate chain
- * fixed association with IEEE 802.1X (no WPA) when dynamic WEP keys
- were used
- * fixed a possible double free in EAP-TTLS fast-reauthentication when
- identity or password is entered through control interface
- * display EAP Notification messages to user through control interface
- with "CTRL-EVENT-EAP-NOTIFICATION" prefix
- * added GUI version of wpa_cli, wpa_gui; this is not build
- automatically with 'make'; use 'make wpa_gui' to build (this requires
- Qt development tools)
- * added 'disconnect' command to control interface for setting
- wpa_supplicant in state where it will not associate before
- 'reassociate' command has been used
- * added support for selecting a network from the list of all configured
- networks ('wpa_cli select_network <network id>'; this disabled all
- other networks; to re-enable, 'wpa_cli select_network any')
- * added support for getting scan results through control interface
- * added EAP workaround for PEAPv1 session resumption: allow outer,
- i.e., not tunneled, EAP-Success to terminate session since; this can
- be disabled with eap_workaround=0
-
-2005-04-25 - v0.4.0 (beginning of 0.4.x development releases)
- * added a new build time option, CONFIG_NO_STDOUT_DEBUG, that can be
- used to reduce the size of the wpa_supplicant considerably if
- debugging code is not needed
- * fixed EAPOL-Key validation to drop packets with invalid Key Data
- Length; such frames could have crashed wpa_supplicant due to buffer
- overflow
- * added support for wired authentication (IEEE 802.1X on wired
- Ethernet); driver interface 'wired'
- * obsoleted set_wpa() handler in the driver interface API (it can be
- replaced by moving enable/disable functionality into init()/deinit())
- (calls to set_wpa() are still present for backwards compatibility,
- but they may be removed in the future)
- * driver_madwifi: fixed association in plaintext mode
- * modified the EAP workaround that accepts EAP-Success with incorrect
- Identifier to be even less strict about verification in order to
- interoperate with some authentication servers
- * added support for sending TLS alerts
- * added support for 'any' SSID wildcard; if ssid is not configured or
- is set to an empty string, any SSID will be accepted for non-WPA AP
- * added support for asking PIN (for SIM) from frontends (e.g.,
- wpa_cli); if a PIN is needed, but not included in the configuration
- file, a control interface request is sent and EAP processing is
- delayed until the PIN is available
- * added support for using external devices (e.g., a smartcard) for
- private key operations in EAP-TLS (CONFIG_SMARTCARD=y in .config);
- new wpa_supplicant.conf variables:
- - global: opensc_engine_path, pkcs11_engine_path, pkcs11_module_path
- - network: engine, engine_id, key_id
- * added experimental support for EAP-PAX
- * added monitor mode for wpa_cli (-a<path to a program to run>) that
- allows external commands (e.g., shell scripts) to be run based on
- wpa_supplicant events, e.g., when authentication has been completed
- and data connection is ready; other related wpa_cli arguments:
- -B (run in background), -P (write PID file); wpa_supplicant has a new
- command line argument (-W) that can be used to make it wait until a
- control interface command is received in order to avoid missing
- events
- * added support for opportunistic WPA2 PMKSA key caching (disabled by
- default, can be enabled with proactive_key_caching=1)
- * fixed RSN IE in 4-Way Handshake message 2/4 for the case where
- Authenticator rejects PMKSA caching attempt and the driver is not
- using assoc_info events
- * added -P<pid file> argument for wpa_supplicant to write the current
- process id into a file
-
-2005-02-12 - v0.3.7 (beginning of 0.3.x stable releases)
- * added new phase1 option parameter, include_tls_length=1, to force
- wpa_supplicant to add TLS Message Length field to all TLS messages
- even if the packet is not fragmented; this may be needed with some
- authentication servers
- * fixed WPA/RSN IE verification in message 3 of 4-Way Handshake when
- using drivers that take care of AP selection (e.g., when using
- ap_scan=2)
- * fixed reprocessing of pending request after ctrl_iface requests for
- identity/password/otp
- * fixed ctrl_iface requests for identity/password/otp in Phase 2 of
- EAP-PEAP and EAP-TTLS
- * all drivers using driver_wext: set interface up and select Managed
- mode when starting wpa_supplicant; set interface down when exiting
- * renamed driver_ipw2100.c to driver_ipw.c since it now supports both
- ipw2100 and ipw2200; please note that this also changed the
- configuration variable in .config to CONFIG_DRIVER_IPW
-
-2005-01-24 - v0.3.6
- * fixed a busy loop introduced in v0.3.5 for scan result processing
- when no matching AP is found
-
-2005-01-23 - v0.3.5
- * added a workaround for an interoperability issue with a Cisco AP
- when using WPA2-PSK
- * fixed non-WPA IEEE 802.1X to use the same authentication timeout as
- WPA with IEEE 802.1X (i.e., timeout 10 -> 70 sec to allow
- retransmission of dropped frames)
- * fixed issues with 64-bit CPUs and SHA1 cleanup in previous version
- (e.g., segfault when processing EAPOL-Key frames)
- * fixed EAP workaround and fast reauthentication configuration for
- RSN pre-authentication; previously these were disabled and
- pre-authentication would fail if the used authentication server
- requires EAP workarounds
- * added support for blacklisting APs that fail or timeout
- authentication in ap_scan=1 mode so that all APs are tried in cases
- where the ones with strongest signal level are failing authentication
- * fixed CA certificate loading after a failed EAP-TLS/PEAP/TTLS
- authentication attempt
- * allow EAP-PEAP/TTLS fast reauthentication only if Phase 2 succeeded
- in the previous authentication (previously, only Phase 1 success was
- verified)
-
-2005-01-09 - v0.3.4
- * added preliminary support for IBSS (ad-hoc) mode configuration
- (mode=1 in network block); this included a new key_mgmt mode
- WPA-NONE, i.e., TKIP or CCMP with a fixed key (based on psk) and no
- key management; see wpa_supplicant.conf for more details and an
- example on how to configure this (note: this is currently implemented
- only for driver_hostapd.c, but the changes should be trivial to add
- in associate() handler for other drivers, too (assuming the driver
- supports WPA-None)
- * added preliminary port for native Windows (i.e., no cygwin) using
- mingw
-
-2005-01-02 - v0.3.3
- * added optional support for GNU Readline and History Libraries for
- wpa_cli (CONFIG_READLINE)
- * cleaned up EAP state machine <-> method interface and number of
- small problems with error case processing not terminating on
- EAP-Failure but waiting for timeout
- * added couple of workarounds for interoperability issues with a
- Cisco AP when using WPA2
- * added support for EAP-FAST (draft-cam-winget-eap-fast-00.txt);
- Note: This requires a patch for openssl to add support for TLS
- extensions and number of workarounds for operations without
- certificates. Proof of concept type of experimental patch is
- included in openssl-tls-extensions.patch.
-
-2004-12-19 - v0.3.2
- * fixed private key loading for cases where passphrase is not set
- * fixed Windows/cygwin L2 packet handler freeing; previous version
- could cause a segfault when RSN pre-authentication was completed
- * added support for PMKSA caching with drivers that generate RSN IEs
- (e.g., NDIS); currently, this is only implemented in driver_ndis.c,
- but similar code can be easily added to driver_ndiswrapper.c once
- ndiswrapper gets full support for RSN PMKSA caching
- * improved recovery from PMKID mismatches by requesting full EAP
- authentication in case of failed PMKSA caching attempt
- * driver_ndis: added support for NDIS NdisMIncidateStatus() events
- (this requires that ndis_events is ran while wpa_supplicant is
- running)
- * driver_ndis: use ADD_WEP/REMOVE_WEP when configuring WEP keys
- * added support for driver interfaces to replace the interface name
- based on driver/OS specific mapping, e.g., in case of driver_ndis,
- this allows the beginning of the adapter description to be used as
- the interface name
- * added support for CR+LF (Windows-style) line ends in configuration
- file
- * driver_ndis: enable radio before starting scanning, disable radio
- when exiting
- * modified association event handler to set portEnabled = FALSE before
- clearing port Valid in order to reset EAP state machine and avoid
- problems with new authentication getting ignored because of state
- machines ending up in AUTHENTICATED/SUCCESS state based on old
- information
- * added support for driver events to add PMKID candidates in order to
- allow drivers to give priority to most likely roaming candidates
- * driver_hostap: moved PrivacyInvoked configuration to associate()
- function so that this will not be set for plaintext connections
- * added KEY_MGMT_802_1X_NO_WPA as a new key_mgmt type so that driver
- interface can distinguish plaintext and IEEE 802.1X (no WPA)
- authentication
- * fixed static WEP key configuration to use broadcast/default type for
- all keys (previously, the default TX key was configured as pairwise/
- unicast key)
- * driver_ndis: added legacy WPA capability detection for non-WPA2
- drivers
- * added support for setting static WEP keys for IEEE 802.1X without
- dynamic WEP keying (eapol_flags=0)
-
-2004-12-12 - v0.3.1
- * added support for reading PKCS#12 (PFX) files (as a replacement for
- PEM/DER) to get certificate and private key (CONFIG_PKCS12)
- * fixed compilation with CONFIG_PCSC=y
- * added new ap_scan mode, ap_scan=2, for drivers that take care of
- association, but need to be configured with security policy and SSID,
- e.g., ndiswrapper and NDIS driver; this mode should allow such
- drivers to work with hidden SSIDs and optimized roaming; when
- ap_scan=2 is used, only the first network block in the configuration
- file is used and this configuration should have explicit security
- policy (i.e., only one option in the lists) for key_mgmt, pairwise,
- group, proto variables
- * added experimental port of wpa_supplicant for Windows
- - driver_ndis.c driver interface (NDIS OIDs)
- - currently, this requires cygwin and WinPcap
- - small utility, win_if_list, can be used to get interface name
- * control interface can now be removed at build time; add
- CONFIG_CTRL_IFACE=y to .config to maintain old functionality
- * optional Xsupplicant interface can now be removed at build time;
- (CONFIG_XSUPPLICANT_IFACE=y in .config to bring it back)
- * added auth_alg to driver interface associate() parameters to make it
- easier for drivers to configure authentication algorithm as part of
- the association
-
-2004-12-05 - v0.3.0 (beginning of 0.3.x development releases)
- * driver_broadcom: added new driver interface for Broadcom wl.o driver
- (a generic driver for Broadcom IEEE 802.11a/g cards)
- * wpa_cli: fixed parsing of -p <path> command line argument
- * PEAPv1: fixed tunneled EAP-Success reply handling to reply with TLS
- ACK, not tunneled EAP-Success (of which only the first byte was
- actually send due to a bug in previous code); this seems to
- interoperate with most RADIUS servers that implements PEAPv1
- * PEAPv1: added support for terminating PEAP authentication on tunneled
- EAP-Success message; this can be configured by adding
- peap_outer_success=0 on phase1 parameters in wpa_supplicant.conf
- (some RADIUS servers require this whereas others require a tunneled
- reply
- * PEAPv1: changed phase1 option peaplabel to use default to 0, i.e., to
- the old label for key derivation; previously, the default was 1,
- but it looks like most existing PEAPv1 implementations use the old
- label which is thus more suitable default option
- * added support for EAP-PSK (draft-bersani-eap-psk-03.txt)
- * fixed parsing of wep_tx_keyidx
- * added support for configuring list of allowed Phase 2 EAP types
- (for both EAP-PEAP and EAP-TTLS) instead of only one type
- * added support for configuring IEEE 802.11 authentication algorithm
- (auth_alg; mainly for using Shared Key authentication with static
- WEP keys)
- * added support for EAP-AKA (with UMTS SIM)
- * fixed couple of errors in PCSC handling that could have caused
- random-looking errors for EAP-SIM
- * added support for EAP-SIM pseudonyms and fast re-authentication
- * added support for EAP-TLS/PEAP/TTLS fast re-authentication (TLS
- session resumption)
- * added support for EAP-SIM with two challenges
- (phase1="sim_min_num_chal=3" can be used to require three challenges)
- * added support for configuring DH/DSA parameters for an ephemeral DH
- key exchange (EAP-TLS/PEAP/TTLS) using new configuration parameters
- dh_file and dh_file2 (phase 2); this adds support for using DSA keys
- and optional DH key exchange to achieve forward secracy with RSA keys
- * added support for matching subject of the authentication server
- certificate with a substring when using EAP-TLS/PEAP/TTLS; new
- configuration variables subject_match and subject_match2
- * changed SSID configuration in driver_wext.c (used by many driver
- interfaces) to use ssid_len+1 as the length for SSID since some Linux
- drivers expect this
- * fixed couple of unaligned reads in scan result parsing to fix WPA
- connection on some platforms (e.g., ARM)
- * added driver interface for Intel ipw2100 driver
- * added support for LEAP with WPA
- * added support for larger scan results report (old limit was 4 kB of
- data, i.e., about 35 or so APs) when using Linux wireless extensions
- v17 or newer
- * fixed a bug in PMKSA cache processing: skip sending of EAPOL-Start
- only if there is a PMKSA cache entry for the current AP
- * fixed error handling for case where reading of scan results fails:
- must schedule a new scan or wpa_supplicant will remain waiting
- forever
- * changed debug output to remove shared password/key material by
- default; all key information can be included with -K command line
- argument to match the previous behavior
- * added support for timestamping debug log messages (disabled by
- default, can be enabled with -t command line argument)
- * set pairwise/group cipher suite for non-WPA IEEE 802.1X to WEP-104
- if keys are not configured to be used; this fixes IEEE 802.1X mode
- with drivers that use this information to configure whether Privacy
- bit can be in Beacon frames (e.g., ndiswrapper)
- * avoid clearing driver keys if no keys have been configured since last
- key clear request; this seems to improve reliability of group key
- handshake for ndiswrapper & NDIS driver which seems to be suffering
- of some kind of timing issue when the keys are cleared again after
- association
- * changed driver interface API:
- - WPA_SUPPLICANT_DRIVER_VERSION define can be used to determine which
- version is being used (now, this is set to 2; previously, it was
- not defined)
- - pass pointer to private data structure to all calls
- - the new API is not backwards compatible; all in-tree driver
- interfaces has been converted to the new API
- * added support for controlling multiple interfaces (radios) per
- wpa_supplicant process; each interface needs to be listed on the
- command line (-c, -i, -D arguments) with -N as a separator
- (-cwpa1.conf -iwlan0 -Dhostap -N -cwpa2.conf -iath0 -Dmadwifi)
- * added a workaround for EAP servers that incorrectly use same Id for
- sequential EAP packets
- * changed libpcap/libdnet configuration to use .config variable,
- CONFIG_DNET_PCAP, instead of requiring Makefile modification
- * improved downgrade attack detection in IE verification of msg 3/4:
- verify both WPA and RSN IEs, if present, not only the selected one;
- reject the AP if an RSN IE is found in msg 3/4, but not in Beacon or
- Probe Response frame, and RSN is enabled in wpa_supplicant
- configuration
- * fixed WPA msg 3/4 processing to allow Key Data field contain other
- IEs than just one WPA IE
- * added support for FreeBSD and driver interface for the BSD net80211
- layer (CONFIG_DRIVER_BSD=y in .config); please note that some of the
- required kernel mods have not yet been committed
- * made EAP workarounds configurable; enabled by default, can be
- disabled with network block option eap_workaround=0
-
-2004-07-17 - v0.2.4 (beginning of 0.2.x stable releases)
- * resolved couple of interoperability issues with EAP-PEAPv1 and
- Phase 2 (inner EAP) fragment reassembly
- * driver_madwifi: fixed WEP key configuration for IEEE 802.1X when the
- AP is using non-zero key index for the unicast key and key index zero
- for the broadcast key
- * driver_hostap: fixed IEEE 802.1X WEP key updates and
- re-authentication by allowing unencrypted EAPOL frames when not using
- WPA
- * added a new driver interface, 'wext', which uses only standard,
- driver independent functionality in Linux wireless extensions;
- currently, this can be used only for non-WPA IEEE 802.1X mode, but
- eventually, this is to be extended to support full WPA/WPA2 once
- Linux wireless extensions get support for this
- * added support for mode in which the driver is responsible for AP
- scanning and selection; this is disabled by default and can be
- enabled with global ap_scan=0 variable in wpa_supplicant.conf;
- this mode can be used, e.g., with generic 'wext' driver interface to
- use wpa_supplicant as IEEE 802.1X Supplicant with any Linux driver
- supporting wireless extensions.
- * driver_madwifi: fixed WPA2 configuration and scan_ssid=1 (e.g.,
- operation with an AP that does not include SSID in the Beacon frames)
- * added support for new EAP authentication methods:
- EAP-TTLS/EAP-OTP, EAP-PEAPv0/OTP, EAP-PEAPv1/OTP, EAP-OTP
- * added support for asking one-time-passwords from frontends (e.g.,
- wpa_cli); this 'otp' command works otherwise like 'password' command,
- but the password is used only once and the frontend will be asked for
- a new password whenever a request from authenticator requires a
- password; this can be used with both EAP-OTP and EAP-GTC
- * changed wpa_cli to automatically re-establish connection so that it
- does not need to be re-started when wpa_supplicant is terminated and
- started again
- * improved user data (identity/password/otp) requests through
- frontends: process pending EAPOL packets after getting new
- information so that full authentication does not need to be
- restarted; in addition, send pending requests again whenever a new
- frontend is attached
- * changed control frontends to use a new directory for socket files to
- make it easier for wpa_cli to automatically select between interfaces
- and to provide access control for the control interface;
- wpa_supplicant.conf: ctrl_interface is now a path
- (/var/run/wpa_supplicant is the recommended path) and
- ctrl_interface_group can be used to select which group gets access to
- the control interface;
- wpa_cli: by default, try to connect to the first interface available
- in /var/run/wpa_supplicant; this path can be overridden with -p option
- and an interface can be selected with -i option (i.e., in most common
- cases, wpa_cli does not need to get any arguments)
- * added support for LEAP
- * added driver interface for Linux ndiswrapper
- * added priority option for network blocks in the configuration file;
- this allows networks to be grouped based on priority (the scan
- results are searched for matches with network blocks in this order)
-
-2004-06-20 - v0.2.3
- * sort scan results to improve AP selection
- * fixed control interface socket removal for some error cases
- * improved scan requesting and authentication timeout
- * small improvements/bug fixes for EAP-MSCHAPv2, EAP-PEAP, and
- TLS processing
- * PEAP version can now be forced with phase1="peapver=<ver>"
- (mostly for testing; by default, the highest version supported by
- both the Supplicant and Authentication Server is selected
- automatically)
- * added support for madwifi driver (Atheros ar521x)
- * added a workaround for cases where AP sets Install Tx/Rx bit for
- WPA Group Key messages when pairwise keys are used (without this,
- the Group Key would be used for Tx and the AP would drop frames
- from the station)
- * added GSM SIM/USIM interface for GSM authentication algorithm for
- EAP-SIM; this requires pcsc-lite
- * added support for ATMEL AT76C5XXx driver
- * fixed IEEE 802.1X WEP key derivation in the case where Authenticator
- does not include key data in the EAPOL-Key frame (i.e., part of
- EAP keying material is used as data encryption key)
- * added support for using plaintext and static WEP networks
- (key_mgmt=NONE)
-
-2004-05-31 - v0.2.2
- * added support for new EAP authentication methods:
- EAP-TTLS/EAP-MD5-Challenge
- EAP-TTLS/EAP-GTC
- EAP-TTLS/EAP-MSCHAPv2
- EAP-TTLS/EAP-TLS
- EAP-TTLS/MSCHAPv2
- EAP-TTLS/MSCHAP
- EAP-TTLS/PAP
- EAP-TTLS/CHAP
- EAP-PEAP/TLS
- EAP-PEAP/GTC
- EAP-PEAP/MD5-Challenge
- EAP-GTC
- EAP-SIM (not yet complete; needs GSM/SIM authentication interface)
- * added support for anonymous identity (to be used when identity is
- sent in plaintext; real identity will be used within TLS protected
- tunnel (e.g., with EAP-TTLS)
- * added event messages from wpa_supplicant to frontends, e.g., wpa_cli
- * added support for requesting identity and password information using
- control interface; in other words, the password for EAP-PEAP or
- EAP-TTLS does not need to be included in the configuration file since
- a frontand (e.g., wpa_cli) can ask it from the user
- * improved RSN pre-authentication to use a candidate list and process
- all candidates from each scan; not only one per scan
- * fixed RSN IE and WPA IE capabilities field parsing
- * ignore Tx bit in GTK IE when Pairwise keys are used
- * avoid making new scan requests during IEEE 802.1X negotiation
- * use openssl/libcrypto for MD5 and SHA-1 when compiling wpa_supplicant
- with TLS support (this replaces the included implementation with
- library code to save about 8 kB since the library code is needed
- anyway for TLS)
- * fixed WPA-PSK only mode when compiled without IEEE 802.1X support
- (i.e., without CONFIG_IEEE8021X_EAPOL=y in .config)
-
-2004-05-06 - v0.2.1
- * added support for internal IEEE 802.1X (actually, IEEE 802.1aa/D6.1)
- Supplicant
- - EAPOL state machines for Supplicant [IEEE 802.1aa/D6.1]
- - EAP peer state machine [draft-ietf-eap-statemachine-02.pdf]
- - EAP-MD5 (cannot be used with WPA-RADIUS)
- [draft-ietf-eap-rfc2284bis-09.txt]
- - EAP-TLS [RFC 2716]
- - EAP-MSCHAPv2 (currently used only with EAP-PEAP)
- - EAP-PEAP/MSCHAPv2 [draft-josefsson-pppext-eap-tls-eap-07.txt]
- [draft-kamath-pppext-eap-mschapv2-00.txt]
- (PEAP version 0, 1, and parts of 2; only 0 and 1 are enabled by
- default; tested with FreeRADIUS, Microsoft IAS, and Funk Odyssey)
- - new configuration file options: eap, identity, password, ca_cert,
- client_cert, privatekey, private_key_passwd
- - Xsupplicant is not required anymore, but it can be used by
- disabling the internal IEEE 802.1X Supplicant with -e command line
- option
- - this code is not included in the default build; Makefile need to
- be edited for this (uncomment lines for selected functionality)
- - EAP-TLS and EAP-PEAP require openssl libraries
- * use module prefix in debug messages (WPA, EAP, EAP-TLS, ..)
- * added support for non-WPA IEEE 802.1X mode with dynamic WEP keys
- (i.e., complete IEEE 802.1X/EAP authentication and use IEEE 802.1X
- EAPOL-Key frames instead of WPA key handshakes)
- * added support for IEEE 802.11i/RSN (WPA2)
- - improved PTK Key Handshake
- - PMKSA caching, pre-authentication
- * fixed wpa_supplicant to ignore possible extra data after WPA
- EAPOL-Key packets (this fixes 'Invalid EAPOL-Key MIC when using
- TPTK' error from message 3 of 4-Way Handshake in case the AP
- includes extra data after the EAPOL-Key)
- * added interface for external programs (frontends) to control
- wpa_supplicant
- - CLI example (wpa_cli) with interactive mode and command line
- mode
- - replaced SIGUSR1 status/statistics with the new control interface
- * made some feature compile time configurable
- - .config file for make
- - driver interfaces (hostap, hermes, ..)
- - EAPOL/EAP functions
-
-2004-02-15 - v0.2.0
- * Initial version of wpa_supplicant
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
deleted file mode 100644
index cb66defac7c8..000000000000
--- a/wpa_supplicant/Makefile
+++ /dev/null
@@ -1,2074 +0,0 @@
-BINALL=wpa_supplicant wpa_cli
-
-ifndef CONFIG_NO_WPA_PASSPHRASE
-BINALL += wpa_passphrase
-endif
-
-ALL = $(BINALL)
-ALL += systemd/wpa_supplicant.service
-ALL += systemd/wpa_supplicant@.service
-ALL += systemd/wpa_supplicant-nl80211@.service
-ALL += systemd/wpa_supplicant-wired@.service
-ALL += dbus/fi.w1.wpa_supplicant1.service
-ifdef CONFIG_BUILD_WPA_CLIENT_SO
-ALL += libwpa_client.so
-endif
-
-EXTRA_TARGETS=dynamic_eap_methods
-
-CONFIG_FILE=.config
-include ../src/build.rules
-
-ifdef LIBS
-# If LIBS is set with some global build system defaults, clone those for
-# LIBS_c and LIBS_p to cover wpa_passphrase and wpa_cli as well.
-ifndef LIBS_c
-LIBS_c := $(LIBS)
-endif
-ifndef LIBS_p
-LIBS_p := $(LIBS)
-endif
-endif
-
-export LIBDIR ?= /usr/local/lib
-export INCDIR ?= /usr/local/include
-export BINDIR ?= /usr/local/sbin
-PKG_CONFIG ?= pkg-config
-
-CFLAGS += $(EXTRA_CFLAGS)
-CFLAGS += -I$(abspath ../src)
-CFLAGS += -I$(abspath ../src/utils)
-
-ifndef CONFIG_NO_GITVER
-# Add VERSION_STR postfix for builds from a git repository
-ifeq ($(wildcard ../.git),../.git)
-GITVER := $(shell git describe --dirty=+)
-ifneq ($(GITVER),)
-CFLAGS += -DGIT_VERSION_STR_POSTFIX=\"-$(GITVER)\"
-endif
-endif
-endif
-
-ifdef CONFIG_TESTING_OPTIONS
-CFLAGS += -DCONFIG_TESTING_OPTIONS
-CONFIG_WPS_TESTING=y
-CONFIG_TDLS_TESTING=y
-endif
-
-mkconfig:
- @if [ -f .config ]; then \
- echo '.config exists - did not replace it'; \
- exit 1; \
- fi
- echo CONFIG_DRIVER_HOSTAP=y >> .config
- echo CONFIG_DRIVER_WEXT=y >> .config
-
-$(DESTDIR)$(BINDIR)/%: %
- install -D $(<) $(@)
-
-install: $(addprefix $(DESTDIR)$(BINDIR)/,$(BINALL))
- $(MAKE) -C ../src install
-ifdef CONFIG_BUILD_WPA_CLIENT_SO
- install -m 0644 -D libwpa_client.so $(DESTDIR)/$(LIBDIR)/libwpa_client.so
- install -m 0644 -D ../src/common/wpa_ctrl.h $(DESTDIR)/$(INCDIR)/wpa_ctrl.h
-endif
- if ls eap_*.so >/dev/null 2>&1; then \
- install -d $(DESTDIR)$(LIBDIR)/wpa_supplicant && \
- cp *.so $(DESTDIR)$(LIBDIR)/wpa_supplicant \
- ; fi
-
-ifdef CONFIG_FIPS
-CONFIG_NO_RANDOM_POOL=
-CONFIG_OPENSSL_CMAC=y
-endif
-
-OBJS = config.o
-OBJS += notify.o
-OBJS += bss.o
-OBJS += eap_register.o
-OBJS += ../src/utils/common.o
-OBJS += ../src/utils/config.o
-OBJS += ../src/utils/wpa_debug.o
-OBJS += ../src/utils/wpabuf.o
-OBJS += ../src/utils/bitfield.o
-OBJS += ../src/utils/ip_addr.o
-OBJS += ../src/utils/crc32.o
-OBJS += op_classes.o
-OBJS += rrm.o
-OBJS += twt.o
-OBJS += robust_av.o
-OBJS_p = wpa_passphrase.o
-OBJS_p += ../src/utils/common.o
-OBJS_p += ../src/utils/wpa_debug.o
-OBJS_p += ../src/utils/wpabuf.o
-OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
-OBJS_c += ../src/utils/wpa_debug.o
-OBJS_c += ../src/utils/common.o
-OBJS_c += ../src/common/cli.o
-OBJS += wmm_ac.o
-
-ifndef CONFIG_OS
-ifdef CONFIG_NATIVE_WINDOWS
-CONFIG_OS=win32
-else
-CONFIG_OS=unix
-endif
-endif
-
-ifeq ($(CONFIG_OS), internal)
-CFLAGS += -DOS_NO_C_LIB_DEFINES
-endif
-
-OBJS += ../src/utils/os_$(CONFIG_OS).o
-OBJS_p += ../src/utils/os_$(CONFIG_OS).o
-OBJS_c += ../src/utils/os_$(CONFIG_OS).o
-
-ifdef CONFIG_WPA_TRACE
-CFLAGS += -DWPA_TRACE
-OBJS += ../src/utils/trace.o
-OBJS_p += ../src/utils/trace.o
-OBJS_c += ../src/utils/trace.o
-OBJS_priv += ../src/utils/trace.o
-LIBCTRL += ../src/utils/trace.o
-LIBCTRLSO += ../src/utils/trace.c
-LDFLAGS += -rdynamic
-CFLAGS += -funwind-tables
-ifdef CONFIG_WPA_TRACE_BFD
-CFLAGS += -DPACKAGE="wpa_supplicant" -DWPA_TRACE_BFD
-LIBS += -lbfd -ldl -liberty -lz
-LIBS_p += -lbfd -ldl -liberty -lz
-LIBS_c += -lbfd -ldl -liberty -lz
-endif
-endif
-
-ifndef CONFIG_ELOOP
-CONFIG_ELOOP=eloop
-endif
-OBJS += ../src/utils/$(CONFIG_ELOOP).o
-OBJS_c += ../src/utils/$(CONFIG_ELOOP).o
-
-ifndef CONFIG_OSX
-ifeq ($(CONFIG_ELOOP), eloop)
-# Using glibc < 2.17 requires -lrt for clock_gettime()
-# OS X has an alternate implementation
-LIBS += -lrt
-LIBS_c += -lrt
-LIBS_p += -lrt
-endif
-endif
-
-ifdef CONFIG_ELOOP_POLL
-CFLAGS += -DCONFIG_ELOOP_POLL
-endif
-
-ifdef CONFIG_ELOOP_EPOLL
-CFLAGS += -DCONFIG_ELOOP_EPOLL
-endif
-
-ifdef CONFIG_ELOOP_KQUEUE
-CFLAGS += -DCONFIG_ELOOP_KQUEUE
-endif
-
-ifdef CONFIG_EAPOL_TEST
-CFLAGS += -Werror -DEAPOL_TEST
-endif
-
-ifdef CONFIG_CODE_COVERAGE
-CFLAGS += -O0 -fprofile-arcs -ftest-coverage
-LIBS += -lgcov
-LIBS_c += -lgcov
-LIBS_p += -lgcov
-endif
-
-ifdef CONFIG_HT_OVERRIDES
-CFLAGS += -DCONFIG_HT_OVERRIDES
-endif
-
-ifdef CONFIG_VHT_OVERRIDES
-CFLAGS += -DCONFIG_VHT_OVERRIDES
-endif
-
-ifdef CONFIG_HE_OVERRIDES
-CFLAGS += -DCONFIG_HE_OVERRIDES
-endif
-
-ifndef CONFIG_BACKEND
-CONFIG_BACKEND=file
-endif
-
-ifeq ($(CONFIG_BACKEND), file)
-OBJS += config_file.o
-ifndef CONFIG_NO_CONFIG_BLOBS
-NEED_BASE64=y
-endif
-CFLAGS += -DCONFIG_BACKEND_FILE
-endif
-
-ifeq ($(CONFIG_BACKEND), winreg)
-OBJS += config_winreg.o
-endif
-
-ifeq ($(CONFIG_BACKEND), none)
-OBJS += config_none.o
-endif
-
-ifdef CONFIG_NO_CONFIG_WRITE
-CFLAGS += -DCONFIG_NO_CONFIG_WRITE
-endif
-
-ifdef CONFIG_NO_CONFIG_BLOBS
-CFLAGS += -DCONFIG_NO_CONFIG_BLOBS
-endif
-
-ifdef CONFIG_NO_SCAN_PROCESSING
-CFLAGS += -DCONFIG_NO_SCAN_PROCESSING
-endif
-
-ifdef CONFIG_SUITEB
-CFLAGS += -DCONFIG_SUITEB
-endif
-
-ifdef CONFIG_SUITEB192
-CFLAGS += -DCONFIG_SUITEB192
-NEED_SHA384=y
-endif
-
-ifdef CONFIG_OCV
-CFLAGS += -DCONFIG_OCV
-OBJS += ../src/common/ocv.o
-endif
-
-ifdef CONFIG_IEEE80211R
-CFLAGS += -DCONFIG_IEEE80211R
-OBJS += ../src/rsn_supp/wpa_ft.o
-endif
-
-ifdef CONFIG_MESH
-NEED_80211_COMMON=y
-NEED_AES_SIV=y
-CONFIG_SAE=y
-CONFIG_AP=y
-CFLAGS += -DCONFIG_MESH
-OBJS += mesh.o
-OBJS += mesh_mpm.o
-OBJS += mesh_rsn.o
-endif
-
-ifdef CONFIG_SAE
-CFLAGS += -DCONFIG_SAE
-OBJS += ../src/common/sae.o
-ifdef CONFIG_SAE_PK
-CFLAGS += -DCONFIG_SAE_PK
-OBJS += ../src/common/sae_pk.o
-endif
-NEED_ECC=y
-NEED_DH_GROUPS=y
-NEED_HMAC_SHA256_KDF=y
-NEED_DRAGONFLY=y
-ifdef CONFIG_TESTING_OPTIONS
-NEED_DH_GROUPS_ALL=y
-endif
-endif
-
-ifdef CONFIG_DPP
-CFLAGS += -DCONFIG_DPP
-OBJS += ../src/common/dpp.o
-OBJS += ../src/common/dpp_auth.o
-OBJS += ../src/common/dpp_backup.o
-OBJS += ../src/common/dpp_crypto.o
-OBJS += ../src/common/dpp_pkex.o
-OBJS += ../src/common/dpp_reconfig.o
-OBJS += ../src/common/dpp_tcp.o
-OBJS += dpp_supplicant.o
-NEED_AES_SIV=y
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_HMAC_SHA512_KDF=y
-NEED_SHA384=y
-NEED_SHA512=y
-NEED_ECC=y
-NEED_JSON=y
-NEED_GAS_SERVER=y
-NEED_BASE64=y
-NEED_ASN1=y
-ifdef CONFIG_DPP2
-CFLAGS += -DCONFIG_DPP2
-endif
-ifdef CONFIG_DPP3
-CFLAGS += -DCONFIG_DPP3
-endif
-endif
-
-ifdef CONFIG_OWE
-CFLAGS += -DCONFIG_OWE
-NEED_ECC=y
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_HMAC_SHA512_KDF=y
-NEED_SHA384=y
-NEED_SHA512=y
-endif
-
-ifdef CONFIG_FILS
-CFLAGS += -DCONFIG_FILS
-NEED_SHA384=y
-NEED_AES_SIV=y
-ifdef CONFIG_FILS_SK_PFS
-CFLAGS += -DCONFIG_FILS_SK_PFS
-NEED_ECC=y
-endif
-endif
-
-ifdef CONFIG_MBO
-CONFIG_WNM=y
-endif
-
-ifdef CONFIG_WNM
-CFLAGS += -DCONFIG_WNM
-OBJS += wnm_sta.o
-endif
-
-ifdef CONFIG_TDLS
-CFLAGS += -DCONFIG_TDLS
-OBJS += ../src/rsn_supp/tdls.o
-endif
-
-ifdef CONFIG_TDLS_TESTING
-CFLAGS += -DCONFIG_TDLS_TESTING
-endif
-
-ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-CFLAGS += -DCONFIG_PMKSA_CACHE_EXTERNAL
-endif
-
-ifndef CONFIG_NO_WPA
-OBJS += ../src/rsn_supp/wpa.o
-OBJS += ../src/rsn_supp/preauth.o
-OBJS += ../src/rsn_supp/pmksa_cache.o
-OBJS += ../src/rsn_supp/wpa_ie.o
-OBJS += ../src/common/wpa_common.o
-NEED_AES=y
-NEED_SHA1=y
-NEED_MD5=y
-NEED_RC4=y
-else
-CFLAGS += -DCONFIG_NO_WPA
-ifeq ($(CONFIG_TLS), internal)
-NEED_SHA1=y
-NEED_MD5=y
-endif
-endif
-
-ifdef CONFIG_IBSS_RSN
-NEED_RSN_AUTHENTICATOR=y
-CFLAGS += -DCONFIG_IBSS_RSN
-CFLAGS += -DCONFIG_NO_VLAN
-OBJS += ibss_rsn.o
-endif
-
-ifdef CONFIG_MATCH_IFACE
-CFLAGS += -DCONFIG_MATCH_IFACE
-endif
-
-ifdef CONFIG_P2P
-OBJS += p2p_supplicant.o
-OBJS += p2p_supplicant_sd.o
-OBJS += ../src/p2p/p2p.o
-OBJS += ../src/p2p/p2p_utils.o
-OBJS += ../src/p2p/p2p_parse.o
-OBJS += ../src/p2p/p2p_build.o
-OBJS += ../src/p2p/p2p_go_neg.o
-OBJS += ../src/p2p/p2p_sd.o
-OBJS += ../src/p2p/p2p_pd.o
-OBJS += ../src/p2p/p2p_invitation.o
-OBJS += ../src/p2p/p2p_dev_disc.o
-OBJS += ../src/p2p/p2p_group.o
-OBJS += ../src/ap/p2p_hostapd.o
-CFLAGS += -DCONFIG_P2P
-NEED_GAS=y
-NEED_OFFCHANNEL=y
-CONFIG_WPS=y
-CONFIG_AP=y
-ifdef CONFIG_P2P_STRICT
-CFLAGS += -DCONFIG_P2P_STRICT
-endif
-ifdef CONFIG_WIFI_DISPLAY
-CFLAGS += -DCONFIG_WIFI_DISPLAY
-OBJS += wifi_display.o
-endif
-endif
-
-ifdef CONFIG_PASN
-CFLAGS += -DCONFIG_PASN
-CFLAGS += -DCONFIG_PTKSA_CACHE
-NEED_HMAC_SHA256_KDF=y
-NEED_HMAC_SHA384_KDF=y
-NEED_SHA256=y
-NEED_SHA384=y
-OBJS += ../src/common/ptksa_cache.o
-OBJS += pasn_supplicant.o
-endif
-
-ifdef CONFIG_HS20
-OBJS += hs20_supplicant.o
-CFLAGS += -DCONFIG_HS20
-CONFIG_INTERWORKING=y
-endif
-
-ifdef CONFIG_INTERWORKING
-OBJS += interworking.o
-CFLAGS += -DCONFIG_INTERWORKING
-NEED_GAS=y
-endif
-
-ifdef CONFIG_NO_ROAMING
-CFLAGS += -DCONFIG_NO_ROAMING
-endif
-
-include ../src/drivers/drivers.mak
-ifdef CONFIG_AP
-OBJS_d += $(DRV_BOTH_OBJS)
-CFLAGS += $(DRV_BOTH_CFLAGS)
-LDFLAGS += $(DRV_BOTH_LDFLAGS)
-LIBS += $(DRV_BOTH_LIBS)
-else
-NEED_AP_MLME=
-OBJS_d += $(DRV_WPA_OBJS)
-CFLAGS += $(DRV_WPA_CFLAGS)
-LDFLAGS += $(DRV_WPA_LDFLAGS)
-LIBS += $(DRV_WPA_LIBS)
-endif
-
-ifndef CONFIG_L2_PACKET
-CONFIG_L2_PACKET=linux
-endif
-
-OBJS_l2 += ../src/l2_packet/l2_packet_$(CONFIG_L2_PACKET).o
-
-ifeq ($(CONFIG_L2_PACKET), pcap)
-ifdef CONFIG_WINPCAP
-CFLAGS += -DCONFIG_WINPCAP
-LIBS += -lwpcap -lpacket
-LIBS_w += -lwpcap
-else
-LIBS += -ldnet -lpcap
-endif
-endif
-
-ifeq ($(CONFIG_L2_PACKET), winpcap)
-LIBS += -lwpcap -lpacket
-LIBS_w += -lwpcap
-endif
-
-ifeq ($(CONFIG_L2_PACKET), freebsd)
-LIBS += -lpcap
-endif
-
-ifdef CONFIG_ERP
-CFLAGS += -DCONFIG_ERP
-NEED_HMAC_SHA256_KDF=y
-endif
-
-ifdef CONFIG_EAP_TLS
-# EAP-TLS
-ifeq ($(CONFIG_EAP_TLS), dyn)
-CFLAGS += -DEAP_TLS_DYNAMIC
-EAPDYN += eap_tls.so
-else
-CFLAGS += -DEAP_TLS
-OBJS += ../src/eap_peer/eap_tls.o
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_UNAUTH_TLS
-# EAP-UNAUTH-TLS
-CFLAGS += -DEAP_UNAUTH_TLS
-ifndef CONFIG_EAP_TLS
-OBJS += ../src/eap_peer/eap_tls.o
-TLS_FUNCS=y
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_PEAP
-# EAP-PEAP
-SRC_EAP_PEAP = ../src/eap_peer/eap_peap.c ../src/eap_common/eap_peap_common.c
-ifeq ($(CONFIG_EAP_PEAP), dyn)
-CFLAGS += -DEAP_PEAP_DYNAMIC
-EAPDYN += eap_peap.so
-else
-CFLAGS += -DEAP_PEAP
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PEAP))
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_TTLS
-# EAP-TTLS
-ifeq ($(CONFIG_EAP_TTLS), dyn)
-CFLAGS += -DEAP_TTLS_DYNAMIC
-EAPDYN += eap_ttls.so
-else
-CFLAGS += -DEAP_TTLS
-OBJS += ../src/eap_peer/eap_ttls.o
-endif
-TLS_FUNCS=y
-ifndef CONFIG_FIPS
-MS_FUNCS=y
-CHAP=y
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_MD5
-# EAP-MD5
-ifeq ($(CONFIG_EAP_MD5), dyn)
-CFLAGS += -DEAP_MD5_DYNAMIC
-EAPDYN += eap_md5.so
-else
-CFLAGS += -DEAP_MD5
-OBJS += ../src/eap_peer/eap_md5.o
-endif
-CHAP=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-# backwards compatibility for old spelling
-ifdef CONFIG_MSCHAPV2
-ifndef CONFIG_EAP_MSCHAPV2
-CONFIG_EAP_MSCHAPV2=y
-endif
-endif
-
-ifdef CONFIG_EAP_MSCHAPV2
-# EAP-MSCHAPv2
-SRC_EAP_MSCHAPV2 = ../src/eap_peer/eap_mschapv2.c ../src/eap_peer/mschapv2.c
-ifeq ($(CONFIG_EAP_MSCHAPV2), dyn)
-CFLAGS += -DEAP_MSCHAPv2_DYNAMIC
-EAPDYN += eap_mschapv2.so
-else
-CFLAGS += -DEAP_MSCHAPv2
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_MSCHAPV2))
-endif
-MS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_GTC
-# EAP-GTC
-ifeq ($(CONFIG_EAP_GTC), dyn)
-CFLAGS += -DEAP_GTC_DYNAMIC
-EAPDYN += eap_gtc.so
-else
-CFLAGS += -DEAP_GTC
-OBJS += ../src/eap_peer/eap_gtc.o
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_OTP
-# EAP-OTP
-ifeq ($(CONFIG_EAP_OTP), dyn)
-CFLAGS += -DEAP_OTP_DYNAMIC
-EAPDYN += eap_otp.so
-else
-CFLAGS += -DEAP_OTP
-OBJS += ../src/eap_peer/eap_otp.o
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_SIM
-# EAP-SIM
-ifeq ($(CONFIG_EAP_SIM), dyn)
-CFLAGS += -DEAP_SIM_DYNAMIC
-EAPDYN += eap_sim.so
-else
-CFLAGS += -DEAP_SIM
-OBJS += ../src/eap_peer/eap_sim.o
-endif
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_SIM_COMMON=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_EAP_LEAP
-# EAP-LEAP
-ifeq ($(CONFIG_EAP_LEAP), dyn)
-CFLAGS += -DEAP_LEAP_DYNAMIC
-EAPDYN += eap_leap.so
-else
-CFLAGS += -DEAP_LEAP
-OBJS += ../src/eap_peer/eap_leap.o
-endif
-MS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_PSK
-# EAP-PSK
-SRC_EAP_PSK = ../src/eap_peer/eap_psk.c ../src/eap_common/eap_psk_common.c
-ifeq ($(CONFIG_EAP_PSK), dyn)
-CFLAGS += -DEAP_PSK_DYNAMIC
-EAPDYN += eap_psk.so
-else
-CFLAGS += -DEAP_PSK
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PSK))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_AES=y
-NEED_AES_ENCBLOCK=y
-NEED_AES_EAX=y
-endif
-
-ifdef CONFIG_EAP_AKA
-# EAP-AKA
-ifeq ($(CONFIG_EAP_AKA), dyn)
-CFLAGS += -DEAP_AKA_DYNAMIC
-EAPDYN += eap_aka.so
-else
-CFLAGS += -DEAP_AKA
-OBJS += ../src/eap_peer/eap_aka.o
-endif
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_SIM_COMMON=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_EAP_PROXY
-CFLAGS += -DCONFIG_EAP_PROXY
-OBJS += ../src/eap_peer/eap_proxy_$(CONFIG_EAP_PROXY).o
-include eap_proxy_$(CONFIG_EAP_PROXY).mak
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_AKA_PRIME
-# EAP-AKA'
-ifeq ($(CONFIG_EAP_AKA_PRIME), dyn)
-CFLAGS += -DEAP_AKA_PRIME_DYNAMIC
-else
-CFLAGS += -DEAP_AKA_PRIME
-endif
-endif
-
-ifdef CONFIG_EAP_SIM_COMMON
-OBJS += ../src/eap_common/eap_sim_common.o
-NEED_AES=y
-NEED_FIPS186_2_PRF=y
-endif
-
-ifdef CONFIG_EAP_FAST
-# EAP-FAST
-SRC_EAP_FAST = ../src/eap_peer/eap_fast.c ../src/eap_peer/eap_fast_pac.c
-SRC_EAP_FAST += ../src/eap_common/eap_fast_common.c
-ifeq ($(CONFIG_EAP_FAST), dyn)
-CFLAGS += -DEAP_FAST_DYNAMIC
-EAPDYN += eap_fast.so
-else
-CFLAGS += -DEAP_FAST
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_FAST))
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-NEED_T_PRF=y
-endif
-
-ifdef CONFIG_EAP_TEAP
-# EAP-TEAP
-SRC_EAP_TEAP = ../src/eap_peer/eap_teap.c ../src/eap_peer/eap_teap_pac.c
-SRC_EAP_TEAP += ../src/eap_common/eap_teap_common.c
-ifeq ($(CONFIG_EAP_TEAP), dyn)
-CFLAGS += -DEAP_TEAP_DYNAMIC
-EAPDYN += eap_teap.so
-else
-CFLAGS += -DEAP_TEAP
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_TEAP))
-endif
-TLS_FUNCS=y
-CONFIG_IEEE8021X_EAPOL=y
-NEED_T_PRF=y
-NEED_SHA384=y
-NEED_TLS_PRF_SHA256=y
-NEED_TLS_PRF_SHA384=y
-endif
-
-ifdef CONFIG_EAP_PAX
-# EAP-PAX
-SRC_EAP_PAX = ../src/eap_peer/eap_pax.c ../src/eap_common/eap_pax_common.c
-ifeq ($(CONFIG_EAP_PAX), dyn)
-CFLAGS += -DEAP_PAX_DYNAMIC
-EAPDYN += eap_pax.so
-else
-CFLAGS += -DEAP_PAX
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PAX))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_SAKE
-# EAP-SAKE
-SRC_EAP_SAKE = ../src/eap_peer/eap_sake.c ../src/eap_common/eap_sake_common.c
-ifeq ($(CONFIG_EAP_SAKE), dyn)
-CFLAGS += -DEAP_SAKE_DYNAMIC
-EAPDYN += eap_sake.so
-else
-CFLAGS += -DEAP_SAKE
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_SAKE))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_GPSK
-# EAP-GPSK
-SRC_EAP_GPSK = ../src/eap_peer/eap_gpsk.c ../src/eap_common/eap_gpsk_common.c
-ifeq ($(CONFIG_EAP_GPSK), dyn)
-CFLAGS += -DEAP_GPSK_DYNAMIC
-EAPDYN += eap_gpsk.so
-else
-CFLAGS += -DEAP_GPSK
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_GPSK))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-ifdef CONFIG_EAP_GPSK_SHA256
-CFLAGS += -DEAP_GPSK_SHA256
-endif
-endif
-
-ifdef CONFIG_EAP_PWD
-CFLAGS += -DEAP_PWD
-ifeq ($(CONFIG_TLS), wolfssl)
-CFLAGS += -DCONFIG_ECC
-endif
-OBJS += ../src/eap_peer/eap_pwd.o ../src/eap_common/eap_pwd_common.o
-CONFIG_IEEE8021X_EAPOL=y
-NEED_ECC=y
-NEED_DRAGONFLY=y
-endif
-
-ifdef CONFIG_EAP_EKE
-# EAP-EKE
-SRC_EAP_EKE = ../src/eap_peer/eap_eke.c ../src/eap_common/eap_eke_common.c
-ifeq ($(CONFIG_EAP_EKE), dyn)
-CFLAGS += -DEAP_EKE_DYNAMIC
-EAPDYN += eap_eke.so
-else
-CFLAGS += -DEAP_EKE
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_EKE))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_DH_GROUPS_ALL=y
-NEED_AES_CBC=y
-endif
-
-ifdef CONFIG_WPS
-# EAP-WSC
-CFLAGS += -DCONFIG_WPS -DEAP_WSC
-OBJS += wps_supplicant.o
-OBJS += ../src/utils/uuid.o
-OBJS += ../src/eap_peer/eap_wsc.o ../src/eap_common/eap_wsc_common.o
-OBJS += ../src/wps/wps.o
-OBJS += ../src/wps/wps_common.o
-OBJS += ../src/wps/wps_attr_parse.o
-OBJS += ../src/wps/wps_attr_build.o
-OBJS += ../src/wps/wps_attr_process.o
-OBJS += ../src/wps/wps_dev_attr.o
-OBJS += ../src/wps/wps_enrollee.o
-OBJS += ../src/wps/wps_registrar.o
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_BASE64=y
-NEED_AES_CBC=y
-NEED_MODEXP=y
-
-ifdef CONFIG_WPS_NFC
-CFLAGS += -DCONFIG_WPS_NFC
-OBJS += ../src/wps/ndef.o
-NEED_WPS_OOB=y
-endif
-
-ifdef NEED_WPS_OOB
-CFLAGS += -DCONFIG_WPS_OOB
-endif
-
-ifdef CONFIG_WPS_ER
-CONFIG_WPS_UPNP=y
-CFLAGS += -DCONFIG_WPS_ER
-OBJS += ../src/wps/wps_er.o
-OBJS += ../src/wps/wps_er_ssdp.o
-endif
-
-ifdef CONFIG_WPS_UPNP
-CFLAGS += -DCONFIG_WPS_UPNP
-OBJS += ../src/wps/wps_upnp.o
-OBJS += ../src/wps/wps_upnp_ssdp.o
-OBJS += ../src/wps/wps_upnp_web.o
-OBJS += ../src/wps/wps_upnp_event.o
-OBJS += ../src/wps/wps_upnp_ap.o
-OBJS += ../src/wps/upnp_xml.o
-OBJS += ../src/wps/httpread.o
-OBJS += ../src/wps/http_client.o
-OBJS += ../src/wps/http_server.o
-endif
-
-ifdef CONFIG_WPS_STRICT
-CFLAGS += -DCONFIG_WPS_STRICT
-OBJS += ../src/wps/wps_validate.o
-endif
-
-ifdef CONFIG_WPS_TESTING
-CFLAGS += -DCONFIG_WPS_TESTING
-endif
-
-ifdef CONFIG_WPS_REG_DISABLE_OPEN
-CFLAGS += -DCONFIG_WPS_REG_DISABLE_OPEN
-endif
-
-endif
-
-ifdef CONFIG_EAP_IKEV2
-# EAP-IKEv2
-SRC_EAP_IKEV2 = ../src/eap_peer/eap_ikev2.c
-SRC_EAP_IKEV2 += ../src/eap_peer/ikev2.c
-SRC_EAP_IKEV2 += ../src/eap_common/eap_ikev2_common.c
-SRC_EAP_IKEV2 += ../src/eap_common/ikev2_common.c
-ifeq ($(CONFIG_EAP_IKEV2), dyn)
-CFLAGS += -DEAP_IKEV2_DYNAMIC
-EAPDYN += eap_ikev2.so
-else
-CFLAGS += -DEAP_IKEV2
-OBJS += $(patsubst %.c, %.o, $(SRC_EAP_IKEV2))
-endif
-CONFIG_IEEE8021X_EAPOL=y
-NEED_DH_GROUPS=y
-NEED_DH_GROUPS_ALL=y
-NEED_MODEXP=y
-NEED_CIPHER=y
-endif
-
-ifdef CONFIG_EAP_VENDOR_TEST
-ifeq ($(CONFIG_EAP_VENDOR_TEST), dyn)
-CFLAGS += -DEAP_VENDOR_TEST_DYNAMIC
-EAPDYN += eap_vendor_test.so
-else
-CFLAGS += -DEAP_VENDOR_TEST
-OBJS += ../src/eap_peer/eap_vendor_test.o
-endif
-CONFIG_IEEE8021X_EAPOL=y
-endif
-
-ifdef CONFIG_EAP_TNC
-# EAP-TNC
-CFLAGS += -DEAP_TNC
-OBJS += ../src/eap_peer/eap_tnc.o
-OBJS += ../src/eap_peer/tncc.o
-NEED_BASE64=y
-ifndef CONFIG_NATIVE_WINDOWS
-ifndef CONFIG_DRIVER_BSD
-LIBS += -ldl
-endif
-endif
-endif
-
-ifdef CONFIG_MACSEC
-CFLAGS += -DCONFIG_MACSEC
-CONFIG_IEEE8021X_EAPOL=y
-NEED_AES_ENCBLOCK=y
-NEED_AES_UNWRAP=y
-NEED_AES_WRAP=y
-OBJS += wpas_kay.o
-OBJS += ../src/pae/ieee802_1x_cp.o
-OBJS += ../src/pae/ieee802_1x_kay.o
-OBJS += ../src/pae/ieee802_1x_key.o
-OBJS += ../src/pae/ieee802_1x_secy_ops.o
-ifdef CONFIG_AP
-OBJS += ../src/ap/wpa_auth_kay.o
-endif
-endif
-
-ifdef CONFIG_IEEE8021X_EAPOL
-# IEEE 802.1X/EAPOL state machines (e.g., for RADIUS authentication)
-CFLAGS += -DIEEE8021X_EAPOL
-OBJS += ../src/eapol_supp/eapol_supp_sm.o
-OBJS += ../src/eap_peer/eap.o ../src/eap_peer/eap_methods.o
-NEED_EAP_COMMON=y
-ifdef CONFIG_DYNAMIC_EAP_METHODS
-CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
-LIBS += -ldl -rdynamic
-endif
-endif
-
-ifdef CONFIG_AP
-NEED_EAP_COMMON=y
-NEED_RSN_AUTHENTICATOR=y
-CFLAGS += -DCONFIG_AP
-OBJS += ap.o
-CFLAGS += -DCONFIG_NO_RADIUS
-CFLAGS += -DCONFIG_NO_ACCOUNTING
-CFLAGS += -DCONFIG_NO_VLAN
-OBJS += ../src/ap/hostapd.o
-OBJS += ../src/ap/wpa_auth_glue.o
-OBJS += ../src/ap/utils.o
-OBJS += ../src/ap/authsrv.o
-OBJS += ../src/ap/ap_config.o
-OBJS += ../src/ap/sta_info.o
-OBJS += ../src/ap/tkip_countermeasures.o
-OBJS += ../src/ap/ap_mlme.o
-OBJS += ../src/ap/ieee802_1x.o
-OBJS += ../src/eapol_auth/eapol_auth_sm.o
-OBJS += ../src/ap/ieee802_11_auth.o
-OBJS += ../src/ap/ieee802_11_shared.o
-OBJS += ../src/ap/drv_callbacks.o
-OBJS += ../src/ap/ap_drv_ops.o
-OBJS += ../src/ap/beacon.o
-OBJS += ../src/ap/bss_load.o
-OBJS += ../src/ap/eap_user_db.o
-OBJS += ../src/ap/neighbor_db.o
-OBJS += ../src/ap/rrm.o
-OBJS += ../src/ap/ieee802_11_ht.o
-ifdef CONFIG_IEEE80211AC
-OBJS += ../src/ap/ieee802_11_vht.o
-endif
-ifdef CONFIG_IEEE80211AX
-OBJS += ../src/ap/ieee802_11_he.o
-endif
-ifdef CONFIG_WNM_AP
-CFLAGS += -DCONFIG_WNM_AP
-OBJS += ../src/ap/wnm_ap.o
-endif
-ifdef CONFIG_MBO
-OBJS += ../src/ap/mbo_ap.o
-endif
-ifdef CONFIG_FILS
-OBJS += ../src/ap/fils_hlp.o
-endif
-ifdef CONFIG_CTRL_IFACE
-OBJS += ../src/ap/ctrl_iface_ap.o
-endif
-
-CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
-OBJS += ../src/eap_server/eap_server.o
-OBJS += ../src/eap_server/eap_server_identity.o
-OBJS += ../src/eap_server/eap_server_methods.o
-
-ifdef CONFIG_IEEE80211AC
-CFLAGS += -DCONFIG_IEEE80211AC
-endif
-ifdef CONFIG_IEEE80211AX
-CFLAGS += -DCONFIG_IEEE80211AX
-endif
-
-ifdef NEED_AP_MLME
-OBJS += ../src/ap/wmm.o
-OBJS += ../src/ap/ap_list.o
-OBJS += ../src/ap/ieee802_11.o
-OBJS += ../src/ap/hw_features.o
-OBJS += ../src/ap/dfs.o
-CFLAGS += -DNEED_AP_MLME
-endif
-ifdef CONFIG_WPS
-CFLAGS += -DEAP_SERVER_WSC
-OBJS += ../src/ap/wps_hostapd.o
-OBJS += ../src/eap_server/eap_server_wsc.o
-endif
-ifdef CONFIG_DPP
-OBJS += ../src/ap/dpp_hostapd.o
-OBJS += ../src/ap/gas_query_ap.o
-NEED_AP_GAS_SERV=y
-endif
-ifdef CONFIG_INTERWORKING
-NEED_AP_GAS_SERV=y
-endif
-ifdef NEED_AP_GAS_SERV
-OBJS += ../src/ap/gas_serv.o
-endif
-ifdef CONFIG_HS20
-OBJS += ../src/ap/hs20.o
-endif
-endif
-
-ifdef CONFIG_MBO
-OBJS += mbo.o
-CFLAGS += -DCONFIG_MBO
-endif
-
-ifdef NEED_RSN_AUTHENTICATOR
-CFLAGS += -DCONFIG_NO_RADIUS
-NEED_AES_WRAP=y
-OBJS += ../src/ap/wpa_auth.o
-OBJS += ../src/ap/wpa_auth_ie.o
-OBJS += ../src/ap/pmksa_cache_auth.o
-endif
-
-ifdef CONFIG_ACS
-CFLAGS += -DCONFIG_ACS
-OBJS += ../src/ap/acs.o
-LIBS += -lm
-endif
-
-ifdef CONFIG_PCSC
-# PC/SC interface for smartcards (USIM, GSM SIM)
-CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
-OBJS += ../src/utils/pcsc_funcs.o
-ifdef CONFIG_NATIVE_WINDOWS
-#Once MinGW gets support for WinScard, -lwinscard could be used instead of the
-#dynamic symbol loading that is now used in pcsc_funcs.c
-#LIBS += -lwinscard
-else
-ifdef CONFIG_OSX
-LIBS += -framework PCSC
-else
-LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite)
-endif
-endif
-endif
-
-ifdef CONFIG_SIM_SIMULATOR
-CFLAGS += -DCONFIG_SIM_SIMULATOR
-NEED_MILENAGE=y
-endif
-
-ifdef CONFIG_USIM_SIMULATOR
-CFLAGS += -DCONFIG_USIM_SIMULATOR
-NEED_MILENAGE=y
-endif
-
-ifdef NEED_MILENAGE
-OBJS += ../src/crypto/milenage.o
-NEED_AES_ENCBLOCK=y
-endif
-
-ifdef CONFIG_PKCS12
-CFLAGS += -DPKCS12_FUNCS
-endif
-
-ifdef CONFIG_SMARTCARD
-CFLAGS += -DCONFIG_SMARTCARD
-endif
-
-ifdef NEED_DRAGONFLY
-OBJS += ../src/common/dragonfly.o
-endif
-
-ifdef MS_FUNCS
-OBJS += ../src/crypto/ms_funcs.o
-NEED_DES=y
-NEED_MD4=y
-endif
-
-ifdef CHAP
-OBJS += ../src/eap_common/chap.o
-endif
-
-ifdef TLS_FUNCS
-NEED_DES=y
-# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, EAP_TTLS, EAP_FAST, and
-# EAP_TEAP)
-OBJS += ../src/eap_peer/eap_tls_common.o
-ifndef CONFIG_FIPS
-NEED_TLS_PRF=y
-NEED_SHA1=y
-NEED_MD5=y
-endif
-endif
-
-ifndef CONFIG_TLS
-CONFIG_TLS=openssl
-endif
-
-ifdef CONFIG_TLSV11
-CFLAGS += -DCONFIG_TLSV11
-endif
-
-ifdef CONFIG_TLSV12
-CFLAGS += -DCONFIG_TLSV12
-endif
-
-ifeq ($(CONFIG_TLS), wolfssl)
-ifdef TLS_FUNCS
-CFLAGS += -DWOLFSSL_DER_LOAD
-OBJS += ../src/crypto/tls_wolfssl.o
-endif
-OBJS += ../src/crypto/crypto_wolfssl.o
-OBJS_p += ../src/crypto/crypto_wolfssl.o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_wolfssl.o
-endif
-NEED_TLS_PRF_SHA256=y
-LIBS += -lwolfssl -lm
-LIBS_p += -lwolfssl -lm
-endif
-
-ifeq ($(CONFIG_TLS), openssl)
-ifdef TLS_FUNCS
-CFLAGS += -DEAP_TLS_OPENSSL
-OBJS += ../src/crypto/tls_openssl.o
-OBJS += ../src/crypto/tls_openssl_ocsp.o
-LIBS += -lssl
-endif
-OBJS += ../src/crypto/crypto_openssl.o
-OBJS_p += ../src/crypto/crypto_openssl.o
-OBJS_priv += ../src/crypto/crypto_openssl.o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_openssl.o
-endif
-NEED_TLS_PRF_SHA256=y
-LIBS += -lcrypto
-LIBS_p += -lcrypto
-ifdef CONFIG_TLS_ADD_DL
-LIBS += -ldl
-LIBS_p += -ldl
-endif
-ifndef CONFIG_TLS_DEFAULT_CIPHERS
-CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW"
-endif
-CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\"
-endif
-
-ifeq ($(CONFIG_TLS), gnutls)
-ifndef CONFIG_CRYPTO
-# default to libgcrypt
-CONFIG_CRYPTO=gnutls
-endif
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/tls_gnutls.o
-LIBS += -lgnutls -lgpg-error
-endif
-OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
-OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
-OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_internal.o
-SHA1OBJS += ../src/crypto/sha1-internal.o
-endif
-ifeq ($(CONFIG_CRYPTO), gnutls)
-LIBS += -lgcrypt
-LIBS_p += -lgcrypt
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), nettle)
-LIBS += -lnettle -lgmp
-LIBS_p += -lnettle -lgmp
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-endif
-
-ifeq ($(CONFIG_TLS), internal)
-ifndef CONFIG_CRYPTO
-CONFIG_CRYPTO=internal
-endif
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/crypto_internal-rsa.o
-OBJS += ../src/crypto/tls_internal.o
-OBJS += ../src/tls/tlsv1_common.o
-OBJS += ../src/tls/tlsv1_record.o
-OBJS += ../src/tls/tlsv1_cred.o
-OBJS += ../src/tls/tlsv1_client.o
-OBJS += ../src/tls/tlsv1_client_write.o
-OBJS += ../src/tls/tlsv1_client_read.o
-OBJS += ../src/tls/tlsv1_client_ocsp.o
-OBJS += ../src/tls/rsa.o
-OBJS += ../src/tls/x509v3.o
-OBJS += ../src/tls/pkcs1.o
-OBJS += ../src/tls/pkcs5.o
-OBJS += ../src/tls/pkcs8.o
-NEED_ASN1=y
-NEED_BASE64=y
-NEED_TLS_PRF=y
-ifdef CONFIG_TLSV12
-NEED_TLS_PRF_SHA256=y
-endif
-NEED_MODEXP=y
-NEED_CIPHER=y
-CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
-endif
-ifdef NEED_CIPHER
-NEED_DES=y
-OBJS += ../src/crypto/crypto_internal-cipher.o
-endif
-ifdef NEED_MODEXP
-OBJS += ../src/crypto/crypto_internal-modexp.o
-OBJS += ../src/tls/bignum.o
-endif
-ifeq ($(CONFIG_CRYPTO), libtomcrypt)
-OBJS += ../src/crypto/crypto_libtomcrypt.o
-OBJS_p += ../src/crypto/crypto_libtomcrypt.o
-LIBS += -ltomcrypt -ltfm
-LIBS_p += -ltomcrypt -ltfm
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), internal)
-OBJS += ../src/crypto/crypto_internal.o
-OBJS_p += ../src/crypto/crypto_internal.o
-NEED_AES_ENC=y
-CFLAGS += -DCONFIG_CRYPTO_INTERNAL
-ifdef CONFIG_INTERNAL_LIBTOMMATH
-CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
-ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
-CFLAGS += -DLTM_FAST
-endif
-else
-LIBS += -ltommath
-LIBS_p += -ltommath
-endif
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_DES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD4=y
-CONFIG_INTERNAL_MD5=y
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_SHA384=y
-CONFIG_INTERNAL_SHA512=y
-CONFIG_INTERNAL_RC4=y
-CONFIG_INTERNAL_DH_GROUP5=y
-endif
-ifeq ($(CONFIG_CRYPTO), cryptoapi)
-OBJS += ../src/crypto/crypto_cryptoapi.o
-OBJS_p += ../src/crypto/crypto_cryptoapi.o
-CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-endif
-endif
-
-ifeq ($(CONFIG_TLS), linux)
-OBJS += ../src/crypto/crypto_linux.o
-OBJS_p += ../src/crypto/crypto_linux.o
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/crypto_internal-rsa.o
-OBJS += ../src/crypto/tls_internal.o
-OBJS += ../src/tls/tlsv1_common.o
-OBJS += ../src/tls/tlsv1_record.o
-OBJS += ../src/tls/tlsv1_cred.o
-OBJS += ../src/tls/tlsv1_client.o
-OBJS += ../src/tls/tlsv1_client_write.o
-OBJS += ../src/tls/tlsv1_client_read.o
-OBJS += ../src/tls/tlsv1_client_ocsp.o
-OBJS += ../src/tls/rsa.o
-OBJS += ../src/tls/x509v3.o
-OBJS += ../src/tls/pkcs1.o
-OBJS += ../src/tls/pkcs5.o
-OBJS += ../src/tls/pkcs8.o
-NEED_ASN1=y
-NEED_BASE64=y
-NEED_TLS_PRF=y
-ifdef CONFIG_TLSV12
-NEED_TLS_PRF_SHA256=y
-endif
-NEED_MODEXP=y
-NEED_CIPHER=y
-CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
-endif
-ifdef NEED_MODEXP
-OBJS += ../src/crypto/crypto_internal-modexp.o
-OBJS += ../src/tls/bignum.o
-CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
-CFLAGS += -DLTM_FAST
-endif
-CONFIG_INTERNAL_DH_GROUP5=y
-ifdef NEED_FIPS186_2_PRF
-OBJS += ../src/crypto/fips_prf_internal.o
-OBJS += ../src/crypto/sha1-internal.o
-endif
-endif
-
-ifeq ($(CONFIG_TLS), none)
-ifdef TLS_FUNCS
-OBJS += ../src/crypto/tls_none.o
-CFLAGS += -DEAP_TLS_NONE
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD5=y
-endif
-OBJS += ../src/crypto/crypto_none.o
-OBJS_p += ../src/crypto/crypto_none.o
-CONFIG_INTERNAL_SHA256=y
-CONFIG_INTERNAL_RC4=y
-endif
-
-ifdef TLS_FUNCS
-ifdef CONFIG_SMARTCARD
-ifndef CONFIG_NATIVE_WINDOWS
-ifneq ($(CONFIG_L2_PACKET), freebsd)
-LIBS += -ldl
-endif
-endif
-endif
-endif
-
-ifndef TLS_FUNCS
-OBJS += ../src/crypto/tls_none.o
-ifeq ($(CONFIG_TLS), internal)
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD5=y
-CONFIG_INTERNAL_RC4=y
-endif
-endif
-
-AESOBJS = # none so far (see below)
-ifdef CONFIG_INTERNAL_AES
-AESOBJS += ../src/crypto/aes-internal.o ../src/crypto/aes-internal-dec.o
-endif
-
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), wolfssl)
-NEED_INTERNAL_AES_WRAP=y
-endif
-endif
-ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP
-# Seems to be needed at least with BoringSSL
-NEED_INTERNAL_AES_WRAP=y
-CFLAGS += -DCONFIG_OPENSSL_INTERNAL_AES_WRAP
-endif
-ifdef CONFIG_FIPS
-# Have to use internal AES key wrap routines to use OpenSSL EVP since the
-# OpenSSL AES_wrap_key()/AES_unwrap_key() API is not available in FIPS mode.
-NEED_INTERNAL_AES_WRAP=y
-endif
-
-ifdef NEED_INTERNAL_AES_WRAP
-ifneq ($(CONFIG_TLS), linux)
-AESOBJS += ../src/crypto/aes-unwrap.o
-endif
-endif
-ifdef NEED_AES_EAX
-AESOBJS += ../src/crypto/aes-eax.o
-NEED_AES_CTR=y
-endif
-ifdef NEED_AES_SIV
-AESOBJS += ../src/crypto/aes-siv.o
-NEED_AES_CTR=y
-endif
-ifdef NEED_AES_CTR
-AESOBJS += ../src/crypto/aes-ctr.o
-endif
-ifdef NEED_AES_ENCBLOCK
-AESOBJS += ../src/crypto/aes-encblock.o
-endif
-NEED_AES_ENC=y
-ifdef CONFIG_OPENSSL_CMAC
-CFLAGS += -DCONFIG_OPENSSL_CMAC
-else
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), wolfssl)
-AESOBJS += ../src/crypto/aes-omac1.o
-endif
-endif
-endif
-ifdef NEED_AES_WRAP
-NEED_AES_ENC=y
-ifdef NEED_INTERNAL_AES_WRAP
-AESOBJS += ../src/crypto/aes-wrap.o
-endif
-endif
-ifdef NEED_AES_CBC
-NEED_AES_ENC=y
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), wolfssl)
-AESOBJS += ../src/crypto/aes-cbc.o
-endif
-endif
-endif
-endif
-ifdef NEED_AES_ENC
-ifdef CONFIG_INTERNAL_AES
-AESOBJS += ../src/crypto/aes-internal-enc.o
-endif
-endif
-ifdef NEED_AES
-OBJS += $(AESOBJS)
-endif
-
-ifdef NEED_SHA1
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), gnutls)
-ifneq ($(CONFIG_TLS), wolfssl)
-SHA1OBJS += ../src/crypto/sha1.o
-endif
-endif
-endif
-endif
-SHA1OBJS += ../src/crypto/sha1-prf.o
-ifdef CONFIG_INTERNAL_SHA1
-SHA1OBJS += ../src/crypto/sha1-internal.o
-ifdef NEED_FIPS186_2_PRF
-SHA1OBJS += ../src/crypto/fips_prf_internal.o
-endif
-endif
-ifdef CONFIG_NO_WPA_PASSPHRASE
-CFLAGS += -DCONFIG_NO_PBKDF2
-else
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), wolfssl)
-SHA1OBJS += ../src/crypto/sha1-pbkdf2.o
-endif
-endif
-endif
-ifdef NEED_T_PRF
-SHA1OBJS += ../src/crypto/sha1-tprf.o
-endif
-ifdef NEED_TLS_PRF
-SHA1OBJS += ../src/crypto/sha1-tlsprf.o
-endif
-endif
-
-ifndef CONFIG_FIPS
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), gnutls)
-ifneq ($(CONFIG_TLS), wolfssl)
-MD5OBJS += ../src/crypto/md5.o
-endif
-endif
-endif
-endif
-endif
-ifdef NEED_MD5
-ifdef CONFIG_INTERNAL_MD5
-MD5OBJS += ../src/crypto/md5-internal.o
-endif
-OBJS += $(MD5OBJS)
-OBJS_p += $(MD5OBJS)
-OBJS_priv += $(MD5OBJS)
-endif
-
-ifdef NEED_MD4
-ifdef CONFIG_INTERNAL_MD4
-OBJS += ../src/crypto/md4-internal.o
-endif
-endif
-
-DESOBJS = # none needed when not internal
-ifdef NEED_DES
-ifndef CONFIG_FIPS
-CFLAGS += -DCONFIG_DES
-endif
-ifdef CONFIG_INTERNAL_DES
-DESOBJS += ../src/crypto/des-internal.o
-endif
-endif
-
-ifdef CONFIG_NO_RC4
-CFLAGS += -DCONFIG_NO_RC4
-endif
-
-ifdef NEED_RC4
-ifdef CONFIG_INTERNAL_RC4
-ifndef CONFIG_NO_RC4
-OBJS += ../src/crypto/rc4.o
-endif
-endif
-endif
-
-SHA256OBJS = # none by default
-CFLAGS += -DCONFIG_SHA256
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), gnutls)
-ifneq ($(CONFIG_TLS), wolfssl)
-SHA256OBJS += ../src/crypto/sha256.o
-endif
-endif
-endif
-endif
-SHA256OBJS += ../src/crypto/sha256-prf.o
-ifdef CONFIG_INTERNAL_SHA256
-SHA256OBJS += ../src/crypto/sha256-internal.o
-endif
-ifdef CONFIG_INTERNAL_SHA384
-CFLAGS += -DCONFIG_INTERNAL_SHA384
-SHA256OBJS += ../src/crypto/sha384-internal.o
-endif
-ifdef CONFIG_INTERNAL_SHA512
-CFLAGS += -DCONFIG_INTERNAL_SHA512
-SHA256OBJS += ../src/crypto/sha512-internal.o
-endif
-ifdef NEED_TLS_PRF_SHA256
-SHA256OBJS += ../src/crypto/sha256-tlsprf.o
-endif
-ifdef NEED_TLS_PRF_SHA384
-SHA256OBJS += ../src/crypto/sha384-tlsprf.o
-endif
-ifdef NEED_HMAC_SHA256_KDF
-CFLAGS += -DCONFIG_HMAC_SHA256_KDF
-OBJS += ../src/crypto/sha256-kdf.o
-endif
-ifdef NEED_HMAC_SHA384_KDF
-CFLAGS += -DCONFIG_HMAC_SHA384_KDF
-OBJS += ../src/crypto/sha384-kdf.o
-endif
-ifdef NEED_HMAC_SHA512_KDF
-CFLAGS += -DCONFIG_HMAC_SHA512_KDF
-OBJS += ../src/crypto/sha512-kdf.o
-endif
-OBJS += $(SHA256OBJS)
-ifdef NEED_SHA384
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), gnutls)
-ifneq ($(CONFIG_TLS), wolfssl)
-OBJS += ../src/crypto/sha384.o
-endif
-endif
-endif
-endif
-CFLAGS += -DCONFIG_SHA384
-OBJS += ../src/crypto/sha384-prf.o
-endif
-ifdef NEED_SHA512
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), linux)
-ifneq ($(CONFIG_TLS), gnutls)
-ifneq ($(CONFIG_TLS), wolfssl)
-OBJS += ../src/crypto/sha512.o
-endif
-endif
-endif
-endif
-CFLAGS += -DCONFIG_SHA512
-OBJS += ../src/crypto/sha512-prf.o
-endif
-
-ifdef NEED_ASN1
-OBJS += ../src/tls/asn1.o
-endif
-
-ifdef NEED_DH_GROUPS
-OBJS += ../src/crypto/dh_groups.o
-endif
-ifdef NEED_DH_GROUPS_ALL
-CFLAGS += -DALL_DH_GROUPS
-endif
-ifdef CONFIG_INTERNAL_DH_GROUP5
-ifdef NEED_DH_GROUPS
-OBJS += ../src/crypto/dh_group5.o
-endif
-endif
-
-ifdef NEED_ECC
-CFLAGS += -DCONFIG_ECC
-endif
-
-ifdef CONFIG_NO_RANDOM_POOL
-CFLAGS += -DCONFIG_NO_RANDOM_POOL
-else
-ifdef CONFIG_GETRANDOM
-CFLAGS += -DCONFIG_GETRANDOM
-endif
-OBJS += ../src/crypto/random.o
-endif
-
-ifdef CONFIG_CTRL_IFACE
-ifeq ($(CONFIG_CTRL_IFACE), y)
-ifdef CONFIG_NATIVE_WINDOWS
-CONFIG_CTRL_IFACE=named_pipe
-else
-CONFIG_CTRL_IFACE=unix
-endif
-endif
-CFLAGS += -DCONFIG_CTRL_IFACE
-ifeq ($(CONFIG_CTRL_IFACE), unix)
-CFLAGS += -DCONFIG_CTRL_IFACE_UNIX
-OBJS += ../src/common/ctrl_iface_common.o
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp)
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp6)
-CONFIG_CTRL_IFACE=udp
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP_IPV6
-endif
-ifeq ($(CONFIG_CTRL_IFACE), named_pipe)
-CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp-remote)
-CONFIG_CTRL_IFACE=udp
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
-endif
-ifeq ($(CONFIG_CTRL_IFACE), udp6-remote)
-CONFIG_CTRL_IFACE=udp
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
-CFLAGS += -DCONFIG_CTRL_IFACE_UDP_IPV6
-endif
-OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
-endif
-
-ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-OBJS += dbus/dbus_dict_helpers.o
-OBJS += dbus/dbus_new_helpers.o
-OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
-OBJS += dbus/dbus_common.o
-ifdef CONFIG_WPS
-OBJS += dbus/dbus_new_handlers_wps.o
-endif
-ifdef CONFIG_P2P
-OBJS += dbus/dbus_new_handlers_p2p.o
-endif
-ifndef DBUS_LIBS
-DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
-endif
-ifndef DBUS_INCLUDE
-DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
-endif
-ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-OBJS += dbus/dbus_new_introspect.o
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
-endif
-CFLAGS += $(DBUS_INCLUDE)
-LIBS += $(DBUS_LIBS)
-endif
-
-ifdef CONFIG_READLINE
-OBJS_c += ../src/utils/edit_readline.o
-LIBS_c += -lreadline -lncurses
-else
-ifdef CONFIG_WPA_CLI_EDIT
-OBJS_c += ../src/utils/edit.o
-else
-OBJS_c += ../src/utils/edit_simple.o
-endif
-endif
-
-ifdef CONFIG_NATIVE_WINDOWS
-CFLAGS += -DCONFIG_NATIVE_WINDOWS
-LIBS += -lws2_32 -lgdi32 -lcrypt32
-LIBS_c += -lws2_32
-LIBS_p += -lws2_32 -lgdi32
-ifeq ($(CONFIG_CRYPTO), cryptoapi)
-LIBS_p += -lcrypt32
-endif
-endif
-
-ifdef CONFIG_NO_STDOUT_DEBUG
-CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
-ifndef CONFIG_CTRL_IFACE
-CFLAGS += -DCONFIG_NO_WPA_MSG
-endif
-endif
-
-ifdef CONFIG_IPV6
-# for eapol_test only
-CFLAGS += -DCONFIG_IPV6
-endif
-
-ifdef CONFIG_NO_LINUX_PACKET_SOCKET_WAR
-CFLAGS += -DCONFIG_NO_LINUX_PACKET_SOCKET_WAR
-endif
-
-ifdef NEED_BASE64
-OBJS += ../src/utils/base64.o
-endif
-
-ifdef NEED_SME
-OBJS += sme.o
-CFLAGS += -DCONFIG_SME
-endif
-
-OBJS += ../src/common/ieee802_11_common.o
-OBJS += ../src/common/hw_features_common.o
-
-ifdef NEED_EAP_COMMON
-OBJS += ../src/eap_common/eap_common.o
-endif
-
-ifndef CONFIG_MAIN
-CONFIG_MAIN=main
-endif
-
-ifdef CONFIG_DEBUG_SYSLOG
-CFLAGS += -DCONFIG_DEBUG_SYSLOG
-ifdef CONFIG_DEBUG_SYSLOG_FACILITY
-CFLAGS += -DLOG_HOSTAPD="$(CONFIG_DEBUG_SYSLOG_FACILITY)"
-endif
-endif
-
-ifdef CONFIG_DEBUG_LINUX_TRACING
-CFLAGS += -DCONFIG_DEBUG_LINUX_TRACING
-endif
-
-ifdef CONFIG_DEBUG_FILE
-CFLAGS += -DCONFIG_DEBUG_FILE
-endif
-
-ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
-CFLAGS += -DCONFIG_DELAYED_MIC_ERROR_REPORT
-endif
-
-ifdef CONFIG_FIPS
-CFLAGS += -DCONFIG_FIPS
-ifneq ($(CONFIG_TLS), openssl)
-ifneq ($(CONFIG_TLS), wolfssl)
-$(error CONFIG_FIPS=y requires CONFIG_TLS=openssl)
-endif
-endif
-endif
-
-OBJS += $(SHA1OBJS) $(DESOBJS)
-
-OBJS_p += $(SHA1OBJS)
-OBJS_p += $(SHA256OBJS)
-OBJS_priv += $(SHA1OBJS)
-
-ifdef CONFIG_BGSCAN_SIMPLE
-CFLAGS += -DCONFIG_BGSCAN_SIMPLE
-OBJS += bgscan_simple.o
-NEED_BGSCAN=y
-endif
-
-ifdef CONFIG_BGSCAN_LEARN
-CFLAGS += -DCONFIG_BGSCAN_LEARN
-OBJS += bgscan_learn.o
-NEED_BGSCAN=y
-endif
-
-ifdef NEED_BGSCAN
-CFLAGS += -DCONFIG_BGSCAN
-OBJS += bgscan.o
-endif
-
-ifdef CONFIG_AUTOSCAN_EXPONENTIAL
-CFLAGS += -DCONFIG_AUTOSCAN_EXPONENTIAL
-OBJS += autoscan_exponential.o
-NEED_AUTOSCAN=y
-endif
-
-ifdef CONFIG_AUTOSCAN_PERIODIC
-CFLAGS += -DCONFIG_AUTOSCAN_PERIODIC
-OBJS += autoscan_periodic.o
-NEED_AUTOSCAN=y
-endif
-
-ifdef NEED_AUTOSCAN
-CFLAGS += -DCONFIG_AUTOSCAN
-OBJS += autoscan.o
-endif
-
-ifdef CONFIG_EXT_PASSWORD_TEST
-OBJS += ../src/utils/ext_password_test.o
-CFLAGS += -DCONFIG_EXT_PASSWORD_TEST
-NEED_EXT_PASSWORD=y
-endif
-
-ifdef CONFIG_EXT_PASSWORD_FILE
-OBJS += ../src/utils/ext_password_file.o
-CFLAGS += -DCONFIG_EXT_PASSWORD_FILE
-NEED_EXT_PASSWORD=y
-endif
-
-ifdef NEED_EXT_PASSWORD
-OBJS += ../src/utils/ext_password.o
-CFLAGS += -DCONFIG_EXT_PASSWORD
-endif
-
-ifdef NEED_GAS_SERVER
-OBJS += ../src/common/gas_server.o
-CFLAGS += -DCONFIG_GAS_SERVER
-NEED_GAS=y
-endif
-
-ifdef NEED_GAS
-OBJS += ../src/common/gas.o
-OBJS += gas_query.o
-CFLAGS += -DCONFIG_GAS
-NEED_OFFCHANNEL=y
-endif
-
-ifdef NEED_OFFCHANNEL
-OBJS += offchannel.o
-CFLAGS += -DCONFIG_OFFCHANNEL
-endif
-
-ifdef NEED_JSON
-OBJS += ../src/utils/json.o
-CFLAGS += -DCONFIG_JSON
-endif
-
-ifdef CONFIG_MODULE_TESTS
-CFLAGS += -DCONFIG_MODULE_TESTS
-OBJS += wpas_module_tests.o
-OBJS += ../src/utils/utils_module_tests.o
-OBJS += ../src/common/common_module_tests.o
-OBJS += ../src/crypto/crypto_module_tests.o
-ifdef CONFIG_WPS
-OBJS += ../src/wps/wps_module_tests.o
-endif
-endif
-
-OBJS += ../src/drivers/driver_common.o
-OBJS_priv += ../src/drivers/driver_common.o
-
-OBJS += wpa_supplicant.o events.o bssid_ignore.o wpas_glue.o scan.o
-OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o
-OBJS_t += ../src/radius/radius_client.o
-OBJS_t += ../src/radius/radius.o
-OBJS_t2 := $(OBJS) $(OBJS_l2) preauth_test.o
-
-OBJS_nfc := $(OBJS) $(OBJS_l2) nfc_pw_token.o
-OBJS_nfc += $(OBJS_d) ../src/drivers/drivers.o
-
-OBJS += $(CONFIG_MAIN).o
-
-ifdef CONFIG_PRIVSEP
-OBJS_priv += $(OBJS_d) ../src/drivers/drivers.o
-OBJS_priv += $(OBJS_l2)
-OBJS_priv += ../src/utils/os_$(CONFIG_OS).o
-OBJS_priv += ../src/utils/$(CONFIG_ELOOP).o
-OBJS_priv += ../src/utils/common.o
-OBJS_priv += ../src/utils/wpa_debug.o
-OBJS_priv += ../src/utils/wpabuf.o
-OBJS_priv += wpa_priv.o
-ifdef CONFIG_DRIVER_NL80211
-OBJS_priv += ../src/common/ieee802_11_common.o
-endif
-OBJS += ../src/l2_packet/l2_packet_privsep.o
-OBJS += ../src/drivers/driver_privsep.o
-EXTRA_progs += wpa_priv
-else
-OBJS += $(OBJS_d) ../src/drivers/drivers.o
-OBJS += $(OBJS_l2)
-endif
-
-ifdef CONFIG_NDIS_EVENTS_INTEGRATED
-CFLAGS += -DCONFIG_NDIS_EVENTS_INTEGRATED
-OBJS += ../src/drivers/ndis_events.o
-EXTRALIBS += -loleaut32 -lole32 -luuid
-ifdef PLATFORMSDKLIB
-EXTRALIBS += $(PLATFORMSDKLIB)/WbemUuid.Lib
-else
-EXTRALIBS += WbemUuid.Lib
-endif
-endif
-
-ifdef CONFIG_FST
-CFLAGS += -DCONFIG_FST
-ifdef CONFIG_FST_TEST
-CFLAGS += -DCONFIG_FST_TEST
-endif
-FST_OBJS += ../src/fst/fst.o
-FST_OBJS += ../src/fst/fst_session.o
-FST_OBJS += ../src/fst/fst_iface.o
-FST_OBJS += ../src/fst/fst_group.o
-FST_OBJS += ../src/fst/fst_ctrl_aux.o
-ifdef CONFIG_CTRL_IFACE
-FST_OBJS += ../src/fst/fst_ctrl_iface.o
-endif
-OBJS += $(FST_OBJS)
-OBJS_t += $(FST_OBJS)
-OBJS_t2 += $(FST_OBJS)
-OBJS_nfc += $(FST_OBJS)
-endif
-
-ifdef CONFIG_WEP
-CFLAGS += -DCONFIG_WEP
-endif
-
-ifdef CONFIG_NO_TKIP
-CFLAGS += -DCONFIG_NO_TKIP
-endif
-
-dynamic_eap_methods: $(EAPDYN)
-
-_OBJS_VAR := OBJS_priv
-include ../src/objs.mk
-wpa_priv: $(BCHECK) $(OBJS_priv)
- $(Q)$(LDO) $(LDFLAGS) -o wpa_priv $(OBJS_priv) $(LIBS)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS
-include ../src/objs.mk
-wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
- $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS_t
-include ../src/objs.mk
-eapol_test: $(OBJS_t)
- $(Q)$(LDO) $(LDFLAGS) -o eapol_test $(OBJS_t) $(LIBS)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS_t2
-include ../src/objs.mk
-preauth_test: $(OBJS_t2)
- $(Q)$(LDO) $(LDFLAGS) -o preauth_test $(OBJS_t2) $(LIBS)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS_p
-include ../src/objs.mk
-wpa_passphrase: $(OBJS_p)
- $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) $(LIBS)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS_c
-include ../src/objs.mk
-wpa_cli: $(OBJS_c)
- $(Q)$(LDO) $(LDFLAGS) -o wpa_cli $(OBJS_c) $(LIBS_c)
- @$(E) " LD " $@
-
-LIBCTRL += ../src/common/wpa_ctrl.o
-LIBCTRL += ../src/utils/os_$(CONFIG_OS).o
-LIBCTRL += ../src/utils/common.o
-LIBCTRL += ../src/utils/wpa_debug.o
-LIBCTRLSO += ../src/common/wpa_ctrl.c
-LIBCTRLSO += ../src/utils/os_$(CONFIG_OS).c
-LIBCTRLSO += ../src/utils/common.c
-LIBCTRLSO += ../src/utils/wpa_debug.c
-
-_OBJS_VAR := LIBCTRL
-include ../src/objs.mk
-libwpa_client.a: $(LIBCTRL)
- $(Q)rm -f $@
- $(Q)$(AR) crs $@ $?
- @$(E) " AR " $@
-
-libwpa_client.so: $(LIBCTRLSO)
- @$(E) " CC $@ ($^)"
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -fPIC $^
-
-OBJS_wpatest := libwpa_test.o
-_OBJS_VAR := OBJS_wpatest
-include ../src/objs.mk
-libwpa_test1: $(OBJS_wpatest) libwpa_client.a
- $(Q)$(LDO) $(LDFLAGS) -o libwpa_test1 $(OBJS_wpatest) libwpa_client.a $(LIBS_c)
- @$(E) " LD " $@
-
-libwpa_test2: $(OBJS_wpatest) libwpa_client.so
- $(Q)$(LDO) $(LDFLAGS) -o libwpa_test2 $(OBJS_wpatest) -L. -lwpa_client $(LIBS_c)
- @$(E) " LD " $@
-
-_OBJS_VAR := OBJS_nfc
-include ../src/objs.mk
-nfc_pw_token: $(OBJS_nfc)
- $(Q)$(LDO) $(LDFLAGS) -o nfc_pw_token $(OBJS_nfc) $(LIBS)
- @$(E) " LD " $@
-
-win_if_list: win_if_list.c
- $(Q)$(LDO) $(LDFLAGS) -o $@ win_if_list.c $(CFLAGS) $(LIBS_w)
- @$(E) " LD " $@
-
-eap_psk.so: $(SRC_EAP_PSK)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -Deap_peer_psk_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_pax.so: $(SRC_EAP_PAX)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_peap.so: $(SRC_EAP_PEAP)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_sake.so: $(SRC_EAP_SAKE)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_ikev2.so: $(SRC_EAP_IKEV2)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_eke.so: $(SRC_EAP_EKE)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_mschapv2.so: $(SRC_EAP_MSCHAPV2)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_fast.so: $(SRC_EAP_FAST)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_teap.so: $(SRC_EAP_TEAP)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-eap_gpsk.so: $(SRC_EAP_GPSK)
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
- -D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-%.so: ../src/eap_peer/%.c
- $(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \
- -D$(*F:eap_%=eap_peer_%)_register=eap_peer_method_dynamic_init
- @$(E) " CC/LD " $@
-
-%.service: %.service.in
- $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
- @$(E) " sed" $<
-
-%@.service: %.service.arg.in
- $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
- @$(E) " sed" $<
-
-wpa_supplicant.exe: wpa_supplicant
- mv -f $< $@
-wpa_cli.exe: wpa_cli
- mv -f $< $@
-wpa_passphrase.exe: wpa_passphrase
- mv -f $< $@
-win_if_list.exe: win_if_list
- mv -f $< $@
-eapol_test.exe: eapol_test
- mv -f $< $@
-
-WINALL=wpa_supplicant.exe wpa_cli.exe wpa_passphrase.exe win_if_list.exe
-
-windows-bin: $(WINALL)
- $(STRIP) $(WINALL)
-
-wpa_gui:
- @echo "wpa_gui has been removed - see wpa_gui-qt4 for replacement"
-
-wpa_gui-qt4/Makefile:
- qmake -o wpa_gui-qt4/Makefile wpa_gui-qt4/wpa_gui.pro
-
-wpa_gui-qt4/lang/wpa_gui_de.qm: wpa_gui-qt4/lang/wpa_gui_de.ts
- lrelease wpa_gui-qt4/wpa_gui.pro
-
-wpa_gui-qt4: wpa_gui-qt4/Makefile wpa_gui-qt4/lang/wpa_gui_de.qm
- $(MAKE) -C wpa_gui-qt4
-
-FIPSDIR=/usr/local/ssl/fips-2.0
-FIPSLD=$(FIPSDIR)/bin/fipsld
-fips:
- $(MAKE) CC=$(FIPSLD) FIPSLD_CC="$(CC)"
-
-.PHONY: lcov-html
-lcov-html: $(call BUILDOBJ,wpa_supplicant.gcda)
- lcov -c -d $(BUILDDIR) > lcov.info
- genhtml lcov.info --output-directory lcov-html
-
-clean: common-clean
- $(MAKE) -C ../src clean
- $(MAKE) -C dbus clean
- rm -f core *~ *.o *.d *.gcno *.gcda *.gcov
- rm -f eap_*.so $(WINALL) eapol_test preauth_test
- rm -f wpa_priv
- rm -f nfc_pw_token
- rm -f lcov.info
- rm -rf lcov-html
- rm -f libwpa_client.a
- rm -f libwpa_client.so
- rm -f libwpa_test1 libwpa_test2
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
deleted file mode 100644
index 05f15ff46bda..000000000000
--- a/wpa_supplicant/README
+++ /dev/null
@@ -1,1163 +0,0 @@
-wpa_supplicant
-==============
-
-Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors
-All Rights Reserved.
-
-This program is licensed under the BSD license (the one with
-advertisement clause removed).
-
-If you are submitting changes to the project, please see CONTRIBUTIONS
-file for more instructions.
-
-
-
-License
--------
-
-This software may be distributed, used, and modified under the terms of
-BSD license:
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. Neither the name(s) of the above-listed copyright holder(s) nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
-Features
---------
-
-Supported WPA/IEEE 802.11i features:
-- WPA-PSK ("WPA-Personal")
-- WPA with EAP (e.g., with RADIUS authentication server) ("WPA-Enterprise")
- Following authentication methods are supported with an integrate IEEE 802.1X
- Supplicant:
- * EAP-TLS
- * EAP-PEAP/MSCHAPv2 (both PEAPv0 and PEAPv1)
- * EAP-PEAP/TLS (both PEAPv0 and PEAPv1)
- * EAP-PEAP/GTC (both PEAPv0 and PEAPv1)
- * EAP-PEAP/OTP (both PEAPv0 and PEAPv1)
- * EAP-PEAP/MD5-Challenge (both PEAPv0 and PEAPv1)
- * EAP-TTLS/EAP-MD5-Challenge
- * EAP-TTLS/EAP-GTC
- * EAP-TTLS/EAP-OTP
- * EAP-TTLS/EAP-MSCHAPv2
- * EAP-TTLS/EAP-TLS
- * EAP-TTLS/MSCHAPv2
- * EAP-TTLS/MSCHAP
- * EAP-TTLS/PAP
- * EAP-TTLS/CHAP
- * EAP-SIM
- * EAP-AKA
- * EAP-AKA'
- * EAP-PSK
- * EAP-PAX
- * EAP-SAKE
- * EAP-IKEv2
- * EAP-GPSK
- * EAP-pwd
- * LEAP (note: requires special support from the driver for IEEE 802.11
- authentication)
- (following methods are supported, but since they do not generate keying
- material, they cannot be used with WPA or IEEE 802.1X WEP keying)
- * EAP-MD5-Challenge
- * EAP-MSCHAPv2
- * EAP-GTC
- * EAP-OTP
-- key management for CCMP, TKIP, WEP104, WEP40
-- RSN/WPA2 (IEEE 802.11i)
- * pre-authentication
- * PMKSA caching
-
-Supported TLS/crypto libraries:
-- OpenSSL (default)
-- GnuTLS
-
-Internal TLS/crypto implementation (optional):
-- can be used in place of an external TLS/crypto library
-- TLSv1
-- X.509 certificate processing
-- PKCS #1
-- ASN.1
-- RSA
-- bignum
-- minimal size (ca. 50 kB binary, parts of which are already needed for WPA;
- TLSv1/X.509/ASN.1/RSA/bignum parts are about 25 kB on x86)
-
-
-Requirements
-------------
-
-Current hardware/software requirements:
-- Linux kernel 2.4.x or 2.6.x with Linux Wireless Extensions v15 or newer
-- FreeBSD 6-CURRENT
-- NetBSD-current
-- Microsoft Windows with WinPcap (at least WinXP, may work with other versions)
-- drivers:
- Linux drivers that support cfg80211/nl80211. Even though there are
- number of driver specific interface included in wpa_supplicant, please
- note that Linux drivers are moving to use generic wireless configuration
- interface driver_nl80211 (-Dnl80211 on wpa_supplicant command line)
- should be the default option to start with before falling back to driver
- specific interface.
-
- Linux drivers that support WPA/WPA2 configuration with the generic
- Linux wireless extensions (WE-18 or newer). Obsoleted by nl80211.
-
- In theory, any driver that supports Linux wireless extensions can be
- used with IEEE 802.1X (i.e., not WPA) when using ap_scan=0 option in
- configuration file.
-
- Wired Ethernet drivers (with ap_scan=0)
-
- BSD net80211 layer (e.g., Atheros driver)
- At the moment, this is for FreeBSD 6-CURRENT branch and NetBSD-current.
-
- Windows NDIS
- The current Windows port requires WinPcap (http://winpcap.polito.it/).
- See README-Windows.txt for more information.
-
-wpa_supplicant was designed to be portable for different drivers and
-operating systems. Hopefully, support for more wlan cards and OSes will be
-added in the future. See developer's documentation
-(http://hostap.epitest.fi/wpa_supplicant/devel/) for more information about the
-design of wpa_supplicant and porting to other drivers. One main goal
-is to add full WPA/WPA2 support to Linux wireless extensions to allow
-new drivers to be supported without having to implement new
-driver-specific interface code in wpa_supplicant.
-
-Optional libraries for layer2 packet processing:
-- libpcap (tested with 0.7.2, most relatively recent versions assumed to work,
- this is likely to be available with most distributions,
- http://tcpdump.org/)
-- libdnet (tested with v1.4, most versions assumed to work,
- http://libdnet.sourceforge.net/)
-
-These libraries are _not_ used in the default Linux build. Instead,
-internal Linux specific implementation is used. libpcap/libdnet are
-more portable and they can be used by adding CONFIG_L2_PACKET=pcap into
-.config. They may also be selected automatically for other operating
-systems. In case of Windows builds, WinPcap is used by default
-(CONFIG_L2_PACKET=winpcap).
-
-
-Optional libraries for EAP-TLS, EAP-PEAP, and EAP-TTLS:
-- OpenSSL (tested with 1.0.1 and 1.0.2 versions; assumed to
- work with most relatively recent versions; this is likely to be
- available with most distributions, http://www.openssl.org/)
-- GnuTLS
-- internal TLSv1 implementation
-
-One of these libraries is needed when EAP-TLS, EAP-PEAP, EAP-TTLS, or
-EAP-FAST support is enabled. WPA-PSK mode does not require this or EAPOL/EAP
-implementation. A configuration file, .config, for compilation is
-needed to enable IEEE 802.1X/EAPOL and EAP methods. Note that EAP-MD5,
-EAP-GTC, EAP-OTP, and EAP-MSCHAPV2 cannot be used alone with WPA, so
-they should only be enabled if testing the EAPOL/EAP state
-machines. However, there can be used as inner authentication
-algorithms with EAP-PEAP and EAP-TTLS.
-
-See Building and installing section below for more detailed
-information about the wpa_supplicant build time configuration.
-
-
-
-WPA
----
-
-The original security mechanism of IEEE 802.11 standard was not
-designed to be strong and has proven to be insufficient for most
-networks that require some kind of security. Task group I (Security)
-of IEEE 802.11 working group (http://www.ieee802.org/11/) has worked
-to address the flaws of the base standard and has in practice
-completed its work in May 2004. The IEEE 802.11i amendment to the IEEE
-802.11 standard was approved in June 2004 and published in July 2004.
-
-Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version of the
-IEEE 802.11i work (draft 3.0) to define a subset of the security
-enhancements that can be implemented with existing wlan hardware. This
-is called Wi-Fi Protected Access<TM> (WPA). This has now become a
-mandatory component of interoperability testing and certification done
-by Wi-Fi Alliance. Wi-Fi provides information about WPA at its web
-site (http://www.wi-fi.org/OpenSection/protected_access.asp).
-
-IEEE 802.11 standard defined wired equivalent privacy (WEP) algorithm
-for protecting wireless networks. WEP uses RC4 with 40-bit keys,
-24-bit initialization vector (IV), and CRC32 to protect against packet
-forgery. All these choices have proven to be insufficient: key space is
-too small against current attacks, RC4 key scheduling is insufficient
-(beginning of the pseudorandom stream should be skipped), IV space is
-too small and IV reuse makes attacks easier, there is no replay
-protection, and non-keyed authentication does not protect against bit
-flipping packet data.
-
-WPA is an intermediate solution for the security issues. It uses
-Temporal Key Integrity Protocol (TKIP) to replace WEP. TKIP is a
-compromise on strong security and possibility to use existing
-hardware. It still uses RC4 for the encryption like WEP, but with
-per-packet RC4 keys. In addition, it implements replay protection,
-keyed packet authentication mechanism (Michael MIC).
-
-Keys can be managed using two different mechanisms. WPA can either use
-an external authentication server (e.g., RADIUS) and EAP just like
-IEEE 802.1X is using or pre-shared keys without need for additional
-servers. Wi-Fi calls these "WPA-Enterprise" and "WPA-Personal",
-respectively. Both mechanisms will generate a master session key for
-the Authenticator (AP) and Supplicant (client station).
-
-WPA implements a new key handshake (4-Way Handshake and Group Key
-Handshake) for generating and exchanging data encryption keys between
-the Authenticator and Supplicant. This handshake is also used to
-verify that both Authenticator and Supplicant know the master session
-key. These handshakes are identical regardless of the selected key
-management mechanism (only the method for generating master session
-key changes).
-
-
-
-IEEE 802.11i / WPA2
--------------------
-
-The design for parts of IEEE 802.11i that were not included in WPA has
-finished (May 2004) and this amendment to IEEE 802.11 was approved in
-June 2004. Wi-Fi Alliance is using the final IEEE 802.11i as a new
-version of WPA called WPA2. This includes, e.g., support for more
-robust encryption algorithm (CCMP: AES in Counter mode with CBC-MAC)
-to replace TKIP and optimizations for handoff (reduced number of
-messages in initial key handshake, pre-authentication, and PMKSA caching).
-
-
-
-wpa_supplicant
---------------
-
-wpa_supplicant is an implementation of the WPA Supplicant component,
-i.e., the part that runs in the client stations. It implements WPA key
-negotiation with a WPA Authenticator and EAP authentication with
-Authentication Server. In addition, it controls the roaming and IEEE
-802.11 authentication/association of the wlan driver.
-
-wpa_supplicant is designed to be a "daemon" program that runs in the
-background and acts as the backend component controlling the wireless
-connection. wpa_supplicant supports separate frontend programs and an
-example text-based frontend, wpa_cli, is included with wpa_supplicant.
-
-Following steps are used when associating with an AP using WPA:
-
-- wpa_supplicant requests the kernel driver to scan neighboring BSSes
-- wpa_supplicant selects a BSS based on its configuration
-- wpa_supplicant requests the kernel driver to associate with the chosen
- BSS
-- If WPA-EAP: integrated IEEE 802.1X Supplicant completes EAP
- authentication with the authentication server (proxied by the
- Authenticator in the AP)
-- If WPA-EAP: master key is received from the IEEE 802.1X Supplicant
-- If WPA-PSK: wpa_supplicant uses PSK as the master session key
-- wpa_supplicant completes WPA 4-Way Handshake and Group Key Handshake
- with the Authenticator (AP)
-- wpa_supplicant configures encryption keys for unicast and broadcast
-- normal data packets can be transmitted and received
-
-
-
-Building and installing
------------------------
-
-In order to be able to build wpa_supplicant, you will first need to
-select which parts of it will be included. This is done by creating a
-build time configuration file, .config, in the wpa_supplicant root
-directory. Configuration options are text lines using following
-format: CONFIG_<option>=y. Lines starting with # are considered
-comments and are ignored. See defconfig file for an example configuration
-and a list of available options and additional notes.
-
-The build time configuration can be used to select only the needed
-features and limit the binary size and requirements for external
-libraries. The main configuration parts are the selection of which
-driver interfaces (e.g., nl80211, wext, ..) and which authentication
-methods (e.g., EAP-TLS, EAP-PEAP, ..) are included.
-
-Following build time configuration options are used to control IEEE
-802.1X/EAPOL and EAP state machines and all EAP methods. Including
-TLS, PEAP, or TTLS will require linking wpa_supplicant with OpenSSL
-library for TLS implementation. Alternatively, GnuTLS or the internal
-TLSv1 implementation can be used for TLS functionality.
-
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_MD5=y
-CONFIG_EAP_MSCHAPV2=y
-CONFIG_EAP_TLS=y
-CONFIG_EAP_PEAP=y
-CONFIG_EAP_TTLS=y
-CONFIG_EAP_GTC=y
-CONFIG_EAP_OTP=y
-CONFIG_EAP_SIM=y
-CONFIG_EAP_AKA=y
-CONFIG_EAP_AKA_PRIME=y
-CONFIG_EAP_PSK=y
-CONFIG_EAP_SAKE=y
-CONFIG_EAP_GPSK=y
-CONFIG_EAP_PAX=y
-CONFIG_EAP_LEAP=y
-CONFIG_EAP_IKEV2=y
-CONFIG_EAP_PWD=y
-
-Following option can be used to include GSM SIM/USIM interface for GSM/UMTS
-authentication algorithm (for EAP-SIM/EAP-AKA/EAP-AKA'). This requires pcsc-lite
-(http://www.linuxnet.com/) for smart card access.
-
-CONFIG_PCSC=y
-
-Following options can be added to .config to select which driver
-interfaces are included.
-
-CONFIG_DRIVER_NL80211=y
-CONFIG_DRIVER_WEXT=y
-CONFIG_DRIVER_BSD=y
-CONFIG_DRIVER_NDIS=y
-
-Following example includes some more features and driver interfaces that
-are included in the wpa_supplicant package:
-
-CONFIG_DRIVER_NL80211=y
-CONFIG_DRIVER_WEXT=y
-CONFIG_DRIVER_BSD=y
-CONFIG_DRIVER_NDIS=y
-CONFIG_IEEE8021X_EAPOL=y
-CONFIG_EAP_MD5=y
-CONFIG_EAP_MSCHAPV2=y
-CONFIG_EAP_TLS=y
-CONFIG_EAP_PEAP=y
-CONFIG_EAP_TTLS=y
-CONFIG_EAP_GTC=y
-CONFIG_EAP_OTP=y
-CONFIG_EAP_SIM=y
-CONFIG_EAP_AKA=y
-CONFIG_EAP_PSK=y
-CONFIG_EAP_SAKE=y
-CONFIG_EAP_GPSK=y
-CONFIG_EAP_PAX=y
-CONFIG_EAP_LEAP=y
-CONFIG_EAP_IKEV2=y
-CONFIG_PCSC=y
-
-EAP-PEAP and EAP-TTLS will automatically include configured EAP
-methods (MD5, OTP, GTC, MSCHAPV2) for inner authentication selection.
-
-
-After you have created a configuration file, you can build
-wpa_supplicant and wpa_cli with 'make' command. You may then install
-the binaries to a suitable system directory, e.g., /usr/local/bin.
-
-Example commands:
-
-# build wpa_supplicant and wpa_cli
-make
-# install binaries (this may need root privileges)
-cp wpa_cli wpa_supplicant /usr/local/bin
-
-
-You will need to make a configuration file, e.g.,
-/etc/wpa_supplicant.conf, with network configuration for the networks
-you are going to use. Configuration file section below includes
-explanation of the configuration file format and includes various
-examples. Once the configuration is ready, you can test whether the
-configuration work by first running wpa_supplicant with following
-command to start it on foreground with debugging enabled:
-
-wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -d
-
-Assuming everything goes fine, you can start using following command
-to start wpa_supplicant on background without debugging:
-
-wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B
-
-Please note that if you included more than one driver interface in the
-build time configuration (.config), you may need to specify which
-interface to use by including -D<driver name> option on the command
-line. See following section for more details on command line options
-for wpa_supplicant.
-
-
-
-Command line options
---------------------
-
-usage:
- wpa_supplicant [-BddfhKLqqtuvW] [-P<pid file>] [-g<global ctrl>] \
- [-G<group>] \
- -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
- [-b<br_ifname> [-MN -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
- [-p<driver_param>] [-b<br_ifname>] [-m<P2P Device config file>] ...
-
-options:
- -b = optional bridge interface name
- -B = run daemon in the background
- -c = Configuration file
- -C = ctrl_interface parameter (only used if -c is not)
- -i = interface name
- -d = increase debugging verbosity (-dd even more)
- -D = driver name (can be multiple drivers: nl80211,wext)
- -f = Log output to default log location (normally /tmp)
- -g = global ctrl_interface
- -G = global ctrl_interface group
- -K = include keys (passwords, etc.) in debug output
- -t = include timestamp in debug messages
- -h = show this help text
- -L = show license (BSD)
- -p = driver parameters
- -P = PID file
- -q = decrease debugging verbosity (-qq even less)
- -u = enable DBus control interface
- -v = show version
- -W = wait for a control interface monitor before starting
- -M = start describing matching interface
- -N = start describing new interface
- -m = Configuration file for the P2P Device
-
-drivers:
- nl80211 = Linux nl80211/cfg80211
- wext = Linux wireless extensions (generic)
- wired = wpa_supplicant wired Ethernet driver
- roboswitch = wpa_supplicant Broadcom switch driver
- bsd = BSD 802.11 support (Atheros, etc.)
- ndis = Windows NDIS driver
-
-In most common cases, wpa_supplicant is started with
-
-wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0
-
-This makes the process fork into background.
-
-The easiest way to debug problems, and to get debug log for bug
-reports, is to start wpa_supplicant on foreground with debugging
-enabled:
-
-wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0 -d
-
-If the specific driver wrapper is not known beforehand, it is possible
-to specify multiple comma separated driver wrappers on the command
-line. wpa_supplicant will use the first driver wrapper that is able to
-initialize the interface.
-
-wpa_supplicant -Dnl80211,wext -c/etc/wpa_supplicant.conf -iwlan0
-
-
-wpa_supplicant can control multiple interfaces (radios) either by
-running one process for each interface separately or by running just
-one process and list of options at command line. Each interface is
-separated with -N argument. As an example, following command would
-start wpa_supplicant for two interfaces:
-
-wpa_supplicant \
- -c wpa1.conf -i wlan0 -D nl80211 -N \
- -c wpa2.conf -i wlan1 -D wext
-
-
-If the interfaces on which wpa_supplicant is to run are not known or do
-not exist, wpa_supplicant can match an interface when it arrives. Each
-matched interface is separated with -M argument and the -i argument now
-allows for pattern matching.
-
-As an example, the following command would start wpa_supplicant for a
-specific wired interface called lan0, any interface starting with wlan
-and lastly any other interface. Each match has its own configuration
-file, and for the wired interface a specific driver has also been given.
-
-wpa_supplicant \
- -M -c wpa_wired.conf -ilan0 -D wired \
- -M -c wpa1.conf -iwlan* \
- -M -c wpa2.conf
-
-
-If the interface is added in a Linux bridge (e.g., br0), the bridge
-interface needs to be configured to wpa_supplicant in addition to the
-main interface:
-
-wpa_supplicant -cw.conf -Dnl80211 -iwlan0 -bbr0
-
-
-Configuration file
-------------------
-
-wpa_supplicant is configured using a text file that lists all accepted
-networks and security policies, including pre-shared keys. See
-example configuration file, wpa_supplicant.conf, for detailed
-information about the configuration format and supported fields.
-
-Changes to configuration file can be reloaded be sending SIGHUP signal
-to wpa_supplicant ('killall -HUP wpa_supplicant'). Similarly,
-reloading can be triggered with 'wpa_cli reconfigure' command.
-
-Configuration file can include one or more network blocks, e.g., one
-for each used SSID. wpa_supplicant will automatically select the best
-network based on the order of network blocks in the configuration
-file, network security level (WPA/WPA2 is preferred), and signal
-strength.
-
-Example configuration files for some common configurations:
-
-1) WPA-Personal (PSK) as home network and WPA-Enterprise with EAP-TLS as work
- network
-
-# allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-#
-# home network; allow all valid ciphers
-network={
- ssid="home"
- scan_ssid=1
- key_mgmt=WPA-PSK
- psk="very secret passphrase"
-}
-#
-# work network; use EAP-TLS with WPA; allow only CCMP and TKIP ciphers
-network={
- ssid="work"
- scan_ssid=1
- key_mgmt=WPA-EAP
- pairwise=CCMP TKIP
- group=CCMP TKIP
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
-}
-
-
-2) WPA-RADIUS/EAP-PEAP/MSCHAPv2 with RADIUS servers that use old peaplabel
- (e.g., Funk Odyssey and SBR, Meetinghouse Aegis, Interlink RAD-Series)
-
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP
- eap=PEAP
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase1="peaplabel=0"
- phase2="auth=MSCHAPV2"
-}
-
-
-3) EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the
- unencrypted use. Real identity is sent only within an encrypted TLS tunnel.
-
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP
- eap=TTLS
- identity="user@example.com"
- anonymous_identity="anonymous@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase2="auth=MD5"
-}
-
-
-4) IEEE 802.1X (i.e., no WPA) with dynamic WEP keys (require both unicast and
- broadcast); use EAP-TLS for authentication
-
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-network={
- ssid="1x-test"
- scan_ssid=1
- key_mgmt=IEEE8021X
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- eapol_flags=3
-}
-
-
-5) Catch all example that allows more or less all configuration modes. The
- configuration options are used based on what security policy is used in the
- selected SSID. This is mostly for testing and is not recommended for normal
- use.
-
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
- pairwise=CCMP TKIP
- group=CCMP TKIP WEP104 WEP40
- psk="very secret passphrase"
- eap=TTLS PEAP TLS
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- phase1="peaplabel=0"
- ca_cert2="/etc/cert/ca2.pem"
- client_cert2="/etc/cer/user.pem"
- private_key2="/etc/cer/user.prv"
- private_key2_passwd="password"
-}
-
-
-6) Authentication for wired Ethernet. This can be used with 'wired' or
- 'roboswitch' interface (-Dwired or -Droboswitch on command line).
-
-ctrl_interface=/var/run/wpa_supplicant
-ctrl_interface_group=wheel
-ap_scan=0
-network={
- key_mgmt=IEEE8021X
- eap=MD5
- identity="user"
- password="password"
- eapol_flags=0
-}
-
-
-
-Certificates
-------------
-
-Some EAP authentication methods require use of certificates. EAP-TLS
-uses both server side and client certificates whereas EAP-PEAP and
-EAP-TTLS only require the server side certificate. When client
-certificate is used, a matching private key file has to also be
-included in configuration. If the private key uses a passphrase, this
-has to be configured in wpa_supplicant.conf ("private_key_passwd").
-
-wpa_supplicant supports X.509 certificates in PEM and DER
-formats. User certificate and private key can be included in the same
-file.
-
-If the user certificate and private key is received in PKCS#12/PFX
-format, they need to be converted to suitable PEM/DER format for
-wpa_supplicant. This can be done, e.g., with following commands:
-
-# convert client certificate and private key to PEM format
-openssl pkcs12 -in example.pfx -out user.pem -clcerts
-# convert CA certificate (if included in PFX file) to PEM format
-openssl pkcs12 -in example.pfx -out ca.pem -cacerts -nokeys
-
-
-
-wpa_cli
--------
-
-wpa_cli is a text-based frontend program for interacting with
-wpa_supplicant. It is used to query current status, change
-configuration, trigger events, and request interactive user input.
-
-wpa_cli can show the current authentication status, selected security
-mode, dot11 and dot1x MIBs, etc. In addition, it can configure some
-variables like EAPOL state machine parameters and trigger events like
-reassociation and IEEE 802.1X logoff/logon. wpa_cli provides a user
-interface to request authentication information, like username and
-password, if these are not included in the configuration. This can be
-used to implement, e.g., one-time-passwords or generic token card
-authentication where the authentication is based on a
-challenge-response that uses an external device for generating the
-response.
-
-The control interface of wpa_supplicant can be configured to allow
-non-root user access (ctrl_interface_group in the configuration
-file). This makes it possible to run wpa_cli with a normal user
-account.
-
-wpa_cli supports two modes: interactive and command line. Both modes
-share the same command set and the main difference is in interactive
-mode providing access to unsolicited messages (event messages,
-username/password requests).
-
-Interactive mode is started when wpa_cli is executed without including
-the command as a command line parameter. Commands are then entered on
-the wpa_cli prompt. In command line mode, the same commands are
-entered as command line arguments for wpa_cli.
-
-
-Interactive authentication parameters request
-
-When wpa_supplicant need authentication parameters, like username and
-password, which are not present in the configuration file, it sends a
-request message to all attached frontend programs, e.g., wpa_cli in
-interactive mode. wpa_cli shows these requests with
-"CTRL-REQ-<type>-<id>:<text>" prefix. <type> is IDENTITY, PASSWORD, or
-OTP (one-time-password). <id> is a unique identifier for the current
-network. <text> is description of the request. In case of OTP request,
-it includes the challenge from the authentication server.
-
-The reply to these requests can be given with 'identity', 'password',
-and 'otp' commands. <id> needs to be copied from the the matching
-request. 'password' and 'otp' commands can be used regardless of
-whether the request was for PASSWORD or OTP. The main difference
-between these two commands is that values given with 'password' are
-remembered as long as wpa_supplicant is running whereas values given
-with 'otp' are used only once and then forgotten, i.e., wpa_supplicant
-will ask frontend for a new value for every use. This can be used to
-implement one-time-password lists and generic token card -based
-authentication.
-
-Example request for password and a matching reply:
-
-CTRL-REQ-PASSWORD-1:Password needed for SSID foobar
-> password 1 mysecretpassword
-
-Example request for generic token card challenge-response:
-
-CTRL-REQ-OTP-2:Challenge 1235663 needed for SSID foobar
-> otp 2 9876
-
-
-wpa_cli commands
-
- status = get current WPA/EAPOL/EAP status
- mib = get MIB variables (dot1x, dot11)
- help = show this usage help
- interface [ifname] = show interfaces/select interface
- level <debug level> = change debug level
- license = show full wpa_cli license
- logoff = IEEE 802.1X EAPOL state machine logoff
- logon = IEEE 802.1X EAPOL state machine logon
- set = set variables (shows list of variables when run without arguments)
- pmksa = show PMKSA cache
- reassociate = force reassociation
- reconfigure = force wpa_supplicant to re-read its configuration file
- preauthenticate <BSSID> = force preauthentication
- identity <network id> <identity> = configure identity for an SSID
- password <network id> <password> = configure password for an SSID
- pin <network id> <pin> = configure pin for an SSID
- otp <network id> <password> = configure one-time-password for an SSID
- passphrase <network id> <passphrase> = configure private key passphrase
- for an SSID
- bssid <network id> <BSSID> = set preferred BSSID for an SSID
- list_networks = list configured networks
- select_network <network id> = select a network (disable others)
- enable_network <network id> = enable a network
- disable_network <network id> = disable a network
- add_network = add a network
- remove_network <network id> = remove a network
- set_network <network id> <variable> <value> = set network variables (shows
- list of variables when run without arguments)
- get_network <network id> <variable> = get network variables
- save_config = save the current configuration
- disconnect = disconnect and wait for reassociate command before connecting
- scan = request new BSS scan
- scan_results = get latest scan results
- get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilities
- terminate = terminate wpa_supplicant
- quit = exit wpa_cli
-
-
-wpa_cli command line options
-
-wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] [-a<action file>] \
- [-P<pid file>] [-g<global ctrl>] [command..]
- -h = help (show this usage text)
- -v = shown version information
- -a = run in daemon mode executing the action file based on events from
- wpa_supplicant
- -B = run a daemon in the background
- default path: /var/run/wpa_supplicant
- default interface: first interface found in socket path
-
-
-Using wpa_cli to run external program on connect/disconnect
------------------------------------------------------------
-
-wpa_cli can used to run external programs whenever wpa_supplicant
-connects or disconnects from a network. This can be used, e.g., to
-update network configuration and/or trigget DHCP client to update IP
-addresses, etc.
-
-One wpa_cli process in "action" mode needs to be started for each
-interface. For example, the following command starts wpa_cli for the
-default interface (-i can be used to select the interface in case of
-more than one interface being used at the same time):
-
-wpa_cli -a/sbin/wpa_action.sh -B
-
-The action file (-a option, /sbin/wpa_action.sh in this example) will
-be executed whenever wpa_supplicant completes authentication (connect
-event) or detects disconnection). The action script will be called
-with two command line arguments: interface name and event (CONNECTED
-or DISCONNECTED). If the action script needs to get more information
-about the current network, it can use 'wpa_cli status' to query
-wpa_supplicant for more information.
-
-Following example can be used as a simple template for an action
-script:
-
-#!/bin/sh
-
-IFNAME=$1
-CMD=$2
-
-if [ "$CMD" = "CONNECTED" ]; then
- SSID=`wpa_cli -i$IFNAME status | grep ^ssid= | cut -f2- -d=`
- # configure network, signal DHCP client, etc.
-fi
-
-if [ "$CMD" = "DISCONNECTED" ]; then
- # remove network configuration, if needed
- SSID=
-fi
-
-
-
-Integrating with pcmcia-cs/cardmgr scripts
-------------------------------------------
-
-wpa_supplicant needs to be running when using a wireless network with
-WPA. It can be started either from system startup scripts or from
-pcmcia-cs/cardmgr scripts (when using PC Cards). WPA handshake must be
-completed before data frames can be exchanged, so wpa_supplicant
-should be started before DHCP client.
-
-For example, following small changes to pcmcia-cs scripts can be used
-to enable WPA support:
-
-Add MODE="Managed" and WPA="y" to the network scheme in
-/etc/pcmcia/wireless.opts.
-
-Add the following block to the end of 'start' action handler in
-/etc/pcmcia/wireless:
-
- if [ "$WPA" = "y" -a -x /usr/local/bin/wpa_supplicant ]; then
- /usr/local/bin/wpa_supplicant -B -c/etc/wpa_supplicant.conf \
- -i$DEVICE
- fi
-
-Add the following block to the end of 'stop' action handler (may need
-to be separated from other actions) in /etc/pcmcia/wireless:
-
- if [ "$WPA" = "y" -a -x /usr/local/bin/wpa_supplicant ]; then
- killall wpa_supplicant
- fi
-
-This will make cardmgr start wpa_supplicant when the card is plugged
-in.
-
-
-
-Dynamic interface add and operation without configuration files
----------------------------------------------------------------
-
-wpa_supplicant can be started without any configuration files or
-network interfaces. When used in this way, a global (i.e., per
-wpa_supplicant process) control interface is used to add and remove
-network interfaces. Each network interface can then be configured
-through a per-network interface control interface. For example,
-following commands show how to start wpa_supplicant without any
-network interfaces and then add a network interface and configure a
-network (SSID):
-
-# Start wpa_supplicant in the background
-wpa_supplicant -g/var/run/wpa_supplicant-global -B
-
-# Add a new interface (wlan0, no configuration file, driver=nl80211, and
-# enable control interface)
-wpa_cli -g/var/run/wpa_supplicant-global interface_add wlan0 \
- "" nl80211 /var/run/wpa_supplicant
-
-# Configure a network using the newly added network interface:
-wpa_cli -iwlan0 add_network
-wpa_cli -iwlan0 set_network 0 ssid '"test"'
-wpa_cli -iwlan0 set_network 0 key_mgmt WPA-PSK
-wpa_cli -iwlan0 set_network 0 psk '"12345678"'
-wpa_cli -iwlan0 set_network 0 pairwise TKIP
-wpa_cli -iwlan0 set_network 0 group TKIP
-wpa_cli -iwlan0 set_network 0 proto WPA
-wpa_cli -iwlan0 enable_network 0
-
-# At this point, the new network interface should start trying to associate
-# with the WPA-PSK network using SSID test.
-
-# Remove network interface
-wpa_cli -g/var/run/wpa_supplicant-global interface_remove wlan0
-
-
-Privilege separation
---------------------
-
-To minimize the size of code that needs to be run with root privileges
-(e.g., to control wireless interface operation), wpa_supplicant
-supports optional privilege separation. If enabled, this separates the
-privileged operations into a separate process (wpa_priv) while leaving
-rest of the code (e.g., EAP authentication and WPA handshakes) into an
-unprivileged process (wpa_supplicant) that can be run as non-root
-user. Privilege separation restricts the effects of potential software
-errors by containing the majority of the code in an unprivileged
-process to avoid full system compromise.
-
-Privilege separation is not enabled by default and it can be enabled
-by adding CONFIG_PRIVSEP=y to the build configuration (.config). When
-enabled, the privileged operations (driver wrapper and l2_packet) are
-linked into a separate daemon program, wpa_priv. The unprivileged
-program, wpa_supplicant, will be built with a special driver/l2_packet
-wrappers that communicate with the privileged wpa_priv process to
-perform the needed operations. wpa_priv can control what privileged
-are allowed.
-
-wpa_priv needs to be run with network admin privileges (usually, root
-user). It opens a UNIX domain socket for each interface that is
-included on the command line; any other interface will be off limits
-for wpa_supplicant in this kind of configuration. After this,
-wpa_supplicant can be run as a non-root user (e.g., all standard users
-on a laptop or as a special non-privileged user account created just
-for this purpose to limit access to user files even further).
-
-
-Example configuration:
-- create user group for users that are allowed to use wpa_supplicant
- ('wpapriv' in this example) and assign users that should be able to
- use wpa_supplicant into that group
-- create /var/run/wpa_priv directory for UNIX domain sockets and control
- user access by setting it accessible only for the wpapriv group:
- mkdir /var/run/wpa_priv
- chown root:wpapriv /var/run/wpa_priv
- chmod 0750 /var/run/wpa_priv
-- start wpa_priv as root (e.g., from system startup scripts) with the
- enabled interfaces configured on the command line:
- wpa_priv -B -P /var/run/wpa_priv.pid nl80211:wlan0
-- run wpa_supplicant as non-root with a user that is in wpapriv group:
- wpa_supplicant -i ath0 -c wpa_supplicant.conf
-
-wpa_priv does not use the network interface before wpa_supplicant is
-started, so it is fine to include network interfaces that are not
-available at the time wpa_priv is started. As an alternative, wpa_priv
-can be started when an interface is added (hotplug/udev/etc. scripts).
-wpa_priv can control multiple interface with one process, but it is
-also possible to run multiple wpa_priv processes at the same time, if
-desired.
-
-It should be noted that the interface used between wpa_supplicant and
-wpa_priv does not include all the capabilities of the wpa_supplicant
-driver interface and at times, this interface lacks update especially
-for recent addition. Consequently, use of wpa_priv does come with the
-price of somewhat reduced available functionality. The next section
-describing how wpa_supplicant can be used with reduced privileges
-without having to handle the complexity of separate wpa_priv. While that
-approve does not provide separation for network admin capabilities, it
-does allow other root privileges to be dropped without the drawbacks of
-the wpa_priv process.
-
-
-Linux capabilities instead of privileged process
-------------------------------------------------
-
-wpa_supplicant performs operations that need special permissions, e.g.,
-to control the network connection. Traditionally this has been achieved
-by running wpa_supplicant as a privileged process with effective user id
-0 (root). Linux capabilities can be used to provide restricted set of
-capabilities to match the functions needed by wpa_supplicant. The
-minimum set of capabilities needed for the operations is CAP_NET_ADMIN
-and CAP_NET_RAW.
-
-setcap(8) can be used to set file capabilities. For example:
-
-sudo setcap cap_net_raw,cap_net_admin+ep wpa_supplicant
-
-Please note that this would give anyone being able to run that
-wpa_supplicant binary access to the additional capabilities. This can
-further be limited by file owner/group and mode bits. For example:
-
-sudo chown wpas wpa_supplicant
-sudo chmod 0100 wpa_supplicant
-
-This combination of setcap, chown, and chmod commands would allow wpas
-user to execute wpa_supplicant with additional network admin/raw
-capabilities.
-
-Common way style of creating a control interface socket in
-/var/run/wpa_supplicant could not be done by this user, but this
-directory could be created before starting the wpa_supplicant and set to
-suitable mode to allow wpa_supplicant to create sockets
-there. Alternatively, other directory or abstract socket namespace could
-be used for the control interface.
-
-
-External requests for radio control
------------------------------------
-
-External programs can request wpa_supplicant to not start offchannel
-operations during other tasks that may need exclusive control of the
-radio. The RADIO_WORK control interface command can be used for this.
-
-"RADIO_WORK add <name> [freq=<MHz>] [timeout=<seconds>]" command can be
-used to reserve a slot for radio access. If freq is specified, other
-radio work items on the same channel may be completed in
-parallel. Otherwise, all other radio work items are blocked during
-execution. Timeout is set to 10 seconds by default to avoid blocking
-wpa_supplicant operations for excessive time. If a longer (or shorter)
-safety timeout is needed, that can be specified with the optional
-timeout parameter. This command returns an identifier for the radio work
-item.
-
-Once the radio work item has been started, "EXT-RADIO-WORK-START <id>"
-event message is indicated that the external processing can start. Once
-the operation has been completed, "RADIO_WORK done <id>" is used to
-indicate that to wpa_supplicant. This allows other radio works to be
-performed. If this command is forgotten (e.g., due to the external
-program terminating), wpa_supplicant will time out the radio work item
-and send "EXT-RADIO-WORK-TIMEOUT <id>" event to indicate that this has
-happened. "RADIO_WORK done <id>" can also be used to cancel items that
-have not yet been started.
-
-For example, in wpa_cli interactive mode:
-
-> radio_work add test
-1
-<3>EXT-RADIO-WORK-START 1
-> radio_work show
-ext:test@wlan0:0:1:2.487797
-> radio_work done 1
-OK
-> radio_work show
-
-
-> radio_work done 3
-OK
-> radio_work show
-ext:test freq=2412 timeout=30@wlan0:2412:1:28.583483
-<3>EXT-RADIO-WORK-TIMEOUT 2
-
-
-> radio_work add test2 freq=2412 timeout=60
-5
-<3>EXT-RADIO-WORK-START 5
-> radio_work add test3
-6
-> radio_work add test4
-7
-> radio_work show
-ext:test2 freq=2412 timeout=60@wlan0:2412:1:9.751844
-ext:test3@wlan0:0:0:5.071812
-ext:test4@wlan0:0:0:3.143870
-> radio_work done 6
-OK
-> radio_work show
-ext:test2 freq=2412 timeout=60@wlan0:2412:1:16.287869
-ext:test4@wlan0:0:0:9.679895
-> radio_work done 5
-OK
-<3>EXT-RADIO-WORK-START 7
-<3>EXT-RADIO-WORK-TIMEOUT 7
-
-
-DSCP policy procedures
-----------------------
-
-DSCP policy procedures defined in WFA QoS Management-R2 program
-facilitates AP devices to configure DSCP settings for specific uplink
-data streams.
-
-An AP may transmit a DSCP Policy Request frame containing zero or more
-QoS Management IEs to an associated STA which supports DSCP policy
-procedures. Each QoS Management element in a DSCP Policy Request frame
-represents one DSCP policy, and shall include one DSCP Policy attribute
-including a DSCP Policy ID, Request type, and a DSCP value.
-
-wpa_supplicant sends control interface event messages consisting details
-of DSCP policies requested by the AP through a DSCP Policy Request frame
-to external programs. The format of the control interface event messages
-is as shown below:
-
-- Control interface event message format to indicate DSCP request start
-
- <3>CTRL-EVENT-DSCP-POLICY request_start [clear_all] [more]
-
- clear_all - AP requested to clear all DSCP policies configured earlier
- more - AP may request to configure more DSCP policies with new DSCP
- request
-
-- Control interface event message format to add new policy
-
- <3>CTRL-EVENT-DSCP-POLICY add <policy_id> <dscp_value> <ip_version=0|4|6>
- [protocol] [source ip] [destination_ip]/[domain name] [source port]
- [[<start_port> <end_port>]/destination port]
-
- ip_version = 0: Both IPv4 and IPv6
- = 4: IPv4
- = 6: IPv6
- protocol: Internet Protocol Numbers as per IETF RFCs
- = 6: TCP
- = 17: UDP
- = 50: ESP
-
-- Control interface event message format to remove a particular policy,
- identified by the policy_id attribute.
-
- <3>CTRL-EVENT-DSCP-POLICY remove <policy_id>
-
-- DSCP policy may get rejected due to invalid policy parameters. Ccontrol
- interface event message format for rejected policy.
-
- <3>CTRL-EVENT-DSCP-POLICY reject <policy_id>
-
-- Control interface event message format to indicate end of DSCP request.
-
- <3>CTRL-EVENT-DSCP-POLICY request_end
-
-- External applications shall clear active DSCP policies upon receiving
- "CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
-
-- Control interface event message format to indicate wpa_supplicant started
- a timer to wait until the unsolicited DSCP request from the AP.
-
- <3>CTRL-EVENT-DSCP-POLICY request_wait start
-
-- Control interface event message format to indicate timeout to receive the
- unsolicited DSCP request. This event is expected only when an unsolicited
- DSCP request is not received from the AP before timeout.
-
- <3>CTRL-EVENT-DSCP-POLICY request_wait end
-
-DSCP Response:
-A QoS Management STA that enables DSCP Policy capability shall respond
-with DSCP response on receipt of a successful DSCP request from its
-associated AP. wpa_supplicant sends DSCP policy response based on the
-control interface command received from the user is as below:
-
-DSCP_RESP <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
-
-DSCP Query:
-DSCP Policy Query enables a STA to query its associated AP for DSCP
-policies applicable to the STA. Currently, this includes support to send
-a wildcard DSCP query or a DSCP query with a single domain name
-attribute. The command format for the DSCP query command is as follows:
-DSCP_QUERY <wildcard>/<domain_name=<string>>
diff --git a/wpa_supplicant/README-DPP b/wpa_supplicant/README-DPP
deleted file mode 100644
index d378245cd6de..000000000000
--- a/wpa_supplicant/README-DPP
+++ /dev/null
@@ -1,204 +0,0 @@
-Device Provisioning Protocol (DPP)
-==================================
-
-This document describes how the Device Provisioning Protocol (DPP)
-implementation in wpa_supplicant and hostapd can be configured and how
-the STA device and AP can be configured to connect each other using DPP
-Connector mechanism.
-
-Introduction to DPP
--------------------
-
-Device Provisioning Protocol (also known as Wi-Fi Easy Connect) allows
-enrolling of interface-less devices in a secure Wi-Fi network using many
-methods like QR code based authentication (detailed below), PKEX based
-authentication (password with in-band provisioning), etc. In DPP a
-Configurator is used to provide network credentials to the devices. The
-three phases of DPP connection are authentication, configuration and
-network introduction.
-
-More information about Wi-Fi Easy Connect is available from this Wi-Fi
-Alliance web page:
-https://www.wi-fi.org/discover-wi-fi/wi-fi-easy-connect
-
-Build config setup
-------------------
-
-The following parameters must be included in the config file used to
-compile hostapd and wpa_supplicant.
-
-wpa_supplicant build config
----------------------------
-
-Enable DPP in wpa_supplicant build config file
-
-CONFIG_DPP=y
-
-hostapd build config
---------------------
-
-Enable DPP in hostapd build config file
-
-CONFIG_DPP=y
-
-Configurator build config
--------------------------
-
-Any STA or AP device can act as a Configurator. Enable DPP in build
-config. For an AP to act as a Configurator, Interworking needs to be
-enabled for GAS. For wpa_supplicant it is not required.
-
-CONFIG_INTERWORKING=y
-
-
-Sample supplicant config file before provisioning
--------------------------------------------------
-
-ctrl_interface=DIR=/var/run/wpa_supplicant
-ctrl_interface_group=0
-update_config=1
-pmf=2
-dpp_config_processing=2
-
-Sample hostapd config file before provisioning
-----------------------------------------------
-
-interface=wlan0
-driver=nl80211
-ctrl_interface=/var/run/hostapd
-ssid=test
-channel=1
-wpa=2
-wpa_key_mgmt=DPP
-ieee80211w=1
-wpa_pairwise=CCMP
-rsn_pairwise=CCMP
-
-
-Pre-requisites
---------------
-
-It is assumed that an AP and client station are up by running hostapd
-and wpa_supplicant using respective config files.
-
-
-Creating Configurator
----------------------
-
-Add a Configurator over the control interface (wpa_cli/hostapd_cli)
-
-> dpp_configurator_add
-(returns id)
-
-To get key of Configurator
-> dpp_configurator_get_key <id>
-
-
-How to configure an Enrollee using Configurator
------------------------------------------------
-
-On Enrollee side:
-
-Generate QR code for the device. Store the QR code id returned by the
-command.
-
-> dpp_bootstrap_gen type=qrcode mac=<mac-address-of-device> chan=<operating-class/channel> key=<key of the device>
-(Returns bootstrapping info id. If the key parameter is not included, a new key
-is generated automatically. The MAC address is specified without octet
-separating colons. The channel list includes the possible channels on which the
-device is waiting. This uses global operating classes; e.g., 81/1 is the 2.4
-GHz channel 1 on 2412 MHz.)
-
-Get URI for the QR Code of device using the bootstrap info id.
-> dpp_bootstrap_get_uri <bootstrap-id>
-
-Make device listen to DPP request. The central frequency of the 2.4 GHz
-band channel 1 is 2412 MHz) in case the Enrollee is a client device. An
-AP as an Enrollee is listening on its operating channel.
-
-> dpp_listen <frequency>
-
-On Configurator side:
-
-Enter the QR Code in the Configurator.
-> dpp_qr_code "<URI-from-QR-Code-read-from-enrollee>"
-
-On successfully adding QR Code, a bootstrapping info id is returned.
-
-Send provisioning request to Enrollee. (conf is ap-dpp if Enrollee is an
-AP. conf is sta-dpp if Enrollee is a client)
-> dpp_auth_init peer=<qr-code-id> conf=<ap-dpp|sta-dpp> ssid=<SSID hexdump> configurator=<configurator-id>
-or for legacy (PSK/SAE) provisioning for a station Enrollee:
-> dpp_auth_init peer=<qr-code-id> conf=sta-psk ssid=<SSID hexdump> pass=<passphrase hexdump>
-
-The DPP values will be printed in the console. Save these values into the
-config file. If the Enrollee is an AP, we need to manually write these
-values to the hostapd config file. If the Enrollee is a client device,
-these details can be automatically saved to config file using the
-following command.
-
-> save_config
-
-To set values in runtime for AP enrollees
-
-> set dpp_connector <Connector-value-printed-on-console>
-> set dpp_csign <csign-value-on-console>
-> set dpp_netaccesskey <netaccess-value-on-console>
-
-To set values in runtime for client enrollees, set dpp_config_processing
-to 2 in wpa_supplicant conf file.
-
-Once the values are set in run-time (if not set in run-time, but saved
-in config files, they are taken up in next restart), the client device
-will automatically connect to the already provisioned AP and connection
-will be established.
-
-
-Self-configuring a device
--------------------------
-
-It is possible for a device to configure itself if it is the
-Configurator for the network.
-
-Create a Configurator in the device and use the dpp_configurator_sign
-command to get DPP credentials.
-
-> dpp_configurator_add
-(returns configurator id)
-> dpp_configurator_sign conf=<ap-dpp|sta-dpp> configurator=<configurator-id> ssid=<SSID hexdump>
-
-
-Sample AP configuration files after provisioning
-------------------------------------------------
-
-interface=wlan0
-driver=nl80211
-ctrl_interface=/var/run/hostapd
-ssid=test
-channel=1
-wpa=2
-wpa_key_mgmt=DPP
-ieee80211w=1
-wpa_pairwise=CCMP
-rsn_pairwise=CCMP
-dpp_connector=<Connector value provided by Configurator>
-dpp_csign=<C-Sign-Key value provided by Configurator>
-dpp_netaccesskey=<Net access key provided by Configurator>
-
-
-Sample station configuration file after provisioning
-----------------------------------------------------
-
-ctrl_interface=DIR=/var/run/wpa_supplicant
-ctrl_interface_group=0
-update_config=1
-pmf=2
-dpp_config_processing=2
-network={
- ssid="test"
- key_mgmt=DPP
- ieee80211w=2
- dpp_connector="<Connector value provided by Configurator>"
- dpp_netaccesskey=<Net access key provided by Configurator>
- dpp_csign=<C-sign-key value provided by Configurator>
-}
diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20
deleted file mode 100644
index b076621db527..000000000000
--- a/wpa_supplicant/README-HS20
+++ /dev/null
@@ -1,654 +0,0 @@
-wpa_supplicant and Hotspot 2.0
-==============================
-
-This document describe how the IEEE 802.11u Interworking and Wi-Fi
-Hotspot 2.0 (Release 1) implementation in wpa_supplicant can be
-configured and how an external component on the client e.g., management
-GUI or Wi-Fi framework) is used to manage this functionality.
-
-
-Introduction to Wi-Fi Hotspot 2.0
----------------------------------
-
-Hotspot 2.0 is the name of the Wi-Fi Alliance specification that is used
-in the Wi-Fi CERTIFIED Passpoint<TM> program. More information about
-this is available in this white paper:
-
-http://www.wi-fi.org/knowledge-center/white-papers/wi-fi-certified-passpoint%E2%84%A2-new-program-wi-fi-alliance%C2%AE-enable-seamless
-
-The Hotspot 2.0 specification is also available from WFA:
-https://www.wi-fi.org/knowledge-center/published-specifications
-
-The core Interworking functionality (network selection, GAS/ANQP) were
-standardized in IEEE Std 802.11u-2011 which is now part of the IEEE Std
-802.11-2012.
-
-
-wpa_supplicant network selection
---------------------------------
-
-Interworking support added option for configuring credentials that can
-work with multiple networks as an alternative to configuration of
-network blocks (e.g., per-SSID parameters). When requested to perform
-network selection, wpa_supplicant picks the highest priority enabled
-network block or credential. If a credential is picked (based on ANQP
-information from APs), a temporary network block is created
-automatically for the matching network. This temporary network block is
-used similarly to the network blocks that can be configured by the user,
-but it is not stored into the configuration file and is meant to be used
-only for temporary period of time since a new one can be created
-whenever needed based on ANQP information and the credential.
-
-By default, wpa_supplicant is not using automatic network selection
-unless requested explicitly with the interworking_select command. This
-can be changed with the auto_interworking=1 parameter to perform network
-selection automatically whenever trying to find a network for connection
-and none of the enabled network blocks match with the scan results. This
-case works similarly to "interworking_select auto", i.e., wpa_supplicant
-will internally determine which network or credential is going to be
-used based on configured priorities, scan results, and ANQP information.
-
-
-wpa_supplicant configuration
-----------------------------
-
-Interworking and Hotspot 2.0 functionality are optional components that
-need to be enabled in the wpa_supplicant build configuration
-(.config). This is done by adding following parameters into that file:
-
-CONFIG_INTERWORKING=y
-CONFIG_HS20=y
-
-It should be noted that this functionality requires a driver that
-supports GAS/ANQP operations. This uses the same design as P2P, i.e.,
-Action frame processing and building in user space within
-wpa_supplicant. The Linux nl80211 driver interface provides the needed
-functionality for this.
-
-
-There are number of run-time configuration parameters (e.g., in
-wpa_supplicant.conf when using the configuration file) that can be used
-to control Hotspot 2.0 operations.
-
-# Enable Interworking
-interworking=1
-
-# Enable Hotspot 2.0
-hs20=1
-
-# Parameters for controlling scanning
-
-# Homogeneous ESS identifier
-# If this is set, scans will be used to request response only from BSSes
-# belonging to the specified Homogeneous ESS. This is used only if interworking
-# is enabled.
-#hessid=00:11:22:33:44:55
-
-# Access Network Type
-# When Interworking is enabled, scans can be limited to APs that advertise the
-# specified Access Network Type (0..15; with 15 indicating wildcard match).
-# This value controls the Access Network Type value in Probe Request frames.
-#access_network_type=15
-
-# Automatic network selection behavior
-# 0 = do not automatically go through Interworking network selection
-# (i.e., require explicit interworking_select command for this; default)
-# 1 = perform Interworking network selection if one or more
-# credentials have been configured and scan did not find a
-# matching network block
-#auto_interworking=0
-
-
-Credentials can be pre-configured for automatic network selection:
-
-# credential block
-#
-# Each credential used for automatic network selection is configured as a set
-# of parameters that are compared to the information advertised by the APs when
-# interworking_select and interworking_connect commands are used.
-#
-# credential fields:
-#
-# temporary: Whether this credential is temporary and not to be saved
-#
-# priority: Priority group
-# By default, all networks and credentials get the same priority group
-# (0). This field can be used to give higher priority for credentials
-# (and similarly in struct wpa_ssid for network blocks) to change the
-# Interworking automatic networking selection behavior. The matching
-# network (based on either an enabled network block or a credential)
-# with the highest priority value will be selected.
-#
-# pcsc: Use PC/SC and SIM/USIM card
-#
-# realm: Home Realm for Interworking
-#
-# username: Username for Interworking network selection
-#
-# password: Password for Interworking network selection
-#
-# ca_cert: CA certificate for Interworking network selection
-#
-# client_cert: File path to client certificate file (PEM/DER)
-# This field is used with Interworking networking selection for a case
-# where client certificate/private key is used for authentication
-# (EAP-TLS). Full path to the file should be used since working
-# directory may change when wpa_supplicant is run in the background.
-#
-# Alternatively, a named configuration blob can be used by setting
-# this to blob://blob_name.
-#
-# private_key: File path to client private key file (PEM/DER/PFX)
-# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
-# commented out. Both the private key and certificate will be read
-# from the PKCS#12 file in this case. Full path to the file should be
-# used since working directory may change when wpa_supplicant is run
-# in the background.
-#
-# Windows certificate store can be used by leaving client_cert out and
-# configuring private_key in one of the following formats:
-#
-# cert://substring_to_match
-#
-# hash://certificate_thumbprint_in_hex
-#
-# For example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
-#
-# Note that when running wpa_supplicant as an application, the user
-# certificate store (My user account) is used, whereas computer store
-# (Computer account) is used when running wpasvc as a service.
-#
-# Alternatively, a named configuration blob can be used by setting
-# this to blob://blob_name.
-#
-# private_key_passwd: Password for private key file
-#
-# imsi: IMSI in <MCC> | <MNC> | '-' | <MSIN> format
-#
-# milenage: Milenage parameters for SIM/USIM simulator in <Ki>:<OPc>:<SQN>
-# format
-#
-# domain_suffix_match: Constraint for server domain name
-# If set, this FQDN is used as a suffix match requirement for the AAA
-# server certificate in SubjectAltName dNSName element(s). If a
-# matching dNSName is found, this constraint is met. If no dNSName
-# values are present, this constraint is matched against SubjectName CN
-# using same suffix match comparison. Suffix match here means that the
-# host/domain name is compared one label at a time starting from the
-# top-level domain and all the labels in @domain_suffix_match shall be
-# included in the certificate. The certificate may include additional
-# sub-level labels in addition to the required labels.
-#
-# For example, domain_suffix_match=example.com would match
-# test.example.com but would not match test-example.com.
-#
-# domain: Home service provider FQDN(s)
-# This is used to compare against the Domain Name List to figure out
-# whether the AP is operated by the Home SP. Multiple domain entries can
-# be used to configure alternative FQDNs that will be considered home
-# networks.
-#
-# roaming_consortium: Roaming Consortium OI
-# If roaming_consortium_len is non-zero, this field contains the
-# Roaming Consortium OI that can be used to determine which access
-# points support authentication with this credential. This is an
-# alternative to the use of the realm parameter. When using Roaming
-# Consortium to match the network, the EAP parameters need to be
-# pre-configured with the credential since the NAI Realm information
-# may not be available or fetched.
-#
-# required_roaming_consortium: Required Roaming Consortium OI
-# If required_roaming_consortium_len is non-zero, this field contains the
-# Roaming Consortium OI that is required to be advertised by the AP for
-# the credential to be considered matching.
-#
-# roaming_consortiums: Roaming Consortium OI(s) memberships
-# This string field contains one or more comma delimited OIs (hexdump)
-# identifying the roaming consortiums of which the provider is a member.
-# The list is sorted from the most preferred one to the least preferred
-# one. A match between the Roaming Consortium OIs advertised by an AP and
-# the OIs in this list indicates that successful authentication is
-# possible.
-# (Hotspot 2.0 PerProviderSubscription/<X+>/HomeSP/RoamingConsortiumOI)
-#
-# eap: Pre-configured EAP method
-# This optional field can be used to specify which EAP method will be
-# used with this credential. If not set, the EAP method is selected
-# automatically based on ANQP information (e.g., NAI Realm).
-#
-# phase1: Pre-configure Phase 1 (outer authentication) parameters
-# This optional field is used with like the 'eap' parameter.
-#
-# phase2: Pre-configure Phase 2 (inner authentication) parameters
-# This optional field is used with like the 'eap' parameter.
-#
-# excluded_ssid: Excluded SSID
-# This optional field can be used to excluded specific SSID(s) from
-# matching with the network. Multiple entries can be used to specify more
-# than one SSID.
-#
-# roaming_partner: Roaming partner information
-# This optional field can be used to configure preferences between roaming
-# partners. The field is a string in following format:
-# <FQDN>,<0/1 exact match>,<priority>,<* or country code>
-# (non-exact match means any subdomain matches the entry; priority is in
-# 0..255 range with 0 being the highest priority)
-#
-# update_identifier: PPS MO ID
-# (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
-#
-# provisioning_sp: FQDN of the SP that provisioned the credential
-# This optional field can be used to keep track of the SP that provisioned
-# the credential to find the PPS MO (./Wi-Fi/<provisioning_sp>).
-#
-# sp_priority: Credential priority within a provisioning SP
-# This is the priority of the credential among all credentials
-# provisioned by the same SP (i.e., for entries that have identical
-# provisioning_sp value). The range of this priority is 0-255 with 0
-# being the highest and 255 the lower priority.
-#
-# Minimum backhaul threshold (PPS/<X+>/Policy/MinBackhauldThreshold/*)
-# These fields can be used to specify minimum download/upload backhaul
-# bandwidth that is preferred for the credential. This constraint is
-# ignored if the AP does not advertise WAN Metrics information or if the
-# limit would prevent any connection. Values are in kilobits per second.
-# min_dl_bandwidth_home
-# min_ul_bandwidth_home
-# min_dl_bandwidth_roaming
-# min_ul_bandwidth_roaming
-#
-# max_bss_load: Maximum BSS Load Channel Utilization (1..255)
-# (PPS/<X+>/Policy/MaximumBSSLoadValue)
-# This value is used as the maximum channel utilization for network
-# selection purposes for home networks. If the AP does not advertise
-# BSS Load or if the limit would prevent any connection, this constraint
-# will be ignored.
-#
-# req_conn_capab: Required connection capability
-# (PPS/<X+>/Policy/RequiredProtoPortTuple)
-# This value is used to configure set of required protocol/port pairs that
-# a roaming network shall support (include explicitly in Connection
-# Capability ANQP element). This constraint is ignored if the AP does not
-# advertise Connection Capability or if this constraint would prevent any
-# network connection. This policy is not used in home networks.
-# Format: <protocol>[:<comma-separated list of ports]
-# Multiple entries can be used to list multiple requirements.
-# For example, number of common TCP protocols:
-# req_conn_capab=6:22,80,443
-# For example, IPSec/IKE:
-# req_conn_capab=17:500
-# req_conn_capab=50
-#
-# ocsp: Whether to use/require OCSP to check server certificate
-# 0 = do not use OCSP stapling (TLS certificate status extension)
-# 1 = try to use OCSP stapling, but not require response
-# 2 = require valid OCSP stapling response
-#
-# sim_num: Identifier for which SIM to use in multi-SIM devices
-#
-# engine: Whether to use an engine for private key operations (0/1)
-# engine_id: String identifying the engine to use
-# ca_cert_id: The CA certificate identifier when using an engine
-# cert_id: The certificate identifier when using an engine
-# key_id: The private key identifier when using an engine
-#
-# for example:
-#
-#cred={
-# realm="example.com"
-# username="user@example.com"
-# password="password"
-# ca_cert="/etc/wpa_supplicant/ca.pem"
-# domain="example.com"
-# domain_suffix_match="example.com"
-#}
-#
-#cred={
-# imsi="310026-000000000"
-# milenage="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82"
-#}
-#
-#cred={
-# realm="example.com"
-# username="user"
-# password="password"
-# ca_cert="/etc/wpa_supplicant/ca.pem"
-# domain="example.com"
-# roaming_consortium=223344
-# roaming_consortiums="112233,4455667788,aabbcc"
-# eap=TTLS
-# phase2="auth=MSCHAPV2"
-#}
-
-
-Control interface
------------------
-
-wpa_supplicant provides a control interface that can be used from
-external programs to manage various operations. The included command
-line tool, wpa_cli, can be used for manual testing with this interface.
-
-Following wpa_cli interactive mode commands show some examples of manual
-operations related to Hotspot 2.0:
-
-Remove configured networks and credentials:
-
-> remove_network all
-OK
-> remove_cred all
-OK
-
-
-Add a username/password credential:
-
-> add_cred
-0
-> set_cred 0 realm "mail.example.com"
-OK
-> set_cred 0 username "username"
-OK
-> set_cred 0 password "password"
-OK
-> set_cred 0 priority 1
-OK
-> set_cred 0 temporary 1
-OK
-
-Add a SIM credential using a simulated SIM/USIM card for testing:
-
-> add_cred
-1
-> set_cred 1 imsi "23456-0000000000"
-OK
-> set_cred 1 milenage "90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123"
-OK
-> set_cred 1 priority 1
-OK
-
-Note: the return value of add_cred is used as the first argument to
-the following set_cred commands.
-
-Add a SIM credential using a external SIM/USIM processing:
-
-> set external_sim 1
-OK
-> add_cred
-1
-> set_cred 1 imsi "23456-0000000000"
-OK
-> set_cred 1 eap SIM
-OK
-
-
-Add a WPA2-Enterprise network:
-
-> add_network
-0
-> set_network 0 key_mgmt WPA-EAP
-OK
-> set_network 0 ssid "enterprise"
-OK
-> set_network 0 eap TTLS
-OK
-> set_network 0 anonymous_identity "anonymous"
-OK
-> set_network 0 identity "user"
-OK
-> set_network 0 password "password"
-OK
-> set_network 0 priority 0
-OK
-> enable_network 0 no-connect
-OK
-
-
-Add an open network:
-
-> add_network
-3
-> set_network 3 key_mgmt NONE
-OK
-> set_network 3 ssid "coffee-shop"
-OK
-> select_network 3
-OK
-
-Note: the return value of add_network is used as the first argument to
-the following set_network commands.
-
-The preferred credentials/networks can be indicated with the priority
-parameter (1 is higher priority than 0).
-
-
-Interworking network selection can be started with interworking_select
-command. This instructs wpa_supplicant to run a network scan and iterate
-through the discovered APs to request ANQP information from the APs that
-advertise support for Interworking/Hotspot 2.0:
-
-> interworking_select
-OK
-<3>Starting ANQP fetch for 02:00:00:00:01:00
-<3>RX-ANQP 02:00:00:00:01:00 ANQP Capability list
-<3>RX-ANQP 02:00:00:00:01:00 Roaming Consortium list
-<3>RX-HS20-ANQP 02:00:00:00:01:00 HS Capability List
-<3>ANQP fetch completed
-<3>INTERWORKING-AP 02:00:00:00:01:00 type=unknown
-
-
-INTERWORKING-AP event messages indicate the APs that support network
-selection and for which there is a matching
-credential. interworking_connect command can be used to select a network
-to connect with:
-
-
-> interworking_connect 02:00:00:00:01:00
-OK
-<3>CTRL-EVENT-SCAN-RESULTS
-<3>SME: Trying to authenticate with 02:00:00:00:01:00 (SSID='Example Network' freq=2412 MHz)
-<3>Trying to associate with 02:00:00:00:01:00 (SSID='Example Network' freq=2412 MHz)
-<3>Associated with 02:00:00:00:01:00
-<3>CTRL-EVENT-EAP-STARTED EAP authentication started
-<3>CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=21
-<3>CTRL-EVENT-EAP-METHOD EAP vendor 0 method 21 (TTLS) selected
-<3>CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
-<3>WPA: Key negotiation completed with 02:00:00:00:01:00 [PTK=CCMP GTK=CCMP]
-<3>CTRL-EVENT-CONNECTED - Connection to 02:00:00:00:01:00 completed (auth) [id=0 id_str=]
-
-
-wpa_supplicant creates a temporary network block for the selected
-network based on the configured credential and ANQP information from the
-AP:
-
-> list_networks
-network id / ssid / bssid / flags
-0 Example Network any [CURRENT]
-> get_network 0 key_mgmt
-WPA-EAP
-> get_network 0 eap
-TTLS
-
-
-Alternatively to using an external program to select the network,
-"interworking_select auto" command can be used to request wpa_supplicant
-to select which network to use based on configured priorities:
-
-
-> remove_network all
-OK
-<3>CTRL-EVENT-DISCONNECTED bssid=02:00:00:00:01:00 reason=1 locally_generated=1
-> interworking_select auto
-OK
-<3>Starting ANQP fetch for 02:00:00:00:01:00
-<3>RX-ANQP 02:00:00:00:01:00 ANQP Capability list
-<3>RX-ANQP 02:00:00:00:01:00 Roaming Consortium list
-<3>RX-HS20-ANQP 02:00:00:00:01:00 HS Capability List
-<3>ANQP fetch completed
-<3>INTERWORKING-AP 02:00:00:00:01:00 type=unknown
-<3>CTRL-EVENT-SCAN-RESULTS
-<3>SME: Trying to authenticate with 02:00:00:00:01:00 (SSID='Example Network' freq=2412 MHz)
-<3>Trying to associate with 02:00:00:00:01:00 (SSID='Example Network' freq=2412 MHz)
-<3>Associated with 02:00:00:00:01:00
-<3>CTRL-EVENT-EAP-STARTED EAP authentication started
-<3>CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=21
-<3>CTRL-EVENT-EAP-METHOD EAP vendor 0 method 21 (TTLS) selected
-<3>CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
-<3>WPA: Key negotiation completed with 02:00:00:00:01:00 [PTK=CCMP GTK=CCMP]
-<3>CTRL-EVENT-CONNECTED - Connection to 02:00:00:00:01:00 completed (reauth) [id=0 id_str=]
-
-
-The connection status can be shown with the status command:
-
-> status
-bssid=02:00:00:00:01:00
-ssid=Example Network
-id=0
-mode=station
-pairwise_cipher=CCMP <--- link layer security indication
-group_cipher=CCMP
-key_mgmt=WPA2/IEEE 802.1X/EAP
-wpa_state=COMPLETED
-p2p_device_address=02:00:00:00:00:00
-address=02:00:00:00:00:00
-hs20=1 <--- HS 2.0 indication
-Supplicant PAE state=AUTHENTICATED
-suppPortStatus=Authorized
-EAP state=SUCCESS
-selectedMethod=21 (EAP-TTLS)
-EAP TLS cipher=AES-128-SHA
-EAP-TTLSv0 Phase2 method=PAP
-
-
-> status
-bssid=02:00:00:00:02:00
-ssid=coffee-shop
-id=3
-mode=station
-pairwise_cipher=NONE
-group_cipher=NONE
-key_mgmt=NONE
-wpa_state=COMPLETED
-p2p_device_address=02:00:00:00:00:00
-address=02:00:00:00:00:00
-
-
-Note: The Hotspot 2.0 indication is shown as "hs20=1" in the status
-command output. Link layer security is indicated with the
-pairwise_cipher (CCMP = secure, NONE = no encryption used).
-
-
-Also the scan results include the Hotspot 2.0 indication:
-
-> scan_results
-bssid / frequency / signal level / flags / ssid
-02:00:00:00:01:00 2412 -30 [WPA2-EAP-CCMP][ESS][HS20] Example Network
-
-
-ANQP information for the BSS can be fetched using the BSS command:
-
-> bss 02:00:00:00:01:00
-id=1
-bssid=02:00:00:00:01:00
-freq=2412
-beacon_int=100
-capabilities=0x0411
-qual=0
-noise=-92
-level=-30
-tsf=1345573286517276
-age=105
-ie=000f4578616d706c65204e6574776f726b010882848b960c1218240301012a010432043048606c30140100000fac040100000fac040100000fac0100007f04000000806b091e07010203040506076c027f006f1001531122331020304050010203040506dd05506f9a1000
-flags=[WPA2-EAP-CCMP][ESS][HS20]
-ssid=Example Network
-anqp_roaming_consortium=031122330510203040500601020304050603fedcba
-
-
-ANQP queries can also be requested with the anqp_get and hs20_anqp_get
-commands:
-
-> anqp_get 02:00:00:00:01:00 261
-OK
-<3>RX-ANQP 02:00:00:00:01:00 Roaming Consortium list
-> hs20_anqp_get 02:00:00:00:01:00 2
-OK
-<3>RX-HS20-ANQP 02:00:00:00:01:00 HS Capability List
-
-In addition, fetch_anqp command can be used to request similar set of
-ANQP queries to be done as is run as part of interworking_select:
-
-> scan
-OK
-<3>CTRL-EVENT-SCAN-RESULTS
-> fetch_anqp
-OK
-<3>Starting ANQP fetch for 02:00:00:00:01:00
-<3>RX-ANQP 02:00:00:00:01:00 ANQP Capability list
-<3>RX-ANQP 02:00:00:00:01:00 Roaming Consortium list
-<3>RX-HS20-ANQP 02:00:00:00:01:00 HS Capability List
-<3>ANQP fetch completed
-
-
-Hotspot 2.0 Rel 2 online signup and OSEN
-----------------------------------------
-
-Following parameters can be used to create a network profile for
-link-layer protected Hotspot 2.0 online signup connection with
-OSEN. Note that ssid and identify (NAI) values need to be set based on
-the information for the selected provider in the OSU Providers list
-ANQP-element.
-
-network={
- ssid="HS 2.0 OSU"
- proto=OSEN
- key_mgmt=OSEN
- pairwise=CCMP
- group=GTK_NOT_USED
- eap=WFA-UNAUTH-TLS
- identity="anonymous@example.com"
- ca_cert="osu-ca.pem"
- ocsp=2
-}
-
-
-Hotspot 2.0 connection with external network selection
-------------------------------------------------------
-
-When a component controlling wpa_supplicant takes care of Interworking
-network selection, following configuration and network profile
-parameters can be used to configure a temporary network profile for a
-Hotspot 2.0 connection (e.g., with SET, ADD_NETWORK, SET_NETWORK, and
-SELECT_NETWORK control interface commands):
-
-interworking=1
-hs20=1
-auto_interworking=0
-
-network={
- ssid="test-hs20"
- proto=RSN
- key_mgmt=WPA-EAP
- pairwise=CCMP
- anonymous_identity="anonymous@example.com"
- identity="hs20-test@example.com"
- password="password"
- ca_cert="ca.pem"
- eap=TTLS
- phase2="auth=MSCHAPV2"
- update_identifier=54321
- roaming_consortium_selection=112233
- #ocsp=2
-}
-
-
-These parameters are set based on the PPS MO credential and/or NAI Realm
-list ANQP-element:
-
-anonymous_identity: Credential/UsernamePassword/Username with username part
- replaced with "anonymous"
-identity: Credential/UsernamePassword/Username
-password: Credential/UsernamePassword/Password
-update_identifier: PPS/UpdateIdentifier
-ca_cert: from the downloaded trust root based on PPS information
-eap: Credential/UsernamePassword/EAPMethod or NAI Realm list
-phase2: Credential/UsernamePassword/EAPMethod or NAI Realm list
-roaming_consortium_selection: Matching OI from HomeSP/RoamingConsortiumOI
-ocsp: Credential/CheckAAAServerCertStatus
diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P
deleted file mode 100644
index 55a60a296ad7..000000000000
--- a/wpa_supplicant/README-P2P
+++ /dev/null
@@ -1,856 +0,0 @@
-wpa_supplicant and Wi-Fi P2P
-============================
-
-This document describes how the Wi-Fi P2P implementation in
-wpa_supplicant can be configured and how an external component on the
-client (e.g., management GUI) is used to enable WPS enrollment and
-registrar registration.
-
-
-Introduction to Wi-Fi P2P
--------------------------
-
-TODO
-
-More information about Wi-Fi P2P is available from Wi-Fi Alliance:
-http://www.wi-fi.org/Wi-Fi_Direct.php
-
-
-wpa_supplicant implementation
------------------------------
-
-TODO
-
-
-wpa_supplicant configuration
-----------------------------
-
-Wi-Fi P2P is an optional component that needs to be enabled in the
-wpa_supplicant build configuration (.config). Here is an example
-configuration that includes Wi-Fi P2P support and Linux nl80211
--based driver interface:
-
-CONFIG_DRIVER_NL80211=y
-CONFIG_CTRL_IFACE=y
-CONFIG_P2P=y
-CONFIG_AP=y
-CONFIG_WPS=y
-
-
-In run-time configuration file (wpa_supplicant.conf), some parameters
-for P2P may be set. In order to make the devices easier to recognize,
-device_name and device_type should be specified. For example,
-something like this should be included:
-
-ctrl_interface=/var/run/wpa_supplicant
-device_name=My P2P Device
-device_type=1-0050F204-1
-
-
-wpa_cli
--------
-
-Actual Wi-Fi P2P operations are requested during runtime. These can be
-done for example using wpa_cli (which is described below) or a GUI
-like wpa_gui-qt4.
-
-
-wpa_cli starts in interactive mode if no command string is included on
-the command line. By default, it will select the first network interface
-that it can find (and that wpa_supplicant controls). If more than one
-interface is in use, it may be necessary to select one of the explicitly
-by adding -i argument on the command line (e.g., 'wpa_cli -i wlan1').
-
-Most of the P2P operations are done on the main interface (e.g., the
-interface that is automatically added when the driver is loaded, e.g.,
-wlan0). When using a separate virtual interface for group operations
-(e.g., wlan1), the control interface for that group interface may need
-to be used for some operations (mainly WPS activation in GO). This may
-change in the future so that all the needed operations could be done
-over the main control interface.
-
-Device Discovery
-
-p2p_find [timeout in seconds] [type=<social|progressive>] \
- [dev_id=<addr>] [dev_type=<device type>] \
- [delay=<search delay in ms>] [seek=<service name>] [freq=<MHz>]
-
-The default behavior is to run a single full scan in the beginning and
-then scan only social channels. type=social will scan only social
-channels, i.e., it skips the initial full scan. type=progressive is
-like the default behavior, but it will scan through all the channels
-progressively one channel at the time in the Search state rounds. This
-will help in finding new groups or groups missed during the initial
-full scan. When the type parameter is not included (i.e., full scan), the
-optional freq parameter can be used to override the first scan to use only
-the specified channel after which only social channels are scanned.
-
-The optional dev_id option can be used to specify a single P2P peer to
-search for. The optional delay parameter can be used to request an extra
-delay to be used between search iterations (e.g., to free up radio
-resources for concurrent operations).
-
-The optional dev_type option can be used to specify a single device type
-(primary or secondary) to search for, e.g.,
-"p2p_find dev_type=1-0050F204-1".
-
-
-With one or more seek arguments, the command sends Probe Request frames
-for a P2PS service. For example,
-p2p_find 5 dev_id=11:22:33:44:55:66 seek=alt.example.chat seek=alt.example.video
-
-Parameters description:
- Timeout - Optional ASCII base-10-encoded u16. If missing, request will not
- time out and must be canceled manually
- dev_id - Optional to request responses from a single known remote device
- Service Name - Mandatory UTF-8 string for ASP seeks
- Service name must match the remote service being advertised exactly
- (no prefix matching).
- Service name may be empty, in which case all ASP services will be
- returned, and may be filtered with p2p_serv_disc_req settings, and
- p2p_serv_asp_resp results.
- Multiple service names may be requested, but if it exceeds internal
- limit, it will automatically revert to requesting all ASP services.
-
-p2p_listen [timeout in seconds]
-
-Start Listen-only state (become discoverable without searching for
-other devices). Optional parameter can be used to specify the duration
-for the Listen operation in seconds. This command may not be of that
-much use during normal operations and is mainly designed for
-testing. It can also be used to keep the device discoverable without
-having to maintain a group.
-
-p2p_stop_find
-
-Stop ongoing P2P device discovery or other operation (connect, listen
-mode).
-
-p2p_flush
-
-Flush P2P peer table and state.
-
-Group Formation
-
-p2p_prov_disc <peer device address> <display|keypad|pbc> [join|auto]
-
-Send P2P provision discovery request to the specified peer. The
-parameters for this command are the P2P device address of the peer and
-the desired configuration method. For example, "p2p_prov_disc
-02:01:02:03:04:05 display" would request the peer to display a PIN for
-us and "p2p_prov_disc 02:01:02:03:04:05 keypad" would request the peer
-to enter a PIN that we display.
-
-The optional "join" parameter can be used to indicate that this command
-is requesting an already running GO to prepare for a new client. This is
-mainly used with "display" to request it to display a PIN. The "auto"
-parameter can be used to request wpa_supplicant to automatically figure
-out whether the peer device is operating as a GO and if so, use
-join-a-group style PD instead of GO Negotiation style PD.
-
-p2p_connect <peer device address> <pbc|pin|PIN#|p2ps> [display|keypad|p2ps]
- [persistent|persistent=<network id>] [join|auth]
- [go_intent=<0..15>] [freq=<in MHz>] [ht40] [vht] [he] [provdisc] [auto]
- [ssid=<hexdump>]
-
-Start P2P group formation with a discovered P2P peer. This includes
-optional group owner negotiation, group interface setup, provisioning,
-and establishing data connection.
-
-The <pbc|pin|PIN#> parameter specifies the WPS provisioning
-method. "pbc" string starts pushbutton method, "pin" string start PIN
-method using an automatically generated PIN (which will be returned as
-the command return code), PIN# means that a pre-selected PIN can be
-used (e.g., 12345670). [display|keypad] is used with PIN method
-to specify which PIN is used (display=dynamically generated random PIN
-from local display, keypad=PIN entered from peer display). "persistent"
-parameter can be used to request a persistent group to be formed. The
-"persistent=<network id>" alternative can be used to pre-populate
-SSID/passphrase configuration based on a previously used persistent
-group where this device was the GO. The previously used parameters will
-then be used if the local end becomes the GO in GO Negotiation (which
-can be forced with go_intent=15).
-
-"join" indicates that this is a command to join an existing group as a
-client. It skips the GO Negotiation part. This will send a Provision
-Discovery Request message to the target GO before associating for WPS
-provisioning.
-
-"auth" indicates that the WPS parameters are authorized for the peer
-device without actually starting GO Negotiation (i.e., the peer is
-expected to initiate GO Negotiation). This is mainly for testing
-purposes.
-
-"go_intent" can be used to override the default GO Intent for this GO
-Negotiation.
-
-"freq" can be used to set a forced operating channel (e.g., freq=2412
-to select 2.4 GHz channel 1).
-
-"provdisc" can be used to request a Provision Discovery exchange to be
-used prior to starting GO Negotiation as a workaround with some deployed
-P2P implementations that require this to allow the user to accept the
-connection.
-
-"auto" can be used to request wpa_supplicant to automatically figure
-out whether the peer device is operating as a GO and if so, use
-join-a-group operation rather than GO Negotiation.
-
-"ssid=<hexdump>" can be used to specify the Group SSID for join
-operations. This allows the P2P Client interface to filter scan results
-based on SSID to avoid selecting an incorrect BSS entry in case the same
-P2P Device or Interface address have been used in multiple groups
-recently.
-
-P2PS attribute changes to p2p_connect command:
-
-P2PS supports two WPS provisioning methods namely PIN method and P2PS default.
-The remaining parameters hold same role as in legacy P2P. In case of P2PS
-default config method "p2ps" keyword is added in p2p_connect command.
-
-For example:
-p2p_connect 02:0a:f5:85:11:00 12345670 p2ps persistent join
- (WPS Method = P2PS default)
-
-p2p_connect 02:0a:f5:85:11:00 45629034 keypad persistent
- (WPS Method = PIN)
-
-p2p_asp_provision <peer MAC address> <adv_id=peer adv id>
- <adv_mac=peer MAC address> [role=2|4|1] <session=session id>
- <session_mac=initiator mac address>
- [info='service info'] <method=Default|keypad|Display>
-
-This command starts provision discovery with the P2PS enabled peer device.
-
-For example,
-p2p_asp_provision 00:11:22:33:44:55 adv_id=4d6fc7 adv_mac=00:55:44:33:22:11 role=1 session=12ab34 session_mac=00:11:22:33:44:55 info='name=john' method=1000
-
-Parameter description:
- MAC address - Mandatory
- adv_id - Mandatory remote Advertising ID of service connection is being
- established for
- adv_mac - Mandatory MAC address that owns/registered the service
- role - Optional
- 2 (group client only) or 4 (group owner only)
- if not present (or 1) role is negotiated by the two peers.
- session - Mandatory Session ID of the first session to be established
- session_mac - Mandatory MAC address that owns/initiated the session
- method - Optional method to request for provisioning (1000 - P2PS Default,
- 100 - Keypad(PIN), 8 - Display(PIN))
- info - Optional UTF-8 string. Hint for service to indicate possible usage
- parameters - Escape single quote & backslash:
- with a backslash 0x27 == ' == \', and 0x5c == \ == \\
-
-p2p_asp_provision_resp <peer mac address> <adv_id= local adv id>
- <adv_mac=local MAC address> <role=1|2|4> <status=0>
- <session=session id> <session_mac=peer MAC address>
-
-This command sends a provision discovery response from responder side.
-
-For example,
-p2p_asp_provision_resp 00:55:44:33:22:11 adv_id=4d6fc7 adv_mac=00:55:44:33:22:11 role=1 status=0 session=12ab34 session_mac=00:11:22:33:44:55
-
-Parameters definition:
- MAC address - Mandatory
- adv_id - Mandatory local Advertising ID of service connection is being
- established for
- adv_mac - Mandatory MAC address that owns/registered the service
- role - Optional 2 (group client only) or 4 (group owner only)
- if not present (or 1) role is negotiated by the two peers.
- status - Mandatory Acceptance/Rejection code of Provisioning
- session - Mandatory Session ID of the first session to be established
- session_mac - Mandatory MAC address that owns/initiated the session
-
-p2p_group_add [persistent|persistent=<network id>] [freq=<freq in MHz>]
- [ht40] [vht] [he]
-
-Set up a P2P group owner manually (i.e., without group owner
-negotiation with a specific peer). This is also known as autonomous
-GO. Optional persistent=<network id> can be used to specify restart of
-a persistent group. Optional freq=<freq in MHz> can be used to force
-the GO to be started on a specific frequency. Special freq=2 or freq=5
-options can be used to request the best 2.4 GHz or 5 GHz band channel
-to be selected automatically.
-
-p2p_reject <peer device address>
-
-Reject connection attempt from a peer (specified with a device
-address). This is a mechanism to reject a pending GO Negotiation with
-a peer and request to automatically block any further connection or
-discovery of the peer.
-
-p2p_group_remove <group interface>
-
-Terminate a P2P group. If a new virtual network interface was used for
-the group, it will also be removed. The network interface name of the
-group interface is used as a parameter for this command.
-
-p2p_cancel
-
-Cancel an ongoing P2P group formation and joining-a-group related
-operation. This operation unauthorizes the specific peer device (if any
-had been authorized to start group formation), stops P2P find (if in
-progress), stops pending operations for join-a-group, and removes the
-P2P group interface (if one was used) that is in the WPS provisioning
-step. If the WPS provisioning step has been completed, the group is not
-terminated.
-
-p2p_remove_client <peer's P2P Device Address|iface=<interface address>>
-
-This command can be used to remove the specified client from all groups
-(operating and persistent) from the local GO. Note that the peer device
-can rejoin the group if it is in possession of a valid key. See p2p_set
-per_sta_psk command below for more details on how the peer can be
-removed securely.
-
-Service Discovery
-
-p2p_service_add asp <auto accept> <adv id> <status 0/1> <Config Methods>
- <Service name> [Service Information] [Response Info]
-
-This command can be used to search for a P2PS service which includes
-Play, Send, Display, and Print service. The parameters for this command
-are "asp" to identify the command as P2PS one, auto accept value,
-advertisement id which uniquely identifies the service requests, state
-of the service whether the service is available or not, config methods
-which can be either P2PS method or PIN method, service name followed by
-two optional parameters service information, and response info.
-
-For example,
-p2p_service_add asp 1 4d6fc7 0 1108 alt.example.chat svc_info='name=john' rsp_info='enter PIN 1234'
-
-Parameters definition:
- asp - Mandatory for ASP service registration
- auto accept - Mandatory ASCII hex-encoded boolean (0 == no auto-accept,
- 1 == auto-accept ANY role, 2 == auto-accept CLIENT role,
- 4 == auto-accept GO role)
- Advertisement ID - Mandatory non-zero ASCII hex-encoded u32
- (Must be unique/not yet exist in svc db)
- State - Mandatory ASCII hex-encoded u8 (0 -- Svc not available,
- 1 -- Svc available, 2-0xff Application defined)
- Config Methods - Mandatory ASCII hex-encoded u16 (bitmask of WSC config
- methods)
- Service Name - Mandatory UTF-8 string
- Service Information - Optional UTF-8 string
- Escape single quote & backslash with a backslash:
- 0x27 == ' == \', and 0x5c == \ == \\
- Session response information - Optional (used only if auto accept is TRUE)
- UTF-8 string
- Escape single quote & backslash with a backslash:
- 0x27 == ' == \', and 0x5c == \ == \\
-
-p2p_service_rep asp <auto accept> <adv id> <status 0/1> <Config Methods>
- <Service name> [Service Information] [Response Info]
-
-This command can be used to replace the existing service request
-attributes from the initiator side. The replacement is only allowed if
-the advertisement id issued in the command matches with any one entry in
-the list of existing SD queries. If advertisement id doesn't match the
-command returns a failure.
-
-For example,
-p2p_service_rep asp 1 4d6fc7 1 1108 alt.example.chat svc_info='name=john' rsp_info='enter PIN 1234'
-
-Parameters definition:
- asp - Mandatory for ASP service registration
- auto accept - Mandatory ASCII hex-encoded boolean (1 == true, 0 == false)
- Advertisement ID - Mandatory non-zero ASCII hex-encoded u32
- (Must already exist in svc db)
- State - Mandatory ASCII hex-encoded u8 (can be used to indicate svc
- available or not available for instance)
- Config Methods - Mandatory ASCII hex-encoded u16 (bitmask of WSC config
- methods)
- Service Name - Mandatory UTF-8 string (Must match existing string in svc db)
- Service Information - Optional UTF-8 string
- Escape single quote & backslash with a backslash:
- 0x27 == ' == \', and 0x5c == \ == \\
- Session response information - Optional (used only if auto accept is TRUE)
- UTF-8 string
- Escape single quote & backslash with a backslash:
- 0x27 == ' == \', and 0x5c == \ == \\
-
-p2p_serv_disc_req
-
-Schedule a P2P service discovery request. The parameters for this
-command are the device address of the peer device (or 00:00:00:00:00:00
-for wildcard query that is sent to every discovered P2P peer that
-supports service discovery) and P2P Service Query TLV(s) as hexdump. For
-example,
-
-p2p_serv_disc_req 00:00:00:00:00:00 02000001
-
-schedules a request for listing all available services of all service
-discovery protocols and requests this to be sent to all discovered
-peers (note: this can result in long response frames). The pending
-requests are sent during device discovery (see p2p_find).
-
-There can be multiple pending peer device specific queries (each will be
-sent in sequence whenever the peer is found).
-
-This command returns an identifier for the pending query (e.g.,
-"1f77628") that can be used to cancel the request. Directed requests
-will be automatically removed when the specified peer has replied to
-it.
-
-Service Query TLV has following format:
-Length (2 octets, little endian) - length of following data
-Service Protocol Type (1 octet) - see the table below
-Service Transaction ID (1 octet) - nonzero identifier for the TLV
-Query Data (Length - 2 octets of data) - service protocol specific data
-
-Service Protocol Types:
-0 = All service protocols
-1 = Bonjour
-2 = UPnP
-3 = WS-Discovery
-4 = Wi-Fi Display
-
-For UPnP, an alternative command format can be used to specify a
-single query TLV (i.e., a service discovery for a specific UPnP
-service):
-
-p2p_serv_disc_req 00:00:00:00:00:00 upnp <version hex> <ST: from M-SEARCH>
-
-For example:
-
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 urn:schemas-upnp-org:device:InternetGatewayDevice:1
-
-Additional examples for queries:
-
-# list of all Bonjour services
-p2p_serv_disc_req 00:00:00:00:00:00 02000101
-
-# list of all UPnP services
-p2p_serv_disc_req 00:00:00:00:00:00 02000201
-
-# list of all WS-Discovery services
-p2p_serv_disc_req 00:00:00:00:00:00 02000301
-
-# list of all Bonjour and UPnP services
-p2p_serv_disc_req 00:00:00:00:00:00 0200010102000202
-
-# Apple File Sharing over TCP
-p2p_serv_disc_req 00:00:00:00:00:00 130001010b5f6166706f766572746370c00c000c01
-
-# Bonjour SSTH (supported service type hash)
-p2p_serv_disc_req 00:00:00:00:00:00 05000101000000
-
-# UPnP examples
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 ssdp:all
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 upnp:rootdevice
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 urn:schemas-upnp-org:service:ContentDirectory:2
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
-p2p_serv_disc_req 00:00:00:00:00:00 upnp 10 urn:schemas-upnp-org:device:InternetGatewayDevice:1
-
-# Wi-Fi Display examples
-# format: wifi-display <list of roles> <list of subelements>
-p2p_serv_disc_req 00:00:00:00:00:00 wifi-display [source] 2,3,4,5
-p2p_serv_disc_req 02:01:02:03:04:05 wifi-display [pri-sink] 3
-p2p_serv_disc_req 00:00:00:00:00:00 wifi-display [sec-source] 2
-p2p_serv_disc_req 00:00:00:00:00:00 wifi-display [source+sink] 2,3,4,5
-p2p_serv_disc_req 00:00:00:00:00:00 wifi-display [source][pri-sink] 2,3,4,5
-
-p2p_serv_disc_req <Unicast|Broadcast mac address> asp <Transaction ID>
- <Service Name> [Service Information]
-
-The command can be used for service discovery for P2PS enabled devices.
-
-For example: p2p_serv_disc_req 00:00:00:00:00:00 asp a1 alt.example 'john'
-
-Parameters definition:
- MAC address - Mandatory Existing
- asp - Mandatory for ASP queries
- Transaction ID - Mandatory non-zero ASCII hex-encoded u8 for GAS
- Service Name Prefix - Mandatory UTF-8 string.
- Will match from beginning of remote Service Name
- Service Information Substring - Optional UTF-8 string
- If Service Information Substring is not included, all services matching
- Service Name Prefix will be returned.
- If Service Information Substring is included, both the Substring and the
- Service Name Prefix must match for service to be returned.
- If remote service has no Service Information, all Substring searches
- will fail.
-
-p2p_serv_disc_cancel_req <query identifier>
-
-Cancel a pending P2P service discovery request. This command takes a
-single parameter: identifier for the pending query (the value returned
-by p2p_serv_disc_req, e.g., "p2p_serv_disc_cancel_req 1f77628".
-
-p2p_serv_disc_resp
-
-Reply to a service discovery query. This command takes following
-parameters: frequency in MHz, destination address, dialog token,
-response TLV(s). The first three parameters are copied from the
-request event. For example, "p2p_serv_disc_resp 2437 02:40:61:c2:f3:b7
-1 0300000101". This command is used only if external program is used
-to process the request (see p2p_serv_disc_external).
-
-p2p_service_update
-
-Indicate that local services have changed. This is used to increment
-the P2P service indicator value so that peers know when previously
-cached information may have changed. This is only needed when external
-service discovery processing is enabled since the commands to
-pre-configure services for internal processing will increment the
-indicator automatically.
-
-p2p_serv_disc_external <0|1>
-
-Configure external processing of P2P service requests: 0 (default) =
-no external processing of requests (i.e., internal code will process
-each request based on pre-configured services), 1 = external
-processing of requests (external program is responsible for replying
-to service discovery requests with p2p_serv_disc_resp). Please note
-that there is quite strict limit on how quickly the response needs to
-be transmitted, so use of the internal processing is strongly
-recommended.
-
-p2p_service_add bonjour <query hexdump> <RDATA hexdump>
-
-Add a local Bonjour service for internal SD query processing.
-
-Examples:
-
-# AFP Over TCP (PTR)
-p2p_service_add bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027
-# AFP Over TCP (TXT) (RDATA=null)
-p2p_service_add bonjour 076578616d706c650b5f6166706f766572746370c00c001001 00
-
-# IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
-p2p_service_add bonjour 045f697070c00c000c01 094d795072696e746572c027
-# IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
-p2p_service_add bonjour 096d797072696e746572045f697070c00c001001 09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
-
-# Supported Service Type Hash (SSTH)
-p2p_service_add bonjour 000000 <32-byte bitfield as hexdump>
-(note: see P2P spec Annex E.4 for information on how to construct the bitfield)
-
-p2p_service_del bonjour <query hexdump>
-
-Remove a local Bonjour service from internal SD query processing.
-
-p2p_service_add upnp <version hex> <service>
-
-Add a local UPnP service for internal SD query processing.
-
-Examples:
-
-p2p_service_add upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
-p2p_service_add upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::upnp:rootdevice
-p2p_service_add upnp 10 uuid:1122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2
-p2p_service_add upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2
-p2p_service_add upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1
-
-p2p_service_del upnp <version hex> <service>
-
-Remove a local UPnP service from internal SD query processing.
-
-p2p_service_del asp <adv id>
-
-Removes the local asp service from internal SD query list.
-For example: p2p_service_del asp 4d6fc7
-
-p2p_service_flush
-
-Remove all local services from internal SD query processing.
-
-Invitation
-
-p2p_invite [persistent=<network id>|group=<group ifname>] [peer=address]
- [go_dev_addr=address] [freq=<freq in MHz>] [ht40] [vht] [he]
- [pref=<MHz>]
-
-Invite a peer to join a group (e.g., group=wlan1) or to reinvoke a
-persistent group (e.g., persistent=4). If the peer device is the GO of
-the persistent group, the peer parameter is not needed. Otherwise it is
-used to specify which device to invite. go_dev_addr parameter can be
-used to override the GO device address for Invitation Request should
-it be not known for some reason (this should not be needed in most
-cases). When reinvoking a persistent group, the GO device can specify
-the frequency for the group with the freq parameter. When reinvoking a
-persistent group, the P2P client device can use freq parameter to force
-a specific operating channel (or invitation failure if GO rejects that)
-or pref parameter to request a specific channel (while allowing GO to
-select to use another channel, if needed).
-
-Group Operations
-
-(These are used on the group interface.)
-
-wps_pin <any|address> <PIN>
-
-Start WPS PIN method. This allows a single WPS Enrollee to connect to
-the AP/GO. This is used on the GO when a P2P client joins an existing
-group. The second parameter is the address of the Enrollee or a string
-"any" to allow any station to use the entered PIN (which will restrict
-the PIN for one-time-use). PIN is the Enrollee PIN read either from a
-label or display on the P2P Client/WPS Enrollee.
-
-wps_pbc
-
-Start WPS PBC method (i.e., push the button). This allows a single WPS
-Enrollee to connect to the AP/GO. This is used on the GO when a P2P
-client joins an existing group.
-
-p2p_get_passphrase
-
-Get the passphrase for a group (only available when acting as a GO).
-
-p2p_presence_req [<duration> <interval>] [<duration> <interval>]
-
-Send a P2P Presence Request to the GO (this is only available when
-acting as a P2P client). If no duration/interval pairs are given, the
-request indicates that this client has no special needs for GO
-presence. The first parameter pair gives the preferred duration and
-interval values in microseconds. If the second pair is included, that
-indicates which value would be acceptable. This command returns OK
-immediately and the response from the GO is indicated in a
-P2P-PRESENCE-RESPONSE event message.
-
-Parameters
-
-p2p_ext_listen [<period> <interval>]
-
-Configure Extended Listen Timing. If the parameters are omitted, this
-feature is disabled. If the parameters are included, Listen State will
-be entered every interval msec for at least period msec. Both values
-have acceptable range of 1-65535 (with interval obviously having to be
-larger than or equal to duration). If the P2P module is not idle at
-the time the Extended Listen Timing timeout occurs, the Listen State
-operation will be skipped.
-
-The configured values will also be advertised to other P2P Devices. The
-received values are available in the p2p_peer command output:
-
-ext_listen_period=100 ext_listen_interval=5000
-
-p2p_set <field> <value>
-
-Change dynamic P2P parameters
-
-p2p_set discoverability <0/1>
-
-Disable/enable advertisement of client discoverability. This is
-enabled by default and this parameter is mainly used to allow testing
-of device discoverability.
-
-p2p_set managed <0/1>
-
-Disable/enable managed P2P Device operations. This is disabled by
-default.
-
-p2p_set listen_channel <channel> [<op_class>]
-
-Set P2P Listen channel. This is mainly meant for testing purposes and
-changing the Listen channel during normal operations can result in
-protocol failures.
-
-When specifying a social channel on the 2.4 GHz band (1/6/11) there is
-no need to specify the operating class since it defaults to 81. When
-specifying a social channel on the 60 GHz band (2), specify the 60 GHz
-operating class (180).
-
-p2p_set ssid_postfix <postfix>
-
-Set postfix string to be added to the automatically generated P2P SSID
-(DIRECT-<two random characters>). For example, postfix of "-testing"
-could result in the SSID becoming DIRECT-ab-testing.
-
-p2p_set per_sta_psk <0/1>
-
-Disabled(default)/enables use of per-client PSK in the P2P groups. This
-can be used to request GO to assign a unique PSK for each client during
-WPS provisioning. When enabled, this allow clients to be removed from
-the group securely with p2p_remove_client command since that client's
-PSK is removed at the same time to prevent it from connecting back using
-the old PSK. When per-client PSK is not used, the client can still be
-disconnected, but it will be able to re-join the group since the PSK it
-learned previously is still valid. It should be noted that the default
-passphrase on the GO that is normally used to allow legacy stations to
-connect through manual configuration does not change here, so if that is
-shared, devices with knowledge of that passphrase can still connect.
-
-set <field> <value>
-
-Set global configuration parameters which may also affect P2P
-operations. The format on these parameters is same as is used in
-wpa_supplicant.conf. Only the parameters listen here should be
-changed. Modifying other parameters may result in incorrect behavior
-since not all existing users of the parameters are updated.
-
-set uuid <UUID>
-
-Set WPS UUID (by default, this is generated based on the MAC address).
-
-set device_name <device name>
-
-Set WPS Device Name (also included in some P2P messages).
-
-set manufacturer <manufacturer>
-
-Set WPS Manufacturer.
-
-set model_name <model name>
-
-Set WPS Model Name.
-
-set model_number <model number>
-
-Set WPS Model Number.
-
-set serial_number <serial number>
-
-Set WPS Serial Number.
-
-set device_type <device type>
-
-Set WPS Device Type.
-
-set os_version <OS version>
-
-Set WPS OS Version.
-
-set config_methods <config methods>
-
-Set WPS Configuration Methods.
-
-set sec_device_type <device type>
-
-Add a new Secondary Device Type.
-
-set p2p_go_intent <GO intent>
-
-Set the default P2P GO Intent. Note: This value can be overridden in
-p2p_connect command and as such, there should be no need to change the
-default value here during normal operations.
-
-set p2p_ssid_postfix <P2P SSID postfix>
-
-Set P2P SSID postfix.
-
-set persistent_reconnect <0/1>
-
-Disable/enabled persistent reconnect for reinvocation of persistent
-groups. If enabled, invitations to reinvoke a persistent group will be
-accepted without separate authorization (e.g., user interaction).
-
-set country <two character country code>
-
-Set country code (this is included in some P2P messages).
-
-set p2p_search_delay <delay>
-
-Set p2p_search_delay which adds extra delay in milliseconds between
-concurrent search iterations to make p2p_find friendlier to concurrent
-operations by avoiding it from taking 100% of radio resources. The
-default value is 500 ms.
-
-Status
-
-p2p_peers [discovered]
-
-List P2P Device Addresses of all the P2P peers we know. The optional
-"discovered" parameter filters out the peers that we have not fully
-discovered, i.e., which we have only seen in a received Probe Request
-frame.
-
-p2p_peer <P2P Device Address>
-
-Fetch information about a known P2P peer.
-
-Group Status
-
-(These are used on the group interface.)
-
-status
-
-Show status information (connection state, role, use encryption
-parameters, IP address, etc.).
-
-sta
-
-Show information about an associated station (when acting in AP/GO role).
-
-all_sta
-
-Lists the currently associated stations.
-
-Configuration data
-
-list_networks
-
-Lists the configured networks, including stored information for
-persistent groups. The identifier in this list is used with
-p2p_group_add and p2p_invite to indicate which persistent group is to
-be reinvoked.
-
-remove_network <network id>
-
-Remove a network entry from configuration.
-
-
-P2PS Events/Responses:
-
-P2PS-PROV-START: This events gets triggered when provisioning is issued for
-either seeker or advertiser.
-
-For example,
-P2PS-PROV-START 00:55:44:33:22:11 adv_id=111 adv_mac=00:55:44:33:22:11 conncap=1 session=1234567 session_mac=00:11:22:33:44:55 info='xxxx'
-
-Parameters definition:
- MAC address - always
- adv_id - always ASCII hex-encoded u32
- adv_mac - always MAC address that owns/registered the service
- conncap - always mask of 0x01 (new), 0x02 (group client), 0x04 (group owner)
- bits
- session - always Session ID of the first session to be established
- session_mac - always MAC address that owns/initiated the session
- info - if available, UTF-8 string
- Escaped single quote & backslash with a backslash:
- \' == 0x27 == ', and \\ == 0x5c == \
-
-P2PS-PROV-DONE: When provisioning is completed then this event gets triggered.
-
-For example,
-P2PS-PROV-DONE 00:11:22:33:44:55 status=0 adv_id=111 adv_mac=00:55:44:33:22:11 conncap=1 session=1234567 session_mac=00:11:22:33:44:55 [dev_passwd_id=8 | go=p2p-wlan0-0 | join=11:22:33:44:55:66 | persist=0]
-
-Parameters definition:
- MAC address - always main device address of peer. May be different from MAC
- ultimately connected to.
- status - always ascii hex-encoded u8 (0 == success, 12 == deferred success)
- adv_id - always ascii hex-encoded u32
- adv_mac - always MAC address that owns/registered the service
- conncap - always One of: 1 (new), 2 (group client), 4 (group owner) bits
- session - always Session ID of the first session to be established
- session_mac - always MAC address that owns/initiated the session
- dev_passwd_id - only if conncap value == 1 (New GO negotiation)
- 8 - "p2ps" password must be passed in p2p_connect command
- 1 - "display" password must be passed in p2p_connect command
- 5 - "keypad" password must be passed in p2p_connect command
- join only - if conncap value == 2 (Client Only). Display password and "join"
- must be passed in p2p_connect and address must be the MAC specified
- go only - if conncap value == 4 (GO Only). Interface name must be set with a
- password
- persist - only if previous persistent group existed between peers and shall
- be re-used. Group is restarted by sending "p2p_group_add persistent=0"
- where value is taken from P2P-PROV-DONE
-
-Extended Events/Response
-
-P2P-DEVICE-FOUND 00:11:22:33:44:55 p2p_dev_addr=00:11:22:33:44:55 pri_dev_type=0-00000000-0 name='' config_methods=0x108 dev_capab=0x21 group_capab=0x0 adv_id=111 asp_svc=alt.example.chat
-
-Parameters definition:
- adv_id - if ASP ASCII hex-encoded u32. If it is reporting the
- "wildcard service", this value will be 0
- asp_svc - if ASP this is the service string. If it is reporting the
- "wildcard service", this value will be org.wi-fi.wfds
-
-
-wpa_cli action script
----------------------
-
-See examples/p2p-action.sh
-
-TODO: describe DHCP/DNS setup
-TODO: cross-connection
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
deleted file mode 100644
index b884f67a2435..000000000000
--- a/wpa_supplicant/README-WPS
+++ /dev/null
@@ -1,399 +0,0 @@
-wpa_supplicant and Wi-Fi Protected Setup (WPS)
-==============================================
-
-This document describes how the WPS implementation in wpa_supplicant
-can be configured and how an external component on the client (e.g.,
-management GUI) is used to enable WPS enrollment and registrar
-registration.
-
-
-Introduction to WPS
--------------------
-
-Wi-Fi Protected Setup (WPS) is a mechanism for easy configuration of a
-wireless network. It allows automated generation of random keys (WPA
-passphrase/PSK) and configuration of an access point and client
-devices. WPS includes number of methods for setting up connections
-with PIN method and push-button configuration (PBC) being the most
-commonly deployed options.
-
-While WPS can enable more home networks to use encryption in the
-wireless network, it should be noted that the use of the PIN and
-especially PBC mechanisms for authenticating the initial key setup is
-not very secure. As such, use of WPS may not be suitable for
-environments that require secure network access without chance for
-allowing outsiders to gain access during the setup phase.
-
-WPS uses following terms to describe the entities participating in the
-network setup:
-- access point: the WLAN access point
-- Registrar: a device that control a network and can authorize
- addition of new devices); this may be either in the AP ("internal
- Registrar") or in an external device, e.g., a laptop, ("external
- Registrar")
-- Enrollee: a device that is being authorized to use the network
-
-It should also be noted that the AP and a client device may change
-roles (i.e., AP acts as an Enrollee and client device as a Registrar)
-when WPS is used to configure the access point.
-
-
-More information about WPS is available from Wi-Fi Alliance:
-http://www.wi-fi.org/wifi-protected-setup
-
-
-wpa_supplicant implementation
------------------------------
-
-wpa_supplicant includes an optional WPS component that can be used as
-an Enrollee to enroll new network credential or as a Registrar to
-configure an AP.
-
-
-wpa_supplicant configuration
-----------------------------
-
-WPS is an optional component that needs to be enabled in
-wpa_supplicant build configuration (.config). Here is an example
-configuration that includes WPS support and Linux nl80211 -based
-driver interface:
-
-CONFIG_DRIVER_NL80211=y
-CONFIG_WPS=y
-
-If you want to enable WPS external registrar (ER) functionality, you
-will also need to add following line:
-
-CONFIG_WPS_ER=y
-
-Following parameter can be used to enable support for NFC config method:
-
-CONFIG_WPS_NFC=y
-
-
-WPS needs the Universally Unique IDentifier (UUID; see RFC 4122) for
-the device. This is configured in the runtime configuration for
-wpa_supplicant (if not set, UUID will be generated based on local MAC
-address):
-
-# example UUID for WPS
-uuid=12345678-9abc-def0-1234-56789abcdef0
-
-The network configuration blocks needed for WPS are added
-automatically based on control interface commands, so they do not need
-to be added explicitly in the configuration file.
-
-WPS registration will generate new network blocks for the acquired
-credentials. If these are to be stored for future use (after
-restarting wpa_supplicant), wpa_supplicant will need to be configured
-to allow configuration file updates:
-
-update_config=1
-
-
-
-External operations
--------------------
-
-WPS requires either a device PIN code (usually, 8-digit number) or a
-pushbutton event (for PBC) to allow a new WPS Enrollee to join the
-network. wpa_supplicant uses the control interface as an input channel
-for these events.
-
-The PIN value used in the commands must be processed by an UI to
-remove non-digit characters and potentially, to verify the checksum
-digit. "wpa_cli wps_check_pin <PIN>" can be used to do such processing.
-It returns FAIL if the PIN is invalid, or FAIL-CHECKSUM if the checksum
-digit is incorrect, or the processed PIN (non-digit characters removed)
-if the PIN is valid.
-
-If the client device has a display, a random PIN has to be generated
-for each WPS registration session. wpa_supplicant can do this with a
-control interface request, e.g., by calling wpa_cli:
-
-wpa_cli wps_pin any
-
-This will return the generated 8-digit PIN which will then need to be
-entered at the Registrar to complete WPS registration. At that point,
-the client will be enrolled with credentials needed to connect to the
-AP to access the network.
-
-
-If the client device does not have a display that could show the
-random PIN, a hardcoded PIN that is printed on a label can be
-used. wpa_supplicant is notified this with a control interface
-request, e.g., by calling wpa_cli:
-
-wpa_cli wps_pin any 12345670
-
-This starts the WPS negotiation in the same way as above with the
-generated PIN.
-
-When the wps_pin command is issued for an AP (including P2P GO) mode
-interface, an optional timeout parameter can be used to specify
-expiration timeout for the PIN in seconds. For example:
-
-wpa_cli wps_pin any 12345670 300
-
-
-If a random PIN is needed for a user interface, "wpa_cli wps_pin get"
-can be used to generate a new PIN without starting WPS negotiation.
-This random PIN can then be passed as an argument to another wps_pin
-call when the actual operation should be started.
-
-If the client design wants to support optional WPS PBC mode, this can
-be enabled by either a physical button in the client device or a
-virtual button in the user interface. The PBC operation requires that
-a button is also pressed at the AP/Registrar at about the same time (2
-minute window). wpa_supplicant is notified of the local button event
-over the control interface, e.g., by calling wpa_cli:
-
-wpa_cli wps_pbc
-
-At this point, the AP/Registrar has two minutes to complete WPS
-negotiation which will generate a new WPA PSK in the same way as the
-PIN method described above.
-
-
-If the client wants to operate in the Registrar role to learn the
-current AP configuration and optionally, to configure an AP,
-wpa_supplicant is notified over the control interface, e.g., with
-wpa_cli:
-
-wpa_cli wps_reg <AP BSSID> <AP PIN>
-(example: wpa_cli wps_reg 02:34:56:78:9a:bc 12345670)
-
-This is used to fetch the current AP settings instead of actually
-changing them. The main difference with the wps_pin command is that
-wps_reg uses the AP PIN (e.g., from a label on the AP) instead of a
-PIN generated at the client.
-
-In order to change the AP configuration, the new configuration
-parameters are given to the wps_reg command:
-
-wpa_cli wps_reg <AP BSSID> <AP PIN> <new SSID> <auth> <encr> <new key>
-examples:
- wpa_cli wps_reg 02:34:56:78:9a:bc 12345670 testing WPA2PSK CCMP 12345678
- wpa_cli wps_reg 02:34:56:78:9a:bc 12345670 clear OPEN NONE ""
-
-<auth> must be one of the following: OPEN WPAPSK WPA2PSK
-<encr> must be one of the following: NONE WEP TKIP CCMP
-
-
-Scanning
---------
-
-Scan results ('wpa_cli scan_results' or 'wpa_cli bss <idx>') include a
-flags field that is used to indicate whether the BSS support WPS. If
-the AP support WPS, but has not recently activated a Registrar, [WPS]
-flag will be included. If PIN method has been recently selected,
-[WPS-PIN] is shown instead. Similarly, [WPS-PBC] is shown if PBC mode
-is in progress. GUI programs can use these as triggers for suggesting
-a guided WPS configuration to the user. In addition, control interface
-monitor events WPS-AP-AVAILABLE{,-PBC,-PIN} can be used to find out if
-there are WPS enabled APs in scan results without having to go through
-all the details in the GUI. These notification could be used, e.g., to
-suggest possible WPS connection to the user.
-
-
-wpa_gui
--------
-
-wpa_gui-qt4 directory contains a sample GUI that shows an example of
-how WPS support can be integrated into the GUI. Its main window has a
-WPS tab that guides user through WPS registration with automatic AP
-selection. In addition, it shows how WPS can be started manually by
-selecting an AP from scan results.
-
-
-Credential processing
----------------------
-
-By default, wpa_supplicant processes received credentials and updates
-its configuration internally. However, it is possible to
-control these operations from external programs, if desired.
-
-This internal processing can be disabled with wps_cred_processing=1
-option. When this is used, an external program is responsible for
-processing the credential attributes and updating wpa_supplicant
-configuration based on them.
-
-Following control interface messages are sent out for external programs:
-
-WPS-CRED-RECEIVED <hexdump of Credential attribute(s)>
-For example:
-<2>WPS-CRED-RECEIVED 100e006f10260001011045000c6a6b6d2d7770732d74657374100300020020100f000200081027004030653462303435366332363666653064333961643135353461316634626637313234333761636664623766333939653534663166316230323061643434386235102000060266a0ee1727
-
-
-wpa_supplicant as WPS External Registrar (ER)
----------------------------------------------
-
-wpa_supplicant can be used as a WPS ER to configure an AP or enroll
-new Enrollee to join the network. This functionality uses UPnP and
-requires that a working IP connectivity is available with the AP (this
-can be either over a wired or wireless connection).
-
-Separate wpa_supplicant process can be started for WPS ER
-operations. A special "none" driver can be used in such a case to
-indicate that no local network interface is actually controlled. For
-example, following command could be used to start the ER:
-
-wpa_supplicant -Dnone -c er.conf -ieth0
-
-Sample er.conf:
-
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=admin
-device_name=WPS External Registrar
-
-
-wpa_cli commands for ER functionality:
-
-wps_er_start [IP address]
-- start WPS ER functionality
-- the optional IP address parameter can be used to filter operations only
- to include a single AP
-- if run again while ER is active, the stored information (discovered APs
- and Enrollees) are shown again
-
-wps_er_stop
-- stop WPS ER functionality
-
-wps_er_learn <UUID|BSSID> <AP PIN>
-- learn AP configuration
-
-wps_er_set_config <UUID|BSSID> <network id>
-- use AP configuration from a locally configured network (e.g., from
- wps_reg command); this does not change the AP's configuration, but
- only prepares a configuration to be used when enrolling a new device
- to the AP
-
-wps_er_config <UUID|BSSID> <AP PIN> <new SSID> <auth> <encr> <new key>
-- examples:
- wps_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 testing WPA2PSK CCMP 12345678
- wpa_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 clear OPEN NONE ""
-
-<auth> must be one of the following: OPEN WPAPSK WPA2PSK
-<encr> must be one of the following: NONE WEP TKIP CCMP
-
-
-wps_er_pbc <Enrollee UUID|MAC address>
-- accept an Enrollee PBC using External Registrar
-
-wps_er_pin <Enrollee UUID|"any"|MAC address> <PIN> [Enrollee MAC address]
-- add an Enrollee PIN to External Registrar
-- if Enrollee UUID is not known, "any" can be used to add a wildcard PIN
-- if the MAC address of the enrollee is known, it should be configured
- to allow the AP to advertise list of authorized enrollees
-
-
-WPS ER events:
-
-WPS_EVENT_ER_AP_ADD
-- WPS ER discovered an AP
-
-WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1 |Very friendly name|Company|Long description of the model|WAP|http://w1.fi/|http://w1.fi/hostapd/
-
-WPS_EVENT_ER_AP_REMOVE
-- WPS ER removed an AP entry
-
-WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002
-
-WPS_EVENT_ER_ENROLLEE_ADD
-- WPS ER discovered a new Enrollee
-
-WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0 pri_dev_type=1-0050F204-1 |Wireless Client|Company|cmodel|123|12345|
-
-WPS_EVENT_ER_ENROLLEE_REMOVE
-- WPS ER removed an Enrollee entry
-
-WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333 02:66:a0:ee:17:27
-
-WPS-ER-AP-SETTINGS
-- WPS ER learned AP settings
-
-WPS-ER-AP-SETTINGS uuid=fd91b4ec-e3fa-5891-a57d-8c59efeed1d2 ssid=test-wps auth_type=0x0020 encr_type=0x0008 key=12345678
-
-
-WPS with NFC
-------------
-
-WPS can be used with NFC-based configuration method. An NFC tag
-containing a password token from the Enrollee can be used to
-authenticate the connection instead of the PIN. In addition, an NFC tag
-with a configuration token can be used to transfer AP settings without
-going through the WPS protocol.
-
-When the station acts as an Enrollee, a local NFC tag with a password
-token can be used by touching the NFC interface of a Registrar.
-
-"wps_nfc [BSSID]" command starts WPS protocol run with the local end as
-the Enrollee using the NFC password token that is either pre-configured
-in the configuration file (wps_nfc_dev_pw_id, wps_nfc_dh_pubkey,
-wps_nfc_dh_privkey, wps_nfc_dev_pw) or generated dynamically with
-"wps_nfc_token <WPS|NDEF>" command. The included nfc_pw_token tool
-(build with "make nfc_pw_token") can be used to generate NFC password
-tokens during manufacturing (each station needs to have its own random
-keys).
-
-The "wps_nfc_config_token <WPS/NDEF>" command can be used to build an
-NFC configuration token when wpa_supplicant is controlling an AP
-interface (AP or P2P GO). The output value from this command is a
-hexdump of the current AP configuration (WPS parameter requests this to
-include only the WPS attributes; NDEF parameter requests additional NDEF
-encapsulation to be included). This data needs to be written to an NFC
-tag with an external program. Once written, the NFC configuration token
-can be used to touch an NFC interface on a station to provision the
-credentials needed to access the network.
-
-The "wps_nfc_config_token <WPS/NDEF> <network id>" command can be used
-to build an NFC configuration token based on a locally configured
-network.
-
-If the station includes NFC interface and reads an NFC tag with a MIME
-media type "application/vnd.wfa.wsc", the NDEF message payload (with or
-without NDEF encapsulation) can be delivered to wpa_supplicant using the
-following wpa_cli command:
-
-wps_nfc_tag_read <hexdump of payload>
-
-If the NFC tag contains a configuration token, the network is added to
-wpa_supplicant configuration. If the NFC tag contains a password token,
-the token is added to the WPS Registrar component. This information can
-then be used with wps_reg command (when the NFC password token was from
-an AP) using a special value "nfc-pw" in place of the PIN parameter. If
-the ER functionality has been started (wps_er_start), the NFC password
-token is used to enable enrollment of a new station (that was the source
-of the NFC password token).
-
-"nfc_get_handover_req <NDEF> <WPS-CR>" command can be used to build the
-WPS carrier record for a Handover Request Message for connection
-handover. The first argument selects the format of the output data and
-the second argument selects which type of connection handover is
-requested (WPS-CR = Wi-Fi handover as specified in WSC 2.0).
-
-"nfc_get_handover_sel <NDEF> <WPS> [UUID|BSSID]" command can be used to
-build the contents of a Handover Select Message for connection handover
-when this does not depend on the contents of the Handover Request
-Message. The first argument selects the format of the output data and
-the second argument selects which type of connection handover is
-requested (WPS = Wi-Fi handover as specified in WSC 2.0). If the options
-UUID|BSSID argument is included, this is a request to build the handover
-message for the specified AP when wpa_supplicant is operating as a WPS
-ER.
-
-"nfc_report_handover <INIT/RESP> WPS <carrier from handover request>
-<carrier from handover select>" can be used as an alternative way for
-reporting completed NFC connection handover. The first parameter
-indicates whether the local device initiated or responded to the
-connection handover and the carrier records are the selected carrier
-from the handover request and select messages as a hexdump.
-
-The "wps_er_nfc_config_token <WPS/NDEF> <UUID|BSSID>" command can be
-used to build an NFC configuration token for the specified AP when
-wpa_supplicant is operating as a WPS ER. The output value from this
-command is a hexdump of the selected AP configuration (WPS parameter
-requests this to include only the WPS attributes; NDEF parameter
-requests additional NDEF encapsulation to be included). This data needs
-to be written to an NFC tag with an external program. Once written, the
-NFC configuration token can be used to touch an NFC interface on a
-station to provision the credentials needed to access the network.
diff --git a/wpa_supplicant/README-Windows.txt b/wpa_supplicant/README-Windows.txt
deleted file mode 100644
index 7288abd9a161..000000000000
--- a/wpa_supplicant/README-Windows.txt
+++ /dev/null
@@ -1,299 +0,0 @@
-wpa_supplicant for Windows
-==========================
-
-Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors
-All Rights Reserved.
-
-This program is licensed under the BSD license (the one with
-advertisement clause removed).
-
-
-wpa_supplicant has support for being used as a WPA/WPA2/IEEE 802.1X
-Supplicant on Windows. The current port requires that WinPcap
-(http://winpcap.polito.it/) is installed for accessing packets and the
-driver interface. Both release versions 3.0 and 3.1 are supported.
-
-The current port is still somewhat experimental. It has been tested
-mainly on Windows XP (SP2) with limited set of NDIS drivers. In
-addition, the current version has been reported to work with Windows
-2000.
-
-All security modes have been verified to work (at least complete
-authentication and successfully ping a wired host):
-- plaintext
-- static WEP / open system authentication
-- static WEP / shared key authentication
-- IEEE 802.1X with dynamic WEP keys
-- WPA-PSK, TKIP, CCMP, TKIP+CCMP
-- WPA-EAP, TKIP, CCMP, TKIP+CCMP
-- WPA2-PSK, TKIP, CCMP, TKIP+CCMP
-- WPA2-EAP, TKIP, CCMP, TKIP+CCMP
-
-
-Building wpa_supplicant with mingw
-----------------------------------
-
-The default build setup for wpa_supplicant is to use MinGW and
-cross-compiling from Linux to MinGW/Windows. It should also be
-possible to build this under Windows using the MinGW tools, but that
-is not tested nor supported and is likely to require some changes to
-the Makefile unless cygwin is used.
-
-
-Building wpa_supplicant with MSVC
----------------------------------
-
-wpa_supplicant can be built with Microsoft Visual C++ compiler. This
-has been tested with Microsoft Visual C++ Toolkit 2003 and Visual
-Studio 2005 using the included nmake.mak as a Makefile for nmake. IDE
-can also be used by creating a project that includes the files and
-defines mentioned in nmake.mak. Example VS2005 solution and project
-files are included in vs2005 subdirectory. This can be used as a
-starting point for building the programs with VS2005 IDE. Visual Studio
-2008 Express Edition is also able to use these project files.
-
-WinPcap development package is needed for the build and this can be
-downloaded from http://www.winpcap.org/install/bin/WpdPack_4_0_2.zip. The
-default nmake.mak expects this to be unpacked into C:\dev\WpdPack so
-that Include and Lib directories are in this directory. The files can be
-stored elsewhere as long as the WINPCAPDIR in nmake.mak is updated to
-match with the selected directory. In case a project file in the IDE is
-used, these Include and Lib directories need to be added to project
-properties as additional include/library directories.
-
-OpenSSL source package can be downloaded from
-http://www.openssl.org/source/openssl-0.9.8i.tar.gz and built and
-installed following instructions in INSTALL.W32. Note that if EAP-FAST
-support will be included in the wpa_supplicant, OpenSSL needs to be
-patched to# support it openssl-0.9.8i-tls-extensions.patch. The example
-nmake.mak file expects OpenSSL to be installed into C:\dev\openssl, but
-this directory can be modified by changing OPENSSLDIR variable in
-nmake.mak.
-
-If you do not need EAP-FAST support, you may also be able to use Win32
-binary installation package of OpenSSL from
-http://www.slproweb.com/products/Win32OpenSSL.html instead of building
-the library yourself. In this case, you will need to copy Include and
-Lib directories in suitable directory, e.g., C:\dev\openssl for the
-default nmake.mak. Copy {Win32OpenSSLRoot}\include into
-C:\dev\openssl\include and make C:\dev\openssl\lib subdirectory with
-files from {Win32OpenSSLRoot}\VC (i.e., libeay*.lib and ssleay*.lib).
-This will end up using dynamically linked OpenSSL (i.e., .dll files are
-needed) for it. Alternative, you can copy files from
-{Win32OpenSSLRoot}\VC\static to create a static build (no OpenSSL .dll
-files needed).
-
-
-Building wpa_supplicant for cygwin
-----------------------------------
-
-wpa_supplicant can be built for cygwin by installing the needed
-development packages for cygwin. This includes things like compiler,
-make, openssl development package, etc. In addition, developer's pack
-for WinPcap (WPdpack.zip) from
-http://winpcap.polito.it/install/default.htm is needed.
-
-.config file should enable only one driver interface,
-CONFIG_DRIVER_NDIS. In addition, include directories may need to be
-added to match the system. An example configuration is available in
-defconfig. The library and include files for WinPcap will either need
-to be installed in compiler/linker default directories or their
-location will need to be adding to .config when building
-wpa_supplicant.
-
-Othen than this, the build should be more or less identical to Linux
-version, i.e., just run make after having created .config file. An
-additional tool, win_if_list.exe, can be built by running "make
-win_if_list".
-
-
-Building wpa_gui
-----------------
-
-wpa_gui uses Qt application framework from Trolltech. It can be built
-with the open source version of Qt4 and MinGW. Following commands can
-be used to build the binary in the Qt 4 Command Prompt:
-
-# go to the root directory of wpa_supplicant source code
-cd wpa_gui-qt4
-qmake -o Makefile wpa_gui.pro
-make
-# the wpa_gui.exe binary is created into 'release' subdirectory
-
-
-Using wpa_supplicant for Windows
---------------------------------
-
-wpa_supplicant, wpa_cli, and wpa_gui behave more or less identically to
-Linux version, so instructions in README and example wpa_supplicant.conf
-should be applicable for most parts. In addition, there is another
-version of wpa_supplicant, wpasvc.exe, which can be used as a Windows
-service and which reads its configuration from registry instead of
-text file.
-
-When using access points in "hidden SSID" mode, ap_scan=2 mode need to
-be used (see wpa_supplicant.conf for more information).
-
-Windows NDIS/WinPcap uses quite long interface names, so some care
-will be needed when starting wpa_supplicant. Alternatively, the
-adapter description can be used as the interface name which may be
-easier since it is usually in more human-readable
-format. win_if_list.exe can be used to find out the proper interface
-name.
-
-Example steps in starting up wpa_supplicant:
-
-# win_if_list.exe
-ifname: \Device\NPF_GenericNdisWanAdapter
-description: Generic NdisWan adapter
-
-ifname: \Device\NPF_{769E012B-FD17-4935-A5E3-8090C38E25D2}
-description: Atheros Wireless Network Adapter (Microsoft's Packet Scheduler)
-
-ifname: \Device\NPF_{732546E7-E26C-48E3-9871-7537B020A211}
-description: Intel 8255x-based Integrated Fast Ethernet (Microsoft's Packet Scheduler)
-
-
-Since the example configuration used Atheros WLAN card, the middle one
-is the correct interface in this case. The interface name for -i
-command line option is the full string following "ifname:" (the
-"\Device\NPF_" prefix can be removed). In other words, wpa_supplicant
-would be started with the following command:
-
-# wpa_supplicant.exe -i'{769E012B-FD17-4935-A5E3-8090C38E25D2}' -c wpa_supplicant.conf -d
-
--d optional enables some more debugging (use -dd for even more, if
-needed). It can be left out if debugging information is not needed.
-
-With the alternative mechanism for selecting the interface, this
-command has identical results in this case:
-
-# wpa_supplicant.exe -iAtheros -c wpa_supplicant.conf -d
-
-
-Simple configuration example for WPA-PSK:
-
-#ap_scan=2
-ctrl_interface=
-network={
- ssid="test"
- key_mgmt=WPA-PSK
- proto=WPA
- pairwise=TKIP
- psk="secret passphrase"
-}
-
-(remove '#' from the comment out ap_scan line to enable mode in which
-wpa_supplicant tries to associate with the SSID without doing
-scanning; this allows APs with hidden SSIDs to be used)
-
-
-wpa_cli.exe and wpa_gui.exe can be used to interact with the
-wpa_supplicant.exe program in the same way as with Linux. Note that
-ctrl_interface is using UNIX domain sockets when built for cygwin, but
-the native build for Windows uses named pipes and the contents of the
-ctrl_interface configuration item is used to control access to the
-interface. Anyway, this variable has to be included in the configuration
-to enable the control interface.
-
-
-Example SDDL string formats:
-
-(local admins group has permission, but nobody else):
-
-ctrl_interface=SDDL=D:(A;;GA;;;BA)
-
-("A" == "access allowed", "GA" == GENERIC_ALL == all permissions, and
-"BA" == "builtin administrators" == the local admins. The empty fields
-are for flags and object GUIDs, none of which should be required in this
-case.)
-
-(local admins and the local "power users" group have permissions,
-but nobody else):
-
-ctrl_interface=SDDL=D:(A;;GA;;;BA)(A;;GA;;;PU)
-
-(One ACCESS_ALLOWED ACE for GENERIC_ALL for builtin administrators, and
-one ACCESS_ALLOWED ACE for GENERIC_ALL for power users.)
-
-(close to wide open, but you have to be a valid user on
-the machine):
-
-ctrl_interface=SDDL=D:(A;;GA;;;AU)
-
-(One ACCESS_ALLOWED ACE for GENERIC_ALL for the "authenticated users"
-group.)
-
-This one would allow absolutely everyone (including anonymous
-users) -- this is *not* recommended, since named pipes can be attached
-to from anywhere on the network (i.e. there's no "this machine only"
-like there is with 127.0.0.1 sockets):
-
-ctrl_interface=SDDL=D:(A;;GA;;;BU)(A;;GA;;;AN)
-
-(BU == "builtin users", "AN" == "anonymous")
-
-See also [1] for the format of ACEs, and [2] for the possible strings
-that can be used for principal names.
-
-[1]
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/ace_strings.asp
-[2]
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/sid_strings.asp
-
-
-Starting wpa_supplicant as a Windows service (wpasvc.exe)
----------------------------------------------------------
-
-wpa_supplicant can be started as a Windows service by using wpasvc.exe
-program that is alternative build of wpa_supplicant.exe. Most of the
-core functionality of wpasvc.exe is identical to wpa_supplicant.exe,
-but it is using Windows registry for configuration information instead
-of a text file and command line parameters. In addition, it can be
-registered as a service that can be started automatically or manually
-like any other Windows service.
-
-The root of wpa_supplicant configuration in registry is
-HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant. This level includes global
-parameters and a 'interfaces' subkey with all the interface configuration
-(adapter to confname mapping). Each such mapping is a subkey that has
-'adapter', 'config', and 'ctrl_interface' values.
-
-This program can be run either as a normal command line application,
-e.g., for debugging, with 'wpasvc.exe app' or as a Windows service.
-Service need to be registered with 'wpasvc.exe reg <full path to
-wpasvc.exe>'. Alternatively, 'wpasvc.exe reg' can be used to register
-the service with the current location of wpasvc.exe. After this, wpasvc
-can be started like any other Windows service (e.g., 'net start wpasvc')
-or it can be configured to start automatically through the Services tool
-in administrative tasks. The service can be unregistered with
-'wpasvc.exe unreg'.
-
-If the service is set to start during system bootup to make the
-network connection available before any user has logged in, there may
-be a long (half a minute or so) delay in starting up wpa_supplicant
-due to WinPcap needing a driver called "Network Monitor Driver" which
-is started by default on demand.
-
-To speed up wpa_supplicant start during system bootup, "Network
-Monitor Driver" can be configured to be started sooner by setting its
-startup type to System instead of the default Demand. To do this, open
-up Device Manager, select Show Hidden Devices, expand the "Non
-Plug-and-Play devices" branch, double click "Network Monitor Driver",
-go to the Driver tab, and change the Demand setting to System instead.
-
-Configuration data is in HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs
-key. Each configuration profile has its own key under this. In terms of text
-files, each profile would map to a separate text file with possibly multiple
-networks. Under each profile, there is a networks key that lists all
-networks as a subkey. Each network has set of values in the same way as
-network block in the configuration file. In addition, blobs subkey has
-possible blobs as values.
-
-HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000
- ssid="example"
- key_mgmt=WPA-PSK
-
-See win_example.reg for an example on how to setup wpasvc.exe
-parameters in registry. It can also be imported to registry as a
-starting point for the configuration.
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
deleted file mode 100644
index 283f8eb0a995..000000000000
--- a/wpa_supplicant/android.config
+++ /dev/null
@@ -1,545 +0,0 @@
-# Example wpa_supplicant build time configuration
-#
-# This file lists the configuration options that are used when building the
-# wpa_supplicant binary. All lines starting with # are ignored. Configuration
-# option lines must be commented out complete, if they are not to be included,
-# i.e., just setting VARIABLE=n is not disabling that variable.
-#
-# This file is included in Makefile, so variables like CFLAGS and LIBS can also
-# be modified from here. In most cases, these lines should use += in order not
-# to override previous values of the variables.
-
-
-# Uncomment following two lines and fix the paths if you have installed OpenSSL
-# or GnuTLS in non-default location
-#CFLAGS += -I/usr/local/openssl/include
-#LIBS += -L/usr/local/openssl/lib
-
-# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
-# the kerberos files are not in the default include path. Following line can be
-# used to fix build issues on such systems (krb5.h not found).
-#CFLAGS += -I/usr/include/kerberos
-
-# Driver interface for generic Linux wireless extensions
-# Note: WEXT is deprecated in the current Linux kernel version and no new
-# functionality is added to it. nl80211-based interface is the new
-# replacement for WEXT and its use allows wpa_supplicant to properly control
-# the driver to improve existing functionality like roaming and to support new
-# functionality.
-#CONFIG_DRIVER_WEXT=y
-
-# Driver interface for Linux drivers using the nl80211 kernel interface
-#CONFIG_DRIVER_NL80211=y
-CONFIG_LIBNL20=y
-
-# QCA vendor extensions to nl80211
-CONFIG_DRIVER_NL80211_QCA=y
-
-# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
-#CONFIG_DRIVER_BSD=y
-#CFLAGS += -I/usr/local/include
-#LIBS += -L/usr/local/lib
-#LIBS_p += -L/usr/local/lib
-#LIBS_c += -L/usr/local/lib
-
-# Driver interface for Windows NDIS
-#CONFIG_DRIVER_NDIS=y
-#CFLAGS += -I/usr/include/w32api/ddk
-#LIBS += -L/usr/local/lib
-# For native build using mingw
-#CONFIG_NATIVE_WINDOWS=y
-# Additional directories for cross-compilation on Linux host for mingw target
-#CFLAGS += -I/opt/mingw/mingw32/include/ddk
-#LIBS += -L/opt/mingw/mingw32/lib
-#CC=mingw32-gcc
-# By default, driver_ndis uses WinPcap for low-level operations. This can be
-# replaced with the following option which replaces WinPcap calls with NDISUIO.
-# However, this requires that WZC is disabled (net stop wzcsvc) before starting
-# wpa_supplicant.
-# CONFIG_USE_NDISUIO=y
-
-# Driver interface for wired Ethernet drivers
-#CONFIG_DRIVER_WIRED=y
-
-# Driver interface for the Broadcom RoboSwitch family
-#CONFIG_DRIVER_ROBOSWITCH=y
-
-# Driver interface for no driver (e.g., WPS ER only)
-#CONFIG_DRIVER_NONE=y
-
-# Solaris libraries
-#LIBS += -lsocket -ldlpi -lnsl
-#LIBS_c += -lsocket
-
-# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
-# included)
-CONFIG_IEEE8021X_EAPOL=y
-
-# EAP-MD5
-CONFIG_EAP_MD5=y
-
-# EAP-MSCHAPv2
-CONFIG_EAP_MSCHAPV2=y
-
-# EAP-TLS
-CONFIG_EAP_TLS=y
-
-# EAL-PEAP
-CONFIG_EAP_PEAP=y
-
-# EAP-TTLS
-CONFIG_EAP_TTLS=y
-
-# EAP-FAST
-#CONFIG_EAP_FAST=y
-
-# EAP-GTC
-CONFIG_EAP_GTC=y
-
-# EAP-OTP
-CONFIG_EAP_OTP=y
-
-# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
-CONFIG_EAP_SIM=y
-
-# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
-#CONFIG_EAP_PSK=y
-
-# EAP-pwd (secure authentication using only a password)
-CONFIG_EAP_PWD=y
-
-# EAP-PAX
-#CONFIG_EAP_PAX=y
-
-# LEAP
-CONFIG_EAP_LEAP=y
-
-# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
-CONFIG_EAP_AKA=y
-
-# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
-# This requires CONFIG_EAP_AKA to be enabled, too.
-CONFIG_EAP_AKA_PRIME=y
-
-# Enable USIM simulator (Milenage) for EAP-AKA
-#CONFIG_USIM_SIMULATOR=y
-
-# EAP-SAKE
-#CONFIG_EAP_SAKE=y
-
-# EAP-GPSK
-#CONFIG_EAP_GPSK=y
-# Include support for optional SHA256 cipher suite in EAP-GPSK
-#CONFIG_EAP_GPSK_SHA256=y
-
-# EAP-TNC and related Trusted Network Connect support (experimental)
-#CONFIG_EAP_TNC=y
-
-# Wi-Fi Protected Setup (WPS)
-CONFIG_WPS=y
-# Enable WPS external registrar functionality
-CONFIG_WPS_ER=y
-# Disable credentials for an open network by default when acting as a WPS
-# registrar.
-#CONFIG_WPS_REG_DISABLE_OPEN=y
-# Enable WPS support with NFC config method
-CONFIG_WPS_NFC=y
-
-# EAP-IKEv2
-#CONFIG_EAP_IKEV2=y
-
-# EAP-EKE
-#CONFIG_EAP_EKE=y
-
-# PKCS#12 (PFX) support (used to read private key and certificate file from
-# a file that usually has extension .p12 or .pfx)
-CONFIG_PKCS12=y
-
-# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
-# engine.
-CONFIG_SMARTCARD=y
-
-# PC/SC interface for smartcards (USIM, GSM SIM)
-# Enable this if EAP-SIM or EAP-AKA is included
-#CONFIG_PCSC=y
-
-# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
-#CONFIG_HT_OVERRIDES=y
-
-# Support VHT overrides (disable VHT, mask MCS rates, etc.)
-#CONFIG_VHT_OVERRIDES=y
-
-# Development testing
-#CONFIG_EAPOL_TEST=y
-
-# Select control interface backend for external programs, e.g, wpa_cli:
-# unix = UNIX domain sockets (default for Linux/*BSD)
-# udp = UDP sockets using localhost (127.0.0.1)
-# udp6 = UDP IPv6 sockets using localhost (::1)
-# named_pipe = Windows Named Pipe (default for Windows)
-# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
-# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
-# y = use default (backwards compatibility)
-# If this option is commented out, control interface is not included in the
-# build.
-CONFIG_CTRL_IFACE=y
-
-# Include support for GNU Readline and History Libraries in wpa_cli.
-# When building a wpa_cli binary for distribution, please note that these
-# libraries are licensed under GPL and as such, BSD license may not apply for
-# the resulting binary.
-#CONFIG_READLINE=y
-
-# Include internal line edit mode in wpa_cli. This can be used as a replacement
-# for GNU Readline to provide limited command line editing and history support.
-CONFIG_WPA_CLI_EDIT=y
-
-# Remove debugging code that is printing out debug message to stdout.
-# This can be used to reduce the size of the wpa_supplicant considerably
-# if debugging code is not needed. The size reduction can be around 35%
-# (e.g., 90 kB).
-#CONFIG_NO_STDOUT_DEBUG=y
-
-# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
-# 35-50 kB in code size.
-#CONFIG_NO_WPA=y
-
-# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
-# This option can be used to reduce code size by removing support for
-# converting ASCII passphrases into PSK. If this functionality is removed, the
-# PSK can only be configured as the 64-octet hexstring (e.g., from
-# wpa_passphrase). This saves about 0.5 kB in code size.
-#CONFIG_NO_WPA_PASSPHRASE=y
-
-# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
-# This can be used if ap_scan=1 mode is never enabled.
-#CONFIG_NO_SCAN_PROCESSING=y
-
-# Select configuration backend:
-# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
-# path is given on command line, not here; this option is just used to
-# select the backend that allows configuration files to be used)
-# winreg = Windows registry (see win_example.reg for an example)
-CONFIG_BACKEND=file
-
-# Remove configuration write functionality (i.e., to allow the configuration
-# file to be updated based on runtime configuration changes). The runtime
-# configuration can still be changed, the changes are just not going to be
-# persistent over restarts. This option can be used to reduce code size by
-# about 3.5 kB.
-#CONFIG_NO_CONFIG_WRITE=y
-
-# Remove support for configuration blobs to reduce code size by about 1.5 kB.
-#CONFIG_NO_CONFIG_BLOBS=y
-
-# Select program entry point implementation:
-# main = UNIX/POSIX like main() function (default)
-# main_winsvc = Windows service (read parameters from registry)
-# main_none = Very basic example (development use only)
-#CONFIG_MAIN=main
-
-# Select wrapper for operating system and C library specific functions
-# unix = UNIX/POSIX like systems (default)
-# win32 = Windows systems
-# none = Empty template
-CONFIG_OS=unix
-
-# Select event loop implementation
-# eloop = select() loop (default)
-# eloop_win = Windows events and WaitForMultipleObject() loop
-CONFIG_ELOOP=eloop
-
-# Should we use poll instead of select? Select is used by default.
-#CONFIG_ELOOP_POLL=y
-
-# Should we use epoll instead of select? Select is used by default.
-#CONFIG_ELOOP_EPOLL=y
-
-# Should we use kqueue instead of select? Select is used by default.
-#CONFIG_ELOOP_KQUEUE=y
-
-# Select layer 2 packet implementation
-# linux = Linux packet socket (default)
-# pcap = libpcap/libdnet/WinPcap
-# freebsd = FreeBSD libpcap
-# winpcap = WinPcap with receive thread
-# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
-# none = Empty template
-CONFIG_L2_PACKET=linux
-
-# Disable Linux packet socket workaround applicable for station interface
-# in a bridge for EAPOL frames. This should be uncommented only if the kernel
-# is known to not have the regression issue in packet socket behavior with
-# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
-#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
-
-# Support Operating Channel Validation
-#CONFIG_OCV=y
-
-# Select TLS implementation
-# openssl = OpenSSL (default)
-# gnutls = GnuTLS
-# internal = Internal TLSv1 implementation (experimental)
-# none = Empty template
-#CONFIG_TLS=openssl
-
-# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
-# can be enabled to get a stronger construction of messages when block ciphers
-# are used. It should be noted that some existing TLS v1.0 -based
-# implementation may not be compatible with TLS v1.1 message (ClientHello is
-# sent prior to negotiating which version will be used)
-#CONFIG_TLSV11=y
-
-# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
-# can be enabled to enable use of stronger crypto algorithms. It should be
-# noted that some existing TLS v1.0 -based implementation may not be compatible
-# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
-# will be used)
-#CONFIG_TLSV12=y
-
-# Select which ciphers to use by default with OpenSSL if the user does not
-# specify them.
-#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
-
-# If CONFIG_TLS=internal is used, additional library and include paths are
-# needed for LibTomMath. Alternatively, an integrated, minimal version of
-# LibTomMath can be used. See beginning of libtommath.c for details on benefits
-# and drawbacks of this option.
-#CONFIG_INTERNAL_LIBTOMMATH=y
-#ifndef CONFIG_INTERNAL_LIBTOMMATH
-#LTM_PATH=/usr/src/libtommath-0.39
-#CFLAGS += -I$(LTM_PATH)
-#LIBS += -L$(LTM_PATH)
-#LIBS_p += -L$(LTM_PATH)
-#endif
-# At the cost of about 4 kB of additional binary size, the internal LibTomMath
-# can be configured to include faster routines for exptmod, sqr, and div to
-# speed up DH and RSA calculation considerably
-#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
-
-# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
-# This is only for Windows builds and requires WMI-related header files and
-# WbemUuid.Lib from Platform SDK even when building with MinGW.
-#CONFIG_NDIS_EVENTS_INTEGRATED=y
-#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-
-# Add support for new DBus control interface
-# (fi.w1.hostap.wpa_supplicant1)
-#CONFIG_CTRL_IFACE_DBUS_NEW=y
-
-# Add introspection support for new DBus control interface
-#CONFIG_CTRL_IFACE_DBUS_INTRO=y
-
-# Add support for Binder control interface
-# Only applicable for Android platforms.
-#CONFIG_CTRL_IFACE_BINDER=y
-
-# Add support for loading EAP methods dynamically as shared libraries.
-# When this option is enabled, each EAP method can be either included
-# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
-# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
-# be loaded in the beginning of the wpa_supplicant configuration file
-# (see load_dynamic_eap parameter in the example file) before being used in
-# the network blocks.
-#
-# Note that some shared parts of EAP methods are included in the main program
-# and in order to be able to use dynamic EAP methods using these parts, the
-# main program must have been build with the EAP method enabled (=y or =dyn).
-# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
-# unless at least one of them was included in the main build to force inclusion
-# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
-# in the main build to be able to load these methods dynamically.
-#
-# Please also note that using dynamic libraries will increase the total binary
-# size. Thus, it may not be the best option for targets that have limited
-# amount of memory/flash.
-#CONFIG_DYNAMIC_EAP_METHODS=y
-
-# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
-CONFIG_IEEE80211R=y
-
-# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
-#CONFIG_DEBUG_FILE=y
-
-# Send debug messages to syslog instead of stdout
-#CONFIG_DEBUG_SYSLOG=y
-# Set syslog facility for debug messages
-#CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
-
-# Add support for sending all debug messages (regardless of debug verbosity)
-# to the Linux kernel tracing facility. This helps debug the entire stack by
-# making it easy to record everything happening from the driver up into the
-# same file, e.g., using trace-cmd.
-#CONFIG_DEBUG_LINUX_TRACING=y
-
-# Add support for writing debug log to Android logcat instead of standard
-# output
-CONFIG_ANDROID_LOG=y
-
-# Enable privilege separation (see README 'Privilege separation' for details)
-#CONFIG_PRIVSEP=y
-
-# Enable mitigation against certain attacks against TKIP by delaying Michael
-# MIC error reports by a random amount of time between 0 and 60 seconds
-#CONFIG_DELAYED_MIC_ERROR_REPORT=y
-
-# Enable tracing code for developer debugging
-# This tracks use of memory allocations and other registrations and reports
-# incorrect use with a backtrace of call (or allocation) location.
-#CONFIG_WPA_TRACE=y
-# For BSD, uncomment these.
-#LIBS += -lexecinfo
-#LIBS_p += -lexecinfo
-#LIBS_c += -lexecinfo
-
-# Use libbfd to get more details for developer debugging
-# This enables use of libbfd to get more detailed symbols for the backtraces
-# generated by CONFIG_WPA_TRACE=y.
-#CONFIG_WPA_TRACE_BFD=y
-# For BSD, uncomment these.
-#LIBS += -lbfd -liberty -lz
-#LIBS_p += -lbfd -liberty -lz
-#LIBS_c += -lbfd -liberty -lz
-
-# wpa_supplicant depends on strong random number generation being available
-# from the operating system. os_get_random() function is used to fetch random
-# data when needed, e.g., for key generation. On Linux and BSD systems, this
-# works by reading /dev/urandom. It should be noted that the OS entropy pool
-# needs to be properly initialized before wpa_supplicant is started. This is
-# important especially on embedded devices that do not have a hardware random
-# number generator and may by default start up with minimal entropy available
-# for random number generation.
-#
-# As a safety net, wpa_supplicant is by default trying to internally collect
-# additional entropy for generating random data to mix in with the data fetched
-# from the OS. This by itself is not considered to be very strong, but it may
-# help in cases where the system pool is not initialized properly. However, it
-# is very strongly recommended that the system pool is initialized with enough
-# entropy either by using hardware assisted random number generator or by
-# storing state over device reboots.
-#
-# wpa_supplicant can be configured to maintain its own entropy store over
-# restarts to enhance random number generation. This is not perfect, but it is
-# much more secure than using the same sequence of random numbers after every
-# reboot. This can be enabled with -e<entropy file> command line option. The
-# specified file needs to be readable and writable by wpa_supplicant.
-#
-# If the os_get_random() is known to provide strong random data (e.g., on
-# Linux/BSD, the board in question is known to have reliable source of random
-# data from /dev/urandom), the internal wpa_supplicant random pool can be
-# disabled. This will save some in binary size and CPU use. However, this
-# should only be considered for builds that are known to be used on devices
-# that meet the requirements described above.
-
-# Wpa_supplicant's random pool is not necessary on Android. Randomness is
-# already provided by the entropymixer service which ensures sufficient
-# entropy is maintained across reboots. Commit b410eb1913 'Initialize
-# /dev/urandom earlier in boot' seeds /dev/urandom with that entropy before
-# either wpa_supplicant or hostapd are run.
-CONFIG_NO_RANDOM_POOL=y
-
-# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
-#CONFIG_IEEE80211AC=y
-
-# Wireless Network Management (IEEE Std 802.11v-2011)
-# Note: This is experimental and not complete implementation.
-CONFIG_WNM=y
-
-# Interworking (IEEE 802.11u)
-# This can be used to enable functionality to improve interworking with
-# external networks (GAS/ANQP to learn more about the networks and network
-# selection based on available credentials).
-CONFIG_INTERWORKING=y
-
-# Hotspot 2.0
-CONFIG_HS20=y
-
-# Enable interface matching in wpa_supplicant
-#CONFIG_MATCH_IFACE=y
-
-# Disable roaming in wpa_supplicant
-CONFIG_NO_ROAMING=y
-
-# AP mode operations with wpa_supplicant
-# This can be used for controlling AP mode operations with wpa_supplicant. It
-# should be noted that this is mainly aimed at simple cases like
-# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
-# external RADIUS server can be supported with hostapd.
-CONFIG_AP=y
-
-# P2P (Wi-Fi Direct)
-# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
-# more information on P2P operations.
-CONFIG_P2P=y
-
-# Enable TDLS support
-CONFIG_TDLS=y
-
-# Wi-Fi Display
-# This can be used to enable Wi-Fi Display extensions for P2P using an external
-# program to control the additional information exchanges in the messages.
-CONFIG_WIFI_DISPLAY=y
-
-# Autoscan
-# This can be used to enable automatic scan support in wpa_supplicant.
-# See wpa_supplicant.conf for more information on autoscan usage.
-#
-# Enabling directly a module will enable autoscan support.
-# For exponential module:
-#CONFIG_AUTOSCAN_EXPONENTIAL=y
-# For periodic module:
-#CONFIG_AUTOSCAN_PERIODIC=y
-
-# Password (and passphrase, etc.) backend for external storage
-# These optional mechanisms can be used to add support for storing passwords
-# and other secrets in external (to wpa_supplicant) location. This allows, for
-# example, operating system specific key storage to be used
-#
-# External password backend for testing purposes (developer use)
-#CONFIG_EXT_PASSWORD_TEST=y
-
-# Enable Fast Session Transfer (FST)
-#CONFIG_FST=y
-
-# Support Multi Band Operation
-#CONFIG_MBO=y
-
-# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-#CONFIG_FILS=y
-
-# Support RSN on IBSS networks
-# This is needed to be able to use mode=1 network profile with proto=RSN and
-# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
-#CONFIG_IBSS_RSN=y
-
-# External PMKSA cache control
-# This can be used to enable control interface commands that allow the current
-# PMKSA cache entries to be fetched and new entries to be added.
-#CONFIG_PMKSA_CACHE_EXTERNAL=y
-
-# Mesh Networking (IEEE 802.11s)
-#CONFIG_MESH=y
-
-# Background scanning modules
-# These can be used to request wpa_supplicant to perform background scanning
-# operations for roaming within an ESS (same SSID). See the bgscan parameter in
-# the wpa_supplicant.conf file for more details.
-# Periodic background scans based on signal strength
-#CONFIG_BGSCAN_SIMPLE=y
-# Learn channels used by the network and try to avoid bgscans on other
-# channels (experimental)
-#CONFIG_BGSCAN_LEARN=y
-
-# Opportunistic Wireless Encryption (OWE)
-# Experimental implementation of draft-harkins-owe-07.txt
-#CONFIG_OWE=y
-
-# Wired equivalent privacy (WEP)
-# WEP is an obsolete cryptographic data confidentiality algorithm that is not
-# considered secure. It should not be used for anything anymore. The
-# functionality needed to use WEP is available in the current wpa_supplicant
-# release under this optional build parameter. This functionality is subject to
-# be completely removed in a future release.
-CONFIG_WEP=y
-
-include $(wildcard $(LOCAL_PATH)/android_config_*.inc)
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
deleted file mode 100644
index 6a0a69e68ee6..000000000000
--- a/wpa_supplicant/ap.c
+++ /dev/null
@@ -1,1945 +0,0 @@
-/*
- * WPA Supplicant - Basic AP mode support routines
- * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2009, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/uuid.h"
-#include "common/ieee802_11_defs.h"
-#include "common/wpa_ctrl.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "crypto/dh_group5.h"
-#include "ap/hostapd.h"
-#include "ap/ap_config.h"
-#include "ap/ap_drv_ops.h"
-#ifdef NEED_AP_MLME
-#include "ap/ieee802_11.h"
-#endif /* NEED_AP_MLME */
-#include "ap/beacon.h"
-#include "ap/ieee802_1x.h"
-#include "ap/wps_hostapd.h"
-#include "ap/ctrl_iface_ap.h"
-#include "ap/dfs.h"
-#include "wps/wps.h"
-#include "common/ieee802_11_defs.h"
-#include "config_ssid.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "p2p_supplicant.h"
-#include "ap.h"
-#include "ap/sta_info.h"
-#include "notify.h"
-
-
-#ifdef CONFIG_WPS
-static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
-#endif /* CONFIG_WPS */
-
-
-#ifdef CONFIG_P2P
-static bool is_chanwidth160_supported(struct hostapd_hw_modes *mode,
- struct hostapd_config *conf)
-{
-#ifdef CONFIG_IEEE80211AX
- if (conf->ieee80211ax) {
- struct he_capabilities *he_cap;
-
- he_cap = &mode->he_capab[IEEE80211_MODE_AP];
- if (he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- (HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G |
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))
- return true;
- }
-#endif /* CONFIG_IEEE80211AX */
- if (mode->vht_capab & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
- VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
- return true;
- return false;
-}
-#endif /* CONFIG_P2P */
-
-
-static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_config *conf,
- struct hostapd_hw_modes *mode)
-{
-#ifdef CONFIG_P2P
- u8 center_chan = 0;
- u8 channel = conf->channel;
-#endif /* CONFIG_P2P */
- u8 freq_seg_idx;
-
- if (!conf->secondary_channel)
- goto no_vht;
-
- /* Use the maximum oper channel width if it's given. */
- if (ssid->max_oper_chwidth)
- hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
- if (hostapd_get_oper_chwidth(conf))
- ieee80211_freq_to_channel_ext(ssid->frequency, 0,
- hostapd_get_oper_chwidth(conf),
- &conf->op_class,
- &conf->channel);
-
- if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
- ieee80211_freq_to_chan(ssid->vht_center_freq2,
- &freq_seg_idx);
- hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
- }
-
- if (!ssid->p2p_group) {
- if (!ssid->vht_center_freq1)
- goto no_vht;
- ieee80211_freq_to_chan(ssid->vht_center_freq1,
- &freq_seg_idx);
- hostapd_set_oper_centr_freq_seg0_idx(conf, freq_seg_idx);
-
- wpa_printf(MSG_DEBUG,
- "VHT seg0 index %d and seg1 index %d for AP",
- hostapd_get_oper_centr_freq_seg0_idx(conf),
- hostapd_get_oper_centr_freq_seg1_idx(conf));
- return;
- }
-
-#ifdef CONFIG_P2P
- switch (hostapd_get_oper_chwidth(conf)) {
- case CHANWIDTH_80MHZ:
- case CHANWIDTH_80P80MHZ:
- center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel,
- conf->op_class);
- wpa_printf(MSG_DEBUG,
- "VHT center channel %u for 80 or 80+80 MHz bandwidth",
- center_chan);
- break;
- case CHANWIDTH_160MHZ:
- center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
- conf->op_class);
- wpa_printf(MSG_DEBUG,
- "VHT center channel %u for 160 MHz bandwidth",
- center_chan);
- break;
- default:
- /*
- * conf->vht_oper_chwidth might not be set for non-P2P GO cases,
- * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
- * not supported.
- */
- hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
- ieee80211_freq_to_channel_ext(ssid->frequency, 0,
- conf->vht_oper_chwidth,
- &conf->op_class,
- &conf->channel);
- center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
- conf->op_class);
- if (center_chan && is_chanwidth160_supported(mode, conf)) {
- wpa_printf(MSG_DEBUG,
- "VHT center channel %u for auto-selected 160 MHz bandwidth",
- center_chan);
- } else {
- hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
- ieee80211_freq_to_channel_ext(ssid->frequency, 0,
- conf->vht_oper_chwidth,
- &conf->op_class,
- &conf->channel);
- center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
- channel,
- conf->op_class);
- wpa_printf(MSG_DEBUG,
- "VHT center channel %u for auto-selected 80 MHz bandwidth",
- center_chan);
- }
- break;
- }
- if (!center_chan)
- goto no_vht;
-
- hostapd_set_oper_centr_freq_seg0_idx(conf, center_chan);
- wpa_printf(MSG_DEBUG, "VHT seg0 index %d for P2P GO",
- hostapd_get_oper_centr_freq_seg0_idx(conf));
- return;
-#endif /* CONFIG_P2P */
-
-no_vht:
- wpa_printf(MSG_DEBUG,
- "No VHT higher bandwidth support for the selected channel %d",
- conf->channel);
- hostapd_set_oper_centr_freq_seg0_idx(
- conf, conf->channel + conf->secondary_channel * 2);
- hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
-}
-
-
-static struct hostapd_hw_modes *
-wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
- enum hostapd_hw_mode hw_mode)
-{
- struct hostapd_hw_modes *mode = NULL;
- int i;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode) {
- mode = &wpa_s->hw.modes[i];
- break;
- }
- }
-
- return mode;
-}
-
-
-#ifdef CONFIG_P2P
-
-static int get_max_oper_chwidth_6ghz(int chwidth)
-{
- switch (chwidth) {
- case CHANWIDTH_USE_HT:
- return 20;
- case CHANWIDTH_40MHZ_6GHZ:
- return 40;
- case CHANWIDTH_80MHZ:
- return 80;
- case CHANWIDTH_80P80MHZ:
- case CHANWIDTH_160MHZ:
- return 160;
- default:
- return 0;
- }
-}
-
-
-static void wpas_conf_ap_he_6ghz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- struct wpa_ssid *ssid,
- struct hostapd_config *conf)
-{
- bool is_chanwidth_40_80, is_chanwidth_160;
- int he_chanwidth;
-
- he_chanwidth =
- mode->he_capab[wpas_mode_to_ieee80211_mode(
- ssid->mode)].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
- is_chanwidth_40_80 = he_chanwidth &
- HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
- is_chanwidth_160 = he_chanwidth &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
-
- wpa_printf(MSG_DEBUG,
- "Enable HE support (p2p_group=%d he_chwidth_cap=%d)",
- ssid->p2p_group, he_chanwidth);
-
- if (mode->he_capab[wpas_mode_to_ieee80211_mode(
- ssid->mode)].he_supported &&
- ssid->he)
- conf->ieee80211ax = 1;
-
- if (is_chanwidth_40_80 && ssid->p2p_group &&
- get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 40) {
- conf->secondary_channel =
- wpas_p2p_get_sec_channel_offset_40mhz(
- wpa_s, mode, conf->channel);
- wpa_printf(MSG_DEBUG,
- "Secondary channel offset %d for P2P group",
- conf->secondary_channel);
- if (ssid->max_oper_chwidth == CHANWIDTH_40MHZ_6GHZ)
- ssid->max_oper_chwidth = CHANWIDTH_USE_HT;
- }
-
- if ((is_chanwidth_40_80 || is_chanwidth_160) && ssid->p2p_group &&
- get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 80)
- wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
-}
-
-#endif /* CONFIG_P2P */
-
-
-int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_config *conf)
-{
- conf->hw_mode = ieee80211_freq_to_channel_ext(ssid->frequency, 0,
- CHANWIDTH_USE_HT,
- &conf->op_class,
- &conf->channel);
- if (conf->hw_mode == NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
- ssid->frequency);
- return -1;
- }
-
- /*
- * Enable HT20 if the driver supports it, by setting conf->ieee80211n
- * and a mask of allowed capabilities within conf->ht_capab.
- * Using default config settings for: conf->ht_op_mode_fixed,
- * conf->secondary_channel, conf->require_ht
- */
- if (wpa_s->hw.modes) {
- struct hostapd_hw_modes *mode = NULL;
- int no_ht = 0;
-
- wpa_printf(MSG_DEBUG,
- "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
- ssid->frequency, conf->channel);
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- conf->hw_mode, is_6ghz_freq(ssid->frequency));
-
- /* May drop to IEEE 802.11b if the driver does not support IEEE
- * 802.11g */
- if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
- conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
- wpa_printf(MSG_INFO,
- "Try downgrade to IEEE 802.11b as 802.11g is not supported by the current hardware");
- mode = wpa_supplicant_find_hw_mode(wpa_s,
- conf->hw_mode);
- }
-
- if (!mode) {
- wpa_printf(MSG_ERROR,
- "No match between requested and supported hw modes found");
- return -1;
- }
-
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht)
- ssid->ht = 0;
-#endif /* CONFIG_HT_OVERRIDES */
-
- if (!ssid->ht) {
- wpa_printf(MSG_DEBUG,
- "HT not enabled in network profile");
- conf->ieee80211n = 0;
- conf->ht_capab = 0;
- no_ht = 1;
- }
-
- if (mode && is_6ghz_freq(ssid->frequency) &&
- conf->hw_mode == HOSTAPD_MODE_IEEE80211A) {
-#ifdef CONFIG_P2P
- wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf);
-#endif /* CONFIG_P2P */
- } else if (!no_ht && mode && mode->ht_capab) {
- wpa_printf(MSG_DEBUG,
- "Enable HT support (p2p_group=%d 11a=%d ht40_hw_capab=%d ssid->ht40=%d)",
- ssid->p2p_group,
- conf->hw_mode == HOSTAPD_MODE_IEEE80211A,
- !!(mode->ht_capab &
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
- ssid->ht40);
- conf->ieee80211n = 1;
-
- if (ssid->ht40 &&
- (mode->ht_capab &
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
- conf->secondary_channel = ssid->ht40;
- else
- conf->secondary_channel = 0;
-
-#ifdef CONFIG_P2P
- if (ssid->p2p_group &&
- conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
- (mode->ht_capab &
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
- ssid->ht40) {
- conf->secondary_channel =
- wpas_p2p_get_sec_channel_offset_40mhz(
- wpa_s, mode, conf->channel);
- wpa_printf(MSG_DEBUG,
- "HT secondary channel offset %d for P2P group",
- conf->secondary_channel);
- } else if (ssid->p2p_group && conf->secondary_channel &&
- conf->hw_mode != HOSTAPD_MODE_IEEE80211A) {
- /* This ended up trying to configure invalid
- * 2.4 GHz channels (e.g., HT40+ on channel 11)
- * in some cases, so clear the secondary channel
- * configuration now to avoid such cases that
- * would lead to group formation failures. */
- wpa_printf(MSG_DEBUG,
- "Disable HT secondary channel for P2P group on 2.4 GHz");
- conf->secondary_channel = 0;
- }
-#endif /* CONFIG_P2P */
-
- if (!ssid->p2p_group &&
- (mode->ht_capab &
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
- conf->secondary_channel = ssid->ht40;
- wpa_printf(MSG_DEBUG,
- "HT secondary channel offset %d for AP",
- conf->secondary_channel);
- }
-
- if (conf->secondary_channel)
- conf->ht_capab |=
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
-
- /*
- * white-list capabilities that won't cause issues
- * to connecting stations, while leaving the current
- * capabilities intact (currently disabled SMPS).
- */
- conf->ht_capab |= mode->ht_capab &
- (HT_CAP_INFO_GREEN_FIELD |
- HT_CAP_INFO_SHORT_GI20MHZ |
- HT_CAP_INFO_SHORT_GI40MHZ |
- HT_CAP_INFO_RX_STBC_MASK |
- HT_CAP_INFO_TX_STBC |
- HT_CAP_INFO_MAX_AMSDU_SIZE);
-
- /* check this before VHT, because setting oper chan
- * width and friends is the same call for HE and VHT
- * and checks if conf->ieee8021ax == 1 */
- if (mode->he_capab[wpas_mode_to_ieee80211_mode(
- ssid->mode)].he_supported &&
- ssid->he)
- conf->ieee80211ax = 1;
-
- if (mode->vht_capab && ssid->vht) {
- conf->ieee80211ac = 1;
- conf->vht_capab |= mode->vht_capab;
- wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
- }
- }
- }
-
- if (conf->secondary_channel) {
- struct wpa_supplicant *iface;
-
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
- {
- if (iface == wpa_s ||
- iface->wpa_state < WPA_AUTHENTICATING ||
- (int) iface->assoc_freq != ssid->frequency)
- continue;
-
- /*
- * Do not allow 40 MHz co-ex PRI/SEC switch to force us
- * to change our PRI channel since we have an existing,
- * concurrent connection on that channel and doing
- * multi-channel concurrency is likely to cause more
- * harm than using different PRI/SEC selection in
- * environment with multiple BSSes on these two channels
- * with mixed 20 MHz or PRI channel selection.
- */
- conf->no_pri_sec_switch = 1;
- }
- }
-
- return 0;
-}
-
-
-static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_config *conf)
-{
- struct hostapd_bss_config *bss = conf->bss[0];
-
- conf->driver = wpa_s->driver;
-
- os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
-
- if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf))
- return -1;
-
- if (ssid->pbss > 1) {
- wpa_printf(MSG_ERROR, "Invalid pbss value(%d) for AP mode",
- ssid->pbss);
- return -1;
- }
- bss->pbss = ssid->pbss;
-
-#ifdef CONFIG_ACS
- if (ssid->acs) {
- /* Setting channel to 0 in order to enable ACS */
- conf->channel = 0;
- wpa_printf(MSG_DEBUG, "Use automatic channel selection");
- }
-#endif /* CONFIG_ACS */
-
- if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
- wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
- conf->ieee80211h = 1;
- conf->ieee80211d = 1;
- conf->country[0] = wpa_s->conf->country[0];
- conf->country[1] = wpa_s->conf->country[1];
- conf->country[2] = ' ';
- }
-
-#ifdef CONFIG_P2P
- if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
- (ssid->mode == WPAS_MODE_P2P_GO ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
- /* Remove 802.11b rates from supported and basic rate sets */
- int *list = os_malloc(4 * sizeof(int));
- if (list) {
- list[0] = 60;
- list[1] = 120;
- list[2] = 240;
- list[3] = -1;
- }
- conf->basic_rates = list;
-
- list = os_malloc(9 * sizeof(int));
- if (list) {
- list[0] = 60;
- list[1] = 90;
- list[2] = 120;
- list[3] = 180;
- list[4] = 240;
- list[5] = 360;
- list[6] = 480;
- list[7] = 540;
- list[8] = -1;
- }
- conf->supported_rates = list;
- }
-
-#ifdef CONFIG_IEEE80211AX
- if (ssid->mode == WPAS_MODE_P2P_GO ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
- conf->ieee80211ax = ssid->he;
-#endif /* CONFIG_IEEE80211AX */
-
- bss->isolate = !wpa_s->conf->p2p_intra_bss;
- bss->extended_key_id = wpa_s->conf->extended_key_id;
- bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
- bss->wpa_deny_ptk0_rekey = ssid->wpa_deny_ptk0_rekey;
-
- if (ssid->p2p_group) {
- os_memcpy(bss->ip_addr_go, wpa_s->p2pdev->conf->ip_addr_go, 4);
- os_memcpy(bss->ip_addr_mask, wpa_s->p2pdev->conf->ip_addr_mask,
- 4);
- os_memcpy(bss->ip_addr_start,
- wpa_s->p2pdev->conf->ip_addr_start, 4);
- os_memcpy(bss->ip_addr_end, wpa_s->p2pdev->conf->ip_addr_end,
- 4);
- }
-#endif /* CONFIG_P2P */
-
- if (ssid->ssid_len == 0) {
- wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
- return -1;
- }
- os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
- bss->ssid.ssid_len = ssid->ssid_len;
- bss->ssid.ssid_set = 1;
-
- bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
-
- if (ssid->auth_alg)
- bss->auth_algs = ssid->auth_alg;
-
- if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
- bss->wpa = ssid->proto;
- if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
- bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
- else
- bss->wpa_key_mgmt = ssid->key_mgmt;
- bss->wpa_pairwise = ssid->pairwise_cipher;
- if (wpa_key_mgmt_sae(bss->wpa_key_mgmt) && ssid->passphrase) {
- bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
- } else if (ssid->psk_set) {
- bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk));
- bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
- if (bss->ssid.wpa_psk == NULL)
- return -1;
- os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
- bss->ssid.wpa_psk->group = 1;
- bss->ssid.wpa_psk_set = 1;
- } else if (ssid->passphrase) {
- bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
-#ifdef CONFIG_WEP
- } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
- ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
- struct hostapd_wep_keys *wep = &bss->ssid.wep;
- int i;
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i] == 0)
- continue;
- wep->key[i] = os_memdup(ssid->wep_key[i],
- ssid->wep_key_len[i]);
- if (wep->key[i] == NULL)
- return -1;
- wep->len[i] = ssid->wep_key_len[i];
- }
- wep->idx = ssid->wep_tx_keyidx;
- wep->keys_set = 1;
-#endif /* CONFIG_WEP */
- }
-#ifdef CONFIG_SAE
- if (ssid->sae_password) {
- struct sae_password_entry *pw;
-
- pw = os_zalloc(sizeof(*pw));
- if (!pw)
- return -1;
- os_memset(pw->peer_addr, 0xff, ETH_ALEN);
- pw->password = os_strdup(ssid->sae_password);
- if (!pw->password) {
- os_free(pw);
- return -1;
- }
- if (ssid->sae_password_id) {
- pw->identifier = os_strdup(ssid->sae_password_id);
- if (!pw->identifier) {
- str_clear_free(pw->password);
- os_free(pw);
- return -1;
- }
- }
-
- pw->next = bss->sae_passwords;
- bss->sae_passwords = pw;
- }
-
- if (ssid->sae_pwe != DEFAULT_SAE_PWE)
- bss->sae_pwe = ssid->sae_pwe;
- else
- bss->sae_pwe = wpa_s->conf->sae_pwe;
-#endif /* CONFIG_SAE */
-
- if (wpa_s->conf->go_interworking) {
- wpa_printf(MSG_DEBUG,
- "P2P: Enable Interworking with access_network_type: %d",
- wpa_s->conf->go_access_network_type);
- bss->interworking = wpa_s->conf->go_interworking;
- bss->access_network_type = wpa_s->conf->go_access_network_type;
- bss->internet = wpa_s->conf->go_internet;
- if (wpa_s->conf->go_venue_group) {
- wpa_printf(MSG_DEBUG,
- "P2P: Venue group: %d Venue type: %d",
- wpa_s->conf->go_venue_group,
- wpa_s->conf->go_venue_type);
- bss->venue_group = wpa_s->conf->go_venue_group;
- bss->venue_type = wpa_s->conf->go_venue_type;
- bss->venue_info_set = 1;
- }
- }
-
- if (ssid->ap_max_inactivity)
- bss->ap_max_inactivity = ssid->ap_max_inactivity;
-
- if (ssid->dtim_period)
- bss->dtim_period = ssid->dtim_period;
- else if (wpa_s->conf->dtim_period)
- bss->dtim_period = wpa_s->conf->dtim_period;
-
- if (ssid->beacon_int)
- conf->beacon_int = ssid->beacon_int;
- else if (wpa_s->conf->beacon_int)
- conf->beacon_int = wpa_s->conf->beacon_int;
-
-#ifdef CONFIG_P2P
- if (ssid->mode == WPAS_MODE_P2P_GO ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
- if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) {
- wpa_printf(MSG_INFO,
- "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it",
- wpa_s->conf->p2p_go_ctwindow,
- conf->beacon_int);
- conf->p2p_go_ctwindow = 0;
- } else {
- conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow;
- }
- }
-#endif /* CONFIG_P2P */
-
- if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
- bss->rsn_pairwise = bss->wpa_pairwise;
- bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
- bss->rsn_pairwise);
-
- if (bss->wpa && bss->ieee802_1x) {
- bss->ssid.security_policy = SECURITY_WPA;
- } else if (bss->wpa) {
- bss->ssid.security_policy = SECURITY_WPA_PSK;
-#ifdef CONFIG_WEP
- } else if (bss->ieee802_1x) {
- int cipher = WPA_CIPHER_NONE;
- bss->ssid.security_policy = SECURITY_IEEE_802_1X;
- bss->ssid.wep.default_len = bss->default_wep_key_len;
- if (bss->default_wep_key_len)
- cipher = bss->default_wep_key_len >= 13 ?
- WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
- bss->wpa_group = cipher;
- bss->wpa_pairwise = cipher;
- bss->rsn_pairwise = cipher;
- } else if (bss->ssid.wep.keys_set) {
- int cipher = WPA_CIPHER_WEP40;
- if (bss->ssid.wep.len[0] >= 13)
- cipher = WPA_CIPHER_WEP104;
- bss->ssid.security_policy = SECURITY_STATIC_WEP;
- bss->wpa_group = cipher;
- bss->wpa_pairwise = cipher;
- bss->rsn_pairwise = cipher;
-#endif /* CONFIG_WEP */
- } else {
- bss->ssid.security_policy = SECURITY_PLAINTEXT;
- bss->wpa_group = WPA_CIPHER_NONE;
- bss->wpa_pairwise = WPA_CIPHER_NONE;
- bss->rsn_pairwise = WPA_CIPHER_NONE;
- }
-
- if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
- (bss->wpa_group == WPA_CIPHER_CCMP ||
- bss->wpa_group == WPA_CIPHER_GCMP ||
- bss->wpa_group == WPA_CIPHER_CCMP_256 ||
- bss->wpa_group == WPA_CIPHER_GCMP_256)) {
- /*
- * Strong ciphers do not need frequent rekeying, so increase
- * the default GTK rekeying period to 24 hours.
- */
- bss->wpa_group_rekey = 86400;
- }
-
- if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
- bss->ieee80211w = ssid->ieee80211w;
-
-#ifdef CONFIG_OCV
- bss->ocv = ssid->ocv;
-#endif /* CONFIG_OCV */
-
-#ifdef CONFIG_WPS
- /*
- * Enable WPS by default for open and WPA/WPA2-Personal network, but
- * require user interaction to actually use it. Only the internal
- * Registrar is supported.
- */
- if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
- bss->ssid.security_policy != SECURITY_PLAINTEXT)
- goto no_wps;
- if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
- (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) ||
- !(bss->wpa & 2)))
- goto no_wps; /* WPS2 does not allow WPA/TKIP-only
- * configuration */
- if (ssid->wps_disabled)
- goto no_wps;
- bss->eap_server = 1;
-
- if (!ssid->ignore_broadcast_ssid)
- bss->wps_state = 2;
-
- bss->ap_setup_locked = 2;
- if (wpa_s->conf->config_methods)
- bss->config_methods = os_strdup(wpa_s->conf->config_methods);
- os_memcpy(bss->device_type, wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN);
- if (wpa_s->conf->device_name) {
- bss->device_name = os_strdup(wpa_s->conf->device_name);
- bss->friendly_name = os_strdup(wpa_s->conf->device_name);
- }
- if (wpa_s->conf->manufacturer)
- bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
- if (wpa_s->conf->model_name)
- bss->model_name = os_strdup(wpa_s->conf->model_name);
- if (wpa_s->conf->model_number)
- bss->model_number = os_strdup(wpa_s->conf->model_number);
- if (wpa_s->conf->serial_number)
- bss->serial_number = os_strdup(wpa_s->conf->serial_number);
- if (is_nil_uuid(wpa_s->conf->uuid))
- os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
- else
- os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
- os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
- bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
- if (ssid->eap.fragment_size != DEFAULT_FRAGMENT_SIZE)
- bss->fragment_size = ssid->eap.fragment_size;
-no_wps:
-#endif /* CONFIG_WPS */
-
- if (wpa_s->max_stations &&
- wpa_s->max_stations < wpa_s->conf->max_num_sta)
- bss->max_num_sta = wpa_s->max_stations;
- else
- bss->max_num_sta = wpa_s->conf->max_num_sta;
-
- if (!bss->isolate)
- bss->isolate = wpa_s->conf->ap_isolate;
-
- bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
-
- if (wpa_s->conf->ap_vendor_elements) {
- bss->vendor_elements =
- wpabuf_dup(wpa_s->conf->ap_vendor_elements);
- }
- if (wpa_s->conf->ap_assocresp_elements) {
- bss->assocresp_elements =
- wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
- }
-
- bss->ftm_responder = wpa_s->conf->ftm_responder;
- bss->ftm_initiator = wpa_s->conf->ftm_initiator;
-
- bss->transition_disable = ssid->transition_disable;
-
- return 0;
-}
-
-
-static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
-{
-#ifdef CONFIG_P2P
- struct wpa_supplicant *wpa_s = ctx;
- const struct ieee80211_mgmt *mgmt;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
- if (len < IEEE80211_HDRLEN + 1)
- return;
- if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
- return;
- wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- buf + IEEE80211_HDRLEN + 1,
- len - IEEE80211_HDRLEN - 1, freq);
-#endif /* CONFIG_P2P */
-}
-
-
-static void ap_wps_event_cb(void *ctx, enum wps_event event,
- union wps_event_data *data)
-{
-#ifdef CONFIG_P2P
- struct wpa_supplicant *wpa_s = ctx;
-
- if (event == WPS_EV_FAIL) {
- struct wps_event_fail *fail = &data->fail;
-
- if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s &&
- wpa_s == wpa_s->global->p2p_group_formation) {
- /*
- * src/ap/wps_hostapd.c has already sent this on the
- * main interface, so only send on the parent interface
- * here if needed.
- */
- wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
- "msg=%d config_error=%d",
- fail->msg, fail->config_error);
- }
- wpas_p2p_wps_failed(wpa_s, fail);
- }
-#endif /* CONFIG_P2P */
-}
-
-
-static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
- int authorized, const u8 *p2p_dev_addr)
-{
- wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
-}
-
-
-#ifdef CONFIG_P2P
-static void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
- const u8 *psk, size_t psk_len)
-{
-
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
- return;
- wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
-}
-#endif /* CONFIG_P2P */
-
-
-static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
-{
-#ifdef CONFIG_P2P
- struct wpa_supplicant *wpa_s = ctx;
- const struct ieee80211_mgmt *mgmt;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
- if (len < IEEE80211_HDRLEN + 1)
- return -1;
- wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- buf + IEEE80211_HDRLEN + 1,
- len - IEEE80211_HDRLEN - 1, freq);
-#endif /* CONFIG_P2P */
- return 0;
-}
-
-
-static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
- const u8 *bssid, const u8 *ie, size_t ie_len,
- int ssi_signal)
-{
- struct wpa_supplicant *wpa_s = ctx;
- unsigned int freq = 0;
-
- if (wpa_s->ap_iface)
- freq = wpa_s->ap_iface->freq;
-
- return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
- freq, ssi_signal);
-}
-
-
-static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
- const u8 *uuid_e)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpas_p2p_wps_success(wpa_s, mac_addr, 1);
-}
-
-
-static void wpas_ap_configured_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_printf(MSG_DEBUG, "AP interface setup completed - state %s",
- hostapd_state_text(wpa_s->ap_iface->state));
- if (wpa_s->ap_iface->state == HAPD_IFACE_DISABLED) {
- wpa_supplicant_ap_deinit(wpa_s);
- return;
- }
-
-#ifdef CONFIG_ACS
- if (wpa_s->current_ssid && wpa_s->current_ssid->acs) {
- wpa_s->assoc_freq = wpa_s->ap_iface->freq;
- wpa_s->current_ssid->frequency = wpa_s->ap_iface->freq;
- }
-#endif /* CONFIG_ACS */
-
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-
- if (wpa_s->ap_configured_cb)
- wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
- wpa_s->ap_configured_cb_data);
-}
-
-
-int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpa_driver_associate_params params;
- struct hostapd_iface *hapd_iface;
- struct hostapd_config *conf;
- size_t i;
-
- if (ssid->ssid == NULL || ssid->ssid_len == 0) {
- wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
- return -1;
- }
-
- wpa_supplicant_ap_deinit(wpa_s);
-
- wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
-
- os_memset(&params, 0, sizeof(params));
- params.ssid = ssid->ssid;
- params.ssid_len = ssid->ssid_len;
- switch (ssid->mode) {
- case WPAS_MODE_AP:
- case WPAS_MODE_P2P_GO:
- case WPAS_MODE_P2P_GROUP_FORMATION:
- params.mode = IEEE80211_MODE_AP;
- break;
- default:
- return -1;
- }
- if (ssid->frequency == 0)
- ssid->frequency = 2462; /* default channel 11 */
- params.freq.freq = ssid->frequency;
-
- if ((ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO) &&
- ssid->enable_edmg) {
- u8 primary_channel;
-
- if (ieee80211_freq_to_chan(ssid->frequency, &primary_channel) ==
- NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_WARNING,
- "EDMG: Failed to get the primary channel");
- return -1;
- }
-
- hostapd_encode_edmg_chan(ssid->enable_edmg, ssid->edmg_channel,
- primary_channel, &params.freq.edmg);
- }
-
- params.wpa_proto = ssid->proto;
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
- wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
- else if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
- wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
- else
- wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
- params.key_mgmt_suite = wpa_s->key_mgmt;
-
- wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
- 1);
- if (wpa_s->pairwise_cipher < 0) {
- wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
- "cipher.");
- return -1;
- }
- params.pairwise_suite = wpa_s->pairwise_cipher;
- params.group_suite = params.pairwise_suite;
-
-#ifdef CONFIG_P2P
- if (ssid->mode == WPAS_MODE_P2P_GO ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
- params.p2p = 1;
-#endif /* CONFIG_P2P */
-
- if (wpa_s->p2pdev->set_ap_uapsd)
- params.uapsd = wpa_s->p2pdev->ap_uapsd;
- else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
- params.uapsd = 1; /* mandatory for P2P GO */
- else
- params.uapsd = -1;
-
- if (ieee80211_is_dfs(params.freq.freq, wpa_s->hw.modes,
- wpa_s->hw.num_modes))
- params.freq.freq = 0; /* set channel after CAC */
-
- if (params.p2p)
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_GO);
- else
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_AP_BSS);
-
- if (wpa_drv_associate(wpa_s, &params) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
- return -1;
- }
-
- wpa_s->ap_iface = hapd_iface = hostapd_alloc_iface();
- if (hapd_iface == NULL)
- return -1;
- hapd_iface->owner = wpa_s;
- hapd_iface->drv_flags = wpa_s->drv_flags;
- hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
- hapd_iface->extended_capa = wpa_s->extended_capa;
- hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
- hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
-
- wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
- if (conf == NULL) {
- wpa_supplicant_ap_deinit(wpa_s);
- return -1;
- }
-
- os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
- wpa_s->conf->wmm_ac_params,
- sizeof(wpa_s->conf->wmm_ac_params));
-
- os_memcpy(wpa_s->ap_iface->conf->tx_queue, wpa_s->conf->tx_queue,
- sizeof(wpa_s->conf->tx_queue));
-
- if (params.uapsd > 0) {
- conf->bss[0]->wmm_enabled = 1;
- conf->bss[0]->wmm_uapsd = 1;
- }
-
- if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
- wpa_printf(MSG_ERROR, "Failed to create AP configuration");
- wpa_supplicant_ap_deinit(wpa_s);
- return -1;
- }
-
-#ifdef CONFIG_P2P
- if (ssid->mode == WPAS_MODE_P2P_GO)
- conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
- else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
- conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
- P2P_GROUP_FORMATION;
-#endif /* CONFIG_P2P */
-
- hapd_iface->num_bss = conf->num_bss;
- hapd_iface->bss = os_calloc(conf->num_bss,
- sizeof(struct hostapd_data *));
- if (hapd_iface->bss == NULL) {
- wpa_supplicant_ap_deinit(wpa_s);
- return -1;
- }
-
- for (i = 0; i < conf->num_bss; i++) {
- hapd_iface->bss[i] =
- hostapd_alloc_bss_data(hapd_iface, conf,
- conf->bss[i]);
- if (hapd_iface->bss[i] == NULL) {
- wpa_supplicant_ap_deinit(wpa_s);
- return -1;
- }
-
- hapd_iface->bss[i]->msg_ctx = wpa_s;
- hapd_iface->bss[i]->msg_ctx_parent = wpa_s->p2pdev;
- hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
- hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
- hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
- hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
- hostapd_register_probereq_cb(hapd_iface->bss[i],
- ap_probe_req_rx, wpa_s);
- hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
- hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
- hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
- hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
- hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
- hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
-#ifdef CONFIG_P2P
- hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
- hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
- hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
- hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
- ssid);
-#endif /* CONFIG_P2P */
- hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
- hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
-#ifdef CONFIG_TESTING_OPTIONS
- hapd_iface->bss[i]->ext_eapol_frame_io =
- wpa_s->ext_eapol_frame_io;
-#endif /* CONFIG_TESTING_OPTIONS */
- }
-
- os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
- hapd_iface->bss[0]->driver = wpa_s->driver;
- hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
-
- wpa_s->current_ssid = ssid;
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
- wpa_s->assoc_freq = ssid->frequency;
- wpa_s->ap_iface->conf->enable_edmg = ssid->enable_edmg;
- wpa_s->ap_iface->conf->edmg_channel = ssid->edmg_channel;
-
-#if defined(CONFIG_P2P) && defined(CONFIG_ACS)
- if (wpa_s->p2p_go_do_acs) {
- wpa_s->ap_iface->conf->channel = 0;
- wpa_s->ap_iface->conf->hw_mode = wpa_s->p2p_go_acs_band;
- ssid->acs = 1;
- }
-#endif /* CONFIG_P2P && CONFIG_ACS */
-
- if (hostapd_setup_interface(wpa_s->ap_iface)) {
- wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
- wpa_supplicant_ap_deinit(wpa_s);
- return -1;
- }
-
- return 0;
-}
-
-
-void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WPS
- eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
-#endif /* CONFIG_WPS */
-
- if (wpa_s->ap_iface == NULL)
- return;
-
- wpa_s->current_ssid = NULL;
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_s->assoc_freq = 0;
- wpas_p2p_ap_deinit(wpa_s);
- wpa_s->ap_iface->driver_ap_teardown =
- !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
-
- hostapd_interface_deinit(wpa_s->ap_iface);
- hostapd_interface_free(wpa_s->ap_iface);
- wpa_s->ap_iface = NULL;
- wpa_drv_deinit_ap(wpa_s);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
- " reason=%d locally_generated=1",
- MAC2STR(wpa_s->own_addr), WLAN_REASON_DEAUTH_LEAVING);
-}
-
-
-void ap_tx_status(void *ctx, const u8 *addr,
- const u8 *buf, size_t len, int ack)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
-#endif /* NEED_AP_MLME */
-}
-
-
-void ap_eapol_tx_status(void *ctx, const u8 *dst,
- const u8 *data, size_t len, int ack)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- if (!wpa_s->ap_iface)
- return;
- hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
-#endif /* NEED_AP_MLME */
-}
-
-
-void ap_client_poll_ok(void *ctx, const u8 *addr)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->ap_iface)
- hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
-#endif /* NEED_AP_MLME */
-}
-
-
-void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
-#endif /* NEED_AP_MLME */
-}
-
-
-void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- struct hostapd_frame_info fi;
- os_memset(&fi, 0, sizeof(fi));
- fi.datarate = rx_mgmt->datarate;
- fi.ssi_signal = rx_mgmt->ssi_signal;
- ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
- rx_mgmt->frame_len, &fi);
-#endif /* NEED_AP_MLME */
-}
-
-
-void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
-{
-#ifdef NEED_AP_MLME
- struct wpa_supplicant *wpa_s = ctx;
- ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
-#endif /* NEED_AP_MLME */
-}
-
-
-void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
- const u8 *src_addr, const u8 *buf, size_t len)
-{
- ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
-}
-
-
-#ifdef CONFIG_WPS
-
-int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *p2p_dev_addr)
-{
- if (!wpa_s->ap_iface)
- return -1;
- return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
- p2p_dev_addr);
-}
-
-
-int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
-{
- struct wps_registrar *reg;
- int reg_sel = 0, wps_sta = 0;
-
- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
- return -1;
-
- reg = wpa_s->ap_iface->bss[0]->wps->registrar;
- reg_sel = wps_registrar_wps_cancel(reg);
- wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
- ap_sta_wps_cancel, NULL);
-
- if (!reg_sel && !wps_sta) {
- wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
- "time");
- return -1;
- }
-
- /*
- * There are 2 cases to return wps cancel as success:
- * 1. When wps cancel was initiated but no connection has been
- * established with client yet.
- * 2. Client is in the middle of exchanging WPS messages.
- */
-
- return 0;
-}
-
-
-int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, char *buf, size_t buflen,
- int timeout)
-{
- int ret, ret_len = 0;
-
- if (!wpa_s->ap_iface)
- return -1;
-
- if (pin == NULL) {
- unsigned int rpin;
-
- if (wps_generate_pin(&rpin) < 0)
- return -1;
- ret_len = os_snprintf(buf, buflen, "%08d", rpin);
- if (os_snprintf_error(buflen, ret_len))
- return -1;
- pin = buf;
- } else if (buf) {
- ret_len = os_snprintf(buf, buflen, "%s", pin);
- if (os_snprintf_error(buflen, ret_len))
- return -1;
- }
-
- ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
- timeout);
- if (ret)
- return -1;
- return ret_len;
-}
-
-
-static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_data;
- wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
- wpas_wps_ap_pin_disable(wpa_s);
-}
-
-
-static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return;
- hapd = wpa_s->ap_iface->bss[0];
- wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
- hapd->ap_pin_failures = 0;
- eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
- if (timeout > 0)
- eloop_register_timeout(timeout, 0,
- wpas_wps_ap_pin_timeout, wpa_s, NULL);
-}
-
-
-void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return;
- wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
- hapd = wpa_s->ap_iface->bss[0];
- os_free(hapd->conf->ap_pin);
- hapd->conf->ap_pin = NULL;
- eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
-}
-
-
-const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
-{
- struct hostapd_data *hapd;
- unsigned int pin;
- char pin_txt[9];
-
- if (wpa_s->ap_iface == NULL)
- return NULL;
- hapd = wpa_s->ap_iface->bss[0];
- if (wps_generate_pin(&pin) < 0)
- return NULL;
- os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
- os_free(hapd->conf->ap_pin);
- hapd->conf->ap_pin = os_strdup(pin_txt);
- if (hapd->conf->ap_pin == NULL)
- return NULL;
- wpas_wps_ap_pin_enable(wpa_s, timeout);
-
- return hapd->conf->ap_pin;
-}
-
-
-const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_data *hapd;
- if (wpa_s->ap_iface == NULL)
- return NULL;
- hapd = wpa_s->ap_iface->bss[0];
- return hapd->conf->ap_pin;
-}
-
-
-int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
- int timeout)
-{
- struct hostapd_data *hapd;
- char pin_txt[9];
- int ret;
-
- if (wpa_s->ap_iface == NULL)
- return -1;
- hapd = wpa_s->ap_iface->bss[0];
- ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
- if (os_snprintf_error(sizeof(pin_txt), ret))
- return -1;
- os_free(hapd->conf->ap_pin);
- hapd->conf->ap_pin = os_strdup(pin_txt);
- if (hapd->conf->ap_pin == NULL)
- return -1;
- wpas_wps_ap_pin_enable(wpa_s, timeout);
-
- return 0;
-}
-
-
-void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return;
- hapd = wpa_s->ap_iface->bss[0];
-
- /*
- * Registrar failed to prove its knowledge of the AP PIN. Disable AP
- * PIN if this happens multiple times to slow down brute force attacks.
- */
- hapd->ap_pin_failures++;
- wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
- hapd->ap_pin_failures);
- if (hapd->ap_pin_failures < 3)
- return;
-
- wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
- hapd->ap_pin_failures = 0;
- os_free(hapd->conf->ap_pin);
- hapd->conf->ap_pin = NULL;
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return NULL;
- hapd = wpa_s->ap_iface->bss[0];
- return hostapd_wps_nfc_config_token(hapd, ndef);
-}
-
-
-struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return NULL;
- hapd = wpa_s->ap_iface->bss[0];
- return hostapd_wps_nfc_hs_cr(hapd, ndef);
-}
-
-
-int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface == NULL)
- return -1;
- hapd = wpa_s->ap_iface->bss[0];
- return hostapd_wps_nfc_report_handover(hapd, req, sel);
-}
-
-#endif /* CONFIG_WPS_NFC */
-
-#endif /* CONFIG_WPS */
-
-
-#ifdef CONFIG_CTRL_IFACE
-
-int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface)
- hapd = wpa_s->ap_iface->bss[0];
- else if (wpa_s->ifmsh)
- hapd = wpa_s->ifmsh->bss[0];
- else
- return -1;
- return hostapd_ctrl_iface_sta_first(hapd, buf, buflen);
-}
-
-
-int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
- char *buf, size_t buflen)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface)
- hapd = wpa_s->ap_iface->bss[0];
- else if (wpa_s->ifmsh)
- hapd = wpa_s->ifmsh->bss[0];
- else
- return -1;
- return hostapd_ctrl_iface_sta(hapd, txtaddr, buf, buflen);
-}
-
-
-int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
- char *buf, size_t buflen)
-{
- struct hostapd_data *hapd;
-
- if (wpa_s->ap_iface)
- hapd = wpa_s->ap_iface->bss[0];
- else if (wpa_s->ifmsh)
- hapd = wpa_s->ifmsh->bss[0];
- else
- return -1;
- return hostapd_ctrl_iface_sta_next(hapd, txtaddr, buf, buflen);
-}
-
-
-int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
- const char *txtaddr)
-{
- if (wpa_s->ap_iface == NULL)
- return -1;
- return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
- txtaddr);
-}
-
-
-int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
- const char *txtaddr)
-{
- if (wpa_s->ap_iface == NULL)
- return -1;
- return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
- txtaddr);
-}
-
-
-int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
- size_t buflen, int verbose)
-{
- char *pos = buf, *end = buf + buflen;
- int ret;
- struct hostapd_bss_config *conf;
-
- if (wpa_s->ap_iface == NULL)
- return -1;
-
- conf = wpa_s->ap_iface->bss[0]->conf;
- if (conf->wpa == 0)
- return 0;
-
- ret = os_snprintf(pos, end - pos,
- "pairwise_cipher=%s\n"
- "group_cipher=%s\n"
- "key_mgmt=%s\n",
- wpa_cipher_txt(conf->rsn_pairwise),
- wpa_cipher_txt(conf->wpa_group),
- wpa_key_mgmt_txt(conf->wpa_key_mgmt,
- conf->wpa));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- return pos - buf;
-}
-
-#endif /* CONFIG_CTRL_IFACE */
-
-
-int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct hostapd_data *hapd;
-
- if (ssid == NULL || wpa_s->ap_iface == NULL ||
- ssid->mode == WPAS_MODE_INFRA ||
- ssid->mode == WPAS_MODE_IBSS)
- return -1;
-
-#ifdef CONFIG_P2P
- if (ssid->mode == WPAS_MODE_P2P_GO)
- iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
- else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
- iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
- P2P_GROUP_FORMATION;
-#endif /* CONFIG_P2P */
-
- hapd = iface->bss[0];
- if (hapd->drv_priv == NULL)
- return -1;
- ieee802_11_set_beacons(iface);
- hostapd_set_ap_wps_ie(hapd);
-
- return 0;
-}
-
-
-int ap_switch_channel(struct wpa_supplicant *wpa_s,
- struct csa_settings *settings)
-{
-#ifdef NEED_AP_MLME
- struct hostapd_iface *iface = NULL;
-
- if (wpa_s->ap_iface)
- iface = wpa_s->ap_iface;
- else if (wpa_s->ifmsh)
- iface = wpa_s->ifmsh;
-
- if (!iface || !iface->bss[0])
- return -1;
-
- return hostapd_switch_channel(iface->bss[0], settings);
-#else /* NEED_AP_MLME */
- return -1;
-#endif /* NEED_AP_MLME */
-}
-
-
-#ifdef CONFIG_CTRL_IFACE
-int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
-{
- struct csa_settings settings;
- int ret = hostapd_parse_csa_settings(pos, &settings);
-
- if (ret)
- return ret;
-
- return ap_switch_channel(wpa_s, &settings);
-}
-#endif /* CONFIG_CTRL_IFACE */
-
-
-void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- int offset, int width, int cf1, int cf2, int finished)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface)
- return;
- wpa_s->assoc_freq = freq;
- if (wpa_s->current_ssid)
- wpa_s->current_ssid->frequency = freq;
- hostapd_event_ch_switch(iface->bss[0], freq, ht,
- offset, width, cf1, cf2, finished);
-}
-
-
-int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- struct hostapd_data *hapd;
- struct hostapd_bss_config *conf;
-
- if (!wpa_s->ap_iface)
- return -1;
-
- if (addr)
- wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
- MAC2STR(addr));
- else
- wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
-
- hapd = wpa_s->ap_iface->bss[0];
- conf = hapd->conf;
-
- os_free(conf->accept_mac);
- conf->accept_mac = NULL;
- conf->num_accept_mac = 0;
- os_free(conf->deny_mac);
- conf->deny_mac = NULL;
- conf->num_deny_mac = 0;
-
- if (addr == NULL) {
- conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
- return 0;
- }
-
- conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
- conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
- if (conf->accept_mac == NULL)
- return -1;
- os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
- conf->num_accept_mac = 1;
-
- return 0;
-}
-
-
-#ifdef CONFIG_WPS_NFC
-int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
- const struct wpabuf *pw, const u8 *pubkey_hash)
-{
- struct hostapd_data *hapd;
- struct wps_context *wps;
-
- if (!wpa_s->ap_iface)
- return -1;
- hapd = wpa_s->ap_iface->bss[0];
- wps = hapd->wps;
-
- if (wpa_s->p2pdev->conf->wps_nfc_dh_pubkey == NULL ||
- wpa_s->p2pdev->conf->wps_nfc_dh_privkey == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
- return -1;
- }
-
- dh5_free(wps->dh_ctx);
- wpabuf_free(wps->dh_pubkey);
- wpabuf_free(wps->dh_privkey);
- wps->dh_privkey = wpabuf_dup(
- wpa_s->p2pdev->conf->wps_nfc_dh_privkey);
- wps->dh_pubkey = wpabuf_dup(
- wpa_s->p2pdev->conf->wps_nfc_dh_pubkey);
- if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
- wps->dh_ctx = NULL;
- wpabuf_free(wps->dh_pubkey);
- wps->dh_pubkey = NULL;
- wpabuf_free(wps->dh_privkey);
- wps->dh_privkey = NULL;
- return -1;
- }
- wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
- if (wps->dh_ctx == NULL)
- return -1;
-
- return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
- pw_id,
- pw ? wpabuf_head(pw) : NULL,
- pw ? wpabuf_len(pw) : 0, 1);
-}
-#endif /* CONFIG_WPS_NFC */
-
-
-#ifdef CONFIG_CTRL_IFACE
-int wpas_ap_stop_ap(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_data *hapd;
-
- if (!wpa_s->ap_iface)
- return -1;
- hapd = wpa_s->ap_iface->bss[0];
- return hostapd_ctrl_iface_stop_ap(hapd);
-}
-
-
-int wpas_ap_pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf,
- size_t len)
-{
- size_t reply_len = 0, i;
- char ap_delimiter[] = "---- AP ----\n";
- char mesh_delimiter[] = "---- mesh ----\n";
- size_t dlen;
-
- if (wpa_s->ap_iface) {
- dlen = os_strlen(ap_delimiter);
- if (dlen > len - reply_len)
- return reply_len;
- os_memcpy(&buf[reply_len], ap_delimiter, dlen);
- reply_len += dlen;
-
- for (i = 0; i < wpa_s->ap_iface->num_bss; i++) {
- reply_len += hostapd_ctrl_iface_pmksa_list(
- wpa_s->ap_iface->bss[i],
- &buf[reply_len], len - reply_len);
- }
- }
-
- if (wpa_s->ifmsh) {
- dlen = os_strlen(mesh_delimiter);
- if (dlen > len - reply_len)
- return reply_len;
- os_memcpy(&buf[reply_len], mesh_delimiter, dlen);
- reply_len += dlen;
-
- reply_len += hostapd_ctrl_iface_pmksa_list(
- wpa_s->ifmsh->bss[0], &buf[reply_len],
- len - reply_len);
- }
-
- return reply_len;
-}
-
-
-void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
-{
- size_t i;
-
- if (wpa_s->ap_iface) {
- for (i = 0; i < wpa_s->ap_iface->num_bss; i++)
- hostapd_ctrl_iface_pmksa_flush(wpa_s->ap_iface->bss[i]);
- }
-
- if (wpa_s->ifmsh)
- hostapd_ctrl_iface_pmksa_flush(wpa_s->ifmsh->bss[0]);
-}
-
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-#ifdef CONFIG_MESH
-
-int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
- char *buf, size_t len)
-{
- return hostapd_ctrl_iface_pmksa_list_mesh(wpa_s->ifmsh->bss[0], addr,
- &buf[0], len);
-}
-
-
-int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd)
-{
- struct external_pmksa_cache *entry;
- void *pmksa_cache;
-
- pmksa_cache = hostapd_ctrl_iface_pmksa_create_entry(wpa_s->own_addr,
- cmd);
- if (!pmksa_cache)
- return -1;
-
- entry = os_zalloc(sizeof(struct external_pmksa_cache));
- if (!entry)
- return -1;
-
- entry->pmksa_cache = pmksa_cache;
-
- dl_list_add(&wpa_s->mesh_external_pmksa_cache, &entry->list);
-
- return 0;
-}
-
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
-
-int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_data *hapd;
-
- if (!wpa_s->ap_iface)
- return -1;
- hapd = wpa_s->ap_iface->bss[0];
-
- wpabuf_free(hapd->conf->assocresp_elements);
- hapd->conf->assocresp_elements = NULL;
- if (wpa_s->conf->ap_assocresp_elements) {
- hapd->conf->assocresp_elements =
- wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
- }
-
- wpabuf_free(hapd->conf->vendor_elements);
- hapd->conf->vendor_elements = NULL;
- if (wpa_s->conf->ap_vendor_elements) {
- hapd->conf->vendor_elements =
- wpabuf_dup(wpa_s->conf->ap_vendor_elements);
- }
-
- return ieee802_11_set_beacon(hapd);
-}
-
-#endif /* CONFIG_CTRL_IFACE */
-
-
-#ifdef NEED_AP_MLME
-void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface || !iface->bss[0])
- return;
- wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
- hostapd_dfs_radar_detected(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width,
- radar->cf1, radar->cf2);
-}
-
-
-void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface || !iface->bss[0])
- return;
- wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
- hostapd_dfs_start_cac(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
-}
-
-
-void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface || !iface->bss[0])
- return;
- wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
- hostapd_dfs_complete_cac(iface, 1, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
-}
-
-
-void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface || !iface->bss[0])
- return;
- wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
- hostapd_dfs_complete_cac(iface, 0, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
-}
-
-
-void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
- struct hostapd_iface *iface = wpa_s->ap_iface;
-
- if (!iface)
- iface = wpa_s->ifmsh;
- if (!iface || !iface->bss[0])
- return;
- wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
- hostapd_dfs_nop_finished(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
-}
-#endif /* NEED_AP_MLME */
-
-
-void ap_periodic(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->ap_iface)
- hostapd_periodic_iface(wpa_s->ap_iface);
-}
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
deleted file mode 100644
index 7bc1b781e3ac..000000000000
--- a/wpa_supplicant/ap.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * WPA Supplicant - Basic AP mode support routines
- * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2009, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef AP_H
-#define AP_H
-
-int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
- const u8 *src_addr, const u8 *buf, size_t len);
-int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *p2p_dev_addr);
-int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, char *buf, size_t buflen,
- int timeout);
-int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s);
-void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s);
-const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout);
-const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s);
-int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
- int timeout);
-int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen);
-int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
- char *buf, size_t buflen);
-int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
- char *buf, size_t buflen);
-int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
- const char *txtaddr);
-int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
- const char *txtaddr);
-int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
- size_t buflen, int verbose);
-void ap_tx_status(void *ctx, const u8 *addr,
- const u8 *buf, size_t len, int ack);
-void ap_eapol_tx_status(void *ctx, const u8 *dst,
- const u8 *data, size_t len, int ack);
-void ap_client_poll_ok(void *ctx, const u8 *addr);
-void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds);
-void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt);
-void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok);
-int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
- const u8 *addr);
-void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s);
-int ap_switch_channel(struct wpa_supplicant *wpa_s,
- struct csa_settings *settings);
-int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *txtaddr);
-void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- int offset, int width, int cf1, int cf2, int finished);
-struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef);
-#ifdef CONFIG_AP
-struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef);
-#else /* CONFIG_AP */
-static inline struct wpabuf *
-wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef)
-{
- return NULL;
-}
-#endif /* CONFIG_AP */
-
-int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel);
-int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
- const struct wpabuf *pw, const u8 *pubkey_hash);
-
-struct hostapd_config;
-int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_config *conf);
-
-int wpas_ap_stop_ap(struct wpa_supplicant *wpa_s);
-
-int wpas_ap_pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf,
- size_t len);
-void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
-int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
- char *buf, size_t len);
-int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd);
-int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s);
-
-void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar);
-void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar);
-void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar);
-void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar);
-void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar);
-
-void ap_periodic(struct wpa_supplicant *wpa_s);
-
-#endif /* AP_H */
diff --git a/wpa_supplicant/autoscan.c b/wpa_supplicant/autoscan.c
deleted file mode 100644
index 5056a9300a87..000000000000
--- a/wpa_supplicant/autoscan.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * WPA Supplicant - auto scan
- * Copyright (c) 2012, Intel Corporation. All rights reserved.
- * Copyright 2015 Intel Deutschland GmbH
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "bss.h"
-#include "scan.h"
-#include "autoscan.h"
-
-
-static const struct autoscan_ops * autoscan_modules[] = {
-#ifdef CONFIG_AUTOSCAN_EXPONENTIAL
- &autoscan_exponential_ops,
-#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
-#ifdef CONFIG_AUTOSCAN_PERIODIC
- &autoscan_periodic_ops,
-#endif /* CONFIG_AUTOSCAN_PERIODIC */
- NULL
-};
-
-
-static void request_scan(struct wpa_supplicant *wpa_s)
-{
- wpa_s->scan_req = MANUAL_SCAN_REQ;
-
- if (wpa_supplicant_req_sched_scan(wpa_s))
- wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0);
-}
-
-
-int autoscan_init(struct wpa_supplicant *wpa_s, int req_scan)
-{
- const char *name = wpa_s->conf->autoscan;
- const char *params;
- size_t nlen;
- int i;
- const struct autoscan_ops *ops = NULL;
- struct sched_scan_plan *scan_plans;
-
- /* Give preference to scheduled scan plans if supported/configured */
- if (wpa_s->sched_scan_plans) {
- wpa_printf(MSG_DEBUG,
- "autoscan: sched_scan_plans set - use it instead");
- return 0;
- }
-
- if (wpa_s->autoscan && wpa_s->autoscan_priv) {
- wpa_printf(MSG_DEBUG, "autoscan: Already initialized");
- return 0;
- }
-
- if (name == NULL)
- return 0;
-
- params = os_strchr(name, ':');
- if (params == NULL) {
- params = "";
- nlen = os_strlen(name);
- } else {
- nlen = params - name;
- params++;
- }
-
- for (i = 0; autoscan_modules[i]; i++) {
- if (os_strncmp(name, autoscan_modules[i]->name, nlen) == 0) {
- ops = autoscan_modules[i];
- break;
- }
- }
-
- if (ops == NULL) {
- wpa_printf(MSG_ERROR, "autoscan: Could not find module "
- "matching the parameter '%s'", name);
- return -1;
- }
-
- scan_plans = os_malloc(sizeof(*wpa_s->sched_scan_plans));
- if (!scan_plans)
- return -1;
-
- wpa_s->autoscan_params = NULL;
-
- wpa_s->autoscan_priv = ops->init(wpa_s, params);
- if (!wpa_s->autoscan_priv) {
- os_free(scan_plans);
- return -1;
- }
-
- scan_plans[0].interval = 5;
- scan_plans[0].iterations = 0;
- os_free(wpa_s->sched_scan_plans);
- wpa_s->sched_scan_plans = scan_plans;
- wpa_s->sched_scan_plans_num = 1;
- wpa_s->autoscan = ops;
-
- wpa_printf(MSG_DEBUG, "autoscan: Initialized module '%s' with "
- "parameters '%s'", ops->name, params);
- if (!req_scan)
- return 0;
-
- /*
- * Cancelling existing scan requests, if any.
- */
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
-
- /*
- * Firing first scan, which will lead to call autoscan_notify_scan.
- */
- request_scan(wpa_s);
-
- return 0;
-}
-
-
-void autoscan_deinit(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->autoscan && wpa_s->autoscan_priv) {
- wpa_printf(MSG_DEBUG, "autoscan: Deinitializing module '%s'",
- wpa_s->autoscan->name);
- wpa_s->autoscan->deinit(wpa_s->autoscan_priv);
- wpa_s->autoscan = NULL;
- wpa_s->autoscan_priv = NULL;
-
- wpa_s->scan_interval = 5;
-
- os_free(wpa_s->sched_scan_plans);
- wpa_s->sched_scan_plans = NULL;
- wpa_s->sched_scan_plans_num = 0;
- }
-}
-
-
-int autoscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- int interval;
-
- if (wpa_s->autoscan && wpa_s->autoscan_priv) {
- interval = wpa_s->autoscan->notify_scan(wpa_s->autoscan_priv,
- scan_res);
-
- if (interval <= 0)
- return -1;
-
- wpa_s->scan_interval = interval;
- wpa_s->sched_scan_plans[0].interval = interval;
-
- request_scan(wpa_s);
- }
-
- return 0;
-}
diff --git a/wpa_supplicant/autoscan.h b/wpa_supplicant/autoscan.h
deleted file mode 100644
index 560684fcbf77..000000000000
--- a/wpa_supplicant/autoscan.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * WPA Supplicant - auto scan
- * Copyright (c) 2012, Intel Corporation. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef AUTOSCAN_H
-#define AUTOSCAN_H
-
-struct wpa_supplicant;
-
-struct autoscan_ops {
- const char *name;
-
- void * (*init)(struct wpa_supplicant *wpa_s, const char *params);
- void (*deinit)(void *priv);
-
- int (*notify_scan)(void *priv, struct wpa_scan_results *scan_res);
-};
-
-#ifdef CONFIG_AUTOSCAN
-
-int autoscan_init(struct wpa_supplicant *wpa_s, int req_scan);
-void autoscan_deinit(struct wpa_supplicant *wpa_s);
-int autoscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
-
-/* Available autoscan modules */
-
-#ifdef CONFIG_AUTOSCAN_EXPONENTIAL
-extern const struct autoscan_ops autoscan_exponential_ops;
-#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
-
-#ifdef CONFIG_AUTOSCAN_PERIODIC
-extern const struct autoscan_ops autoscan_periodic_ops;
-#endif /* CONFIG_AUTOSCAN_PERIODIC */
-
-#else /* CONFIG_AUTOSCAN */
-
-static inline int autoscan_init(struct wpa_supplicant *wpa_s, int req_scan)
-{
- return 0;
-}
-
-static inline void autoscan_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int autoscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- return 0;
-}
-
-#endif /* CONFIG_AUTOSCAN */
-
-#endif /* AUTOSCAN_H */
diff --git a/wpa_supplicant/autoscan_exponential.c b/wpa_supplicant/autoscan_exponential.c
deleted file mode 100644
index 424477be8d43..000000000000
--- a/wpa_supplicant/autoscan_exponential.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * WPA Supplicant - auto scan exponential module
- * Copyright (c) 2012, Intel Corporation. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "autoscan.h"
-
-struct autoscan_exponential_data {
- struct wpa_supplicant *wpa_s;
- int base;
- int limit;
- int interval;
-};
-
-
-static int
-autoscan_exponential_get_params(struct autoscan_exponential_data *data,
- const char *params)
-{
- const char *pos;
-
- if (params == NULL)
- return -1;
-
- data->base = atoi(params);
-
- pos = os_strchr(params, ':');
- if (pos == NULL)
- return -1;
-
- pos++;
- data->limit = atoi(pos);
-
- return 0;
-}
-
-
-static void * autoscan_exponential_init(struct wpa_supplicant *wpa_s,
- const char *params)
-{
- struct autoscan_exponential_data *data;
-
- data = os_zalloc(sizeof(struct autoscan_exponential_data));
- if (data == NULL)
- return NULL;
-
- if (autoscan_exponential_get_params(data, params) < 0) {
- os_free(data);
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "autoscan exponential: base exponential is %d "
- "and limit is %d", data->base, data->limit);
-
- data->wpa_s = wpa_s;
-
- return data;
-}
-
-
-static void autoscan_exponential_deinit(void *priv)
-{
- struct autoscan_exponential_data *data = priv;
-
- os_free(data);
-}
-
-
-static int autoscan_exponential_notify_scan(void *priv,
- struct wpa_scan_results *scan_res)
-{
- struct autoscan_exponential_data *data = priv;
-
- wpa_printf(MSG_DEBUG, "autoscan exponential: scan result "
- "notification");
-
- if (data->interval >= data->limit)
- return data->limit;
-
- if (data->interval <= 0)
- data->interval = data->base;
- else {
- data->interval = data->interval * data->base;
- if (data->interval > data->limit)
- return data->limit;
- }
-
- return data->interval;
-}
-
-
-const struct autoscan_ops autoscan_exponential_ops = {
- .name = "exponential",
- .init = autoscan_exponential_init,
- .deinit = autoscan_exponential_deinit,
- .notify_scan = autoscan_exponential_notify_scan,
-};
diff --git a/wpa_supplicant/autoscan_periodic.c b/wpa_supplicant/autoscan_periodic.c
deleted file mode 100644
index 102d7234d35d..000000000000
--- a/wpa_supplicant/autoscan_periodic.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * WPA Supplicant - auto scan periodic module
- * Copyright (c) 2012, Intel Corporation. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "autoscan.h"
-
-
-struct autoscan_periodic_data {
- int periodic_interval;
-};
-
-
-static int autoscan_periodic_get_params(struct autoscan_periodic_data *data,
- const char *params)
-{
- int interval;
-
- if (params == NULL)
- return -1;
-
- interval = atoi(params);
-
- if (interval < 0)
- return -1;
-
- data->periodic_interval = interval;
-
- return 0;
-}
-
-
-static void * autoscan_periodic_init(struct wpa_supplicant *wpa_s,
- const char *params)
-{
- struct autoscan_periodic_data *data;
-
- data = os_zalloc(sizeof(struct autoscan_periodic_data));
- if (data == NULL)
- return NULL;
-
- if (autoscan_periodic_get_params(data, params) < 0) {
- os_free(data);
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "autoscan periodic: interval is %d",
- data->periodic_interval);
-
- return data;
-}
-
-
-static void autoscan_periodic_deinit(void *priv)
-{
- struct autoscan_periodic_data *data = priv;
-
- os_free(data);
-}
-
-
-static int autoscan_periodic_notify_scan(void *priv,
- struct wpa_scan_results *scan_res)
-{
- struct autoscan_periodic_data *data = priv;
-
- wpa_printf(MSG_DEBUG, "autoscan periodic: scan result notification");
-
- return data->periodic_interval;
-}
-
-
-const struct autoscan_ops autoscan_periodic_ops = {
- .name = "periodic",
- .init = autoscan_periodic_init,
- .deinit = autoscan_periodic_deinit,
- .notify_scan = autoscan_periodic_notify_scan,
-};
diff --git a/wpa_supplicant/bgscan.c b/wpa_supplicant/bgscan.c
deleted file mode 100644
index 1ea640114c8e..000000000000
--- a/wpa_supplicant/bgscan.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * WPA Supplicant - background scan and roaming interface
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "config_ssid.h"
-#include "bgscan.h"
-
-
-static const struct bgscan_ops * bgscan_modules[] = {
-#ifdef CONFIG_BGSCAN_SIMPLE
- &bgscan_simple_ops,
-#endif /* CONFIG_BGSCAN_SIMPLE */
-#ifdef CONFIG_BGSCAN_LEARN
- &bgscan_learn_ops,
-#endif /* CONFIG_BGSCAN_LEARN */
- NULL
-};
-
-
-int bgscan_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const char *name)
-{
- const char *params;
- size_t nlen;
- int i;
- const struct bgscan_ops *ops = NULL;
-
- bgscan_deinit(wpa_s);
-
- params = os_strchr(name, ':');
- if (params == NULL) {
- params = "";
- nlen = os_strlen(name);
- } else {
- nlen = params - name;
- params++;
- }
-
- for (i = 0; bgscan_modules[i]; i++) {
- if (os_strncmp(name, bgscan_modules[i]->name, nlen) == 0) {
- ops = bgscan_modules[i];
- break;
- }
- }
-
- if (ops == NULL) {
- wpa_printf(MSG_ERROR, "bgscan: Could not find module "
- "matching the parameter '%s'", name);
- return -1;
- }
-
- wpa_s->bgscan_priv = ops->init(wpa_s, params, ssid);
- if (wpa_s->bgscan_priv == NULL)
- return -1;
- wpa_s->bgscan = ops;
- wpa_printf(MSG_DEBUG, "bgscan: Initialized module '%s' with "
- "parameters '%s'", ops->name, params);
-
- return 0;
-}
-
-
-void bgscan_deinit(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->bgscan && wpa_s->bgscan_priv) {
- wpa_printf(MSG_DEBUG, "bgscan: Deinitializing module '%s'",
- wpa_s->bgscan->name);
- wpa_s->bgscan->deinit(wpa_s->bgscan_priv);
- wpa_s->bgscan = NULL;
- wpa_s->bgscan_priv = NULL;
- }
-}
-
-
-int bgscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- if (wpa_s->bgscan && wpa_s->bgscan_priv)
- return wpa_s->bgscan->notify_scan(wpa_s->bgscan_priv,
- scan_res);
- return 0;
-}
-
-
-void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->bgscan && wpa_s->bgscan_priv)
- wpa_s->bgscan->notify_beacon_loss(wpa_s->bgscan_priv);
-}
-
-
-void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
- int current_signal, int current_noise,
- int current_txrate)
-{
- if (wpa_s->bgscan && wpa_s->bgscan_priv)
- wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above,
- current_signal,
- current_noise,
- current_txrate);
-}
diff --git a/wpa_supplicant/bgscan.h b/wpa_supplicant/bgscan.h
deleted file mode 100644
index 3df1550a97dd..000000000000
--- a/wpa_supplicant/bgscan.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * WPA Supplicant - background scan and roaming interface
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef BGSCAN_H
-#define BGSCAN_H
-
-struct wpa_supplicant;
-struct wpa_ssid;
-
-struct bgscan_ops {
- const char *name;
-
- void * (*init)(struct wpa_supplicant *wpa_s, const char *params,
- const struct wpa_ssid *ssid);
- void (*deinit)(void *priv);
-
- int (*notify_scan)(void *priv, struct wpa_scan_results *scan_res);
- void (*notify_beacon_loss)(void *priv);
- void (*notify_signal_change)(void *priv, int above,
- int current_signal,
- int current_noise,
- int current_txrate);
-};
-
-#ifdef CONFIG_BGSCAN
-
-int bgscan_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const char *name);
-void bgscan_deinit(struct wpa_supplicant *wpa_s);
-int bgscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
-void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s);
-void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
- int current_signal, int current_noise,
- int current_txrate);
-
-/* Available bgscan modules */
-
-#ifdef CONFIG_BGSCAN_SIMPLE
-extern const struct bgscan_ops bgscan_simple_ops;
-#endif /* CONFIG_BGSCAN_SIMPLE */
-#ifdef CONFIG_BGSCAN_LEARN
-extern const struct bgscan_ops bgscan_learn_ops;
-#endif /* CONFIG_BGSCAN_LEARN */
-
-#else /* CONFIG_BGSCAN */
-
-static inline int bgscan_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, const char name)
-{
- return 0;
-}
-
-static inline void bgscan_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int bgscan_notify_scan(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- return 0;
-}
-
-static inline void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s,
- int above, int current_signal,
- int current_noise,
- int current_txrate)
-{
-}
-
-#endif /* CONFIG_BGSCAN */
-
-#endif /* BGSCAN_H */
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
deleted file mode 100644
index cb732f709b9e..000000000000
--- a/wpa_supplicant/bgscan_learn.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * WPA Supplicant - background scan and roaming module: learn
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "list.h"
-#include "common/ieee802_11_defs.h"
-#include "drivers/driver.h"
-#include "config_ssid.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "scan.h"
-#include "bgscan.h"
-
-struct bgscan_learn_bss {
- struct dl_list list;
- u8 bssid[ETH_ALEN];
- int freq;
- u8 *neigh; /* num_neigh * ETH_ALEN buffer */
- size_t num_neigh;
-};
-
-struct bgscan_learn_data {
- struct wpa_supplicant *wpa_s;
- const struct wpa_ssid *ssid;
- int scan_interval;
- int signal_threshold;
- int short_interval; /* use if signal < threshold */
- int long_interval; /* use if signal > threshold */
- struct os_reltime last_bgscan;
- char *fname;
- struct dl_list bss;
- int *supp_freqs;
- int probe_idx;
-};
-
-
-static void bss_free(struct bgscan_learn_bss *bss)
-{
- os_free(bss->neigh);
- os_free(bss);
-}
-
-
-static int bssid_in_array(u8 *array, size_t array_len, const u8 *bssid)
-{
- size_t i;
-
- if (array == NULL || array_len == 0)
- return 0;
-
- for (i = 0; i < array_len; i++) {
- if (os_memcmp(array + i * ETH_ALEN, bssid, ETH_ALEN) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static void bgscan_learn_add_neighbor(struct bgscan_learn_bss *bss,
- const u8 *bssid)
-{
- u8 *n;
-
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
- return;
- if (bssid_in_array(bss->neigh, bss->num_neigh, bssid))
- return;
-
- n = os_realloc_array(bss->neigh, bss->num_neigh + 1, ETH_ALEN);
- if (n == NULL)
- return;
-
- os_memcpy(n + bss->num_neigh * ETH_ALEN, bssid, ETH_ALEN);
- bss->neigh = n;
- bss->num_neigh++;
-}
-
-
-static struct bgscan_learn_bss * bgscan_learn_get_bss(
- struct bgscan_learn_data *data, const u8 *bssid)
-{
- struct bgscan_learn_bss *bss;
-
- dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
- return bss;
- }
- return NULL;
-}
-
-
-static int bgscan_learn_load(struct bgscan_learn_data *data)
-{
- FILE *f;
- char buf[128];
- struct bgscan_learn_bss *bss;
-
- if (data->fname == NULL)
- return 0;
-
- f = fopen(data->fname, "r");
- if (f == NULL)
- return 0;
-
- wpa_printf(MSG_DEBUG, "bgscan learn: Loading data from %s",
- data->fname);
-
- if (fgets(buf, sizeof(buf), f) == NULL ||
- os_strncmp(buf, "wpa_supplicant-bgscan-learn\n", 28) != 0) {
- wpa_printf(MSG_INFO, "bgscan learn: Invalid data file %s",
- data->fname);
- fclose(f);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- if (os_strncmp(buf, "BSS ", 4) == 0) {
- bss = os_zalloc(sizeof(*bss));
- if (!bss)
- continue;
- if (hwaddr_aton(buf + 4, bss->bssid) < 0) {
- bss_free(bss);
- continue;
- }
- bss->freq = atoi(buf + 4 + 18);
- dl_list_add(&data->bss, &bss->list);
- wpa_printf(MSG_DEBUG, "bgscan learn: Loaded BSS "
- "entry: " MACSTR " freq=%d",
- MAC2STR(bss->bssid), bss->freq);
- }
-
- if (os_strncmp(buf, "NEIGHBOR ", 9) == 0) {
- u8 addr[ETH_ALEN];
-
- if (hwaddr_aton(buf + 9, addr) < 0)
- continue;
- bss = bgscan_learn_get_bss(data, addr);
- if (bss == NULL)
- continue;
- if (hwaddr_aton(buf + 9 + 18, addr) < 0)
- continue;
-
- bgscan_learn_add_neighbor(bss, addr);
- }
- }
-
- fclose(f);
- return 0;
-}
-
-
-static void bgscan_learn_save(struct bgscan_learn_data *data)
-{
- FILE *f;
- struct bgscan_learn_bss *bss;
-
- if (data->fname == NULL)
- return;
-
- wpa_printf(MSG_DEBUG, "bgscan learn: Saving data to %s",
- data->fname);
-
- f = fopen(data->fname, "w");
- if (f == NULL)
- return;
- fprintf(f, "wpa_supplicant-bgscan-learn\n");
-
- dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) {
- fprintf(f, "BSS " MACSTR " %d\n",
- MAC2STR(bss->bssid), bss->freq);
- }
-
- dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) {
- size_t i;
- for (i = 0; i < bss->num_neigh; i++) {
- fprintf(f, "NEIGHBOR " MACSTR " " MACSTR "\n",
- MAC2STR(bss->bssid),
- MAC2STR(bss->neigh + i * ETH_ALEN));
- }
- }
-
- fclose(f);
-}
-
-
-static int in_array(int *array, int val)
-{
- int i;
-
- if (array == NULL)
- return 0;
-
- for (i = 0; array[i]; i++) {
- if (array[i] == val)
- return 1;
- }
-
- return 0;
-}
-
-
-static int * bgscan_learn_get_freqs(struct bgscan_learn_data *data,
- size_t *count)
-{
- struct bgscan_learn_bss *bss;
- int *freqs = NULL, *n;
-
- *count = 0;
-
- dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) {
- if (in_array(freqs, bss->freq))
- continue;
- n = os_realloc_array(freqs, *count + 2, sizeof(int));
- if (n == NULL)
- return freqs;
- freqs = n;
- freqs[*count] = bss->freq;
- (*count)++;
- freqs[*count] = 0;
- }
-
- return freqs;
-}
-
-
-static int * bgscan_learn_get_probe_freq(struct bgscan_learn_data *data,
- int *freqs, size_t count)
-{
- int idx, *n;
-
- if (data->supp_freqs == NULL)
- return freqs;
-
- idx = data->probe_idx;
- do {
- if (!in_array(freqs, data->supp_freqs[idx])) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Probe new freq "
- "%u", data->supp_freqs[idx]);
- data->probe_idx = idx + 1;
- if (data->supp_freqs[data->probe_idx] == 0)
- data->probe_idx = 0;
- n = os_realloc_array(freqs, count + 2, sizeof(int));
- if (n == NULL)
- return freqs;
- freqs = n;
- freqs[count] = data->supp_freqs[idx];
- count++;
- freqs[count] = 0;
- break;
- }
-
- idx++;
- if (data->supp_freqs[idx] == 0)
- idx = 0;
- } while (idx != data->probe_idx);
-
- return freqs;
-}
-
-
-static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct bgscan_learn_data *data = eloop_ctx;
- struct wpa_supplicant *wpa_s = data->wpa_s;
- struct wpa_driver_scan_params params;
- int *freqs = NULL;
- size_t count, i;
- char msg[100], *pos;
-
- os_memset(&params, 0, sizeof(params));
- params.num_ssids = 1;
- params.ssids[0].ssid = data->ssid->ssid;
- params.ssids[0].ssid_len = data->ssid->ssid_len;
- if (data->ssid->scan_freq)
- params.freqs = data->ssid->scan_freq;
- else {
- freqs = bgscan_learn_get_freqs(data, &count);
- wpa_printf(MSG_DEBUG, "bgscan learn: BSSes in this ESS have "
- "been seen on %u channels", (unsigned int) count);
- freqs = bgscan_learn_get_probe_freq(data, freqs, count);
-
- msg[0] = '\0';
- pos = msg;
- for (i = 0; freqs && freqs[i]; i++) {
- int ret;
- ret = os_snprintf(pos, msg + sizeof(msg) - pos, " %d",
- freqs[i]);
- if (os_snprintf_error(msg + sizeof(msg) - pos, ret))
- break;
- pos += ret;
- }
- pos[0] = '\0';
- wpa_printf(MSG_DEBUG, "bgscan learn: Scanning frequencies:%s",
- msg);
- params.freqs = freqs;
- }
-
- wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan");
- if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan");
- eloop_register_timeout(data->scan_interval, 0,
- bgscan_learn_timeout, data, NULL);
- } else
- os_get_reltime(&data->last_bgscan);
- os_free(freqs);
-}
-
-
-static int bgscan_learn_get_params(struct bgscan_learn_data *data,
- const char *params)
-{
- const char *pos;
-
- data->short_interval = atoi(params);
-
- pos = os_strchr(params, ':');
- if (pos == NULL)
- return 0;
- pos++;
- data->signal_threshold = atoi(pos);
- pos = os_strchr(pos, ':');
- if (pos == NULL) {
- wpa_printf(MSG_ERROR, "bgscan learn: Missing scan interval "
- "for high signal");
- return -1;
- }
- pos++;
- data->long_interval = atoi(pos);
- pos = os_strchr(pos, ':');
- if (pos) {
- pos++;
- data->fname = os_strdup(pos);
- }
-
- return 0;
-}
-
-
-static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_hw_modes *modes;
- int i, j, *freqs = NULL, *n;
- size_t count = 0;
-
- modes = wpa_s->hw.modes;
- if (modes == NULL)
- return NULL;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- for (j = 0; j < modes[i].num_channels; j++) {
- if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- /* some hw modes (e.g. 11b & 11g) contain same freqs */
- if (in_array(freqs, modes[i].channels[j].freq))
- continue;
- n = os_realloc_array(freqs, count + 2, sizeof(int));
- if (n == NULL)
- continue;
-
- freqs = n;
- freqs[count] = modes[i].channels[j].freq;
- count++;
- freqs[count] = 0;
- }
- }
-
- return freqs;
-}
-
-
-static void * bgscan_learn_init(struct wpa_supplicant *wpa_s,
- const char *params,
- const struct wpa_ssid *ssid)
-{
- struct bgscan_learn_data *data;
-
- data = os_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- dl_list_init(&data->bss);
- data->wpa_s = wpa_s;
- data->ssid = ssid;
- if (bgscan_learn_get_params(data, params) < 0) {
- os_free(data->fname);
- os_free(data);
- return NULL;
- }
- if (data->short_interval <= 0)
- data->short_interval = 30;
- if (data->long_interval <= 0)
- data->long_interval = 30;
-
- if (bgscan_learn_load(data) < 0) {
- os_free(data->fname);
- os_free(data);
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "bgscan learn: Signal strength threshold %d "
- "Short bgscan interval %d Long bgscan interval %d",
- data->signal_threshold, data->short_interval,
- data->long_interval);
-
- if (data->signal_threshold &&
- wpa_drv_signal_monitor(wpa_s, data->signal_threshold, 4) < 0) {
- wpa_printf(MSG_ERROR, "bgscan learn: Failed to enable "
- "signal strength monitoring");
- }
-
- data->supp_freqs = bgscan_learn_get_supp_freqs(wpa_s);
- data->scan_interval = data->short_interval;
- if (data->signal_threshold) {
- /* Poll for signal info to set initial scan interval */
- struct wpa_signal_info siginfo;
- if (wpa_drv_signal_poll(wpa_s, &siginfo) == 0 &&
- siginfo.current_signal >= data->signal_threshold)
- data->scan_interval = data->long_interval;
- }
-
- eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout,
- data, NULL);
-
- /*
- * This function is called immediately after an association, so it is
- * reasonable to assume that a scan was completed recently. This makes
- * us skip an immediate new scan in cases where the current signal
- * level is below the bgscan threshold.
- */
- os_get_reltime(&data->last_bgscan);
-
- return data;
-}
-
-
-static void bgscan_learn_deinit(void *priv)
-{
- struct bgscan_learn_data *data = priv;
- struct bgscan_learn_bss *bss, *n;
-
- bgscan_learn_save(data);
- eloop_cancel_timeout(bgscan_learn_timeout, data, NULL);
- if (data->signal_threshold)
- wpa_drv_signal_monitor(data->wpa_s, 0, 0);
- os_free(data->fname);
- dl_list_for_each_safe(bss, n, &data->bss, struct bgscan_learn_bss,
- list) {
- dl_list_del(&bss->list);
- bss_free(bss);
- }
- os_free(data->supp_freqs);
- os_free(data);
-}
-
-
-static int bgscan_learn_bss_match(struct bgscan_learn_data *data,
- struct wpa_scan_res *bss)
-{
- const u8 *ie;
-
- ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
- if (ie == NULL)
- return 0;
-
- if (data->ssid->ssid_len != ie[1] ||
- os_memcmp(data->ssid->ssid, ie + 2, ie[1]) != 0)
- return 0; /* SSID mismatch */
-
- return 1;
-}
-
-
-static int bgscan_learn_notify_scan(void *priv,
- struct wpa_scan_results *scan_res)
-{
- struct bgscan_learn_data *data = priv;
- size_t i, j;
-#define MAX_BSS 50
- u8 bssid[MAX_BSS * ETH_ALEN];
- size_t num_bssid = 0;
-
- wpa_printf(MSG_DEBUG, "bgscan learn: scan result notification");
-
- eloop_cancel_timeout(bgscan_learn_timeout, data, NULL);
- eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout,
- data, NULL);
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *res = scan_res->res[i];
- if (!bgscan_learn_bss_match(data, res))
- continue;
-
- if (num_bssid < MAX_BSS) {
- os_memcpy(bssid + num_bssid * ETH_ALEN, res->bssid,
- ETH_ALEN);
- num_bssid++;
- }
- }
- wpa_printf(MSG_DEBUG, "bgscan learn: %u matching BSSes in scan "
- "results", (unsigned int) num_bssid);
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *res = scan_res->res[i];
- struct bgscan_learn_bss *bss;
-
- if (!bgscan_learn_bss_match(data, res))
- continue;
-
- bss = bgscan_learn_get_bss(data, res->bssid);
- if (bss && bss->freq != res->freq) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Update BSS "
- MACSTR " freq %d -> %d",
- MAC2STR(res->bssid), bss->freq, res->freq);
- bss->freq = res->freq;
- } else if (!bss) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Add BSS " MACSTR
- " freq=%d", MAC2STR(res->bssid), res->freq);
- bss = os_zalloc(sizeof(*bss));
- if (!bss)
- continue;
- os_memcpy(bss->bssid, res->bssid, ETH_ALEN);
- bss->freq = res->freq;
- dl_list_add(&data->bss, &bss->list);
- }
-
- for (j = 0; j < num_bssid; j++) {
- u8 *addr = bssid + j * ETH_ALEN;
- bgscan_learn_add_neighbor(bss, addr);
- }
- }
-
- /*
- * A more advanced bgscan could process scan results internally, select
- * the BSS and request roam if needed. This sample uses the existing
- * BSS/ESS selection routine. Change this to return 1 if selection is
- * done inside the bgscan module.
- */
-
- return 0;
-}
-
-
-static void bgscan_learn_notify_beacon_loss(void *priv)
-{
- wpa_printf(MSG_DEBUG, "bgscan learn: beacon loss");
- /* TODO: speed up background scanning */
-}
-
-
-static void bgscan_learn_notify_signal_change(void *priv, int above,
- int current_signal,
- int current_noise,
- int current_txrate)
-{
- struct bgscan_learn_data *data = priv;
- int scan = 0;
- struct os_reltime now;
-
- if (data->short_interval == data->long_interval ||
- data->signal_threshold == 0)
- return;
-
- wpa_printf(MSG_DEBUG, "bgscan learn: signal level changed "
- "(above=%d current_signal=%d current_noise=%d "
- "current_txrate=%d)", above, current_signal,
- current_noise, current_txrate);
- if (data->scan_interval == data->long_interval && !above) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Start using short bgscan "
- "interval");
- data->scan_interval = data->short_interval;
- os_get_reltime(&now);
- if (now.sec > data->last_bgscan.sec + 1)
- scan = 1;
- } else if (data->scan_interval == data->short_interval && above) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Start using long bgscan "
- "interval");
- data->scan_interval = data->long_interval;
- eloop_cancel_timeout(bgscan_learn_timeout, data, NULL);
- eloop_register_timeout(data->scan_interval, 0,
- bgscan_learn_timeout, data, NULL);
- } else if (!above) {
- /*
- * Signal dropped further 4 dB. Request a new scan if we have
- * not yet scanned in a while.
- */
- os_get_reltime(&now);
- if (now.sec > data->last_bgscan.sec + 10)
- scan = 1;
- }
-
- if (scan) {
- wpa_printf(MSG_DEBUG, "bgscan learn: Trigger immediate scan");
- eloop_cancel_timeout(bgscan_learn_timeout, data, NULL);
- eloop_register_timeout(0, 0, bgscan_learn_timeout, data, NULL);
- }
-}
-
-
-const struct bgscan_ops bgscan_learn_ops = {
- .name = "learn",
- .init = bgscan_learn_init,
- .deinit = bgscan_learn_deinit,
- .notify_scan = bgscan_learn_notify_scan,
- .notify_beacon_loss = bgscan_learn_notify_beacon_loss,
- .notify_signal_change = bgscan_learn_notify_signal_change,
-};
diff --git a/wpa_supplicant/bgscan_simple.c b/wpa_supplicant/bgscan_simple.c
deleted file mode 100644
index 41a26df0d635..000000000000
--- a/wpa_supplicant/bgscan_simple.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * WPA Supplicant - background scan and roaming module: simple
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "drivers/driver.h"
-#include "config_ssid.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "scan.h"
-#include "bgscan.h"
-
-struct bgscan_simple_data {
- struct wpa_supplicant *wpa_s;
- const struct wpa_ssid *ssid;
- int scan_interval;
- int signal_threshold;
- int short_scan_count; /* counter for scans using short scan interval */
- int max_short_scans; /* maximum times we short-scan before back-off */
- int short_interval; /* use if signal < threshold */
- int long_interval; /* use if signal > threshold */
- struct os_reltime last_bgscan;
-};
-
-
-static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct bgscan_simple_data *data = eloop_ctx;
- struct wpa_supplicant *wpa_s = data->wpa_s;
- struct wpa_driver_scan_params params;
-
- os_memset(&params, 0, sizeof(params));
- params.num_ssids = 1;
- params.ssids[0].ssid = data->ssid->ssid;
- params.ssids[0].ssid_len = data->ssid->ssid_len;
- params.freqs = data->ssid->scan_freq;
-
- /*
- * A more advanced bgscan module would learn about most like channels
- * over time and request scans only for some channels (probing others
- * every now and then) to reduce effect on the data connection.
- */
-
- wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan");
- if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
- wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan");
- eloop_register_timeout(data->scan_interval, 0,
- bgscan_simple_timeout, data, NULL);
- } else {
- if (data->scan_interval == data->short_interval) {
- data->short_scan_count++;
- if (data->short_scan_count >= data->max_short_scans) {
- data->scan_interval = data->long_interval;
- wpa_printf(MSG_DEBUG, "bgscan simple: Backing "
- "off to long scan interval");
- }
- } else if (data->short_scan_count > 0) {
- /*
- * If we lasted a long scan interval without any
- * CQM triggers, decrease the short-scan count,
- * which allows 1 more short-scan interval to
- * occur in the future when CQM triggers.
- */
- data->short_scan_count--;
- }
- os_get_reltime(&data->last_bgscan);
- }
-}
-
-
-static int bgscan_simple_get_params(struct bgscan_simple_data *data,
- const char *params)
-{
- const char *pos;
-
- data->short_interval = atoi(params);
-
- pos = os_strchr(params, ':');
- if (pos == NULL)
- return 0;
- pos++;
- data->signal_threshold = atoi(pos);
- pos = os_strchr(pos, ':');
- if (pos == NULL) {
- wpa_printf(MSG_ERROR, "bgscan simple: Missing scan interval "
- "for high signal");
- return -1;
- }
- pos++;
- data->long_interval = atoi(pos);
-
- return 0;
-}
-
-
-static void * bgscan_simple_init(struct wpa_supplicant *wpa_s,
- const char *params,
- const struct wpa_ssid *ssid)
-{
- struct bgscan_simple_data *data;
-
- data = os_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- data->wpa_s = wpa_s;
- data->ssid = ssid;
- if (bgscan_simple_get_params(data, params) < 0) {
- os_free(data);
- return NULL;
- }
- if (data->short_interval <= 0)
- data->short_interval = 30;
- if (data->long_interval <= 0)
- data->long_interval = 30;
-
- wpa_printf(MSG_DEBUG, "bgscan simple: Signal strength threshold %d "
- "Short bgscan interval %d Long bgscan interval %d",
- data->signal_threshold, data->short_interval,
- data->long_interval);
-
- if (data->signal_threshold &&
- wpa_drv_signal_monitor(wpa_s, data->signal_threshold, 4) < 0) {
- wpa_printf(MSG_ERROR, "bgscan simple: Failed to enable "
- "signal strength monitoring");
- }
-
- data->scan_interval = data->short_interval;
- data->max_short_scans = data->long_interval / data->short_interval + 1;
- if (data->signal_threshold) {
- /* Poll for signal info to set initial scan interval */
- struct wpa_signal_info siginfo;
- if (wpa_drv_signal_poll(wpa_s, &siginfo) == 0 &&
- siginfo.current_signal >= data->signal_threshold)
- data->scan_interval = data->long_interval;
- }
- wpa_printf(MSG_DEBUG, "bgscan simple: Init scan interval: %d",
- data->scan_interval);
- eloop_register_timeout(data->scan_interval, 0, bgscan_simple_timeout,
- data, NULL);
-
- /*
- * This function is called immediately after an association, so it is
- * reasonable to assume that a scan was completed recently. This makes
- * us skip an immediate new scan in cases where the current signal
- * level is below the bgscan threshold.
- */
- os_get_reltime(&data->last_bgscan);
-
- return data;
-}
-
-
-static void bgscan_simple_deinit(void *priv)
-{
- struct bgscan_simple_data *data = priv;
- eloop_cancel_timeout(bgscan_simple_timeout, data, NULL);
- if (data->signal_threshold)
- wpa_drv_signal_monitor(data->wpa_s, 0, 0);
- os_free(data);
-}
-
-
-static int bgscan_simple_notify_scan(void *priv,
- struct wpa_scan_results *scan_res)
-{
- struct bgscan_simple_data *data = priv;
-
- wpa_printf(MSG_DEBUG, "bgscan simple: scan result notification");
-
- eloop_cancel_timeout(bgscan_simple_timeout, data, NULL);
- eloop_register_timeout(data->scan_interval, 0, bgscan_simple_timeout,
- data, NULL);
-
- /*
- * A more advanced bgscan could process scan results internally, select
- * the BSS and request roam if needed. This sample uses the existing
- * BSS/ESS selection routine. Change this to return 1 if selection is
- * done inside the bgscan module.
- */
-
- return 0;
-}
-
-
-static void bgscan_simple_notify_beacon_loss(void *priv)
-{
- wpa_printf(MSG_DEBUG, "bgscan simple: beacon loss");
- /* TODO: speed up background scanning */
-}
-
-
-static void bgscan_simple_notify_signal_change(void *priv, int above,
- int current_signal,
- int current_noise,
- int current_txrate)
-{
- struct bgscan_simple_data *data = priv;
- int scan = 0;
- struct os_reltime now;
-
- if (data->short_interval == data->long_interval ||
- data->signal_threshold == 0)
- return;
-
- wpa_printf(MSG_DEBUG, "bgscan simple: signal level changed "
- "(above=%d current_signal=%d current_noise=%d "
- "current_txrate=%d))", above, current_signal,
- current_noise, current_txrate);
- if (data->scan_interval == data->long_interval && !above) {
- wpa_printf(MSG_DEBUG, "bgscan simple: Start using short "
- "bgscan interval");
- data->scan_interval = data->short_interval;
- os_get_reltime(&now);
- if (now.sec > data->last_bgscan.sec + 1 &&
- data->short_scan_count <= data->max_short_scans)
- /*
- * If we haven't just previously (<1 second ago)
- * performed a scan, and we haven't depleted our
- * budget for short-scans, perform a scan
- * immediately.
- */
- scan = 1;
- else if (data->last_bgscan.sec + data->long_interval >
- now.sec + data->scan_interval) {
- /*
- * Restart scan interval timer if currently scheduled
- * scan is too far in the future.
- */
- eloop_cancel_timeout(bgscan_simple_timeout, data,
- NULL);
- eloop_register_timeout(data->scan_interval, 0,
- bgscan_simple_timeout, data,
- NULL);
- }
- } else if (data->scan_interval == data->short_interval && above) {
- wpa_printf(MSG_DEBUG, "bgscan simple: Start using long bgscan "
- "interval");
- data->scan_interval = data->long_interval;
- eloop_cancel_timeout(bgscan_simple_timeout, data, NULL);
- eloop_register_timeout(data->scan_interval, 0,
- bgscan_simple_timeout, data, NULL);
- } else if (!above) {
- /*
- * Signal dropped further 4 dB. Request a new scan if we have
- * not yet scanned in a while.
- */
- os_get_reltime(&now);
- if (now.sec > data->last_bgscan.sec + 10)
- scan = 1;
- }
-
- if (scan) {
- wpa_printf(MSG_DEBUG, "bgscan simple: Trigger immediate scan");
- eloop_cancel_timeout(bgscan_simple_timeout, data, NULL);
- eloop_register_timeout(0, 0, bgscan_simple_timeout, data,
- NULL);
- }
-}
-
-
-const struct bgscan_ops bgscan_simple_ops = {
- .name = "simple",
- .init = bgscan_simple_init,
- .deinit = bgscan_simple_deinit,
- .notify_scan = bgscan_simple_notify_scan,
- .notify_beacon_loss = bgscan_simple_notify_beacon_loss,
- .notify_signal_change = bgscan_simple_notify_signal_change,
-};
diff --git a/wpa_supplicant/binder/.clang-format b/wpa_supplicant/binder/.clang-format
deleted file mode 100644
index dbfdabfc07fd..000000000000
--- a/wpa_supplicant/binder/.clang-format
+++ /dev/null
@@ -1,9 +0,0 @@
-BasedOnStyle: LLVM
-IndentWidth: 8
-UseTab: Always
-BreakBeforeBraces: Mozilla
-AllowShortIfStatementsOnASingleLine: false
-IndentCaseLabels: false
-AccessModifierOffset: -8
-AlignAfterOpenBracket: AlwaysBreak
-SortIncludes: false
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
deleted file mode 100644
index 750e87818b20..000000000000
--- a/wpa_supplicant/binder/binder.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-
-#include "binder_manager.h"
-
-extern "C" {
-#include "binder.h"
-#include "binder_i.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-}
-
-void wpas_binder_sock_handler(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_global *global = (wpa_global *)eloop_ctx;
- struct wpas_binder_priv *priv = (wpas_binder_priv *)sock_ctx;
-
- wpa_printf(
- MSG_DEBUG, "Processing binder events on FD %d", priv->binder_fd);
- android::IPCThreadState::self()->handlePolledCommands();
-}
-
-struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global)
-{
- struct wpas_binder_priv *priv;
- wpa_supplicant_binder::BinderManager *binder_manager;
-
- priv = (wpas_binder_priv *)os_zalloc(sizeof(*priv));
- if (!priv)
- return NULL;
- priv->global = global;
-
- android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
- android::IPCThreadState::self()->disableBackgroundScheduling(true);
- android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
- wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
- if (priv->binder_fd < 0)
- goto err;
- /* Look for read events from the binder socket in the eloop. */
- if (eloop_register_read_sock(
- priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
- goto err;
-
- binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
- if (!binder_manager)
- goto err;
- binder_manager->registerBinderService(global);
- /* We may not need to store this binder manager reference in the
- * global data strucure because we've made it a singleton class. */
- priv->binder_manager = (void *)binder_manager;
-
- return priv;
-
-err:
- wpas_binder_deinit(priv);
- return NULL;
-}
-
-void wpas_binder_deinit(struct wpas_binder_priv *priv)
-{
- if (!priv)
- return;
-
- wpa_supplicant_binder::BinderManager::destroyInstance();
- eloop_unregister_read_sock(priv->binder_fd);
- android::IPCThreadState::shutdown();
-}
-
-int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->global->binder)
- return 1;
-
- wpa_supplicant_binder::BinderManager *binder_manager =
- wpa_supplicant_binder::BinderManager::getInstance();
- if (!binder_manager)
- return 1;
-
- return binder_manager->registerInterface(wpa_s);
-}
-
-int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->global->binder)
- return 1;
-
- wpa_supplicant_binder::BinderManager *binder_manager =
- wpa_supplicant_binder::BinderManager::getInstance();
- if (!binder_manager)
- return 1;
-
- return binder_manager->unregisterInterface(wpa_s);
-}
diff --git a/wpa_supplicant/binder/binder.h b/wpa_supplicant/binder/binder.h
deleted file mode 100644
index 6d7abb134894..000000000000
--- a/wpa_supplicant/binder/binder.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_BINDER_BINDER_H
-#define WPA_SUPPLICANT_BINDER_BINDER_H
-
-#ifdef _cplusplus
-extern "C" {
-#endif /* _cplusplus */
-
-/**
- * This is the binder RPC interface entry point to the wpa_supplicant core.
- * This initializes the binder driver & BinderManager instance and then forwards
- * all the notifications from the supplicant core to the BinderManager.
- */
-struct wpas_binder_priv;
-struct wpa_global;
-
-struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global);
-void wpas_binder_deinit(struct wpas_binder_priv *priv);
-
-#ifdef CONFIG_CTRL_IFACE_BINDER
-int wpas_binder_register_interface(struct wpa_supplicant *wpa_s);
-int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s);
-#else /* CONFIG_CTRL_IFACE_BINDER */
-static inline int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-static inline int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-#endif /* CONFIG_CTRL_IFACE_BINDER */
-
-#ifdef _cplusplus
-}
-#endif /* _cplusplus */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_H */
diff --git a/wpa_supplicant/binder/binder_constants.cpp b/wpa_supplicant/binder/binder_constants.cpp
deleted file mode 100644
index 0d452b11baec..000000000000
--- a/wpa_supplicant/binder/binder_constants.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "binder_constants.h"
-
-namespace wpa_supplicant_binder {
-namespace binder_constants {
-
-const char kServiceName[] = "wpa_supplicant";
-
-} /* namespace binder_constants */
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/binder_constants.h b/wpa_supplicant/binder/binder_constants.h
deleted file mode 100644
index a4d9b558edc0..000000000000
--- a/wpa_supplicant/binder/binder_constants.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H
-#define WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H
-
-namespace wpa_supplicant_binder {
-namespace binder_constants {
-
-extern const char kServiceName[];
-
-} /* namespace binder_constants */
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H */
diff --git a/wpa_supplicant/binder/binder_i.h b/wpa_supplicant/binder/binder_i.h
deleted file mode 100644
index 5140d6d6c01d..000000000000
--- a/wpa_supplicant/binder/binder_i.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef BINDER_I_H
-#define BINDER_I_H
-
-#ifdef _cplusplus
-extern "C" {
-#endif // _cplusplus
-
-struct wpas_binder_priv
-{
- int binder_fd;
- struct wpa_global *global;
- void *binder_manager;
-};
-
-#ifdef _cplusplus
-}
-#endif /* _cplusplus */
-
-#endif /* BINDER_I_H */
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
deleted file mode 100644
index 27e8dedca44a..000000000000
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <binder/IServiceManager.h>
-
-#include "binder_constants.h"
-#include "binder_manager.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-}
-
-namespace wpa_supplicant_binder {
-
-BinderManager *BinderManager::instance_ = NULL;
-
-BinderManager *BinderManager::getInstance()
-{
- if (!instance_)
- instance_ = new BinderManager();
- return instance_;
-}
-
-void BinderManager::destroyInstance()
-{
- if (instance_)
- delete instance_;
- instance_ = NULL;
-}
-
-int BinderManager::registerBinderService(struct wpa_global *global)
-{
- /* Create the main binder service object and register with
- * system service manager. */
- supplicant_object_ = new Supplicant(global);
- android::String16 service_name(binder_constants::kServiceName);
- android::defaultServiceManager()->addService(
- service_name, android::IInterface::asBinder(supplicant_object_));
- return 0;
-}
-
-int BinderManager::registerInterface(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s)
- return 1;
-
- /* Using the corresponding wpa_supplicant pointer as key to our
- * object map. */
- const void *iface_key = wpa_s;
-
- /* Return failure if we already have an object for that iface_key. */
- if (iface_object_map_.find(iface_key) != iface_object_map_.end())
- return 1;
-
- iface_object_map_[iface_key] = new Iface(wpa_s);
- if (!iface_object_map_[iface_key].get())
- return 1;
-
- wpa_s->binder_object_key = iface_key;
-
- return 0;
-}
-
-int BinderManager::unregisterInterface(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s || !wpa_s->binder_object_key)
- return 1;
-
- const void *iface_key = wpa_s;
- if (iface_object_map_.find(iface_key) == iface_object_map_.end())
- return 1;
-
- /* Delete the corresponding iface object from our map. */
- iface_object_map_.erase(iface_key);
- wpa_s->binder_object_key = NULL;
- return 0;
-}
-
-int BinderManager::getIfaceBinderObjectByKey(
- const void *iface_object_key,
- android::sp<fi::w1::wpa_supplicant::IIface> *iface_object)
-{
- if (!iface_object_key || !iface_object)
- return 1;
-
- if (iface_object_map_.find(iface_object_key) == iface_object_map_.end())
- return 1;
-
- *iface_object = iface_object_map_[iface_object_key];
- return 0;
-}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
deleted file mode 100644
index d8b7dd0f8726..000000000000
--- a/wpa_supplicant/binder/binder_manager.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
-#define WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
-
-#include <map>
-#include <string>
-
-#include "iface.h"
-#include "supplicant.h"
-
-struct wpa_global;
-struct wpa_supplicant;
-
-namespace wpa_supplicant_binder {
-
-/**
- * BinderManager is responsible for managing the lifetime of all
- * binder objects created by wpa_supplicant. This is a singleton
- * class which is created by the supplicant core and can be used
- * to get references to the binder objects.
- */
-class BinderManager
-{
-public:
- static BinderManager *getInstance();
- static void destroyInstance();
- int registerBinderService(struct wpa_global *global);
- int registerInterface(struct wpa_supplicant *wpa_s);
- int unregisterInterface(struct wpa_supplicant *wpa_s);
- int getIfaceBinderObjectByKey(
- const void *iface_object_key,
- android::sp<fi::w1::wpa_supplicant::IIface> *iface_object);
-
-private:
- BinderManager() = default;
- ~BinderManager() = default;
-
- /* Singleton instance of this class. */
- static BinderManager *instance_;
- /* The main binder service object. */
- android::sp<Supplicant> supplicant_object_;
- /* Map of all the interface specific binder objects controlled by
- * wpa_supplicant. This map is keyed in by the corresponding
- * wpa_supplicant structure pointer. */
- std::map<const void *, android::sp<Iface>> iface_object_map_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H */
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
deleted file mode 100644
index ea11d426df1f..000000000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-package fi.w1.wpa_supplicant;
-
-/**
- * Interface exposed by wpa_supplicant for each network interface it controls.
- */
-interface IIface {
-}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
deleted file mode 100644
index 1cbee20a620f..000000000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * WPA Supplicant - binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-package fi.w1.wpa_supplicant;
-
-import android.os.PersistableBundle;
-import fi.w1.wpa_supplicant.IIface;
-
-/**
- * Interface exposed by the wpa_supplicant binder service registered
- * with the service manager with name: fi.w1.wpa_supplicant.
- */
-interface ISupplicant {
- /* Error values returned by the service to RPC method calls. */
- const int ERROR_INVALID_ARGS = 1;
- const int ERROR_UNKNOWN = 2;
- const int ERROR_IFACE_EXISTS = 3;
- const int ERROR_IFACE_UNKNOWN = 4;
-
- /**
- * Registers a wireless interface in wpa_supplicant.
- *
- * @param args A dictionary with arguments used to add the interface to
- * wpa_supplicant.
- * The dictionary may contain the following entries:
- * Ifname(String) Name of the network interface to control, e.g.,
- * wlan0.
- * BridgeIfname(String) Name of the bridge interface to control, e.g.,
- * br0.
- * Driver(String) Driver name which the interface uses, e.g., nl80211.
- * ConfigFile(String) Configuration file path.
- *
- * @return Binder object representing the interface.
- */
- IIface CreateInterface(in PersistableBundle args);
-
- /**
- * Deregisters a wireless interface from wpa_supplicant.
- *
- * @param ifname Name of the network interface, e.g., wlan0
- */
- void RemoveInterface(in @utf8InCpp String ifname);
-
- /**
- * Gets a binder object for the interface corresponding to ifname
- * which wpa_supplicant already controls.
- *
- * @param ifname Name of the network interface, e.g., wlan0
- *
- * @return Binder object representing the interface.
- */
- IIface GetInterface(in @utf8InCpp String ifname);
-}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
deleted file mode 100644
index d624d9133603..000000000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-package fi.w1.wpa_supplicant;
-
-import android.os.PersistableBundle;
-
-/**
- * Callback Interface exposed by the wpa_supplicant service. Clients need
- * to host an instance of this binder object and pass a reference of the object
- * to wpa_supplicant via the registerCallbacksObject method.
- */
-interface ISupplicantCallbacks {
-}
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
deleted file mode 100644
index c61b3b006427..000000000000
--- a/wpa_supplicant/binder/iface.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "iface.h"
-
-namespace wpa_supplicant_binder {
-
-Iface::Iface(struct wpa_supplicant *wpa_s) : wpa_s_(wpa_s) {}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
deleted file mode 100644
index c0ee12c65fa5..000000000000
--- a/wpa_supplicant/binder/iface.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_BINDER_IFACE_H
-#define WPA_SUPPLICANT_BINDER_IFACE_H
-
-#include "fi/w1/wpa_supplicant/BnIface.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "../wpa_supplicant_i.h"
-}
-
-namespace wpa_supplicant_binder {
-
-/**
- * Implementation of Iface binder object. Each unique binder
- * object is used for control operations on a specific interface
- * controlled by wpa_supplicant.
- */
-class Iface : public fi::w1::wpa_supplicant::BnIface
-{
-public:
- Iface(struct wpa_supplicant *wpa_s);
- virtual ~Iface() = default;
-
-private:
- /* Raw pointer to the structure maintained by the core for this
- * interface. */
- struct wpa_supplicant *wpa_s_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_IFACE_H */
diff --git a/wpa_supplicant/binder/supplicant.cpp b/wpa_supplicant/binder/supplicant.cpp
deleted file mode 100644
index 76569b1471fb..000000000000
--- a/wpa_supplicant/binder/supplicant.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "supplicant.h"
-#include "binder_manager.h"
-
-namespace wpa_supplicant_binder {
-
-Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {}
-
-android::binder::Status Supplicant::CreateInterface(
- const android::os::PersistableBundle &params,
- android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-{
- android::String16 driver, ifname, confname, bridge_ifname;
-
- /* Check if required Ifname argument is missing */
- if (!params.getString(android::String16("Ifname"), &ifname))
- return android::binder::Status::fromServiceSpecificError(
- ERROR_INVALID_ARGS,
- android::String8("Ifname missing in params."));
- /* Retrieve the remaining params from the dictionary */
- params.getString(android::String16("Driver"), &driver);
- params.getString(android::String16("ConfigFile"), &confname);
- params.getString(android::String16("BridgeIfname"), &bridge_ifname);
-
- /*
- * Try to get the wpa_supplicant record for this iface, return
- * an error if we already control it.
- */
- if (wpa_supplicant_get_iface(
- wpa_global_, android::String8(ifname).string()) != NULL)
- return android::binder::Status::fromServiceSpecificError(
- ERROR_IFACE_EXISTS,
- android::String8("wpa_supplicant already controls this "
- "interface."));
-
- android::binder::Status status;
- struct wpa_supplicant *wpa_s = NULL;
- struct wpa_interface iface;
-
- os_memset(&iface, 0, sizeof(iface));
- iface.driver = os_strdup(android::String8(driver).string());
- iface.ifname = os_strdup(android::String8(ifname).string());
- iface.confname = os_strdup(android::String8(confname).string());
- iface.bridge_ifname =
- os_strdup(android::String8(bridge_ifname).string());
- /* Otherwise, have wpa_supplicant attach to it. */
- wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
- /* The supplicant core creates a corresponding binder object via
- * BinderManager when |wpa_supplicant_add_iface| is called. */
- if (!wpa_s || !wpa_s->binder_object_key) {
- status = android::binder::Status::fromServiceSpecificError(
- ERROR_UNKNOWN,
- android::String8(
- "wpa_supplicant couldn't grab this interface."));
- } else {
- BinderManager *binder_manager = BinderManager::getInstance();
-
- if (!binder_manager ||
- binder_manager->getIfaceBinderObjectByKey(
- wpa_s->binder_object_key, aidl_return))
- status =
- android::binder::Status::fromServiceSpecificError(
- ERROR_UNKNOWN,
- android::String8("wpa_supplicant encountered a "
- "binder error."));
- else
- status = android::binder::Status::ok();
- }
- os_free((void *)iface.driver);
- os_free((void *)iface.ifname);
- os_free((void *)iface.confname);
- os_free((void *)iface.bridge_ifname);
- return status;
-}
-
-android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
-{
- struct wpa_supplicant *wpa_s;
-
- wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
- if (!wpa_s || !wpa_s->binder_object_key)
- return android::binder::Status::fromServiceSpecificError(
- ERROR_IFACE_UNKNOWN,
- android::String8("wpa_supplicant does not control this "
- "interface."));
- if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
- return android::binder::Status::fromServiceSpecificError(
- ERROR_UNKNOWN,
- android::String8(
- "wpa_supplicant couldn't remove this interface."));
- return android::binder::Status::ok();
-}
-
-android::binder::Status Supplicant::GetInterface(
- const std::string &ifname,
- android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-{
- struct wpa_supplicant *wpa_s;
-
- wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
- if (!wpa_s || !wpa_s->binder_object_key)
- return android::binder::Status::fromServiceSpecificError(
- ERROR_IFACE_UNKNOWN,
- android::String8(
- "wpa_supplicant does not control this interface."));
-
- BinderManager *binder_manager = BinderManager::getInstance();
- if (!binder_manager ||
- binder_manager->getIfaceBinderObjectByKey(
- wpa_s->binder_object_key, aidl_return))
- return android::binder::Status::fromServiceSpecificError(
- ERROR_UNKNOWN,
- android::String8(
- "wpa_supplicant encountered a binder error."));
-
- return android::binder::Status::ok();
-}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/supplicant.h b/wpa_supplicant/binder/supplicant.h
deleted file mode 100644
index 136b99b14327..000000000000
--- a/wpa_supplicant/binder/supplicant.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_BINDER_SUPPLICANT_H
-#define WPA_SUPPLICANT_BINDER_SUPPLICANT_H
-
-#include "fi/w1/wpa_supplicant/BnSupplicant.h"
-#include "fi/w1/wpa_supplicant/IIface.h"
-#include "fi/w1/wpa_supplicant/ISupplicantCallbacks.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "../wpa_supplicant_i.h"
-}
-
-namespace wpa_supplicant_binder {
-
-/**
- * Implementation of the supplicant binder object. This binder
- * object is used core for global control operations on
- * wpa_supplicant.
- */
-class Supplicant : public fi::w1::wpa_supplicant::BnSupplicant
-{
-public:
- Supplicant(struct wpa_global *global);
- virtual ~Supplicant() = default;
-
- android::binder::Status CreateInterface(
- const android::os::PersistableBundle &params,
- android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
- android::binder::Status
- RemoveInterface(const std::string &ifname) override;
- android::binder::Status GetInterface(
- const std::string &ifname,
- android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
-
-private:
- /* Raw pointer to the global structure maintained by the core. */
- struct wpa_global *wpa_global_;
- /* All the callback objects registered by the clients. */
- std::vector<android::sp<fi::w1::wpa_supplicant::ISupplicantCallbacks>>
- callbacks_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_SUPPLICANT_H */
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
deleted file mode 100644
index e13783ce1995..000000000000
--- a/wpa_supplicant/bss.c
+++ /dev/null
@@ -1,1385 +0,0 @@
-/*
- * BSS table
- * Copyright (c) 2009-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_defs.h"
-#include "drivers/driver.h"
-#include "eap_peer/eap.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "notify.h"
-#include "scan.h"
-#include "bss.h"
-
-static void wpa_bss_set_hessid(struct wpa_bss *bss)
-{
-#ifdef CONFIG_INTERWORKING
- const u8 *ie = wpa_bss_get_ie(bss, WLAN_EID_INTERWORKING);
- if (ie == NULL || (ie[1] != 7 && ie[1] != 9)) {
- os_memset(bss->hessid, 0, ETH_ALEN);
- return;
- }
- if (ie[1] == 7)
- os_memcpy(bss->hessid, ie + 3, ETH_ALEN);
- else
- os_memcpy(bss->hessid, ie + 5, ETH_ALEN);
-#endif /* CONFIG_INTERWORKING */
-}
-
-
-/**
- * wpa_bss_anqp_alloc - Allocate ANQP data structure for a BSS entry
- * Returns: Allocated ANQP data structure or %NULL on failure
- *
- * The allocated ANQP data structure has its users count set to 1. It may be
- * shared by multiple BSS entries and each shared entry is freed with
- * wpa_bss_anqp_free().
- */
-struct wpa_bss_anqp * wpa_bss_anqp_alloc(void)
-{
- struct wpa_bss_anqp *anqp;
- anqp = os_zalloc(sizeof(*anqp));
- if (anqp == NULL)
- return NULL;
-#ifdef CONFIG_INTERWORKING
- dl_list_init(&anqp->anqp_elems);
-#endif /* CONFIG_INTERWORKING */
- anqp->users = 1;
- return anqp;
-}
-
-
-/**
- * wpa_bss_anqp_clone - Clone an ANQP data structure
- * @anqp: ANQP data structure from wpa_bss_anqp_alloc()
- * Returns: Cloned ANQP data structure or %NULL on failure
- */
-static struct wpa_bss_anqp * wpa_bss_anqp_clone(struct wpa_bss_anqp *anqp)
-{
- struct wpa_bss_anqp *n;
-
- n = os_zalloc(sizeof(*n));
- if (n == NULL)
- return NULL;
-
-#define ANQP_DUP(f) if (anqp->f) n->f = wpabuf_dup(anqp->f)
-#ifdef CONFIG_INTERWORKING
- dl_list_init(&n->anqp_elems);
- ANQP_DUP(capability_list);
- ANQP_DUP(venue_name);
- ANQP_DUP(network_auth_type);
- ANQP_DUP(roaming_consortium);
- ANQP_DUP(ip_addr_type_availability);
- ANQP_DUP(nai_realm);
- ANQP_DUP(anqp_3gpp);
- ANQP_DUP(domain_name);
- ANQP_DUP(fils_realm_info);
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_HS20
- ANQP_DUP(hs20_capability_list);
- ANQP_DUP(hs20_operator_friendly_name);
- ANQP_DUP(hs20_wan_metrics);
- ANQP_DUP(hs20_connection_capability);
- ANQP_DUP(hs20_operating_class);
- ANQP_DUP(hs20_osu_providers_list);
- ANQP_DUP(hs20_operator_icon_metadata);
- ANQP_DUP(hs20_osu_providers_nai_list);
-#endif /* CONFIG_HS20 */
-#undef ANQP_DUP
-
- return n;
-}
-
-
-/**
- * wpa_bss_anqp_unshare_alloc - Unshare ANQP data (if shared) in a BSS entry
- * @bss: BSS entry
- * Returns: 0 on success, -1 on failure
- *
- * This function ensures the specific BSS entry has an ANQP data structure that
- * is not shared with any other BSS entry.
- */
-int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss)
-{
- struct wpa_bss_anqp *anqp;
-
- if (bss->anqp && bss->anqp->users > 1) {
- /* allocated, but shared - clone an unshared copy */
- anqp = wpa_bss_anqp_clone(bss->anqp);
- if (anqp == NULL)
- return -1;
- anqp->users = 1;
- bss->anqp->users--;
- bss->anqp = anqp;
- return 0;
- }
-
- if (bss->anqp)
- return 0; /* already allocated and not shared */
-
- /* not allocated - allocate a new storage area */
- bss->anqp = wpa_bss_anqp_alloc();
- return bss->anqp ? 0 : -1;
-}
-
-
-/**
- * wpa_bss_anqp_free - Free an ANQP data structure
- * @anqp: ANQP data structure from wpa_bss_anqp_alloc() or wpa_bss_anqp_clone()
- */
-static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
-{
-#ifdef CONFIG_INTERWORKING
- struct wpa_bss_anqp_elem *elem;
-#endif /* CONFIG_INTERWORKING */
-
- if (anqp == NULL)
- return;
-
- anqp->users--;
- if (anqp->users > 0) {
- /* Another BSS entry holds a pointer to this ANQP info */
- return;
- }
-
-#ifdef CONFIG_INTERWORKING
- wpabuf_free(anqp->capability_list);
- wpabuf_free(anqp->venue_name);
- wpabuf_free(anqp->network_auth_type);
- wpabuf_free(anqp->roaming_consortium);
- wpabuf_free(anqp->ip_addr_type_availability);
- wpabuf_free(anqp->nai_realm);
- wpabuf_free(anqp->anqp_3gpp);
- wpabuf_free(anqp->domain_name);
- wpabuf_free(anqp->fils_realm_info);
-
- while ((elem = dl_list_first(&anqp->anqp_elems,
- struct wpa_bss_anqp_elem, list))) {
- dl_list_del(&elem->list);
- wpabuf_free(elem->payload);
- os_free(elem);
- }
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_HS20
- wpabuf_free(anqp->hs20_capability_list);
- wpabuf_free(anqp->hs20_operator_friendly_name);
- wpabuf_free(anqp->hs20_wan_metrics);
- wpabuf_free(anqp->hs20_connection_capability);
- wpabuf_free(anqp->hs20_operating_class);
- wpabuf_free(anqp->hs20_osu_providers_list);
- wpabuf_free(anqp->hs20_operator_icon_metadata);
- wpabuf_free(anqp->hs20_osu_providers_nai_list);
-#endif /* CONFIG_HS20 */
-
- os_free(anqp);
-}
-
-
-static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s,
- struct wpa_bss *old_bss,
- struct wpa_bss *new_bss)
-{
- struct wpa_radio_work *work;
- struct wpa_connect_work *cwork;
-
- work = radio_work_pending(wpa_s, "sme-connect");
- if (!work)
- work = radio_work_pending(wpa_s, "connect");
- if (!work)
- return;
-
- cwork = work->ctx;
- if (cwork->bss != old_bss)
- return;
-
- wpa_printf(MSG_DEBUG,
- "Update BSS pointer for the pending connect radio work");
- cwork->bss = new_bss;
- if (!new_bss)
- cwork->bss_removed = 1;
-}
-
-
-void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- const char *reason)
-{
- if (wpa_s->last_scan_res) {
- unsigned int i;
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- if (wpa_s->last_scan_res[i] == bss) {
- os_memmove(&wpa_s->last_scan_res[i],
- &wpa_s->last_scan_res[i + 1],
- (wpa_s->last_scan_res_used - i - 1)
- * sizeof(struct wpa_bss *));
- wpa_s->last_scan_res_used--;
- break;
- }
- }
- }
- wpa_bss_update_pending_connect(wpa_s, bss, NULL);
- dl_list_del(&bss->list);
- dl_list_del(&bss->list_id);
- wpa_s->num_bss--;
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR
- " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
- wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
- wpa_bss_anqp_free(bss->anqp);
- os_free(bss);
-}
-
-
-/**
- * wpa_bss_get - Fetch a BSS table entry based on BSSID and SSID
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID
- * @ssid: SSID
- * @ssid_len: Length of @ssid
- * Returns: Pointer to the BSS entry or %NULL if not found
- */
-struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ssid, size_t ssid_len)
-{
- struct wpa_bss *bss;
- if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
- return NULL;
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
- bss->ssid_len == ssid_len &&
- os_memcmp(bss->ssid, ssid, ssid_len) == 0)
- return bss;
- }
- return NULL;
-}
-
-
-void calculate_update_time(const struct os_reltime *fetch_time,
- unsigned int age_ms,
- struct os_reltime *update_time)
-{
- os_time_t usec;
-
- update_time->sec = fetch_time->sec;
- update_time->usec = fetch_time->usec;
- update_time->sec -= age_ms / 1000;
- usec = (age_ms % 1000) * 1000;
- if (update_time->usec < usec) {
- update_time->sec--;
- update_time->usec += 1000000;
- }
- update_time->usec -= usec;
-}
-
-
-static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
- struct os_reltime *fetch_time)
-{
- dst->flags = src->flags;
- os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
- dst->freq = src->freq;
- dst->beacon_int = src->beacon_int;
- dst->caps = src->caps;
- dst->qual = src->qual;
- dst->noise = src->noise;
- dst->level = src->level;
- dst->tsf = src->tsf;
- dst->est_throughput = src->est_throughput;
- dst->snr = src->snr;
-
- calculate_update_time(fetch_time, src->age, &dst->last_update);
-}
-
-
-static int wpa_bss_is_wps_candidate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
-#ifdef CONFIG_WPS
- struct wpa_ssid *ssid;
- struct wpabuf *wps_ie;
- int pbc = 0, ret;
-
- wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- if (!wps_ie)
- return 0;
-
- if (wps_is_selected_pbc_registrar(wps_ie)) {
- pbc = 1;
- } else if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
- wpabuf_free(wps_ie);
- return 0;
- }
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
- continue;
- if (ssid->ssid_len &&
- (ssid->ssid_len != bss->ssid_len ||
- os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) != 0))
- continue;
-
- if (pbc)
- ret = eap_is_wps_pbc_enrollee(&ssid->eap);
- else
- ret = eap_is_wps_pin_enrollee(&ssid->eap);
- wpabuf_free(wps_ie);
- return ret;
- }
- wpabuf_free(wps_ie);
-#endif /* CONFIG_WPS */
-
- return 0;
-}
-
-
-static bool is_p2p_pending_bss(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
-#ifdef CONFIG_P2P
- u8 addr[ETH_ALEN];
-
- if (os_memcmp(bss->bssid, wpa_s->pending_join_iface_addr,
- ETH_ALEN) == 0)
- return true;
- if (!is_zero_ether_addr(wpa_s->pending_join_dev_addr) &&
- p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len, addr) == 0 &&
- os_memcmp(addr, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0)
- return true;
-#endif /* CONFIG_P2P */
- return false;
-}
-
-
-static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
- struct wpa_ssid *ssid;
-
- if (is_p2p_pending_bss(wpa_s, bss))
- return 1;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid->ssid == NULL || ssid->ssid_len == 0)
- continue;
- if (ssid->ssid_len == bss->ssid_len &&
- os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
- if (bss == wpa_s->current_bss)
- return 1;
-
- if (wpa_s->current_bss &&
- (bss->ssid_len != wpa_s->current_bss->ssid_len ||
- os_memcmp(bss->ssid, wpa_s->current_bss->ssid,
- bss->ssid_len) != 0))
- return 0; /* SSID has changed */
-
- return !is_zero_ether_addr(bss->bssid) &&
- (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
- os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0);
-}
-
-
-static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (!wpa_bss_known(wpa_s, bss) &&
- !wpa_bss_is_wps_candidate(wpa_s, bss)) {
- wpa_bss_remove(wpa_s, bss, __func__);
- return 0;
- }
- }
-
- return -1;
-}
-
-
-static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
-
- /*
- * Remove the oldest entry that does not match with any configured
- * network.
- */
- if (wpa_bss_remove_oldest_unknown(wpa_s) == 0)
- return 0;
-
- /*
- * Remove the oldest entry that isn't currently in use.
- */
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (!wpa_bss_in_use(wpa_s, bss)) {
- wpa_bss_remove(wpa_s, bss, __func__);
- return 0;
- }
- }
-
- return -1;
-}
-
-
-static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
- const u8 *ssid, size_t ssid_len,
- struct wpa_scan_res *res,
- struct os_reltime *fetch_time)
-{
- struct wpa_bss *bss;
- char extra[50];
-
- bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
- if (bss == NULL)
- return NULL;
- bss->id = wpa_s->bss_next_id++;
- bss->last_update_idx = wpa_s->bss_update_idx;
- wpa_bss_copy_res(bss, res, fetch_time);
- os_memcpy(bss->ssid, ssid, ssid_len);
- bss->ssid_len = ssid_len;
- bss->ie_len = res->ie_len;
- bss->beacon_ie_len = res->beacon_ie_len;
- os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
- wpa_bss_set_hessid(bss);
-
- if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
- wpa_bss_remove_oldest(wpa_s) != 0) {
- wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
- "because all BSSes are in use. We should normally "
- "not get here!", (int) wpa_s->num_bss + 1);
- wpa_s->conf->bss_max_count = wpa_s->num_bss + 1;
- }
-
- dl_list_add_tail(&wpa_s->bss, &bss->list);
- dl_list_add_tail(&wpa_s->bss_id, &bss->list_id);
- wpa_s->num_bss++;
- if (!is_zero_ether_addr(bss->hessid))
- os_snprintf(extra, sizeof(extra), " HESSID " MACSTR,
- MAC2STR(bss->hessid));
- else
- extra[0] = '\0';
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR
- " SSID '%s' freq %d%s",
- bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len),
- bss->freq, extra);
- wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
- return bss;
-}
-
-
-static int are_ies_equal(const struct wpa_bss *old,
- const struct wpa_scan_res *new_res, u32 ie)
-{
- const u8 *old_ie, *new_ie;
- struct wpabuf *old_ie_buff = NULL;
- struct wpabuf *new_ie_buff = NULL;
- int new_ie_len, old_ie_len, ret, is_multi;
-
- switch (ie) {
- case WPA_IE_VENDOR_TYPE:
- old_ie = wpa_bss_get_vendor_ie(old, ie);
- new_ie = wpa_scan_get_vendor_ie(new_res, ie);
- is_multi = 0;
- break;
- case WPS_IE_VENDOR_TYPE:
- old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie);
- new_ie_buff = wpa_scan_get_vendor_ie_multi(new_res, ie);
- is_multi = 1;
- break;
- case WLAN_EID_RSN:
- case WLAN_EID_SUPP_RATES:
- case WLAN_EID_EXT_SUPP_RATES:
- old_ie = wpa_bss_get_ie(old, ie);
- new_ie = wpa_scan_get_ie(new_res, ie);
- is_multi = 0;
- break;
- default:
- wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__);
- return 0;
- }
-
- if (is_multi) {
- /* in case of multiple IEs stored in buffer */
- old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL;
- new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL;
- old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0;
- new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0;
- } else {
- /* in case of single IE */
- old_ie_len = old_ie ? old_ie[1] + 2 : 0;
- new_ie_len = new_ie ? new_ie[1] + 2 : 0;
- }
-
- if (!old_ie || !new_ie)
- ret = !old_ie && !new_ie;
- else
- ret = (old_ie_len == new_ie_len &&
- os_memcmp(old_ie, new_ie, old_ie_len) == 0);
-
- wpabuf_free(old_ie_buff);
- wpabuf_free(new_ie_buff);
-
- return ret;
-}
-
-
-static u32 wpa_bss_compare_res(const struct wpa_bss *old,
- const struct wpa_scan_res *new_res)
-{
- u32 changes = 0;
- int caps_diff = old->caps ^ new_res->caps;
-
- if (old->freq != new_res->freq)
- changes |= WPA_BSS_FREQ_CHANGED_FLAG;
-
- if (old->level != new_res->level)
- changes |= WPA_BSS_SIGNAL_CHANGED_FLAG;
-
- if (caps_diff & IEEE80211_CAP_PRIVACY)
- changes |= WPA_BSS_PRIVACY_CHANGED_FLAG;
-
- if (caps_diff & IEEE80211_CAP_IBSS)
- changes |= WPA_BSS_MODE_CHANGED_FLAG;
-
- if (old->ie_len == new_res->ie_len &&
- os_memcmp(wpa_bss_ie_ptr(old), new_res + 1, old->ie_len) == 0)
- return changes;
- changes |= WPA_BSS_IES_CHANGED_FLAG;
-
- if (!are_ies_equal(old, new_res, WPA_IE_VENDOR_TYPE))
- changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
-
- if (!are_ies_equal(old, new_res, WLAN_EID_RSN))
- changes |= WPA_BSS_RSNIE_CHANGED_FLAG;
-
- if (!are_ies_equal(old, new_res, WPS_IE_VENDOR_TYPE))
- changes |= WPA_BSS_WPS_CHANGED_FLAG;
-
- if (!are_ies_equal(old, new_res, WLAN_EID_SUPP_RATES) ||
- !are_ies_equal(old, new_res, WLAN_EID_EXT_SUPP_RATES))
- changes |= WPA_BSS_RATES_CHANGED_FLAG;
-
- return changes;
-}
-
-
-void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
- const struct wpa_bss *bss)
-{
- if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
- wpas_notify_bss_freq_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_SIGNAL_CHANGED_FLAG)
- wpas_notify_bss_signal_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_PRIVACY_CHANGED_FLAG)
- wpas_notify_bss_privacy_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_MODE_CHANGED_FLAG)
- wpas_notify_bss_mode_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_WPAIE_CHANGED_FLAG)
- wpas_notify_bss_wpaie_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_RSNIE_CHANGED_FLAG)
- wpas_notify_bss_rsnie_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_WPS_CHANGED_FLAG)
- wpas_notify_bss_wps_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_IES_CHANGED_FLAG)
- wpas_notify_bss_ies_changed(wpa_s, bss->id);
-
- if (changes & WPA_BSS_RATES_CHANGED_FLAG)
- wpas_notify_bss_rates_changed(wpa_s, bss->id);
-
- wpas_notify_bss_seen(wpa_s, bss->id);
-}
-
-
-static struct wpa_bss *
-wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- struct wpa_scan_res *res, struct os_reltime *fetch_time)
-{
- u32 changes;
-
- if (bss->last_update_idx == wpa_s->bss_update_idx) {
- struct os_reltime update_time;
-
- /*
- * Some drivers (e.g., cfg80211) include multiple BSS entries
- * for the same BSS if that BSS's channel changes. The BSS list
- * implementation in wpa_supplicant does not do that and we need
- * to filter out the obsolete results here to make sure only the
- * most current BSS information remains in the table.
- */
- wpa_printf(MSG_DEBUG, "BSS: " MACSTR
- " has multiple entries in the scan results - select the most current one",
- MAC2STR(bss->bssid));
- calculate_update_time(fetch_time, res->age, &update_time);
- wpa_printf(MSG_DEBUG,
- "Previous last_update: %u.%06u (freq %d%s)",
- (unsigned int) bss->last_update.sec,
- (unsigned int) bss->last_update.usec,
- bss->freq,
- (bss->flags & WPA_BSS_ASSOCIATED) ? " assoc" : "");
- wpa_printf(MSG_DEBUG, "New last_update: %u.%06u (freq %d%s)",
- (unsigned int) update_time.sec,
- (unsigned int) update_time.usec,
- res->freq,
- (res->flags & WPA_SCAN_ASSOCIATED) ? " assoc" : "");
- if ((bss->flags & WPA_BSS_ASSOCIATED) ||
- (!(res->flags & WPA_SCAN_ASSOCIATED) &&
- !os_reltime_before(&bss->last_update, &update_time))) {
- wpa_printf(MSG_DEBUG,
- "Ignore this BSS entry since the previous update looks more current");
- return bss;
- }
- wpa_printf(MSG_DEBUG,
- "Accept this BSS entry since it looks more current than the previous update");
- }
-
- changes = wpa_bss_compare_res(bss, res);
- if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
- wpa_printf(MSG_DEBUG, "BSS: " MACSTR " changed freq %d --> %d",
- MAC2STR(bss->bssid), bss->freq, res->freq);
- bss->scan_miss_count = 0;
- bss->last_update_idx = wpa_s->bss_update_idx;
- wpa_bss_copy_res(bss, res, fetch_time);
- /* Move the entry to the end of the list */
- dl_list_del(&bss->list);
-#ifdef CONFIG_P2P
- if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
- !wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE)) {
- /*
- * This can happen when non-P2P station interface runs a scan
- * without P2P IE in the Probe Request frame. P2P GO would reply
- * to that with a Probe Response that does not include P2P IE.
- * Do not update the IEs in this BSS entry to avoid such loss of
- * information that may be needed for P2P operations to
- * determine group information.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Do not update scan IEs for "
- MACSTR " since that would remove P2P IE information",
- MAC2STR(bss->bssid));
- } else
-#endif /* CONFIG_P2P */
- if (bss->ie_len + bss->beacon_ie_len >=
- res->ie_len + res->beacon_ie_len) {
- os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
- bss->ie_len = res->ie_len;
- bss->beacon_ie_len = res->beacon_ie_len;
- } else {
- struct wpa_bss *nbss;
- struct dl_list *prev = bss->list_id.prev;
- dl_list_del(&bss->list_id);
- nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
- res->beacon_ie_len);
- if (nbss) {
- unsigned int i;
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- if (wpa_s->last_scan_res[i] == bss) {
- wpa_s->last_scan_res[i] = nbss;
- break;
- }
- }
- if (wpa_s->current_bss == bss)
- wpa_s->current_bss = nbss;
- wpa_bss_update_pending_connect(wpa_s, bss, nbss);
- bss = nbss;
- os_memcpy(bss->ies, res + 1,
- res->ie_len + res->beacon_ie_len);
- bss->ie_len = res->ie_len;
- bss->beacon_ie_len = res->beacon_ie_len;
- }
- dl_list_add(prev, &bss->list_id);
- }
- if (changes & WPA_BSS_IES_CHANGED_FLAG)
- wpa_bss_set_hessid(bss);
- dl_list_add_tail(&wpa_s->bss, &bss->list);
-
- notify_bss_changes(wpa_s, changes, bss);
-
- return bss;
-}
-
-
-/**
- * wpa_bss_update_start - Start a BSS table update from scan results
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is called at the start of each BSS table update round for new
- * scan results. The actual scan result entries are indicated with calls to
- * wpa_bss_update_scan_res() and the update round is finished with a call to
- * wpa_bss_update_end().
- */
-void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
-{
- wpa_s->bss_update_idx++;
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Start scan result update %u",
- wpa_s->bss_update_idx);
- wpa_s->last_scan_res_used = 0;
-}
-
-
-/**
- * wpa_bss_update_scan_res - Update a BSS table entry based on a scan result
- * @wpa_s: Pointer to wpa_supplicant data
- * @res: Scan result
- * @fetch_time: Time when the result was fetched from the driver
- *
- * This function updates a BSS table entry (or adds one) based on a scan result.
- * This is called separately for each scan result between the calls to
- * wpa_bss_update_start() and wpa_bss_update_end().
- */
-void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res,
- struct os_reltime *fetch_time)
-{
- const u8 *ssid, *p2p, *mesh;
- struct wpa_bss *bss;
-
- if (wpa_s->conf->ignore_old_scan_res) {
- struct os_reltime update;
- calculate_update_time(fetch_time, res->age, &update);
- if (os_reltime_before(&update, &wpa_s->scan_trigger_time)) {
- struct os_reltime age;
- os_reltime_sub(&wpa_s->scan_trigger_time, &update,
- &age);
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Ignore driver BSS "
- "table entry that is %u.%06u seconds older "
- "than our scan trigger",
- (unsigned int) age.sec,
- (unsigned int) age.usec);
- return;
- }
- }
-
- ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
- if (ssid == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: No SSID IE included for "
- MACSTR, MAC2STR(res->bssid));
- return;
- }
- if (ssid[1] > SSID_MAX_LEN) {
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Too long SSID IE included for "
- MACSTR, MAC2STR(res->bssid));
- return;
- }
-
- p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
-#ifdef CONFIG_P2P
- if (p2p == NULL &&
- wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
- /*
- * If it's a P2P specific interface, then don't update
- * the scan result without a P2P IE.
- */
- wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR
- " update for P2P interface", MAC2STR(res->bssid));
- return;
- }
-#endif /* CONFIG_P2P */
- if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
- os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
- return; /* Skip P2P listen discovery results here */
-
- /* TODO: add option for ignoring BSSes we are not interested in
- * (to save memory) */
-
- mesh = wpa_scan_get_ie(res, WLAN_EID_MESH_ID);
- if (mesh && mesh[1] <= SSID_MAX_LEN)
- ssid = mesh;
-
- bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
- if (bss == NULL)
- bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res, fetch_time);
- else {
- bss = wpa_bss_update(wpa_s, bss, res, fetch_time);
- if (wpa_s->last_scan_res) {
- unsigned int i;
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- if (bss == wpa_s->last_scan_res[i]) {
- /* Already in the list */
- return;
- }
- }
- }
- }
-
- if (bss == NULL)
- return;
- if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) {
- struct wpa_bss **n;
- unsigned int siz;
- if (wpa_s->last_scan_res_size == 0)
- siz = 32;
- else
- siz = wpa_s->last_scan_res_size * 2;
- n = os_realloc_array(wpa_s->last_scan_res, siz,
- sizeof(struct wpa_bss *));
- if (n == NULL)
- return;
- wpa_s->last_scan_res = n;
- wpa_s->last_scan_res_size = siz;
- }
-
- if (wpa_s->last_scan_res)
- wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss;
-}
-
-
-static int wpa_bss_included_in_scan(const struct wpa_bss *bss,
- const struct scan_info *info)
-{
- int found;
- size_t i;
-
- if (info == NULL)
- return 1;
-
- if (info->num_freqs) {
- found = 0;
- for (i = 0; i < info->num_freqs; i++) {
- if (bss->freq == info->freqs[i]) {
- found = 1;
- break;
- }
- }
- if (!found)
- return 0;
- }
-
- if (info->num_ssids) {
- found = 0;
- for (i = 0; i < info->num_ssids; i++) {
- const struct wpa_driver_scan_ssid *s = &info->ssids[i];
- if ((s->ssid == NULL || s->ssid_len == 0) ||
- (s->ssid_len == bss->ssid_len &&
- os_memcmp(s->ssid, bss->ssid, bss->ssid_len) ==
- 0)) {
- found = 1;
- break;
- }
- }
- if (!found)
- return 0;
- }
-
- return 1;
-}
-
-
-/**
- * wpa_bss_update_end - End a BSS table update from scan results
- * @wpa_s: Pointer to wpa_supplicant data
- * @info: Information about scan parameters
- * @new_scan: Whether this update round was based on a new scan
- *
- * This function is called at the end of each BSS table update round for new
- * scan results. The start of the update was indicated with a call to
- * wpa_bss_update_start().
- */
-void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
- int new_scan)
-{
- struct wpa_bss *bss, *n;
-
- os_get_reltime(&wpa_s->last_scan);
- if ((info && info->aborted) || !new_scan)
- return; /* do not expire entries without new scan */
-
- dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
- if (wpa_bss_in_use(wpa_s, bss))
- continue;
- if (!wpa_bss_included_in_scan(bss, info))
- continue; /* expire only BSSes that were scanned */
- if (bss->last_update_idx < wpa_s->bss_update_idx)
- bss->scan_miss_count++;
- if (bss->scan_miss_count >=
- wpa_s->conf->bss_expiration_scan_count) {
- wpa_bss_remove(wpa_s, bss, "no match in scan");
- }
- }
-
- wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%zu/%zu",
- wpa_s->last_scan_res_used, wpa_s->last_scan_res_size);
-}
-
-
-/**
- * wpa_bss_flush_by_age - Flush old BSS entries
- * @wpa_s: Pointer to wpa_supplicant data
- * @age: Maximum entry age in seconds
- *
- * Remove BSS entries that have not been updated during the last @age seconds.
- */
-void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age)
-{
- struct wpa_bss *bss, *n;
- struct os_reltime t;
-
- if (dl_list_empty(&wpa_s->bss))
- return;
-
- os_get_reltime(&t);
- t.sec -= age;
-
- dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
- if (wpa_bss_in_use(wpa_s, bss))
- continue;
-
- if (os_reltime_before(&bss->last_update, &t)) {
- wpa_bss_remove(wpa_s, bss, __func__);
- } else
- break;
- }
-}
-
-
-/**
- * wpa_bss_init - Initialize BSS table
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success, -1 on failure
- *
- * This prepares BSS table lists and timer for periodic updates. The BSS table
- * is deinitialized with wpa_bss_deinit() once not needed anymore.
- */
-int wpa_bss_init(struct wpa_supplicant *wpa_s)
-{
- dl_list_init(&wpa_s->bss);
- dl_list_init(&wpa_s->bss_id);
- return 0;
-}
-
-
-/**
- * wpa_bss_flush - Flush all unused BSS entries
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void wpa_bss_flush(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss, *n;
-
- wpa_s->clear_driver_scan_cache = 1;
-
- if (wpa_s->bss.next == NULL)
- return; /* BSS table not yet initialized */
-
- dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
- if (wpa_bss_in_use(wpa_s, bss))
- continue;
- wpa_bss_remove(wpa_s, bss, __func__);
- }
-}
-
-
-/**
- * wpa_bss_deinit - Deinitialize BSS table
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void wpa_bss_deinit(struct wpa_supplicant *wpa_s)
-{
- wpa_bss_flush(wpa_s);
-}
-
-
-/**
- * wpa_bss_get_bssid - Fetch a BSS table entry based on BSSID
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID
- * Returns: Pointer to the BSS entry or %NULL if not found
- */
-struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- struct wpa_bss *bss;
- if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
- return NULL;
- dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
- return bss;
- }
- return NULL;
-}
-
-
-/**
- * wpa_bss_get_bssid_latest - Fetch the latest BSS table entry based on BSSID
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID
- * Returns: Pointer to the BSS entry or %NULL if not found
- *
- * This function is like wpa_bss_get_bssid(), but full BSS table is iterated to
- * find the entry that has the most recent update. This can help in finding the
- * correct entry in cases where the SSID of the AP may have changed recently
- * (e.g., in WPS reconfiguration cases).
- */
-struct wpa_bss * wpa_bss_get_bssid_latest(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- struct wpa_bss *bss, *found = NULL;
- if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
- return NULL;
- dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) != 0)
- continue;
- if (found == NULL ||
- os_reltime_before(&found->last_update, &bss->last_update))
- found = bss;
- }
- return found;
-}
-
-
-#ifdef CONFIG_P2P
-/**
- * wpa_bss_get_p2p_dev_addr - Fetch the latest BSS table entry based on P2P Device Addr
- * @wpa_s: Pointer to wpa_supplicant data
- * @dev_addr: P2P Device Address of the GO
- * Returns: Pointer to the BSS entry or %NULL if not found
- *
- * This function tries to find the entry that has the most recent update. This
- * can help in finding the correct entry in cases where the SSID of the P2P
- * Device may have changed recently.
- */
-struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- struct wpa_bss *bss, *found = NULL;
- dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
- u8 addr[ETH_ALEN];
- if (p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len,
- addr) != 0 ||
- os_memcmp(addr, dev_addr, ETH_ALEN) != 0)
- continue;
- if (!found ||
- os_reltime_before(&found->last_update, &bss->last_update))
- found = bss;
- }
- return found;
-}
-#endif /* CONFIG_P2P */
-
-
-/**
- * wpa_bss_get_id - Fetch a BSS table entry based on identifier
- * @wpa_s: Pointer to wpa_supplicant data
- * @id: Unique identifier (struct wpa_bss::id) assigned for the entry
- * Returns: Pointer to the BSS entry or %NULL if not found
- */
-struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- struct wpa_bss *bss;
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (bss->id == id)
- return bss;
- }
- return NULL;
-}
-
-
-/**
- * wpa_bss_get_id_range - Fetch a BSS table entry based on identifier range
- * @wpa_s: Pointer to wpa_supplicant data
- * @idf: Smallest allowed identifier assigned for the entry
- * @idf: Largest allowed identifier assigned for the entry
- * Returns: Pointer to the BSS entry or %NULL if not found
- *
- * This function is similar to wpa_bss_get_id() but allows a BSS entry with the
- * smallest id value to be fetched within the specified range without the
- * caller having to know the exact id.
- */
-struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s,
- unsigned int idf, unsigned int idl)
-{
- struct wpa_bss *bss;
- dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
- if (bss->id >= idf && bss->id <= idl)
- return bss;
- }
- return NULL;
-}
-
-
-/**
- * wpa_bss_get_ie - Fetch a specified information element from a BSS entry
- * @bss: BSS table entry
- * @ie: Information element identitifier (WLAN_EID_*)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the BSS
- * entry.
- */
-const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie)
-{
- return get_ie(wpa_bss_ie_ptr(bss), bss->ie_len, ie);
-}
-
-
-/**
- * wpa_bss_get_ie_ext - Fetch a specified extended IE from a BSS entry
- * @bss: BSS table entry
- * @ext: Information element extension identifier (WLAN_EID_EXT_*)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the BSS
- * entry.
- */
-const u8 * wpa_bss_get_ie_ext(const struct wpa_bss *bss, u8 ext)
-{
- return get_ie_ext(wpa_bss_ie_ptr(bss), bss->ie_len, ext);
-}
-
-
-/**
- * wpa_bss_get_vendor_ie - Fetch a vendor information element from a BSS entry
- * @bss: BSS table entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the BSS
- * entry.
- */
-const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type)
-{
- const u8 *ies;
- const struct element *elem;
-
- ies = wpa_bss_ie_ptr(bss);
-
- for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, bss->ie_len) {
- if (elem->datalen >= 4 &&
- vendor_type == WPA_GET_BE32(elem->data))
- return &elem->id;
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_bss_get_vendor_ie_beacon - Fetch a vendor information from a BSS entry
- * @bss: BSS table entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the BSS
- * entry.
- *
- * This function is like wpa_bss_get_vendor_ie(), but uses IE buffer only
- * from Beacon frames instead of either Beacon or Probe Response frames.
- */
-const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss,
- u32 vendor_type)
-{
- const u8 *ies;
- const struct element *elem;
-
- if (bss->beacon_ie_len == 0)
- return NULL;
-
- ies = wpa_bss_ie_ptr(bss);
- ies += bss->ie_len;
-
- for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies,
- bss->beacon_ie_len) {
- if (elem->datalen >= 4 &&
- vendor_type == WPA_GET_BE32(elem->data))
- return &elem->id;
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_bss_get_vendor_ie_multi - Fetch vendor IE data from a BSS entry
- * @bss: BSS table entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element payload or %NULL if not found
- *
- * This function returns concatenated payload of possibly fragmented vendor
- * specific information elements in the BSS entry. The caller is responsible for
- * freeing the returned buffer.
- */
-struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss,
- u32 vendor_type)
-{
- struct wpabuf *buf;
- const u8 *end, *pos;
-
- buf = wpabuf_alloc(bss->ie_len);
- if (buf == NULL)
- return NULL;
-
- pos = wpa_bss_ie_ptr(bss);
- end = pos + bss->ie_len;
-
- while (end - pos > 1) {
- u8 ie, len;
-
- ie = pos[0];
- len = pos[1];
- if (len > end - pos - 2)
- break;
- pos += 2;
- if (ie == WLAN_EID_VENDOR_SPECIFIC && len >= 4 &&
- vendor_type == WPA_GET_BE32(pos))
- wpabuf_put_data(buf, pos + 4, len - 4);
- pos += len;
- }
-
- if (wpabuf_len(buf) == 0) {
- wpabuf_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-
-
-/**
- * wpa_bss_get_vendor_ie_multi_beacon - Fetch vendor IE data from a BSS entry
- * @bss: BSS table entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element payload or %NULL if not found
- *
- * This function returns concatenated payload of possibly fragmented vendor
- * specific information elements in the BSS entry. The caller is responsible for
- * freeing the returned buffer.
- *
- * This function is like wpa_bss_get_vendor_ie_multi(), but uses IE buffer only
- * from Beacon frames instead of either Beacon or Probe Response frames.
- */
-struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss,
- u32 vendor_type)
-{
- struct wpabuf *buf;
- const u8 *end, *pos;
-
- buf = wpabuf_alloc(bss->beacon_ie_len);
- if (buf == NULL)
- return NULL;
-
- pos = wpa_bss_ie_ptr(bss);
- pos += bss->ie_len;
- end = pos + bss->beacon_ie_len;
-
- while (end - pos > 1) {
- if (2 + pos[1] > end - pos)
- break;
- if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
- vendor_type == WPA_GET_BE32(&pos[2]))
- wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
- pos += 2 + pos[1];
- }
-
- if (wpabuf_len(buf) == 0) {
- wpabuf_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-
-
-/**
- * wpa_bss_get_max_rate - Get maximum legacy TX rate supported in a BSS
- * @bss: BSS table entry
- * Returns: Maximum legacy rate in units of 500 kbps
- */
-int wpa_bss_get_max_rate(const struct wpa_bss *bss)
-{
- int rate = 0;
- const u8 *ie;
- int i;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- for (i = 0; ie && i < ie[1]; i++) {
- if ((ie[i + 2] & 0x7f) > rate)
- rate = ie[i + 2] & 0x7f;
- }
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
- for (i = 0; ie && i < ie[1]; i++) {
- if ((ie[i + 2] & 0x7f) > rate)
- rate = ie[i + 2] & 0x7f;
- }
-
- return rate;
-}
-
-
-/**
- * wpa_bss_get_bit_rates - Get legacy TX rates supported in a BSS
- * @bss: BSS table entry
- * @rates: Buffer for returning a pointer to the rates list (units of 500 kbps)
- * Returns: number of legacy TX rates or -1 on failure
- *
- * The caller is responsible for freeing the returned buffer with os_free() in
- * case of success.
- */
-int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates)
-{
- const u8 *ie, *ie2;
- int i, j;
- unsigned int len;
- u8 *r;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- ie2 = wpa_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
-
- len = (ie ? ie[1] : 0) + (ie2 ? ie2[1] : 0);
-
- r = os_malloc(len);
- if (!r)
- return -1;
-
- for (i = 0; ie && i < ie[1]; i++)
- r[i] = ie[i + 2] & 0x7f;
-
- for (j = 0; ie2 && j < ie2[1]; j++)
- r[i + j] = ie2[j + 2] & 0x7f;
-
- *rates = r;
- return len;
-}
-
-
-#ifdef CONFIG_FILS
-const u8 * wpa_bss_get_fils_cache_id(const struct wpa_bss *bss)
-{
- const u8 *ie;
-
- if (bss) {
- ie = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
- if (ie && ie[1] >= 4 && WPA_GET_LE16(ie + 2) & BIT(7))
- return ie + 4;
- }
-
- return NULL;
-}
-#endif /* CONFIG_FILS */
-
-
-int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab)
-{
- if (!bss)
- return 0;
- return ieee802_11_ext_capab(wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB),
- capab);
-}
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
deleted file mode 100644
index 4078b9b9d0a4..000000000000
--- a/wpa_supplicant/bss.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * BSS table
- * Copyright (c) 2009-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef BSS_H
-#define BSS_H
-
-struct wpa_scan_res;
-
-#define WPA_BSS_QUAL_INVALID BIT(0)
-#define WPA_BSS_NOISE_INVALID BIT(1)
-#define WPA_BSS_LEVEL_INVALID BIT(2)
-#define WPA_BSS_LEVEL_DBM BIT(3)
-#define WPA_BSS_AUTHENTICATED BIT(4)
-#define WPA_BSS_ASSOCIATED BIT(5)
-#define WPA_BSS_ANQP_FETCH_TRIED BIT(6)
-#define WPA_BSS_OWE_TRANSITION BIT(7)
-
-#define WPA_BSS_FREQ_CHANGED_FLAG BIT(0)
-#define WPA_BSS_SIGNAL_CHANGED_FLAG BIT(1)
-#define WPA_BSS_PRIVACY_CHANGED_FLAG BIT(2)
-#define WPA_BSS_MODE_CHANGED_FLAG BIT(3)
-#define WPA_BSS_WPAIE_CHANGED_FLAG BIT(4)
-#define WPA_BSS_RSNIE_CHANGED_FLAG BIT(5)
-#define WPA_BSS_WPS_CHANGED_FLAG BIT(6)
-#define WPA_BSS_RATES_CHANGED_FLAG BIT(7)
-#define WPA_BSS_IES_CHANGED_FLAG BIT(8)
-
-struct wpa_bss_anqp_elem {
- struct dl_list list;
- u16 infoid;
- bool protected_response; /* received in a protected GAS response */
- struct wpabuf *payload;
-};
-
-/**
- * struct wpa_bss_anqp - ANQP data for a BSS entry (struct wpa_bss)
- */
-struct wpa_bss_anqp {
- /** Number of BSS entries referring to this ANQP data instance */
- unsigned int users;
-#ifdef CONFIG_INTERWORKING
- struct wpabuf *capability_list;
- struct wpabuf *venue_name;
- struct wpabuf *network_auth_type;
- struct wpabuf *roaming_consortium;
- struct wpabuf *ip_addr_type_availability;
- struct wpabuf *nai_realm;
- struct wpabuf *anqp_3gpp;
- struct wpabuf *domain_name;
- struct wpabuf *fils_realm_info;
- struct dl_list anqp_elems; /* list of struct wpa_bss_anqp_elem */
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_HS20
- struct wpabuf *hs20_capability_list;
- struct wpabuf *hs20_operator_friendly_name;
- struct wpabuf *hs20_wan_metrics;
- struct wpabuf *hs20_connection_capability;
- struct wpabuf *hs20_operating_class;
- struct wpabuf *hs20_osu_providers_list;
- struct wpabuf *hs20_operator_icon_metadata;
- struct wpabuf *hs20_osu_providers_nai_list;
-#endif /* CONFIG_HS20 */
-};
-
-/**
- * struct wpa_bss - BSS table
- *
- * This structure is used to store information about neighboring BSSes in
- * generic format. It is mainly updated based on scan results from the driver.
- */
-struct wpa_bss {
- /** List entry for struct wpa_supplicant::bss */
- struct dl_list list;
- /** List entry for struct wpa_supplicant::bss_id */
- struct dl_list list_id;
- /** Unique identifier for this BSS entry */
- unsigned int id;
- /** Number of counts without seeing this BSS */
- unsigned int scan_miss_count;
- /** Index of the last scan update */
- unsigned int last_update_idx;
- /** Information flags about the BSS/IBSS (WPA_BSS_*) */
- unsigned int flags;
- /** BSSID */
- u8 bssid[ETH_ALEN];
- /** HESSID */
- u8 hessid[ETH_ALEN];
- /** SSID */
- u8 ssid[SSID_MAX_LEN];
- /** Length of SSID */
- size_t ssid_len;
- /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
- int freq;
- /** Beacon interval in TUs (host byte order) */
- u16 beacon_int;
- /** Capability information field in host byte order */
- u16 caps;
- /** Signal quality */
- int qual;
- /** Noise level */
- int noise;
- /** Signal level */
- int level;
- /** Timestamp of last Beacon/Probe Response frame */
- u64 tsf;
- /** Time of the last update (i.e., Beacon or Probe Response RX) */
- struct os_reltime last_update;
- /** Estimated throughput in kbps */
- unsigned int est_throughput;
- /** Signal-to-noise ratio in dB */
- int snr;
- /** ANQP data */
- struct wpa_bss_anqp *anqp;
- /** Length of the following IE field in octets (from Probe Response) */
- size_t ie_len;
- /** Length of the following Beacon IE field in octets */
- size_t beacon_ie_len;
- /* followed by ie_len octets of IEs */
- /* followed by beacon_ie_len octets of IEs */
- u8 ies[];
-};
-
-static inline const u8 * wpa_bss_ie_ptr(const struct wpa_bss *bss)
-{
- return bss->ies;
-}
-
-void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
- const struct wpa_bss *bss);
-void wpa_bss_update_start(struct wpa_supplicant *wpa_s);
-void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res,
- struct os_reltime *fetch_time);
-void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- const char *reason);
-void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
- int new_scan);
-int wpa_bss_init(struct wpa_supplicant *wpa_s);
-void wpa_bss_deinit(struct wpa_supplicant *wpa_s);
-void wpa_bss_flush(struct wpa_supplicant *wpa_s);
-void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age);
-struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ssid, size_t ssid_len);
-struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
- const u8 *bssid);
-struct wpa_bss * wpa_bss_get_bssid_latest(struct wpa_supplicant *wpa_s,
- const u8 *bssid);
-struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id);
-struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s,
- unsigned int idf, unsigned int idl);
-const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie);
-const u8 * wpa_bss_get_ie_ext(const struct wpa_bss *bss, u8 ext);
-const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type);
-const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss,
- u32 vendor_type);
-struct wpabuf * wpa_bss_get_vendor_ie_multi(const struct wpa_bss *bss,
- u32 vendor_type);
-struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss,
- u32 vendor_type);
-int wpa_bss_get_max_rate(const struct wpa_bss *bss);
-int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates);
-struct wpa_bss_anqp * wpa_bss_anqp_alloc(void);
-int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss);
-const u8 * wpa_bss_get_fils_cache_id(const struct wpa_bss *bss);
-int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab);
-
-static inline int bss_is_dmg(const struct wpa_bss *bss)
-{
- return bss->freq > 45000;
-}
-
-/**
- * Test whether a BSS is a PBSS.
- * This checks whether a BSS is a DMG-band PBSS. PBSS is used for P2P DMG
- * network.
- */
-static inline int bss_is_pbss(struct wpa_bss *bss)
-{
- return bss_is_dmg(bss) &&
- (bss->caps & IEEE80211_CAP_DMG_MASK) == IEEE80211_CAP_DMG_PBSS;
-}
-
-static inline void wpa_bss_update_level(struct wpa_bss *bss, int new_level)
-{
- if (bss != NULL && new_level > -WPA_INVALID_NOISE && new_level < 0)
- bss->level = new_level;
-}
-
-void calculate_update_time(const struct os_reltime *fetch_time,
- unsigned int age_ms,
- struct os_reltime *update_time);
-
-#endif /* BSS_H */
diff --git a/wpa_supplicant/bssid_ignore.c b/wpa_supplicant/bssid_ignore.c
deleted file mode 100644
index e37857798a02..000000000000
--- a/wpa_supplicant/bssid_ignore.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * wpa_supplicant - List of temporarily ignored BSSIDs
- * Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "bssid_ignore.h"
-
-/**
- * wpa_bssid_ignore_get - Get the ignore list entry for a BSSID
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID
- * Returns: Matching entry for the BSSID or %NULL if not found
- */
-struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- struct wpa_bssid_ignore *e;
-
- if (wpa_s == NULL || bssid == NULL)
- return NULL;
-
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->was_recently_reconfigured) {
- wpa_bssid_ignore_clear(wpa_s);
- wpa_s->current_ssid->was_recently_reconfigured = false;
- return NULL;
- }
-
- wpa_bssid_ignore_update(wpa_s);
-
- e = wpa_s->bssid_ignore;
- while (e) {
- if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
- return e;
- e = e->next;
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_bssid_ignore_add - Add an BSSID to the ignore list
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID to be added to the ignore list
- * Returns: Current ignore list count on success, -1 on failure
- *
- * This function adds the specified BSSID to the ignore list or increases the
- * ignore count if the BSSID was already listed. It should be called when
- * an association attempt fails either due to the selected BSS rejecting
- * association or due to timeout.
- *
- * This ignore list is used to force %wpa_supplicant to go through all available
- * BSSes before retrying to associate with an BSS that rejected or timed out
- * association. It does not prevent the listed BSS from being used; it only
- * changes the order in which they are tried.
- */
-int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wpa_bssid_ignore *e;
- struct os_reltime now;
-
- if (wpa_s == NULL || bssid == NULL)
- return -1;
-
- e = wpa_bssid_ignore_get(wpa_s, bssid);
- os_get_reltime(&now);
- if (e) {
- e->start = now;
- e->count++;
- if (e->count > 5)
- e->timeout_secs = 1800;
- else if (e->count == 5)
- e->timeout_secs = 600;
- else if (e->count == 4)
- e->timeout_secs = 120;
- else if (e->count == 3)
- e->timeout_secs = 60;
- else
- e->timeout_secs = 10;
- wpa_printf(MSG_INFO, "BSSID " MACSTR
- " ignore list count incremented to %d, ignoring for %d seconds",
- MAC2STR(bssid), e->count, e->timeout_secs);
- return e->count;
- }
-
- e = os_zalloc(sizeof(*e));
- if (e == NULL)
- return -1;
- os_memcpy(e->bssid, bssid, ETH_ALEN);
- e->count = 1;
- e->timeout_secs = 10;
- e->start = now;
- e->next = wpa_s->bssid_ignore;
- wpa_s->bssid_ignore = e;
- wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR
- " into ignore list, ignoring for %d seconds",
- MAC2STR(bssid), e->timeout_secs);
-
- return e->count;
-}
-
-
-/**
- * wpa_bssid_ignore_del - Remove an BSSID from the ignore list
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID to be removed from the ignore list
- * Returns: 0 on success, -1 on failure
- */
-int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wpa_bssid_ignore *e, *prev = NULL;
-
- if (wpa_s == NULL || bssid == NULL)
- return -1;
-
- e = wpa_s->bssid_ignore;
- while (e) {
- if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
- if (prev == NULL) {
- wpa_s->bssid_ignore = e->next;
- } else {
- prev->next = e->next;
- }
- wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR
- " from ignore list", MAC2STR(bssid));
- os_free(e);
- return 0;
- }
- prev = e;
- e = e->next;
- }
- return -1;
-}
-
-
-/**
- * wpa_bssid_ignore_is_listed - Check whether a BSSID is ignored temporarily
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID to be checked
- * Returns: count if BSS is currently considered to be ignored, 0 otherwise
- */
-int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wpa_bssid_ignore *e;
- struct os_reltime now;
-
- e = wpa_bssid_ignore_get(wpa_s, bssid);
- if (!e)
- return 0;
- os_get_reltime(&now);
- if (os_reltime_expired(&now, &e->start, e->timeout_secs))
- return 0;
- return e->count;
-}
-
-
-/**
- * wpa_bssid_ignore_clear - Clear the ignore list of all entries
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bssid_ignore *e, *prev;
-
- e = wpa_s->bssid_ignore;
- wpa_s->bssid_ignore = NULL;
- while (e) {
- prev = e;
- e = e->next;
- wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR
- " from ignore list (clear)", MAC2STR(prev->bssid));
- os_free(prev);
- }
-}
-
-
-/**
- * wpa_bssid_ignore_update - Update the entries in the ignore list,
- * deleting entries that have been expired for over an hour.
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bssid_ignore *e, *prev = NULL;
- struct os_reltime now;
-
- if (!wpa_s)
- return;
-
- e = wpa_s->bssid_ignore;
- os_get_reltime(&now);
- while (e) {
- if (os_reltime_expired(&now, &e->start,
- e->timeout_secs + 3600)) {
- struct wpa_bssid_ignore *to_delete = e;
-
- if (prev) {
- prev->next = e->next;
- e = prev->next;
- } else {
- wpa_s->bssid_ignore = e->next;
- e = wpa_s->bssid_ignore;
- }
- wpa_printf(MSG_INFO, "Removed BSSID " MACSTR
- " from ignore list (expired)",
- MAC2STR(to_delete->bssid));
- os_free(to_delete);
- } else {
- prev = e;
- e = e->next;
- }
- }
-}
diff --git a/wpa_supplicant/bssid_ignore.h b/wpa_supplicant/bssid_ignore.h
deleted file mode 100644
index 721b0e12665f..000000000000
--- a/wpa_supplicant/bssid_ignore.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * wpa_supplicant - List of temporarily ignored BSSIDs
- * Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef BSSID_IGNORE_H
-#define BSSID_IGNORE_H
-
-struct wpa_bssid_ignore {
- struct wpa_bssid_ignore *next;
- u8 bssid[ETH_ALEN];
- int count;
- /* Time of the most recent trigger to ignore this BSSID. */
- struct os_reltime start;
- /*
- * Number of seconds after start that the entey will be considered
- * valid.
- */
- int timeout_secs;
-};
-
-struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
- const u8 *bssid);
-int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid);
-int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid);
-int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid);
-void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s);
-void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s);
-
-#endif /* BSSID_IGNORE_H */
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
deleted file mode 100644
index bf062b0792b7..000000000000
--- a/wpa_supplicant/config.c
+++ /dev/null
@@ -1,5429 +0,0 @@
-/*
- * WPA Supplicant / Configuration parser and common functions
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "utils/uuid.h"
-#include "utils/ip_addr.h"
-#include "common/ieee802_1x_defs.h"
-#include "common/sae.h"
-#include "crypto/sha1.h"
-#include "rsn_supp/wpa.h"
-#include "eap_peer/eap.h"
-#include "p2p/p2p.h"
-#include "fst/fst.h"
-#include "config.h"
-
-
-#if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
-#define NO_CONFIG_WRITE
-#endif
-
-/*
- * Structure for network configuration parsing. This data is used to implement
- * a generic parser for each network block variable. The table of configuration
- * variables is defined below in this file (ssid_fields[]).
- */
-struct parse_data {
- /* Configuration variable name */
- char *name;
-
- /* Parser function for this variable. The parser functions return 0 or 1
- * to indicate success. Value 0 indicates that the parameter value may
- * have changed while value 1 means that the value did not change.
- * Error cases (failure to parse the string) are indicated by returning
- * -1. */
- int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
- int line, const char *value);
-
-#ifndef NO_CONFIG_WRITE
- /* Writer function (i.e., to get the variable in text format from
- * internal presentation). */
- char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
-#endif /* NO_CONFIG_WRITE */
-
- /* Variable specific parameters for the parser. */
- void *param1, *param2, *param3, *param4;
-
- /* 0 = this variable can be included in debug output and ctrl_iface
- * 1 = this variable contains key/private data and it must not be
- * included in debug output unless explicitly requested. In
- * addition, this variable will not be readable through the
- * ctrl_iface.
- */
- int key_data;
-};
-
-
-static int wpa_config_parse_str(const struct parse_data *data,
- struct wpa_ssid *ssid,
- int line, const char *value)
-{
- size_t res_len, *dst_len, prev_len;
- char **dst, *tmp;
-
- if (os_strcmp(value, "NULL") == 0) {
- wpa_printf(MSG_DEBUG, "Unset configuration string '%s'",
- data->name);
- tmp = NULL;
- res_len = 0;
- goto set;
- }
-
- tmp = wpa_config_parse_string(value, &res_len);
- if (tmp == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
- line, data->name,
- data->key_data ? "[KEY DATA REMOVED]" : value);
- return -1;
- }
-
- if (data->key_data) {
- wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
- (u8 *) tmp, res_len);
- } else {
- wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
- (u8 *) tmp, res_len);
- }
-
- if (data->param3 && res_len < (size_t) data->param3) {
- wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
- "min_len=%ld)", line, data->name,
- (unsigned long) res_len, (long) data->param3);
- os_free(tmp);
- return -1;
- }
-
- if (data->param4 && res_len > (size_t) data->param4) {
- wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
- "max_len=%ld)", line, data->name,
- (unsigned long) res_len, (long) data->param4);
- os_free(tmp);
- return -1;
- }
-
-set:
- dst = (char **) (((u8 *) ssid) + (long) data->param1);
- dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
-
- if (data->param2)
- prev_len = *dst_len;
- else if (*dst)
- prev_len = os_strlen(*dst);
- else
- prev_len = 0;
- if ((*dst == NULL && tmp == NULL) ||
- (*dst && tmp && prev_len == res_len &&
- os_memcmp(*dst, tmp, res_len) == 0)) {
- /* No change to the previously configured value */
- os_free(tmp);
- return 1;
- }
-
- os_free(*dst);
- *dst = tmp;
- if (data->param2)
- *dst_len = res_len;
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
-{
- char *buf;
-
- buf = os_malloc(len + 3);
- if (buf == NULL)
- return NULL;
- buf[0] = '"';
- os_memcpy(buf + 1, value, len);
- buf[len + 1] = '"';
- buf[len + 2] = '\0';
-
- return buf;
-}
-
-
-static char * wpa_config_write_string_hex(const u8 *value, size_t len)
-{
- char *buf;
-
- buf = os_zalloc(2 * len + 1);
- if (buf == NULL)
- return NULL;
- wpa_snprintf_hex(buf, 2 * len + 1, value, len);
-
- return buf;
-}
-
-
-static char * wpa_config_write_string(const u8 *value, size_t len)
-{
- if (value == NULL)
- return NULL;
-
- if (is_hex(value, len))
- return wpa_config_write_string_hex(value, len);
- else
- return wpa_config_write_string_ascii(value, len);
-}
-
-
-static char * wpa_config_write_str(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- size_t len;
- char **src;
-
- src = (char **) (((u8 *) ssid) + (long) data->param1);
- if (*src == NULL)
- return NULL;
-
- if (data->param2)
- len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
- else
- len = os_strlen(*src);
-
- return wpa_config_write_string((const u8 *) *src, len);
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_int(const struct parse_data *data,
- struct wpa_ssid *ssid,
- int line, const char *value)
-{
- int val, *dst;
- char *end;
-
- dst = (int *) (((u8 *) ssid) + (long) data->param1);
- val = strtol(value, &end, 0);
- if (*end) {
- wpa_printf(MSG_ERROR, "Line %d: invalid number \"%s\"",
- line, value);
- return -1;
- }
-
- if (*dst == val)
- return 1;
- *dst = val;
- wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
-
- if (data->param3 && *dst < (long) data->param3) {
- wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
- "min_value=%ld)", line, data->name, *dst,
- (long) data->param3);
- *dst = (long) data->param3;
- return -1;
- }
-
- if (data->param4 && *dst > (long) data->param4) {
- wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
- "max_value=%ld)", line, data->name, *dst,
- (long) data->param4);
- *dst = (long) data->param4;
- return -1;
- }
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_int(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- int *src, res;
- char *value;
-
- src = (int *) (((u8 *) ssid) + (long) data->param1);
-
- value = os_malloc(20);
- if (value == NULL)
- return NULL;
- res = os_snprintf(value, 20, "%d", *src);
- if (os_snprintf_error(20, res)) {
- os_free(value);
- return NULL;
- }
- value[20 - 1] = '\0';
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_addr_list(const struct parse_data *data,
- int line, const char *value,
- u8 **list, size_t *num, char *name,
- u8 abort_on_error, u8 masked)
-{
- const char *pos;
- u8 *buf, *n, addr[2 * ETH_ALEN];
- size_t count;
-
- buf = NULL;
- count = 0;
-
- pos = value;
- while (pos && *pos) {
- while (*pos == ' ')
- pos++;
-
- if (hwaddr_masked_aton(pos, addr, &addr[ETH_ALEN], masked)) {
- if (abort_on_error || count == 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: Invalid %s address '%s'",
- line, name, value);
- os_free(buf);
- return -1;
- }
- /* continue anyway since this could have been from a
- * truncated configuration file line */
- wpa_printf(MSG_INFO,
- "Line %d: Ignore likely truncated %s address '%s'",
- line, name, pos);
- } else {
- n = os_realloc_array(buf, count + 1, 2 * ETH_ALEN);
- if (n == NULL) {
- os_free(buf);
- return -1;
- }
- buf = n;
- os_memmove(buf + 2 * ETH_ALEN, buf,
- count * 2 * ETH_ALEN);
- os_memcpy(buf, addr, 2 * ETH_ALEN);
- count++;
- wpa_printf(MSG_MSGDUMP,
- "%s: addr=" MACSTR " mask=" MACSTR,
- name, MAC2STR(addr),
- MAC2STR(&addr[ETH_ALEN]));
- }
-
- pos = os_strchr(pos, ' ');
- }
-
- os_free(*list);
- *list = buf;
- *num = count;
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_addr_list(const struct parse_data *data,
- const u8 *list, size_t num, char *name)
-{
- char *value, *end, *pos;
- int res;
- size_t i;
-
- if (list == NULL || num == 0)
- return NULL;
-
- value = os_malloc(2 * 20 * num);
- if (value == NULL)
- return NULL;
- pos = value;
- end = value + 2 * 20 * num;
-
- for (i = num; i > 0; i--) {
- const u8 *a = list + (i - 1) * 2 * ETH_ALEN;
- const u8 *m = a + ETH_ALEN;
-
- if (i < num)
- *pos++ = ' ';
- res = hwaddr_mask_txt(pos, end - pos, a, m);
- if (res < 0) {
- os_free(value);
- return NULL;
- }
- pos += res;
- }
-
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-static int wpa_config_parse_bssid(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
- os_strcmp(value, "any") == 0) {
- ssid->bssid_set = 0;
- wpa_printf(MSG_MSGDUMP, "BSSID any");
- return 0;
- }
- if (hwaddr_aton(value, ssid->bssid)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
- line, value);
- return -1;
- }
- ssid->bssid_set = 1;
- wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_bssid(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *value;
- int res;
-
- if (!ssid->bssid_set)
- return NULL;
-
- value = os_malloc(20);
- if (value == NULL)
- return NULL;
- res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
- if (os_snprintf_error(20, res)) {
- os_free(value);
- return NULL;
- }
- value[20 - 1] = '\0';
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_bssid_hint(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
- os_strcmp(value, "any") == 0) {
- ssid->bssid_hint_set = 0;
- wpa_printf(MSG_MSGDUMP, "BSSID hint any");
- return 0;
- }
- if (hwaddr_aton(value, ssid->bssid_hint)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID hint '%s'.",
- line, value);
- return -1;
- }
- ssid->bssid_hint_set = 1;
- wpa_hexdump(MSG_MSGDUMP, "BSSID hint", ssid->bssid_hint, ETH_ALEN);
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_bssid_hint(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *value;
- int res;
-
- if (!ssid->bssid_hint_set)
- return NULL;
-
- value = os_malloc(20);
- if (!value)
- return NULL;
- res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid_hint));
- if (os_snprintf_error(20, res)) {
- os_free(value);
- return NULL;
- }
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_bssid_ignore(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_addr_list(data, line, value,
- &ssid->bssid_ignore,
- &ssid->num_bssid_ignore,
- "bssid_ignore", 1, 1);
-}
-
-
-/* deprecated alias for bssid_ignore for backwards compatibility */
-static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_addr_list(data, line, value,
- &ssid->bssid_ignore,
- &ssid->num_bssid_ignore,
- "bssid_ignore", 1, 1);
-}
-
-
-#ifndef NO_CONFIG_WRITE
-
-static char * wpa_config_write_bssid_ignore(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_addr_list(data, ssid->bssid_ignore,
- ssid->num_bssid_ignore,
- "bssid_ignore");
-}
-
-
-/* deprecated alias for bssid_ignore for backwards compatibility */
-static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_addr_list(data, ssid->bssid_ignore,
- ssid->num_bssid_ignore,
- "bssid_ignore");
-}
-
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_bssid_accept(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_addr_list(data, line, value,
- &ssid->bssid_accept,
- &ssid->num_bssid_accept,
- "bssid_accept", 1, 1);
-}
-
-
-/* deprecated alias for bssid_accept for backwards compatibility */
-static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_addr_list(data, line, value,
- &ssid->bssid_accept,
- &ssid->num_bssid_accept,
- "bssid_accept", 1, 1);
-}
-
-
-#ifndef NO_CONFIG_WRITE
-
-static char * wpa_config_write_bssid_accept(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_addr_list(data, ssid->bssid_accept,
- ssid->num_bssid_accept,
- "bssid_accept");
-}
-
-
-/* deprecated alias for bssid_accept for backwards compatibility */
-static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_addr_list(data, ssid->bssid_accept,
- ssid->num_bssid_accept,
- "bssid_accept");
-}
-
-#endif /* NO_CONFIG_WRITE */
-
-
-#ifndef NO_CONFIG_WRITE
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_psk(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
-#ifdef CONFIG_EXT_PASSWORD
- if (os_strncmp(value, "ext:", 4) == 0) {
- str_clear_free(ssid->passphrase);
- ssid->passphrase = NULL;
- ssid->psk_set = 0;
- os_free(ssid->ext_psk);
- ssid->ext_psk = os_strdup(value + 4);
- if (ssid->ext_psk == NULL)
- return -1;
- wpa_printf(MSG_DEBUG, "PSK: External password '%s'",
- ssid->ext_psk);
- return 0;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (*value == '"') {
-#ifndef CONFIG_NO_PBKDF2
- const char *pos;
- size_t len;
-
- value++;
- pos = os_strrchr(value, '"');
- if (pos)
- len = pos - value;
- else
- len = os_strlen(value);
- if (len < 8 || len > 63) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
- "length %lu (expected: 8..63) '%s'.",
- line, (unsigned long) len, value);
- return -1;
- }
- wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
- (u8 *) value, len);
- if (has_ctrl_char((u8 *) value, len)) {
- wpa_printf(MSG_ERROR,
- "Line %d: Invalid passphrase character",
- line);
- return -1;
- }
- if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
- os_memcmp(ssid->passphrase, value, len) == 0) {
- /* No change to the previously configured value */
- return 1;
- }
- ssid->psk_set = 0;
- str_clear_free(ssid->passphrase);
- ssid->passphrase = dup_binstr(value, len);
- if (ssid->passphrase == NULL)
- return -1;
- return 0;
-#else /* CONFIG_NO_PBKDF2 */
- wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
- "supported.", line);
- return -1;
-#endif /* CONFIG_NO_PBKDF2 */
- }
-
- if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
- value[PMK_LEN * 2] != '\0') {
- wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
- line, value);
- return -1;
- }
-
- str_clear_free(ssid->passphrase);
- ssid->passphrase = NULL;
-
- ssid->psk_set = 1;
- wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_psk(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_EXT_PASSWORD
- if (ssid->ext_psk) {
- size_t len = 4 + os_strlen(ssid->ext_psk) + 1;
- char *buf = os_malloc(len);
- int res;
-
- if (buf == NULL)
- return NULL;
- res = os_snprintf(buf, len, "ext:%s", ssid->ext_psk);
- if (os_snprintf_error(len, res)) {
- os_free(buf);
- buf = NULL;
- }
- return buf;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (ssid->passphrase)
- return wpa_config_write_string_ascii(
- (const u8 *) ssid->passphrase,
- os_strlen(ssid->passphrase));
-
- if (ssid->psk_set)
- return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
-
- return NULL;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_proto(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val = 0, last, errors = 0;
- char *start, *end, *buf;
-
- buf = os_strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (*start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (os_strcmp(start, "WPA") == 0)
- val |= WPA_PROTO_WPA;
- else if (os_strcmp(start, "RSN") == 0 ||
- os_strcmp(start, "WPA2") == 0)
- val |= WPA_PROTO_RSN;
- else if (os_strcmp(start, "OSEN") == 0)
- val |= WPA_PROTO_OSEN;
- else {
- wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
- line, start);
- errors++;
- }
-
- if (last)
- break;
- start = end + 1;
- }
- os_free(buf);
-
- if (val == 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: no proto values configured.", line);
- errors++;
- }
-
- if (!errors && ssid->proto == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
- ssid->proto = val;
- return errors ? -1 : 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_proto(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- int ret;
- char *buf, *pos, *end;
-
- pos = buf = os_zalloc(20);
- if (buf == NULL)
- return NULL;
- end = buf + 20;
-
- if (ssid->proto & WPA_PROTO_WPA) {
- ret = os_snprintf(pos, end - pos, "%sWPA",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- if (ssid->proto & WPA_PROTO_RSN) {
- ret = os_snprintf(pos, end - pos, "%sRSN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- if (ssid->proto & WPA_PROTO_OSEN) {
- ret = os_snprintf(pos, end - pos, "%sOSEN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- if (pos == buf) {
- os_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_key_mgmt(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val = 0, last, errors = 0;
- char *start, *end, *buf;
-
- buf = os_strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (*start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (os_strcmp(start, "WPA-PSK") == 0)
- val |= WPA_KEY_MGMT_PSK;
- else if (os_strcmp(start, "WPA-EAP") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X;
- else if (os_strcmp(start, "IEEE8021X") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
- else if (os_strcmp(start, "NONE") == 0)
- val |= WPA_KEY_MGMT_NONE;
- else if (os_strcmp(start, "WPA-NONE") == 0)
- val |= WPA_KEY_MGMT_WPA_NONE;
-#ifdef CONFIG_IEEE80211R
- else if (os_strcmp(start, "FT-PSK") == 0)
- val |= WPA_KEY_MGMT_FT_PSK;
- else if (os_strcmp(start, "FT-EAP") == 0)
- val |= WPA_KEY_MGMT_FT_IEEE8021X;
-#ifdef CONFIG_SHA384
- else if (os_strcmp(start, "FT-EAP-SHA384") == 0)
- val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
-#endif /* CONFIG_SHA384 */
-#endif /* CONFIG_IEEE80211R */
- else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
- val |= WPA_KEY_MGMT_PSK_SHA256;
- else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
-#ifdef CONFIG_WPS
- else if (os_strcmp(start, "WPS") == 0)
- val |= WPA_KEY_MGMT_WPS;
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_SAE
- else if (os_strcmp(start, "SAE") == 0)
- val |= WPA_KEY_MGMT_SAE;
- else if (os_strcmp(start, "FT-SAE") == 0)
- val |= WPA_KEY_MGMT_FT_SAE;
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_HS20
- else if (os_strcmp(start, "OSEN") == 0)
- val |= WPA_KEY_MGMT_OSEN;
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_SUITEB
- else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
-#endif /* CONFIG_SUITEB */
-#ifdef CONFIG_SUITEB192
- else if (os_strcmp(start, "WPA-EAP-SUITE-B-192") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
-#endif /* CONFIG_SUITEB192 */
-#ifdef CONFIG_FILS
- else if (os_strcmp(start, "FILS-SHA256") == 0)
- val |= WPA_KEY_MGMT_FILS_SHA256;
- else if (os_strcmp(start, "FILS-SHA384") == 0)
- val |= WPA_KEY_MGMT_FILS_SHA384;
-#ifdef CONFIG_IEEE80211R
- else if (os_strcmp(start, "FT-FILS-SHA256") == 0)
- val |= WPA_KEY_MGMT_FT_FILS_SHA256;
- else if (os_strcmp(start, "FT-FILS-SHA384") == 0)
- val |= WPA_KEY_MGMT_FT_FILS_SHA384;
-#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_OWE
- else if (os_strcmp(start, "OWE") == 0)
- val |= WPA_KEY_MGMT_OWE;
-#endif /* CONFIG_OWE */
-#ifdef CONFIG_DPP
- else if (os_strcmp(start, "DPP") == 0)
- val |= WPA_KEY_MGMT_DPP;
-#endif /* CONFIG_DPP */
- else {
- wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
- line, start);
- errors++;
- }
-
- if (last)
- break;
- start = end + 1;
- }
- os_free(buf);
-
- if (val == 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: no key_mgmt values configured.", line);
- errors++;
- }
-
- if (!errors && ssid->key_mgmt == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
- ssid->key_mgmt = val;
- return errors ? -1 : 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_key_mgmt(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *buf, *pos, *end;
- int ret;
-
- pos = buf = os_zalloc(100);
- if (buf == NULL)
- return NULL;
- end = buf + 100;
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
- ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
- ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
- ret = os_snprintf(pos, end - pos, "%sNONE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
- ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
-#ifdef CONFIG_IEEE80211R
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) {
- ret = os_snprintf(pos, end - pos, "%sFT-PSK",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
- ret = os_snprintf(pos, end - pos, "%sFT-EAP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
-#ifdef CONFIG_SHA384
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
- ret = os_snprintf(pos, end - pos, "%sFT-EAP-SHA384",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_SHA384 */
-#endif /* CONFIG_IEEE80211R */
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
-#ifdef CONFIG_WPS
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- ret = os_snprintf(pos, end - pos, "%sWPS",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_SAE
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
- ret = os_snprintf(pos, end - pos, "%sSAE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_SAE) {
- ret = os_snprintf(pos, end - pos, "%sFT-SAE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_HS20
- if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN) {
- ret = os_snprintf(pos, end - pos, "%sOSEN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_HS20 */
-
-#ifdef CONFIG_SUITEB
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
- ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_SUITEB */
-
-#ifdef CONFIG_SUITEB192
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
- ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B-192",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_SUITEB192 */
-
-#ifdef CONFIG_FILS
- if (ssid->key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sFILS-SHA256",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
- if (ssid->key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, "%sFILS-SHA384",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#ifdef CONFIG_IEEE80211R
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA256",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
- if (ssid->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA384",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_DPP
- if (ssid->key_mgmt & WPA_KEY_MGMT_DPP) {
- ret = os_snprintf(pos, end - pos, "%sDPP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_OWE
- if (ssid->key_mgmt & WPA_KEY_MGMT_OWE) {
- ret = os_snprintf(pos, end - pos, "%sOWE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-#endif /* CONFIG_OWE */
-
- if (pos == buf) {
- os_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_cipher(int line, const char *value)
-{
-#ifdef CONFIG_NO_WPA
- return -1;
-#else /* CONFIG_NO_WPA */
- int val = wpa_parse_cipher(value);
- if (val < 0) {
- wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
- line, value);
- return -1;
- }
- if (val == 0) {
- wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
- line);
- return -1;
- }
- return val;
-#endif /* CONFIG_NO_WPA */
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_cipher(int cipher)
-{
-#ifdef CONFIG_NO_WPA
- return NULL;
-#else /* CONFIG_NO_WPA */
- char *buf = os_zalloc(50);
- if (buf == NULL)
- return NULL;
-
- if (wpa_write_ciphers(buf, buf + 50, cipher, " ") < 0) {
- os_free(buf);
- return NULL;
- }
-
- return buf;
-#endif /* CONFIG_NO_WPA */
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_pairwise(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val;
- val = wpa_config_parse_cipher(line, value);
- if (val == -1)
- return -1;
- if (val & ~WPA_ALLOWED_PAIRWISE_CIPHERS) {
- wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
- "(0x%x).", line, val);
- return -1;
- }
-
- if (ssid->pairwise_cipher == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
- ssid->pairwise_cipher = val;
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_pairwise(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_cipher(ssid->pairwise_cipher);
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_group(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val;
- val = wpa_config_parse_cipher(line, value);
- if (val == -1)
- return -1;
-
- /*
- * Backwards compatibility - filter out WEP ciphers that were previously
- * allowed.
- */
- val &= ~(WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40);
-
- if (val & ~WPA_ALLOWED_GROUP_CIPHERS) {
- wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
- "(0x%x).", line, val);
- return -1;
- }
-
- if (ssid->group_cipher == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
- ssid->group_cipher = val;
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_group(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_cipher(ssid->group_cipher);
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_group_mgmt(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val;
-
- val = wpa_config_parse_cipher(line, value);
- if (val == -1)
- return -1;
-
- if (val & ~WPA_ALLOWED_GROUP_MGMT_CIPHERS) {
- wpa_printf(MSG_ERROR,
- "Line %d: not allowed group management cipher (0x%x).",
- line, val);
- return -1;
- }
-
- if (ssid->group_mgmt_cipher == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "group_mgmt: 0x%x", val);
- ssid->group_mgmt_cipher = val;
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_group_mgmt(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_cipher(ssid->group_mgmt_cipher);
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_auth_alg(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int val = 0, last, errors = 0;
- char *start, *end, *buf;
-
- buf = os_strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (*start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (os_strcmp(start, "OPEN") == 0)
- val |= WPA_AUTH_ALG_OPEN;
- else if (os_strcmp(start, "SHARED") == 0)
- val |= WPA_AUTH_ALG_SHARED;
- else if (os_strcmp(start, "LEAP") == 0)
- val |= WPA_AUTH_ALG_LEAP;
- else {
- wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
- line, start);
- errors++;
- }
-
- if (last)
- break;
- start = end + 1;
- }
- os_free(buf);
-
- if (val == 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: no auth_alg values configured.", line);
- errors++;
- }
-
- if (!errors && ssid->auth_alg == val)
- return 1;
- wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
- ssid->auth_alg = val;
- return errors ? -1 : 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_auth_alg(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *buf, *pos, *end;
- int ret;
-
- pos = buf = os_zalloc(30);
- if (buf == NULL)
- return NULL;
- end = buf + 30;
-
- if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
- ret = os_snprintf(pos, end - pos, "%sOPEN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
- ret = os_snprintf(pos, end - pos, "%sSHARED",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
- ret = os_snprintf(pos, end - pos, "%sLEAP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- if (pos == buf) {
- os_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int * wpa_config_parse_int_array(const char *value)
-{
- int *freqs;
- size_t used, len;
- const char *pos;
-
- used = 0;
- len = 10;
- freqs = os_calloc(len + 1, sizeof(int));
- if (freqs == NULL)
- return NULL;
-
- pos = value;
- while (pos) {
- while (*pos == ' ')
- pos++;
- if (used == len) {
- int *n;
- size_t i;
- n = os_realloc_array(freqs, len * 2 + 1, sizeof(int));
- if (n == NULL) {
- os_free(freqs);
- return NULL;
- }
- for (i = len; i <= len * 2; i++)
- n[i] = 0;
- freqs = n;
- len *= 2;
- }
-
- freqs[used] = atoi(pos);
- if (freqs[used] == 0)
- break;
- used++;
- pos = os_strchr(pos + 1, ' ');
- }
-
- return freqs;
-}
-
-
-static int wpa_config_parse_scan_freq(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int *freqs;
-
- freqs = wpa_config_parse_int_array(value);
- if (freqs == NULL)
- return -1;
- if (freqs[0] == 0) {
- os_free(freqs);
- freqs = NULL;
- }
- os_free(ssid->scan_freq);
- ssid->scan_freq = freqs;
-
- return 0;
-}
-
-
-static int wpa_config_parse_freq_list(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int *freqs;
-
- freqs = wpa_config_parse_int_array(value);
- if (freqs == NULL)
- return -1;
- if (freqs[0] == 0) {
- os_free(freqs);
- freqs = NULL;
- }
- os_free(ssid->freq_list);
- ssid->freq_list = freqs;
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_freqs(const struct parse_data *data,
- const int *freqs)
-{
- char *buf, *pos, *end;
- int i, ret;
- size_t count;
-
- if (freqs == NULL)
- return NULL;
-
- count = 0;
- for (i = 0; freqs[i]; i++)
- count++;
-
- pos = buf = os_zalloc(10 * count + 1);
- if (buf == NULL)
- return NULL;
- end = buf + 10 * count + 1;
-
- for (i = 0; freqs[i]; i++) {
- ret = os_snprintf(pos, end - pos, "%s%u",
- i == 0 ? "" : " ", freqs[i]);
- if (os_snprintf_error(end - pos, ret)) {
- end[-1] = '\0';
- return buf;
- }
- pos += ret;
- }
-
- return buf;
-}
-
-
-static char * wpa_config_write_scan_freq(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_freqs(data, ssid->scan_freq);
-}
-
-
-static char * wpa_config_write_freq_list(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_freqs(data, ssid->freq_list);
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-#ifdef IEEE8021X_EAPOL
-static int wpa_config_parse_eap(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int last, errors = 0;
- char *start, *end, *buf;
- struct eap_method_type *methods = NULL, *tmp;
- size_t num_methods = 0;
-
- buf = os_strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (*start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- tmp = methods;
- methods = os_realloc_array(methods, num_methods + 1,
- sizeof(*methods));
- if (methods == NULL) {
- os_free(tmp);
- os_free(buf);
- return -1;
- }
- methods[num_methods].method = eap_peer_get_type(
- start, &methods[num_methods].vendor);
- if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
- methods[num_methods].method == EAP_TYPE_NONE) {
- wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
- "'%s'", line, start);
- wpa_printf(MSG_ERROR, "You may need to add support for"
- " this EAP method during wpa_supplicant\n"
- "build time configuration.\n"
- "See README for more information.");
- errors++;
- } else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
- methods[num_methods].method == EAP_TYPE_LEAP)
- ssid->leap++;
- else
- ssid->non_leap++;
- num_methods++;
- if (last)
- break;
- start = end + 1;
- }
- os_free(buf);
-
- tmp = methods;
- methods = os_realloc_array(methods, num_methods + 1, sizeof(*methods));
- if (methods == NULL) {
- os_free(tmp);
- return -1;
- }
- methods[num_methods].vendor = EAP_VENDOR_IETF;
- methods[num_methods].method = EAP_TYPE_NONE;
- num_methods++;
-
- if (!errors && ssid->eap.eap_methods) {
- struct eap_method_type *prev_m;
- size_t i, j, prev_methods, match = 0;
-
- prev_m = ssid->eap.eap_methods;
- for (i = 0; prev_m[i].vendor != EAP_VENDOR_IETF ||
- prev_m[i].method != EAP_TYPE_NONE; i++) {
- /* Count the methods */
- }
- prev_methods = i + 1;
-
- for (i = 0; prev_methods == num_methods && i < prev_methods;
- i++) {
- for (j = 0; j < num_methods; j++) {
- if (prev_m[i].vendor == methods[j].vendor &&
- prev_m[i].method == methods[j].method) {
- match++;
- break;
- }
- }
- }
- if (match == num_methods) {
- os_free(methods);
- return 1;
- }
- }
- wpa_hexdump(MSG_MSGDUMP, "eap methods",
- (u8 *) methods, num_methods * sizeof(*methods));
- os_free(ssid->eap.eap_methods);
- ssid->eap.eap_methods = methods;
- return errors ? -1 : 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_eap(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- int i, ret;
- char *buf, *pos, *end;
- const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
- const char *name;
-
- if (eap_methods == NULL)
- return NULL;
-
- pos = buf = os_zalloc(100);
- if (buf == NULL)
- return NULL;
- end = buf + 100;
-
- for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
- eap_methods[i].method != EAP_TYPE_NONE; i++) {
- name = eap_get_name(eap_methods[i].vendor,
- eap_methods[i].method);
- if (name) {
- ret = os_snprintf(pos, end - pos, "%s%s",
- pos == buf ? "" : " ", name);
- if (os_snprintf_error(end - pos, ret))
- break;
- pos += ret;
- }
- }
-
- end[-1] = '\0';
-
- return buf;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_password(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- u8 *hash;
-
- if (os_strcmp(value, "NULL") == 0) {
- if (!ssid->eap.password)
- return 1; /* Already unset */
- wpa_printf(MSG_DEBUG, "Unset configuration string 'password'");
- bin_clear_free(ssid->eap.password, ssid->eap.password_len);
- ssid->eap.password = NULL;
- ssid->eap.password_len = 0;
- return 0;
- }
-
-#ifdef CONFIG_EXT_PASSWORD
- if (os_strncmp(value, "ext:", 4) == 0) {
- char *name = os_strdup(value + 4);
- if (!name)
- return -1;
- bin_clear_free(ssid->eap.password, ssid->eap.password_len);
- ssid->eap.password = (u8 *) name;
- ssid->eap.password_len = os_strlen(name);
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
- ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_PASSWORD;
- return 0;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (os_strncmp(value, "hash:", 5) != 0) {
- char *tmp;
- size_t res_len;
-
- tmp = wpa_config_parse_string(value, &res_len);
- if (!tmp) {
- wpa_printf(MSG_ERROR,
- "Line %d: failed to parse password.", line);
- return -1;
- }
- wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
- (u8 *) tmp, res_len);
-
- bin_clear_free(ssid->eap.password, ssid->eap.password_len);
- ssid->eap.password = (u8 *) tmp;
- ssid->eap.password_len = res_len;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
-
- return 0;
- }
-
-
- /* NtPasswordHash: hash:<32 hex digits> */
- if (os_strlen(value + 5) != 2 * 16) {
- wpa_printf(MSG_ERROR,
- "Line %d: Invalid password hash length (expected 32 hex digits)",
- line);
- return -1;
- }
-
- hash = os_malloc(16);
- if (!hash)
- return -1;
-
- if (hexstr2bin(value + 5, hash, 16)) {
- os_free(hash);
- wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
- return -1;
- }
-
- wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
-
- if (ssid->eap.password && ssid->eap.password_len == 16 &&
- os_memcmp(ssid->eap.password, hash, 16) == 0 &&
- (ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
- bin_clear_free(hash, 16);
- return 1;
- }
- bin_clear_free(ssid->eap.password, ssid->eap.password_len);
- ssid->eap.password = hash;
- ssid->eap.password_len = 16;
- ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
-
- return 0;
-}
-
-
-static int wpa_config_parse_machine_password(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- u8 *hash;
-
- if (os_strcmp(value, "NULL") == 0) {
- if (!ssid->eap.machine_password)
- return 1; /* Already unset */
- wpa_printf(MSG_DEBUG,
- "Unset configuration string 'machine_password'");
- bin_clear_free(ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- ssid->eap.machine_password = NULL;
- ssid->eap.machine_password_len = 0;
- return 0;
- }
-
-#ifdef CONFIG_EXT_PASSWORD
- if (os_strncmp(value, "ext:", 4) == 0) {
- char *name = os_strdup(value + 4);
-
- if (!name)
- return -1;
- bin_clear_free(ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- ssid->eap.machine_password = (u8 *) name;
- ssid->eap.machine_password_len = os_strlen(name);
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
- ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
- return 0;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (os_strncmp(value, "hash:", 5) != 0) {
- char *tmp;
- size_t res_len;
-
- tmp = wpa_config_parse_string(value, &res_len);
- if (!tmp) {
- wpa_printf(MSG_ERROR,
- "Line %d: failed to parse machine_password.",
- line);
- return -1;
- }
- wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
- (u8 *) tmp, res_len);
-
- bin_clear_free(ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- ssid->eap.machine_password = (u8 *) tmp;
- ssid->eap.machine_password_len = res_len;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
-
- return 0;
- }
-
-
- /* NtPasswordHash: hash:<32 hex digits> */
- if (os_strlen(value + 5) != 2 * 16) {
- wpa_printf(MSG_ERROR,
- "Line %d: Invalid machine_password hash length (expected 32 hex digits)",
- line);
- return -1;
- }
-
- hash = os_malloc(16);
- if (!hash)
- return -1;
-
- if (hexstr2bin(value + 5, hash, 16)) {
- os_free(hash);
- wpa_printf(MSG_ERROR, "Line %d: Invalid machine_password hash",
- line);
- return -1;
- }
-
- wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
-
- if (ssid->eap.machine_password &&
- ssid->eap.machine_password_len == 16 &&
- os_memcmp(ssid->eap.machine_password, hash, 16) == 0 &&
- (ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
- bin_clear_free(hash, 16);
- return 1;
- }
- bin_clear_free(ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- ssid->eap.machine_password = hash;
- ssid->eap.machine_password_len = 16;
- ssid->eap.flags |= EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
- ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-
-static char * wpa_config_write_password(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *buf;
-
- if (!ssid->eap.password)
- return NULL;
-
-#ifdef CONFIG_EXT_PASSWORD
- if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
- buf = os_zalloc(4 + ssid->eap.password_len + 1);
- if (!buf)
- return NULL;
- os_memcpy(buf, "ext:", 4);
- os_memcpy(buf + 4, ssid->eap.password, ssid->eap.password_len);
- return buf;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
- return wpa_config_write_string(
- ssid->eap.password, ssid->eap.password_len);
- }
-
- buf = os_malloc(5 + 32 + 1);
- if (!buf)
- return NULL;
-
- os_memcpy(buf, "hash:", 5);
- wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16);
-
- return buf;
-}
-
-
-static char * wpa_config_write_machine_password(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *buf;
-
- if (!ssid->eap.machine_password)
- return NULL;
-
-#ifdef CONFIG_EXT_PASSWORD
- if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD) {
- buf = os_zalloc(4 + ssid->eap.machine_password_len + 1);
- if (!buf)
- return NULL;
- os_memcpy(buf, "ext:", 4);
- os_memcpy(buf + 4, ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- return buf;
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
- return wpa_config_write_string(
- ssid->eap.machine_password,
- ssid->eap.machine_password_len);
- }
-
- buf = os_malloc(5 + 32 + 1);
- if (!buf)
- return NULL;
-
- os_memcpy(buf, "hash:", 5);
- wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.machine_password, 16);
-
- return buf;
-}
-
-#endif /* NO_CONFIG_WRITE */
-#endif /* IEEE8021X_EAPOL */
-
-
-#ifdef CONFIG_WEP
-
-static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
- const char *value, int idx)
-{
- char *buf, title[20];
- int res;
-
- buf = wpa_config_parse_string(value, len);
- if (buf == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
- line, idx, value);
- return -1;
- }
- if (*len > MAX_WEP_KEY_LEN) {
- wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
- line, idx, value);
- os_free(buf);
- return -1;
- }
- if (*len && *len != 5 && *len != 13 && *len != 16) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key length %u - "
- "this network block will be ignored",
- line, (unsigned int) *len);
- }
- os_memcpy(key, buf, *len);
- str_clear_free(buf);
- res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
- if (!os_snprintf_error(sizeof(title), res))
- wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
- return 0;
-}
-
-
-static int wpa_config_parse_wep_key0(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_wep_key(ssid->wep_key[0],
- &ssid->wep_key_len[0], line,
- value, 0);
-}
-
-
-static int wpa_config_parse_wep_key1(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_wep_key(ssid->wep_key[1],
- &ssid->wep_key_len[1], line,
- value, 1);
-}
-
-
-static int wpa_config_parse_wep_key2(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_wep_key(ssid->wep_key[2],
- &ssid->wep_key_len[2], line,
- value, 2);
-}
-
-
-static int wpa_config_parse_wep_key3(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_wep_key(ssid->wep_key[3],
- &ssid->wep_key_len[3], line,
- value, 3);
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
-{
- if (ssid->wep_key_len[idx] == 0)
- return NULL;
- return wpa_config_write_string(ssid->wep_key[idx],
- ssid->wep_key_len[idx]);
-}
-
-
-static char * wpa_config_write_wep_key0(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_wep_key(ssid, 0);
-}
-
-
-static char * wpa_config_write_wep_key1(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_wep_key(ssid, 1);
-}
-
-
-static char * wpa_config_write_wep_key2(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_wep_key(ssid, 2);
-}
-
-
-static char * wpa_config_write_wep_key3(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_wep_key(ssid, 3);
-}
-#endif /* NO_CONFIG_WRITE */
-
-#endif /* CONFIG_WEP */
-
-
-#ifdef CONFIG_P2P
-
-static int wpa_config_parse_go_p2p_dev_addr(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
- os_strcmp(value, "any") == 0) {
- os_memset(ssid->go_p2p_dev_addr, 0, ETH_ALEN);
- wpa_printf(MSG_MSGDUMP, "GO P2P Device Address any");
- return 0;
- }
- if (hwaddr_aton(value, ssid->go_p2p_dev_addr)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid GO P2P Device Address '%s'.",
- line, value);
- return -1;
- }
- ssid->bssid_set = 1;
- wpa_printf(MSG_MSGDUMP, "GO P2P Device Address " MACSTR,
- MAC2STR(ssid->go_p2p_dev_addr));
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_go_p2p_dev_addr(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *value;
- int res;
-
- if (is_zero_ether_addr(ssid->go_p2p_dev_addr))
- return NULL;
-
- value = os_malloc(20);
- if (value == NULL)
- return NULL;
- res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->go_p2p_dev_addr));
- if (os_snprintf_error(20, res)) {
- os_free(value);
- return NULL;
- }
- value[20 - 1] = '\0';
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- return wpa_config_parse_addr_list(data, line, value,
- &ssid->p2p_client_list,
- &ssid->num_p2p_clients,
- "p2p_client_list", 0, 0);
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_addr_list(data, ssid->p2p_client_list,
- ssid->num_p2p_clients,
- "p2p_client_list");
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-static int wpa_config_parse_psk_list(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- struct psk_list_entry *p;
- const char *pos;
-
- p = os_zalloc(sizeof(*p));
- if (p == NULL)
- return -1;
-
- pos = value;
- if (os_strncmp(pos, "P2P-", 4) == 0) {
- p->p2p = 1;
- pos += 4;
- }
-
- if (hwaddr_aton(pos, p->addr)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list address '%s'",
- line, pos);
- os_free(p);
- return -1;
- }
- pos += 17;
- if (*pos != '-') {
- wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list '%s'",
- line, pos);
- os_free(p);
- return -1;
- }
- pos++;
-
- if (hexstr2bin(pos, p->psk, PMK_LEN) || pos[PMK_LEN * 2] != '\0') {
- wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list PSK '%s'",
- line, pos);
- os_free(p);
- return -1;
- }
-
- dl_list_add(&ssid->psk_list, &p->list);
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_psk_list(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return NULL;
-}
-#endif /* NO_CONFIG_WRITE */
-
-#endif /* CONFIG_P2P */
-
-
-#ifdef CONFIG_MESH
-
-static int wpa_config_parse_mesh_basic_rates(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- int *rates = wpa_config_parse_int_array(value);
-
- if (rates == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid mesh_basic_rates '%s'",
- line, value);
- return -1;
- }
- if (rates[0] == 0) {
- os_free(rates);
- rates = NULL;
- }
-
- os_free(ssid->mesh_basic_rates);
- ssid->mesh_basic_rates = rates;
-
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-
-static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return wpa_config_write_freqs(data, ssid->mesh_basic_rates);
-}
-
-#endif /* NO_CONFIG_WRITE */
-
-#endif /* CONFIG_MESH */
-
-
-#ifdef CONFIG_MACSEC
-
-static int wpa_config_parse_mka_cak(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- size_t len;
-
- len = os_strlen(value);
- if (len > 2 * MACSEC_CAK_MAX_LEN ||
- (len != 2 * 16 && len != 2 * 32) ||
- hexstr2bin(value, ssid->mka_cak, len / 2)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CAK '%s'.",
- line, value);
- return -1;
- }
- ssid->mka_cak_len = len / 2;
- ssid->mka_psk_set |= MKA_PSK_SET_CAK;
-
- wpa_hexdump_key(MSG_MSGDUMP, "MKA-CAK", ssid->mka_cak,
- ssid->mka_cak_len);
- return 0;
-}
-
-
-static int wpa_config_parse_mka_ckn(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- size_t len;
-
- len = os_strlen(value);
- if (len > 2 * MACSEC_CKN_MAX_LEN || /* too long */
- len < 2 || /* too short */
- len % 2 != 0 /* not an integral number of bytes */) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.",
- line, value);
- return -1;
- }
- ssid->mka_ckn_len = len / 2;
- if (hexstr2bin(value, ssid->mka_ckn, ssid->mka_ckn_len)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.",
- line, value);
- return -1;
- }
-
- ssid->mka_psk_set |= MKA_PSK_SET_CKN;
-
- wpa_hexdump_key(MSG_MSGDUMP, "MKA-CKN", ssid->mka_ckn,
- ssid->mka_ckn_len);
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-
-static char * wpa_config_write_mka_cak(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK))
- return NULL;
-
- return wpa_config_write_string_hex(ssid->mka_cak, ssid->mka_cak_len);
-}
-
-
-static char * wpa_config_write_mka_ckn(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN))
- return NULL;
- return wpa_config_write_string_hex(ssid->mka_ckn, ssid->mka_ckn_len);
-}
-
-#endif /* NO_CONFIG_WRITE */
-
-#endif /* CONFIG_MACSEC */
-
-
-#ifdef CONFIG_OCV
-
-static int wpa_config_parse_ocv(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- char *end;
-
- ssid->ocv = strtol(value, &end, 0);
- if (*end || ssid->ocv < 0 || ssid->ocv > 1) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid ocv value '%s'.",
- line, value);
- return -1;
- }
- if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION)
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_ocv(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- char *value = os_malloc(20);
-
- if (!value)
- return NULL;
- os_snprintf(value, 20, "%d", ssid->ocv);
- value[20 - 1] = '\0';
- return value;
-}
-#endif /* NO_CONFIG_WRITE */
-
-#endif /* CONFIG_OCV */
-
-
-static int wpa_config_parse_peerkey(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
-{
- wpa_printf(MSG_INFO, "NOTE: Obsolete peerkey parameter ignored");
- return 0;
-}
-
-
-#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_peerkey(const struct parse_data *data,
- struct wpa_ssid *ssid)
-{
- return NULL;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-/* Helper macros for network block parser */
-
-#ifdef OFFSET
-#undef OFFSET
-#endif /* OFFSET */
-/* OFFSET: Get offset of a variable within the wpa_ssid structure */
-#define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
-
-/* STR: Define a string variable for an ASCII string; f = field name */
-#ifdef NO_CONFIG_WRITE
-#define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
-#define _STRe(f, m) #f, wpa_config_parse_str, OFFSET(eap.m)
-#else /* NO_CONFIG_WRITE */
-#define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
-#define _STRe(f, m) #f, wpa_config_parse_str, wpa_config_write_str, \
- OFFSET(eap.m)
-#endif /* NO_CONFIG_WRITE */
-#define STR(f) _STR(f), NULL, NULL, NULL, 0
-#define STRe(f, m) _STRe(f, m), NULL, NULL, NULL, 0
-#define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
-#define STR_KEYe(f, m) _STRe(f, m), NULL, NULL, NULL, 1
-
-/* STR_LEN: Define a string variable with a separate variable for storing the
- * data length. Unlike STR(), this can be used to store arbitrary binary data
- * (i.e., even nul termination character). */
-#define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
-#define _STR_LENe(f, m) _STRe(f, m), OFFSET(eap.m ## _len)
-#define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
-#define STR_LENe(f, m) _STR_LENe(f, m), NULL, NULL, 0
-#define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
-
-/* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
- * explicitly specified. */
-#define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
-#define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
-#define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
-
-#ifdef NO_CONFIG_WRITE
-#define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
-#define _INTe(f, m) #f, wpa_config_parse_int, OFFSET(eap.m), (void *) 0
-#else /* NO_CONFIG_WRITE */
-#define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
- OFFSET(f), (void *) 0
-#define _INTe(f, m) #f, wpa_config_parse_int, wpa_config_write_int, \
- OFFSET(eap.m), (void *) 0
-#endif /* NO_CONFIG_WRITE */
-
-/* INT: Define an integer variable */
-#define INT(f) _INT(f), NULL, NULL, 0
-#define INTe(f, m) _INTe(f, m), NULL, NULL, 0
-
-/* INT_RANGE: Define an integer variable with allowed value range */
-#define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
-
-/* FUNC: Define a configuration variable that uses a custom function for
- * parsing and writing the value. */
-#ifdef NO_CONFIG_WRITE
-#define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
-#else /* NO_CONFIG_WRITE */
-#define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
- NULL, NULL, NULL, NULL
-#endif /* NO_CONFIG_WRITE */
-#define FUNC(f) _FUNC(f), 0
-#define FUNC_KEY(f) _FUNC(f), 1
-
-/*
- * Table of network configuration variables. This table is used to parse each
- * network configuration variable, e.g., each line in wpa_supplicant.conf file
- * that is inside a network block.
- *
- * This table is generated using the helper macros defined above and with
- * generous help from the C pre-processor. The field name is stored as a string
- * into .name and for STR and INT types, the offset of the target buffer within
- * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
- * offset to the field containing the length of the configuration variable.
- * .param3 and .param4 can be used to mark the allowed range (length for STR
- * and value for INT).
- *
- * For each configuration line in wpa_supplicant.conf, the parser goes through
- * this table and select the entry that matches with the field name. The parser
- * function (.parser) is then called to parse the actual value of the field.
- *
- * This kind of mechanism makes it easy to add new configuration parameters,
- * since only one line needs to be added into this table and into the
- * struct wpa_ssid definition if the new variable is either a string or
- * integer. More complex types will need to use their own parser and writer
- * functions.
- */
-static const struct parse_data ssid_fields[] = {
- { STR_RANGE(ssid, 0, SSID_MAX_LEN) },
- { INT_RANGE(scan_ssid, 0, 1) },
- { FUNC(bssid) },
- { FUNC(bssid_hint) },
- { FUNC(bssid_ignore) },
- { FUNC(bssid_accept) },
- { FUNC(bssid_blacklist) }, /* deprecated alias for bssid_ignore */
- { FUNC(bssid_whitelist) }, /* deprecated alias for bssid_accept */
- { FUNC_KEY(psk) },
- { INT(mem_only_psk) },
- { STR_KEY(sae_password) },
- { STR(sae_password_id) },
- { FUNC(proto) },
- { FUNC(key_mgmt) },
- { INT(bg_scan_period) },
- { FUNC(pairwise) },
- { FUNC(group) },
- { FUNC(group_mgmt) },
- { FUNC(auth_alg) },
- { FUNC(scan_freq) },
- { FUNC(freq_list) },
- { INT_RANGE(ht, 0, 1) },
- { INT_RANGE(vht, 0, 1) },
- { INT_RANGE(ht40, -1, 1) },
- { INT_RANGE(max_oper_chwidth, CHANWIDTH_USE_HT,
- CHANWIDTH_80P80MHZ) },
- { INT(vht_center_freq1) },
- { INT(vht_center_freq2) },
-#ifdef IEEE8021X_EAPOL
- { FUNC(eap) },
- { STR_LENe(identity, identity) },
- { STR_LENe(anonymous_identity, anonymous_identity) },
- { STR_LENe(imsi_identity, imsi_identity) },
- { STR_LENe(machine_identity, machine_identity) },
- { FUNC_KEY(password) },
- { FUNC_KEY(machine_password) },
- { STRe(ca_cert, cert.ca_cert) },
- { STRe(ca_path, cert.ca_path) },
- { STRe(client_cert, cert.client_cert) },
- { STRe(private_key, cert.private_key) },
- { STR_KEYe(private_key_passwd, cert.private_key_passwd) },
- { STRe(dh_file, cert.dh_file) },
- { STRe(subject_match, cert.subject_match) },
- { STRe(check_cert_subject, cert.check_cert_subject) },
- { STRe(altsubject_match, cert.altsubject_match) },
- { STRe(domain_suffix_match, cert.domain_suffix_match) },
- { STRe(domain_match, cert.domain_match) },
- { STRe(ca_cert2, phase2_cert.ca_cert) },
- { STRe(ca_path2, phase2_cert.ca_path) },
- { STRe(client_cert2, phase2_cert.client_cert) },
- { STRe(private_key2, phase2_cert.private_key) },
- { STR_KEYe(private_key2_passwd, phase2_cert.private_key_passwd) },
- { STRe(dh_file2, phase2_cert.dh_file) },
- { STRe(subject_match2, phase2_cert.subject_match) },
- { STRe(check_cert_subject2, phase2_cert.check_cert_subject) },
- { STRe(altsubject_match2, phase2_cert.altsubject_match) },
- { STRe(domain_suffix_match2, phase2_cert.domain_suffix_match) },
- { STRe(domain_match2, phase2_cert.domain_match) },
- { STRe(phase1, phase1) },
- { STRe(phase2, phase2) },
- { STRe(machine_phase2, machine_phase2) },
- { STRe(pcsc, pcsc) },
- { STR_KEYe(pin, cert.pin) },
- { STRe(engine_id, cert.engine_id) },
- { STRe(key_id, cert.key_id) },
- { STRe(cert_id, cert.cert_id) },
- { STRe(ca_cert_id, cert.ca_cert_id) },
- { STR_KEYe(pin2, phase2_cert.pin) },
- { STRe(engine_id2, phase2_cert.engine_id) },
- { STRe(key_id2, phase2_cert.key_id) },
- { STRe(cert_id2, phase2_cert.cert_id) },
- { STRe(ca_cert_id2, phase2_cert.ca_cert_id) },
- { INTe(engine, cert.engine) },
- { INTe(engine2, phase2_cert.engine) },
- { STRe(machine_ca_cert, machine_cert.ca_cert) },
- { STRe(machine_ca_path, machine_cert.ca_path) },
- { STRe(machine_client_cert, machine_cert.client_cert) },
- { STRe(machine_private_key, machine_cert.private_key) },
- { STR_KEYe(machine_private_key_passwd,
- machine_cert.private_key_passwd) },
- { STRe(machine_dh_file, machine_cert.dh_file) },
- { STRe(machine_subject_match, machine_cert.subject_match) },
- { STRe(machine_check_cert_subject, machine_cert.check_cert_subject) },
- { STRe(machine_altsubject_match, machine_cert.altsubject_match) },
- { STRe(machine_domain_suffix_match,
- machine_cert.domain_suffix_match) },
- { STRe(machine_domain_match, machine_cert.domain_match) },
- { STR_KEYe(machine_pin, machine_cert.pin) },
- { STRe(machine_engine_id, machine_cert.engine_id) },
- { STRe(machine_key_id, machine_cert.key_id) },
- { STRe(machine_cert_id, machine_cert.cert_id) },
- { STRe(machine_ca_cert_id, machine_cert.ca_cert_id) },
- { INTe(machine_engine, machine_cert.engine) },
- { INTe(machine_ocsp, machine_cert.ocsp) },
- { INT(eapol_flags) },
- { INTe(sim_num, sim_num) },
- { STRe(openssl_ciphers, openssl_ciphers) },
- { INTe(erp, erp) },
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_WEP
- { FUNC_KEY(wep_key0) },
- { FUNC_KEY(wep_key1) },
- { FUNC_KEY(wep_key2) },
- { FUNC_KEY(wep_key3) },
- { INT(wep_tx_keyidx) },
-#endif /* CONFIG_WEP */
- { INT(priority) },
-#ifdef IEEE8021X_EAPOL
- { INT(eap_workaround) },
- { STRe(pac_file, pac_file) },
- { INTe(fragment_size, fragment_size) },
- { INTe(ocsp, cert.ocsp) },
- { INTe(ocsp2, phase2_cert.ocsp) },
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_MESH
- { INT_RANGE(mode, 0, 5) },
- { INT_RANGE(no_auto_peer, 0, 1) },
- { INT_RANGE(mesh_fwding, 0, 1) },
- { INT_RANGE(mesh_rssi_threshold, -255, 1) },
-#else /* CONFIG_MESH */
- { INT_RANGE(mode, 0, 4) },
-#endif /* CONFIG_MESH */
- { INT_RANGE(proactive_key_caching, 0, 1) },
- { INT_RANGE(disabled, 0, 2) },
- { STR(id_str) },
- { INT_RANGE(ieee80211w, 0, 2) },
-#ifdef CONFIG_OCV
- { FUNC(ocv) },
-#endif /* CONFIG_OCV */
- { FUNC(peerkey) /* obsolete - removed */ },
- { INT_RANGE(mixed_cell, 0, 1) },
- { INT_RANGE(frequency, 0, 70200) },
- { INT_RANGE(fixed_freq, 0, 1) },
- { INT_RANGE(enable_edmg, 0, 1) },
- { INT_RANGE(edmg_channel, 9, 13) },
-#ifdef CONFIG_ACS
- { INT_RANGE(acs, 0, 1) },
-#endif /* CONFIG_ACS */
-#ifdef CONFIG_MESH
- { FUNC(mesh_basic_rates) },
- { INT(dot11MeshMaxRetries) },
- { INT(dot11MeshRetryTimeout) },
- { INT(dot11MeshConfirmTimeout) },
- { INT(dot11MeshHoldingTimeout) },
-#endif /* CONFIG_MESH */
- { INT(wpa_ptk_rekey) },
- { INT_RANGE(wpa_deny_ptk0_rekey, 0, 2) },
- { INT(group_rekey) },
- { STR(bgscan) },
- { INT_RANGE(ignore_broadcast_ssid, 0, 2) },
-#ifdef CONFIG_P2P
- { FUNC(go_p2p_dev_addr) },
- { FUNC(p2p_client_list) },
- { FUNC(psk_list) },
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_HT_OVERRIDES
- { INT_RANGE(disable_ht, 0, 1) },
- { INT_RANGE(disable_ht40, -1, 1) },
- { INT_RANGE(disable_sgi, 0, 1) },
- { INT_RANGE(disable_ldpc, 0, 1) },
- { INT_RANGE(ht40_intolerant, 0, 1) },
- { INT_RANGE(tx_stbc, -1, 1) },
- { INT_RANGE(rx_stbc, -1, 3) },
- { INT_RANGE(disable_max_amsdu, -1, 1) },
- { INT_RANGE(ampdu_factor, -1, 3) },
- { INT_RANGE(ampdu_density, -1, 7) },
- { STR(ht_mcs) },
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- { INT_RANGE(disable_vht, 0, 1) },
- { INT(vht_capa) },
- { INT(vht_capa_mask) },
- { INT_RANGE(vht_rx_mcs_nss_1, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_2, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_3, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_4, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_5, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_6, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_7, -1, 3) },
- { INT_RANGE(vht_rx_mcs_nss_8, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_1, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_2, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_3, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_4, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_5, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_6, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_7, -1, 3) },
- { INT_RANGE(vht_tx_mcs_nss_8, -1, 3) },
-#endif /* CONFIG_VHT_OVERRIDES */
-#ifdef CONFIG_HE_OVERRIDES
- { INT_RANGE(disable_he, 0, 1)},
-#endif /* CONFIG_HE_OVERRIDES */
- { INT(ap_max_inactivity) },
- { INT(dtim_period) },
- { INT(beacon_int) },
-#ifdef CONFIG_MACSEC
- { INT_RANGE(macsec_policy, 0, 1) },
- { INT_RANGE(macsec_integ_only, 0, 1) },
- { INT_RANGE(macsec_replay_protect, 0, 1) },
- { INT(macsec_replay_window) },
- { INT_RANGE(macsec_port, 1, 65534) },
- { INT_RANGE(mka_priority, 0, 255) },
- { FUNC_KEY(mka_cak) },
- { FUNC_KEY(mka_ckn) },
-#endif /* CONFIG_MACSEC */
-#ifdef CONFIG_HS20
- { INT(update_identifier) },
- { STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
-#endif /* CONFIG_HS20 */
- { INT_RANGE(mac_addr, 0, 2) },
- { INT_RANGE(pbss, 0, 2) },
- { INT_RANGE(wps_disabled, 0, 1) },
- { INT_RANGE(fils_dh_group, 0, 65535) },
-#ifdef CONFIG_DPP
- { STR(dpp_connector) },
- { STR_LEN(dpp_netaccesskey) },
- { INT(dpp_netaccesskey_expiry) },
- { STR_LEN(dpp_csign) },
- { STR_LEN(dpp_pp_key) },
- { INT_RANGE(dpp_pfs, 0, 2) },
-#endif /* CONFIG_DPP */
- { INT_RANGE(owe_group, 0, 65535) },
- { INT_RANGE(owe_only, 0, 1) },
- { INT_RANGE(owe_ptk_workaround, 0, 1) },
- { INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
- { INT_RANGE(ft_eap_pmksa_caching, 0, 1) },
- { INT_RANGE(beacon_prot, 0, 1) },
- { INT_RANGE(transition_disable, 0, 255) },
- { INT_RANGE(sae_pk, 0, 2) },
-};
-
-#undef OFFSET
-#undef _STR
-#undef STR
-#undef STR_KEY
-#undef _STR_LEN
-#undef STR_LEN
-#undef STR_LEN_KEY
-#undef _STR_RANGE
-#undef STR_RANGE
-#undef STR_RANGE_KEY
-#undef _INT
-#undef INT
-#undef INT_RANGE
-#undef _FUNC
-#undef FUNC
-#undef FUNC_KEY
-#define NUM_SSID_FIELDS ARRAY_SIZE(ssid_fields)
-
-
-/**
- * wpa_config_add_prio_network - Add a network to priority lists
- * @config: Configuration data from wpa_config_read()
- * @ssid: Pointer to the network configuration to be added to the list
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to add a network block to the priority list of
- * networks. This must be called for each network when reading in the full
- * configuration. In addition, this can be used indirectly when updating
- * priorities by calling wpa_config_update_prio_list().
- */
-int wpa_config_add_prio_network(struct wpa_config *config,
- struct wpa_ssid *ssid)
-{
- size_t prio;
- struct wpa_ssid *prev, **nlist;
-
- /*
- * Add to an existing priority list if one is available for the
- * configured priority level for this network.
- */
- for (prio = 0; prio < config->num_prio; prio++) {
- prev = config->pssid[prio];
- if (prev->priority == ssid->priority) {
- while (prev->pnext)
- prev = prev->pnext;
- prev->pnext = ssid;
- return 0;
- }
- }
-
- /* First network for this priority - add a new priority list */
- nlist = os_realloc_array(config->pssid, config->num_prio + 1,
- sizeof(struct wpa_ssid *));
- if (nlist == NULL)
- return -1;
-
- for (prio = 0; prio < config->num_prio; prio++) {
- if (nlist[prio]->priority < ssid->priority) {
- os_memmove(&nlist[prio + 1], &nlist[prio],
- (config->num_prio - prio) *
- sizeof(struct wpa_ssid *));
- break;
- }
- }
-
- nlist[prio] = ssid;
- config->num_prio++;
- config->pssid = nlist;
-
- return 0;
-}
-
-
-/**
- * wpa_config_update_prio_list - Update network priority list
- * @config: Configuration data from wpa_config_read()
- * Returns: 0 on success, -1 on failure
- *
- * This function is called to update the priority list of networks in the
- * configuration when a network is being added or removed. This is also called
- * if a priority for a network is changed.
- */
-int wpa_config_update_prio_list(struct wpa_config *config)
-{
- struct wpa_ssid *ssid;
- int ret = 0;
-
- os_free(config->pssid);
- config->pssid = NULL;
- config->num_prio = 0;
-
- ssid = config->ssid;
- while (ssid) {
- ssid->pnext = NULL;
- if (wpa_config_add_prio_network(config, ssid) < 0)
- ret = -1;
- ssid = ssid->next;
- }
-
- return ret;
-}
-
-
-#ifdef IEEE8021X_EAPOL
-
-static void eap_peer_config_free_cert(struct eap_peer_cert_config *cert)
-{
- os_free(cert->ca_cert);
- os_free(cert->ca_path);
- os_free(cert->client_cert);
- os_free(cert->private_key);
- str_clear_free(cert->private_key_passwd);
- os_free(cert->dh_file);
- os_free(cert->subject_match);
- os_free(cert->check_cert_subject);
- os_free(cert->altsubject_match);
- os_free(cert->domain_suffix_match);
- os_free(cert->domain_match);
- str_clear_free(cert->pin);
- os_free(cert->engine_id);
- os_free(cert->key_id);
- os_free(cert->cert_id);
- os_free(cert->ca_cert_id);
-}
-
-
-static void eap_peer_config_free(struct eap_peer_config *eap)
-{
- os_free(eap->eap_methods);
- bin_clear_free(eap->identity, eap->identity_len);
- os_free(eap->anonymous_identity);
- os_free(eap->imsi_identity);
- os_free(eap->machine_identity);
- bin_clear_free(eap->password, eap->password_len);
- bin_clear_free(eap->machine_password, eap->machine_password_len);
- eap_peer_config_free_cert(&eap->cert);
- eap_peer_config_free_cert(&eap->phase2_cert);
- eap_peer_config_free_cert(&eap->machine_cert);
- os_free(eap->phase1);
- os_free(eap->phase2);
- os_free(eap->machine_phase2);
- os_free(eap->pcsc);
- os_free(eap->otp);
- os_free(eap->pending_req_otp);
- os_free(eap->pac_file);
- bin_clear_free(eap->new_password, eap->new_password_len);
- str_clear_free(eap->external_sim_resp);
- os_free(eap->openssl_ciphers);
-}
-
-#endif /* IEEE8021X_EAPOL */
-
-
-/**
- * wpa_config_free_ssid - Free network/ssid configuration data
- * @ssid: Configuration data for the network
- *
- * This function frees all resources allocated for the network configuration
- * data.
- */
-void wpa_config_free_ssid(struct wpa_ssid *ssid)
-{
- struct psk_list_entry *psk;
-
- os_free(ssid->ssid);
- str_clear_free(ssid->passphrase);
- os_free(ssid->ext_psk);
- str_clear_free(ssid->sae_password);
- os_free(ssid->sae_password_id);
-#ifdef IEEE8021X_EAPOL
- eap_peer_config_free(&ssid->eap);
-#endif /* IEEE8021X_EAPOL */
- os_free(ssid->id_str);
- os_free(ssid->scan_freq);
- os_free(ssid->freq_list);
- os_free(ssid->bgscan);
- os_free(ssid->p2p_client_list);
- os_free(ssid->bssid_ignore);
- os_free(ssid->bssid_accept);
-#ifdef CONFIG_HT_OVERRIDES
- os_free(ssid->ht_mcs);
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_MESH
- os_free(ssid->mesh_basic_rates);
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_HS20
- os_free(ssid->roaming_consortium_selection);
-#endif /* CONFIG_HS20 */
- os_free(ssid->dpp_connector);
- bin_clear_free(ssid->dpp_netaccesskey, ssid->dpp_netaccesskey_len);
- os_free(ssid->dpp_csign);
- os_free(ssid->dpp_pp_key);
- while ((psk = dl_list_first(&ssid->psk_list, struct psk_list_entry,
- list))) {
- dl_list_del(&psk->list);
- bin_clear_free(psk, sizeof(*psk));
- }
-#ifdef CONFIG_SAE
- sae_deinit_pt(ssid->pt);
-#endif /* CONFIG_SAE */
- bin_clear_free(ssid, sizeof(*ssid));
-}
-
-
-void wpa_config_free_cred(struct wpa_cred *cred)
-{
- size_t i;
-
- os_free(cred->realm);
- str_clear_free(cred->username);
- str_clear_free(cred->password);
- os_free(cred->ca_cert);
- os_free(cred->client_cert);
- os_free(cred->private_key);
- str_clear_free(cred->private_key_passwd);
- os_free(cred->engine_id);
- os_free(cred->ca_cert_id);
- os_free(cred->cert_id);
- os_free(cred->key_id);
- os_free(cred->imsi);
- str_clear_free(cred->milenage);
- for (i = 0; i < cred->num_domain; i++)
- os_free(cred->domain[i]);
- os_free(cred->domain);
- os_free(cred->domain_suffix_match);
- os_free(cred->eap_method);
- os_free(cred->phase1);
- os_free(cred->phase2);
- os_free(cred->excluded_ssid);
- os_free(cred->roaming_partner);
- os_free(cred->provisioning_sp);
- for (i = 0; i < cred->num_req_conn_capab; i++)
- os_free(cred->req_conn_capab_port[i]);
- os_free(cred->req_conn_capab_port);
- os_free(cred->req_conn_capab_proto);
- os_free(cred);
-}
-
-
-void wpa_config_flush_blobs(struct wpa_config *config)
-{
-#ifndef CONFIG_NO_CONFIG_BLOBS
- struct wpa_config_blob *blob, *prev;
-
- blob = config->blobs;
- config->blobs = NULL;
- while (blob) {
- prev = blob;
- blob = blob->next;
- wpa_config_free_blob(prev);
- }
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-}
-
-
-/**
- * wpa_config_free - Free configuration data
- * @config: Configuration data from wpa_config_read()
- *
- * This function frees all resources allocated for the configuration data by
- * wpa_config_read().
- */
-void wpa_config_free(struct wpa_config *config)
-{
- struct wpa_ssid *ssid, *prev = NULL;
- struct wpa_cred *cred, *cprev;
- int i;
-
- ssid = config->ssid;
- while (ssid) {
- prev = ssid;
- ssid = ssid->next;
- wpa_config_free_ssid(prev);
- }
-
- cred = config->cred;
- while (cred) {
- cprev = cred;
- cred = cred->next;
- wpa_config_free_cred(cprev);
- }
-
- wpa_config_flush_blobs(config);
-
- wpabuf_free(config->wps_vendor_ext_m1);
- for (i = 0; i < MAX_WPS_VENDOR_EXT; i++)
- wpabuf_free(config->wps_vendor_ext[i]);
- os_free(config->ctrl_interface);
- os_free(config->ctrl_interface_group);
- os_free(config->opensc_engine_path);
- os_free(config->pkcs11_engine_path);
- os_free(config->pkcs11_module_path);
- os_free(config->openssl_ciphers);
- os_free(config->pcsc_reader);
- str_clear_free(config->pcsc_pin);
- os_free(config->driver_param);
- os_free(config->device_name);
- os_free(config->manufacturer);
- os_free(config->model_name);
- os_free(config->model_number);
- os_free(config->serial_number);
- os_free(config->config_methods);
- os_free(config->p2p_ssid_postfix);
- os_free(config->pssid);
- os_free(config->p2p_pref_chan);
- os_free(config->p2p_no_go_freq.range);
- os_free(config->autoscan);
- os_free(config->freq_list);
- os_free(config->initial_freq_list);
- wpabuf_free(config->wps_nfc_dh_pubkey);
- wpabuf_free(config->wps_nfc_dh_privkey);
- wpabuf_free(config->wps_nfc_dev_pw);
- os_free(config->ext_password_backend);
- os_free(config->sae_groups);
- wpabuf_free(config->ap_vendor_elements);
- wpabuf_free(config->ap_assocresp_elements);
- os_free(config->osu_dir);
- os_free(config->bgscan);
- os_free(config->wowlan_triggers);
- os_free(config->fst_group_id);
- os_free(config->sched_scan_plans);
-#ifdef CONFIG_MBO
- os_free(config->non_pref_chan);
-#endif /* CONFIG_MBO */
- os_free(config->dpp_name);
- os_free(config->dpp_mud_url);
-
- os_free(config);
-}
-
-
-/**
- * wpa_config_foreach_network - Iterate over each configured network
- * @config: Configuration data from wpa_config_read()
- * @func: Callback function to process each network
- * @arg: Opaque argument to pass to callback function
- *
- * Iterate over the set of configured networks calling the specified
- * function for each item. We guard against callbacks removing the
- * supplied network.
- */
-void wpa_config_foreach_network(struct wpa_config *config,
- void (*func)(void *, struct wpa_ssid *),
- void *arg)
-{
- struct wpa_ssid *ssid, *next;
-
- ssid = config->ssid;
- while (ssid) {
- next = ssid->next;
- func(arg, ssid);
- ssid = next;
- }
-}
-
-
-/**
- * wpa_config_get_network - Get configured network based on id
- * @config: Configuration data from wpa_config_read()
- * @id: Unique network id to search for
- * Returns: Network configuration or %NULL if not found
- */
-struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
-{
- struct wpa_ssid *ssid;
-
- ssid = config->ssid;
- while (ssid) {
- if (id == ssid->id)
- break;
- ssid = ssid->next;
- }
-
- return ssid;
-}
-
-
-/**
- * wpa_config_add_network - Add a new network with empty configuration
- * @config: Configuration data from wpa_config_read()
- * Returns: The new network configuration or %NULL if operation failed
- */
-struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
-{
- int id;
- struct wpa_ssid *ssid, *last = NULL;
-
- id = -1;
- ssid = config->ssid;
- while (ssid) {
- if (ssid->id > id)
- id = ssid->id;
- last = ssid;
- ssid = ssid->next;
- }
- id++;
-
- ssid = os_zalloc(sizeof(*ssid));
- if (ssid == NULL)
- return NULL;
- ssid->id = id;
- dl_list_init(&ssid->psk_list);
- if (last)
- last->next = ssid;
- else
- config->ssid = ssid;
-
- wpa_config_update_prio_list(config);
-
- return ssid;
-}
-
-
-/**
- * wpa_config_remove_network - Remove a configured network based on id
- * @config: Configuration data from wpa_config_read()
- * @id: Unique network id to search for
- * Returns: 0 on success, or -1 if the network was not found
- */
-int wpa_config_remove_network(struct wpa_config *config, int id)
-{
- struct wpa_ssid *ssid, *prev = NULL;
-
- ssid = config->ssid;
- while (ssid) {
- if (id == ssid->id)
- break;
- prev = ssid;
- ssid = ssid->next;
- }
-
- if (ssid == NULL)
- return -1;
-
- if (prev)
- prev->next = ssid->next;
- else
- config->ssid = ssid->next;
-
- wpa_config_update_prio_list(config);
- wpa_config_free_ssid(ssid);
- return 0;
-}
-
-
-/**
- * wpa_config_set_network_defaults - Set network default values
- * @ssid: Pointer to network configuration data
- */
-void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
-{
- ssid->proto = DEFAULT_PROTO;
- ssid->pairwise_cipher = DEFAULT_PAIRWISE;
- ssid->group_cipher = DEFAULT_GROUP;
- ssid->key_mgmt = DEFAULT_KEY_MGMT;
- ssid->wpa_deny_ptk0_rekey = PTK0_REKEY_ALLOW_ALWAYS;
- ssid->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
- ssid->ht = 1;
- ssid->vht = 1;
- ssid->he = 1;
-#ifdef IEEE8021X_EAPOL
- ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
- ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
- ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
- ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM;
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_MESH
- ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES;
- ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
- ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
- ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
- ssid->mesh_fwding = DEFAULT_MESH_FWDING;
- ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_HT_OVERRIDES
- ssid->disable_ht = DEFAULT_DISABLE_HT;
- ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
- ssid->disable_sgi = DEFAULT_DISABLE_SGI;
- ssid->disable_ldpc = DEFAULT_DISABLE_LDPC;
- ssid->tx_stbc = DEFAULT_TX_STBC;
- ssid->rx_stbc = DEFAULT_RX_STBC;
- ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU;
- ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
- ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- ssid->vht_rx_mcs_nss_1 = -1;
- ssid->vht_rx_mcs_nss_2 = -1;
- ssid->vht_rx_mcs_nss_3 = -1;
- ssid->vht_rx_mcs_nss_4 = -1;
- ssid->vht_rx_mcs_nss_5 = -1;
- ssid->vht_rx_mcs_nss_6 = -1;
- ssid->vht_rx_mcs_nss_7 = -1;
- ssid->vht_rx_mcs_nss_8 = -1;
- ssid->vht_tx_mcs_nss_1 = -1;
- ssid->vht_tx_mcs_nss_2 = -1;
- ssid->vht_tx_mcs_nss_3 = -1;
- ssid->vht_tx_mcs_nss_4 = -1;
- ssid->vht_tx_mcs_nss_5 = -1;
- ssid->vht_tx_mcs_nss_6 = -1;
- ssid->vht_tx_mcs_nss_7 = -1;
- ssid->vht_tx_mcs_nss_8 = -1;
-#endif /* CONFIG_VHT_OVERRIDES */
- ssid->proactive_key_caching = -1;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
- ssid->sae_pwe = DEFAULT_SAE_PWE;
-#ifdef CONFIG_MACSEC
- ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
-#endif /* CONFIG_MACSEC */
- ssid->mac_addr = -1;
- ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
-}
-
-
-/**
- * wpa_config_set - Set a variable in network configuration
- * @ssid: Pointer to network configuration data
- * @var: Variable name, e.g., "ssid"
- * @value: Variable value
- * @line: Line number in configuration file or 0 if not used
- * Returns: 0 on success with possible change in the value, 1 on success with
- * no change to previously configured value, or -1 on failure
- *
- * This function can be used to set network configuration variables based on
- * both the configuration file and management interface input. The value
- * parameter must be in the same format as the text-based configuration file is
- * using. For example, strings are using double quotation marks.
- */
-int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
- int line)
-{
- size_t i;
- int ret = 0;
-
- if (ssid == NULL || var == NULL || value == NULL)
- return -1;
-
- for (i = 0; i < NUM_SSID_FIELDS; i++) {
- const struct parse_data *field = &ssid_fields[i];
- if (os_strcmp(var, field->name) != 0)
- continue;
-
- ret = field->parser(field, ssid, line, value);
- if (ret < 0) {
- if (line) {
- wpa_printf(MSG_ERROR, "Line %d: failed to "
- "parse %s '%s'.", line, var, value);
- }
- ret = -1;
- }
-#ifdef CONFIG_SAE
- if (os_strcmp(var, "ssid") == 0 ||
- os_strcmp(var, "psk") == 0 ||
- os_strcmp(var, "sae_password") == 0 ||
- os_strcmp(var, "sae_password_id") == 0) {
- sae_deinit_pt(ssid->pt);
- ssid->pt = NULL;
- }
-#endif /* CONFIG_SAE */
- break;
- }
- if (i == NUM_SSID_FIELDS) {
- if (line) {
- wpa_printf(MSG_ERROR, "Line %d: unknown network field "
- "'%s'.", line, var);
- }
- ret = -1;
- }
- ssid->was_recently_reconfigured = true;
-
- return ret;
-}
-
-
-int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
- const char *value)
-{
- size_t len;
- char *buf;
- int ret;
-
- len = os_strlen(value);
- buf = os_malloc(len + 3);
- if (buf == NULL)
- return -1;
- buf[0] = '"';
- os_memcpy(buf + 1, value, len);
- buf[len + 1] = '"';
- buf[len + 2] = '\0';
- ret = wpa_config_set(ssid, var, buf, 0);
- os_free(buf);
- return ret;
-}
-
-
-/**
- * wpa_config_get_all - Get all options from network configuration
- * @ssid: Pointer to network configuration data
- * @get_keys: Determines if keys/passwords will be included in returned list
- * (if they may be exported)
- * Returns: %NULL terminated list of all set keys and their values in the form
- * of [key1, val1, key2, val2, ... , NULL]
- *
- * This function can be used to get list of all configured network properties.
- * The caller is responsible for freeing the returned list and all its
- * elements.
- */
-char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys)
-{
-#ifdef NO_CONFIG_WRITE
- return NULL;
-#else /* NO_CONFIG_WRITE */
- const struct parse_data *field;
- char *key, *value;
- size_t i;
- char **props;
- int fields_num;
-
- get_keys = get_keys && ssid->export_keys;
-
- props = os_calloc(2 * NUM_SSID_FIELDS + 1, sizeof(char *));
- if (!props)
- return NULL;
-
- fields_num = 0;
- for (i = 0; i < NUM_SSID_FIELDS; i++) {
- field = &ssid_fields[i];
- if (field->key_data && !get_keys)
- continue;
- value = field->writer(field, ssid);
- if (value == NULL)
- continue;
- if (os_strlen(value) == 0) {
- os_free(value);
- continue;
- }
-
- key = os_strdup(field->name);
- if (key == NULL) {
- os_free(value);
- goto err;
- }
-
- props[fields_num * 2] = key;
- props[fields_num * 2 + 1] = value;
-
- fields_num++;
- }
-
- return props;
-
-err:
- for (i = 0; props[i]; i++)
- os_free(props[i]);
- os_free(props);
- return NULL;
-#endif /* NO_CONFIG_WRITE */
-}
-
-
-#ifndef NO_CONFIG_WRITE
-/**
- * wpa_config_get - Get a variable in network configuration
- * @ssid: Pointer to network configuration data
- * @var: Variable name, e.g., "ssid"
- * Returns: Value of the variable or %NULL on failure
- *
- * This function can be used to get network configuration variables. The
- * returned value is a copy of the configuration variable in text format, i.e,.
- * the same format that the text-based configuration file and wpa_config_set()
- * are using for the value. The caller is responsible for freeing the returned
- * value.
- */
-char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
-{
- size_t i;
-
- if (ssid == NULL || var == NULL)
- return NULL;
-
- for (i = 0; i < NUM_SSID_FIELDS; i++) {
- const struct parse_data *field = &ssid_fields[i];
- if (os_strcmp(var, field->name) == 0) {
- char *ret = field->writer(field, ssid);
-
- if (ret && has_newline(ret)) {
- wpa_printf(MSG_ERROR,
- "Found newline in value for %s; not returning it",
- var);
- os_free(ret);
- ret = NULL;
- }
-
- return ret;
- }
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_config_get_no_key - Get a variable in network configuration (no keys)
- * @ssid: Pointer to network configuration data
- * @var: Variable name, e.g., "ssid"
- * Returns: Value of the variable or %NULL on failure
- *
- * This function can be used to get network configuration variable like
- * wpa_config_get(). The only difference is that this functions does not expose
- * key/password material from the configuration. In case a key/password field
- * is requested, the returned value is an empty string or %NULL if the variable
- * is not set or "*" if the variable is set (regardless of its value). The
- * returned value is a copy of the configuration variable in text format, i.e,.
- * the same format that the text-based configuration file and wpa_config_set()
- * are using for the value. The caller is responsible for freeing the returned
- * value.
- */
-char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
-{
- size_t i;
-
- if (ssid == NULL || var == NULL)
- return NULL;
-
- for (i = 0; i < NUM_SSID_FIELDS; i++) {
- const struct parse_data *field = &ssid_fields[i];
- if (os_strcmp(var, field->name) == 0) {
- char *res = field->writer(field, ssid);
- if (field->key_data) {
- if (res && res[0]) {
- wpa_printf(MSG_DEBUG, "Do not allow "
- "key_data field to be "
- "exposed");
- str_clear_free(res);
- return os_strdup("*");
- }
-
- os_free(res);
- return NULL;
- }
- return res;
- }
- }
-
- return NULL;
-}
-#endif /* NO_CONFIG_WRITE */
-
-
-/**
- * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
- * @ssid: Pointer to network configuration data
- *
- * This function must be called to update WPA PSK when either SSID or the
- * passphrase has changed for the network configuration.
- */
-void wpa_config_update_psk(struct wpa_ssid *ssid)
-{
-#ifndef CONFIG_NO_PBKDF2
- pbkdf2_sha1(ssid->passphrase, ssid->ssid, ssid->ssid_len, 4096,
- ssid->psk, PMK_LEN);
- wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
- ssid->psk, PMK_LEN);
- ssid->psk_set = 1;
-#endif /* CONFIG_NO_PBKDF2 */
-}
-
-
-static int wpa_config_set_cred_req_conn_capab(struct wpa_cred *cred,
- const char *value)
-{
- u8 *proto;
- int **port;
- int *ports, *nports;
- const char *pos;
- unsigned int num_ports;
-
- proto = os_realloc_array(cred->req_conn_capab_proto,
- cred->num_req_conn_capab + 1, sizeof(u8));
- if (proto == NULL)
- return -1;
- cred->req_conn_capab_proto = proto;
-
- port = os_realloc_array(cred->req_conn_capab_port,
- cred->num_req_conn_capab + 1, sizeof(int *));
- if (port == NULL)
- return -1;
- cred->req_conn_capab_port = port;
-
- proto[cred->num_req_conn_capab] = atoi(value);
-
- pos = os_strchr(value, ':');
- if (pos == NULL) {
- port[cred->num_req_conn_capab] = NULL;
- cred->num_req_conn_capab++;
- return 0;
- }
- pos++;
-
- ports = NULL;
- num_ports = 0;
-
- while (*pos) {
- nports = os_realloc_array(ports, num_ports + 1, sizeof(int));
- if (nports == NULL) {
- os_free(ports);
- return -1;
- }
- ports = nports;
- ports[num_ports++] = atoi(pos);
-
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- break;
- pos++;
- }
-
- nports = os_realloc_array(ports, num_ports + 1, sizeof(int));
- if (nports == NULL) {
- os_free(ports);
- return -1;
- }
- ports = nports;
- ports[num_ports] = -1;
-
- port[cred->num_req_conn_capab] = ports;
- cred->num_req_conn_capab++;
- return 0;
-}
-
-
-static int wpa_config_set_cred_roaming_consortiums(struct wpa_cred *cred,
- const char *value)
-{
- u8 roaming_consortiums[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN];
- size_t roaming_consortiums_len[MAX_ROAMING_CONS];
- unsigned int num_roaming_consortiums = 0;
- const char *pos, *end;
- size_t len;
-
- os_memset(roaming_consortiums, 0, sizeof(roaming_consortiums));
- os_memset(roaming_consortiums_len, 0, sizeof(roaming_consortiums_len));
-
- for (pos = value;;) {
- end = os_strchr(pos, ',');
- len = end ? (size_t) (end - pos) : os_strlen(pos);
- if (!end && len == 0)
- break;
- if (len == 0 || (len & 1) != 0 ||
- len / 2 > MAX_ROAMING_CONS_OI_LEN ||
- hexstr2bin(pos,
- roaming_consortiums[num_roaming_consortiums],
- len / 2) < 0) {
- wpa_printf(MSG_INFO,
- "Invalid roaming_consortiums entry: %s",
- pos);
- return -1;
- }
- roaming_consortiums_len[num_roaming_consortiums] = len / 2;
- num_roaming_consortiums++;
-
- if (!end)
- break;
-
- if (num_roaming_consortiums >= MAX_ROAMING_CONS) {
- wpa_printf(MSG_INFO,
- "Too many roaming_consortiums OIs");
- return -1;
- }
-
- pos = end + 1;
- }
-
- os_memcpy(cred->roaming_consortiums, roaming_consortiums,
- sizeof(roaming_consortiums));
- os_memcpy(cred->roaming_consortiums_len, roaming_consortiums_len,
- sizeof(roaming_consortiums_len));
- cred->num_roaming_consortiums = num_roaming_consortiums;
-
- return 0;
-}
-
-
-int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
- const char *value, int line)
-{
- char *val;
- size_t len;
- int res;
-
- if (os_strcmp(var, "temporary") == 0) {
- cred->temporary = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "priority") == 0) {
- cred->priority = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "sp_priority") == 0) {
- int prio = atoi(value);
- if (prio < 0 || prio > 255)
- return -1;
- cred->sp_priority = prio;
- return 0;
- }
-
- if (os_strcmp(var, "pcsc") == 0) {
- cred->pcsc = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "eap") == 0) {
- struct eap_method_type method;
- method.method = eap_peer_get_type(value, &method.vendor);
- if (method.vendor == EAP_VENDOR_IETF &&
- method.method == EAP_TYPE_NONE) {
- wpa_printf(MSG_ERROR, "Line %d: unknown EAP type '%s' "
- "for a credential", line, value);
- return -1;
- }
- os_free(cred->eap_method);
- cred->eap_method = os_malloc(sizeof(*cred->eap_method));
- if (cred->eap_method == NULL)
- return -1;
- os_memcpy(cred->eap_method, &method, sizeof(method));
- return 0;
- }
-
- if (os_strcmp(var, "password") == 0 &&
- os_strncmp(value, "ext:", 4) == 0) {
- if (has_newline(value))
- return -1;
- str_clear_free(cred->password);
- cred->password = os_strdup(value);
- cred->ext_password = 1;
- return 0;
- }
-
- if (os_strcmp(var, "update_identifier") == 0) {
- cred->update_identifier = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "min_dl_bandwidth_home") == 0) {
- cred->min_dl_bandwidth_home = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "min_ul_bandwidth_home") == 0) {
- cred->min_ul_bandwidth_home = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "min_dl_bandwidth_roaming") == 0) {
- cred->min_dl_bandwidth_roaming = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "min_ul_bandwidth_roaming") == 0) {
- cred->min_ul_bandwidth_roaming = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "max_bss_load") == 0) {
- cred->max_bss_load = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "req_conn_capab") == 0)
- return wpa_config_set_cred_req_conn_capab(cred, value);
-
- if (os_strcmp(var, "ocsp") == 0) {
- cred->ocsp = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "sim_num") == 0) {
- cred->sim_num = atoi(value);
- return 0;
- }
-
- if (os_strcmp(var, "engine") == 0) {
- cred->engine = atoi(value);
- return 0;
- }
-
- val = wpa_config_parse_string(value, &len);
- if (val == NULL ||
- (os_strcmp(var, "excluded_ssid") != 0 &&
- os_strcmp(var, "roaming_consortium") != 0 &&
- os_strcmp(var, "required_roaming_consortium") != 0 &&
- has_newline(val))) {
- wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
- "value '%s'.", line, var, value);
- os_free(val);
- return -1;
- }
-
- if (os_strcmp(var, "realm") == 0) {
- os_free(cred->realm);
- cred->realm = val;
- return 0;
- }
-
- if (os_strcmp(var, "username") == 0) {
- str_clear_free(cred->username);
- cred->username = val;
- return 0;
- }
-
- if (os_strcmp(var, "password") == 0) {
- str_clear_free(cred->password);
- cred->password = val;
- cred->ext_password = 0;
- return 0;
- }
-
- if (os_strcmp(var, "ca_cert") == 0) {
- os_free(cred->ca_cert);
- cred->ca_cert = val;
- return 0;
- }
-
- if (os_strcmp(var, "client_cert") == 0) {
- os_free(cred->client_cert);
- cred->client_cert = val;
- return 0;
- }
-
- if (os_strcmp(var, "private_key") == 0) {
- os_free(cred->private_key);
- cred->private_key = val;
- return 0;
- }
-
- if (os_strcmp(var, "private_key_passwd") == 0) {
- str_clear_free(cred->private_key_passwd);
- cred->private_key_passwd = val;
- return 0;
- }
-
- if (os_strcmp(var, "engine_id") == 0) {
- os_free(cred->engine_id);
- cred->engine_id = val;
- return 0;
- }
-
- if (os_strcmp(var, "ca_cert_id") == 0) {
- os_free(cred->ca_cert_id);
- cred->ca_cert_id = val;
- return 0;
- }
-
- if (os_strcmp(var, "cert_id") == 0) {
- os_free(cred->cert_id);
- cred->cert_id = val;
- return 0;
- }
-
- if (os_strcmp(var, "key_id") == 0) {
- os_free(cred->key_id);
- cred->key_id = val;
- return 0;
- }
-
- if (os_strcmp(var, "imsi") == 0) {
- os_free(cred->imsi);
- cred->imsi = val;
- return 0;
- }
-
- if (os_strcmp(var, "milenage") == 0) {
- str_clear_free(cred->milenage);
- cred->milenage = val;
- return 0;
- }
-
- if (os_strcmp(var, "domain_suffix_match") == 0) {
- os_free(cred->domain_suffix_match);
- cred->domain_suffix_match = val;
- return 0;
- }
-
- if (os_strcmp(var, "domain") == 0) {
- char **new_domain;
- new_domain = os_realloc_array(cred->domain,
- cred->num_domain + 1,
- sizeof(char *));
- if (new_domain == NULL) {
- os_free(val);
- return -1;
- }
- new_domain[cred->num_domain++] = val;
- cred->domain = new_domain;
- return 0;
- }
-
- if (os_strcmp(var, "phase1") == 0) {
- os_free(cred->phase1);
- cred->phase1 = val;
- return 0;
- }
-
- if (os_strcmp(var, "phase2") == 0) {
- os_free(cred->phase2);
- cred->phase2 = val;
- return 0;
- }
-
- if (os_strcmp(var, "roaming_consortium") == 0) {
- if (len < 3 || len > sizeof(cred->roaming_consortium)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "roaming_consortium length %d (3..15 "
- "expected)", line, (int) len);
- os_free(val);
- return -1;
- }
- os_memcpy(cred->roaming_consortium, val, len);
- cred->roaming_consortium_len = len;
- os_free(val);
- return 0;
- }
-
- if (os_strcmp(var, "required_roaming_consortium") == 0) {
- if (len < 3 || len > sizeof(cred->required_roaming_consortium))
- {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "required_roaming_consortium length %d "
- "(3..15 expected)", line, (int) len);
- os_free(val);
- return -1;
- }
- os_memcpy(cred->required_roaming_consortium, val, len);
- cred->required_roaming_consortium_len = len;
- os_free(val);
- return 0;
- }
-
- if (os_strcmp(var, "roaming_consortiums") == 0) {
- res = wpa_config_set_cred_roaming_consortiums(cred, val);
- if (res < 0)
- wpa_printf(MSG_ERROR,
- "Line %d: invalid roaming_consortiums",
- line);
- os_free(val);
- return res;
- }
-
- if (os_strcmp(var, "excluded_ssid") == 0) {
- struct excluded_ssid *e;
-
- if (len > SSID_MAX_LEN) {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "excluded_ssid length %d", line, (int) len);
- os_free(val);
- return -1;
- }
-
- e = os_realloc_array(cred->excluded_ssid,
- cred->num_excluded_ssid + 1,
- sizeof(struct excluded_ssid));
- if (e == NULL) {
- os_free(val);
- return -1;
- }
- cred->excluded_ssid = e;
-
- e = &cred->excluded_ssid[cred->num_excluded_ssid++];
- os_memcpy(e->ssid, val, len);
- e->ssid_len = len;
-
- os_free(val);
-
- return 0;
- }
-
- if (os_strcmp(var, "roaming_partner") == 0) {
- struct roaming_partner *p;
- char *pos;
-
- p = os_realloc_array(cred->roaming_partner,
- cred->num_roaming_partner + 1,
- sizeof(struct roaming_partner));
- if (p == NULL) {
- os_free(val);
- return -1;
- }
- cred->roaming_partner = p;
-
- p = &cred->roaming_partner[cred->num_roaming_partner];
-
- pos = os_strchr(val, ',');
- if (pos == NULL) {
- os_free(val);
- return -1;
- }
- *pos++ = '\0';
- if (pos - val - 1 >= (int) sizeof(p->fqdn)) {
- os_free(val);
- return -1;
- }
- os_memcpy(p->fqdn, val, pos - val);
-
- p->exact_match = atoi(pos);
-
- pos = os_strchr(pos, ',');
- if (pos == NULL) {
- os_free(val);
- return -1;
- }
- *pos++ = '\0';
-
- p->priority = atoi(pos);
-
- pos = os_strchr(pos, ',');
- if (pos == NULL) {
- os_free(val);
- return -1;
- }
- *pos++ = '\0';
-
- if (os_strlen(pos) >= sizeof(p->country)) {
- os_free(val);
- return -1;
- }
- os_memcpy(p->country, pos, os_strlen(pos) + 1);
-
- cred->num_roaming_partner++;
- os_free(val);
-
- return 0;
- }
-
- if (os_strcmp(var, "provisioning_sp") == 0) {
- os_free(cred->provisioning_sp);
- cred->provisioning_sp = val;
- return 0;
- }
-
- if (line) {
- wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
- line, var);
- }
-
- os_free(val);
-
- return -1;
-}
-
-
-static char * alloc_int_str(int val)
-{
- const unsigned int bufsize = 20;
- char *buf;
- int res;
-
- buf = os_malloc(bufsize);
- if (buf == NULL)
- return NULL;
- res = os_snprintf(buf, bufsize, "%d", val);
- if (os_snprintf_error(bufsize, res)) {
- os_free(buf);
- buf = NULL;
- }
- return buf;
-}
-
-
-static char * alloc_strdup(const char *str)
-{
- if (str == NULL)
- return NULL;
- return os_strdup(str);
-}
-
-
-char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var)
-{
- if (os_strcmp(var, "temporary") == 0)
- return alloc_int_str(cred->temporary);
-
- if (os_strcmp(var, "priority") == 0)
- return alloc_int_str(cred->priority);
-
- if (os_strcmp(var, "sp_priority") == 0)
- return alloc_int_str(cred->sp_priority);
-
- if (os_strcmp(var, "pcsc") == 0)
- return alloc_int_str(cred->pcsc);
-
- if (os_strcmp(var, "eap") == 0) {
- if (!cred->eap_method)
- return NULL;
- return alloc_strdup(eap_get_name(cred->eap_method[0].vendor,
- cred->eap_method[0].method));
- }
-
- if (os_strcmp(var, "update_identifier") == 0)
- return alloc_int_str(cred->update_identifier);
-
- if (os_strcmp(var, "min_dl_bandwidth_home") == 0)
- return alloc_int_str(cred->min_dl_bandwidth_home);
-
- if (os_strcmp(var, "min_ul_bandwidth_home") == 0)
- return alloc_int_str(cred->min_ul_bandwidth_home);
-
- if (os_strcmp(var, "min_dl_bandwidth_roaming") == 0)
- return alloc_int_str(cred->min_dl_bandwidth_roaming);
-
- if (os_strcmp(var, "min_ul_bandwidth_roaming") == 0)
- return alloc_int_str(cred->min_ul_bandwidth_roaming);
-
- if (os_strcmp(var, "max_bss_load") == 0)
- return alloc_int_str(cred->max_bss_load);
-
- if (os_strcmp(var, "req_conn_capab") == 0) {
- unsigned int i;
- char *buf, *end, *pos;
- int ret;
-
- if (!cred->num_req_conn_capab)
- return NULL;
-
- buf = os_malloc(4000);
- if (buf == NULL)
- return NULL;
- pos = buf;
- end = pos + 4000;
- for (i = 0; i < cred->num_req_conn_capab; i++) {
- int *ports;
-
- ret = os_snprintf(pos, end - pos, "%s%u",
- i > 0 ? "\n" : "",
- cred->req_conn_capab_proto[i]);
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
-
- ports = cred->req_conn_capab_port[i];
- if (ports) {
- int j;
- for (j = 0; ports[j] != -1; j++) {
- ret = os_snprintf(pos, end - pos,
- "%s%d",
- j > 0 ? "," : ":",
- ports[j]);
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
- }
- }
-
- return buf;
- }
-
- if (os_strcmp(var, "ocsp") == 0)
- return alloc_int_str(cred->ocsp);
-
- if (os_strcmp(var, "realm") == 0)
- return alloc_strdup(cred->realm);
-
- if (os_strcmp(var, "username") == 0)
- return alloc_strdup(cred->username);
-
- if (os_strcmp(var, "password") == 0) {
- if (!cred->password)
- return NULL;
- return alloc_strdup("*");
- }
-
- if (os_strcmp(var, "ca_cert") == 0)
- return alloc_strdup(cred->ca_cert);
-
- if (os_strcmp(var, "client_cert") == 0)
- return alloc_strdup(cred->client_cert);
-
- if (os_strcmp(var, "private_key") == 0)
- return alloc_strdup(cred->private_key);
-
- if (os_strcmp(var, "private_key_passwd") == 0) {
- if (!cred->private_key_passwd)
- return NULL;
- return alloc_strdup("*");
- }
-
- if (os_strcmp(var, "imsi") == 0)
- return alloc_strdup(cred->imsi);
-
- if (os_strcmp(var, "milenage") == 0) {
- if (!(cred->milenage))
- return NULL;
- return alloc_strdup("*");
- }
-
- if (os_strcmp(var, "domain_suffix_match") == 0)
- return alloc_strdup(cred->domain_suffix_match);
-
- if (os_strcmp(var, "domain") == 0) {
- unsigned int i;
- char *buf, *end, *pos;
- int ret;
-
- if (!cred->num_domain)
- return NULL;
-
- buf = os_malloc(4000);
- if (buf == NULL)
- return NULL;
- pos = buf;
- end = pos + 4000;
-
- for (i = 0; i < cred->num_domain; i++) {
- ret = os_snprintf(pos, end - pos, "%s%s",
- i > 0 ? "\n" : "", cred->domain[i]);
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- return buf;
- }
-
- if (os_strcmp(var, "phase1") == 0)
- return alloc_strdup(cred->phase1);
-
- if (os_strcmp(var, "phase2") == 0)
- return alloc_strdup(cred->phase2);
-
- if (os_strcmp(var, "roaming_consortium") == 0) {
- size_t buflen;
- char *buf;
-
- if (!cred->roaming_consortium_len)
- return NULL;
- buflen = cred->roaming_consortium_len * 2 + 1;
- buf = os_malloc(buflen);
- if (buf == NULL)
- return NULL;
- wpa_snprintf_hex(buf, buflen, cred->roaming_consortium,
- cred->roaming_consortium_len);
- return buf;
- }
-
- if (os_strcmp(var, "required_roaming_consortium") == 0) {
- size_t buflen;
- char *buf;
-
- if (!cred->required_roaming_consortium_len)
- return NULL;
- buflen = cred->required_roaming_consortium_len * 2 + 1;
- buf = os_malloc(buflen);
- if (buf == NULL)
- return NULL;
- wpa_snprintf_hex(buf, buflen, cred->required_roaming_consortium,
- cred->required_roaming_consortium_len);
- return buf;
- }
-
- if (os_strcmp(var, "roaming_consortiums") == 0) {
- size_t buflen;
- char *buf, *pos;
- size_t i;
-
- if (!cred->num_roaming_consortiums)
- return NULL;
- buflen = cred->num_roaming_consortiums *
- MAX_ROAMING_CONS_OI_LEN * 2 + 1;
- buf = os_malloc(buflen);
- if (!buf)
- return NULL;
- pos = buf;
- for (i = 0; i < cred->num_roaming_consortiums; i++) {
- if (i > 0)
- *pos++ = ',';
- pos += wpa_snprintf_hex(
- pos, buf + buflen - pos,
- cred->roaming_consortiums[i],
- cred->roaming_consortiums_len[i]);
- }
- *pos = '\0';
- return buf;
- }
-
- if (os_strcmp(var, "excluded_ssid") == 0) {
- unsigned int i;
- char *buf, *end, *pos;
-
- if (!cred->num_excluded_ssid)
- return NULL;
-
- buf = os_malloc(4000);
- if (buf == NULL)
- return NULL;
- pos = buf;
- end = pos + 4000;
-
- for (i = 0; i < cred->num_excluded_ssid; i++) {
- struct excluded_ssid *e;
- int ret;
-
- e = &cred->excluded_ssid[i];
- ret = os_snprintf(pos, end - pos, "%s%s",
- i > 0 ? "\n" : "",
- wpa_ssid_txt(e->ssid, e->ssid_len));
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- return buf;
- }
-
- if (os_strcmp(var, "roaming_partner") == 0) {
- unsigned int i;
- char *buf, *end, *pos;
-
- if (!cred->num_roaming_partner)
- return NULL;
-
- buf = os_malloc(4000);
- if (buf == NULL)
- return NULL;
- pos = buf;
- end = pos + 4000;
-
- for (i = 0; i < cred->num_roaming_partner; i++) {
- struct roaming_partner *p;
- int ret;
-
- p = &cred->roaming_partner[i];
- ret = os_snprintf(pos, end - pos, "%s%s,%d,%u,%s",
- i > 0 ? "\n" : "",
- p->fqdn, p->exact_match, p->priority,
- p->country);
- if (os_snprintf_error(end - pos, ret))
- return buf;
- pos += ret;
- }
-
- return buf;
- }
-
- if (os_strcmp(var, "provisioning_sp") == 0)
- return alloc_strdup(cred->provisioning_sp);
-
- return NULL;
-}
-
-
-struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id)
-{
- struct wpa_cred *cred;
-
- cred = config->cred;
- while (cred) {
- if (id == cred->id)
- break;
- cred = cred->next;
- }
-
- return cred;
-}
-
-
-struct wpa_cred * wpa_config_add_cred(struct wpa_config *config)
-{
- int id;
- struct wpa_cred *cred, *last = NULL;
-
- id = -1;
- cred = config->cred;
- while (cred) {
- if (cred->id > id)
- id = cred->id;
- last = cred;
- cred = cred->next;
- }
- id++;
-
- cred = os_zalloc(sizeof(*cred));
- if (cred == NULL)
- return NULL;
- cred->id = id;
- cred->sim_num = DEFAULT_USER_SELECTED_SIM;
- if (last)
- last->next = cred;
- else
- config->cred = cred;
-
- return cred;
-}
-
-
-int wpa_config_remove_cred(struct wpa_config *config, int id)
-{
- struct wpa_cred *cred, *prev = NULL;
-
- cred = config->cred;
- while (cred) {
- if (id == cred->id)
- break;
- prev = cred;
- cred = cred->next;
- }
-
- if (cred == NULL)
- return -1;
-
- if (prev)
- prev->next = cred->next;
- else
- config->cred = cred->next;
-
- wpa_config_free_cred(cred);
- return 0;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-/**
- * wpa_config_get_blob - Get a named configuration blob
- * @config: Configuration data from wpa_config_read()
- * @name: Name of the blob
- * Returns: Pointer to blob data or %NULL if not found
- */
-const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
- const char *name)
-{
- struct wpa_config_blob *blob = config->blobs;
-
- while (blob) {
- if (os_strcmp(blob->name, name) == 0)
- return blob;
- blob = blob->next;
- }
- return NULL;
-}
-
-
-/**
- * wpa_config_set_blob - Set or add a named configuration blob
- * @config: Configuration data from wpa_config_read()
- * @blob: New value for the blob
- *
- * Adds a new configuration blob or replaces the current value of an existing
- * blob.
- */
-void wpa_config_set_blob(struct wpa_config *config,
- struct wpa_config_blob *blob)
-{
- wpa_config_remove_blob(config, blob->name);
- blob->next = config->blobs;
- config->blobs = blob;
-}
-
-
-/**
- * wpa_config_free_blob - Free blob data
- * @blob: Pointer to blob to be freed
- */
-void wpa_config_free_blob(struct wpa_config_blob *blob)
-{
- if (blob) {
- os_free(blob->name);
- bin_clear_free(blob->data, blob->len);
- os_free(blob);
- }
-}
-
-
-/**
- * wpa_config_remove_blob - Remove a named configuration blob
- * @config: Configuration data from wpa_config_read()
- * @name: Name of the blob to remove
- * Returns: 0 if blob was removed or -1 if blob was not found
- */
-int wpa_config_remove_blob(struct wpa_config *config, const char *name)
-{
- struct wpa_config_blob *pos = config->blobs, *prev = NULL;
-
- while (pos) {
- if (os_strcmp(pos->name, name) == 0) {
- if (prev)
- prev->next = pos->next;
- else
- config->blobs = pos->next;
- wpa_config_free_blob(pos);
- return 0;
- }
- prev = pos;
- pos = pos->next;
- }
-
- return -1;
-}
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-/**
- * wpa_config_alloc_empty - Allocate an empty configuration
- * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
- * socket
- * @driver_param: Driver parameters
- * Returns: Pointer to allocated configuration data or %NULL on failure
- */
-struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
- const char *driver_param)
-{
-#define ecw2cw(ecw) ((1 << (ecw)) - 1)
-
- struct wpa_config *config;
- const int aCWmin = 4, aCWmax = 10;
- const struct hostapd_wmm_ac_params ac_bk =
- { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
- const struct hostapd_wmm_ac_params ac_be =
- { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
- const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
- { aCWmin - 1, aCWmin, 2, 3008 / 32, 0 };
- const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
- { aCWmin - 2, aCWmin - 1, 2, 1504 / 32, 0 };
- const struct hostapd_tx_queue_params txq_bk =
- { 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
- const struct hostapd_tx_queue_params txq_be =
- { 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0 };
- const struct hostapd_tx_queue_params txq_vi =
- { 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30 };
- const struct hostapd_tx_queue_params txq_vo =
- { 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
- (ecw2cw(aCWmin) + 1) / 2 - 1, 15 };
-
-#undef ecw2cw
-
- config = os_zalloc(sizeof(*config));
- if (config == NULL)
- return NULL;
- config->eapol_version = DEFAULT_EAPOL_VERSION;
- config->ap_scan = DEFAULT_AP_SCAN;
- config->user_mpm = DEFAULT_USER_MPM;
- config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
- config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
- config->mesh_fwding = DEFAULT_MESH_FWDING;
- config->dot11RSNASAERetransPeriod =
- DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
- config->fast_reauth = DEFAULT_FAST_REAUTH;
- config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
- config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
- config->p2p_go_freq_change_policy = DEFAULT_P2P_GO_FREQ_MOVE;
- config->p2p_go_max_inactivity = DEFAULT_P2P_GO_MAX_INACTIVITY;
- config->p2p_optimize_listen_chan = DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN;
- config->p2p_go_ctwindow = DEFAULT_P2P_GO_CTWINDOW;
- config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
- config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
- config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
- config->max_num_sta = DEFAULT_MAX_NUM_STA;
- config->ap_isolate = DEFAULT_AP_ISOLATE;
- config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
- config->scan_cur_freq = DEFAULT_SCAN_CUR_FREQ;
- config->scan_res_valid_for_connect = DEFAULT_SCAN_RES_VALID_FOR_CONNECT;
- config->wmm_ac_params[0] = ac_be;
- config->wmm_ac_params[1] = ac_bk;
- config->wmm_ac_params[2] = ac_vi;
- config->wmm_ac_params[3] = ac_vo;
- config->tx_queue[0] = txq_vo;
- config->tx_queue[1] = txq_vi;
- config->tx_queue[2] = txq_be;
- config->tx_queue[3] = txq_bk;
- config->p2p_search_delay = DEFAULT_P2P_SEARCH_DELAY;
- config->rand_addr_lifetime = DEFAULT_RAND_ADDR_LIFETIME;
- config->key_mgmt_offload = DEFAULT_KEY_MGMT_OFFLOAD;
- config->cert_in_cb = DEFAULT_CERT_IN_CB;
- config->wpa_rsc_relaxation = DEFAULT_WPA_RSC_RELAXATION;
- config->extended_key_id = DEFAULT_EXTENDED_KEY_ID;
-
-#ifdef CONFIG_MBO
- config->mbo_cell_capa = DEFAULT_MBO_CELL_CAPA;
- config->disassoc_imminent_rssi_threshold =
- DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD;
- config->oce = DEFAULT_OCE_SUPPORT;
-#endif /* CONFIG_MBO */
-
- if (ctrl_interface)
- config->ctrl_interface = os_strdup(ctrl_interface);
- if (driver_param)
- config->driver_param = os_strdup(driver_param);
- config->gas_rand_addr_lifetime = DEFAULT_RAND_ADDR_LIFETIME;
-
- return config;
-}
-
-
-#ifndef CONFIG_NO_STDOUT_DEBUG
-/**
- * wpa_config_debug_dump_networks - Debug dump of configured networks
- * @config: Configuration data from wpa_config_read()
- */
-void wpa_config_debug_dump_networks(struct wpa_config *config)
-{
- size_t prio;
- struct wpa_ssid *ssid;
-
- for (prio = 0; prio < config->num_prio; prio++) {
- ssid = config->pssid[prio];
- wpa_printf(MSG_DEBUG, "Priority group %d",
- ssid->priority);
- while (ssid) {
- wpa_printf(MSG_DEBUG, " id=%d ssid='%s'",
- ssid->id,
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- ssid = ssid->pnext;
- }
- }
-}
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
-
-/**
- * Structure for global configuration parsing. This data is used to implement a
- * generic parser for the global interface configuration. The table of variables
- * is defined below in this file (global_fields[]).
- */
-struct global_parse_data {
- /* Configuration variable name */
- char *name;
-
- /* Parser function for this variable. The parser functions return 0 or 1
- * to indicate success. Value 0 indicates that the parameter value may
- * have changed while value 1 means that the value did not change.
- * Error cases (failure to parse the string) are indicated by returning
- * -1. */
- int (*parser)(const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *value);
-
- /* Getter function to print the variable in text format to buf. */
- int (*get)(const char *name, struct wpa_config *config, long offset,
- char *buf, size_t buflen, int pretty_print);
-
- /* Variable specific parameters for the parser. */
- void *param1, *param2, *param3;
-
- /* Indicates which configuration variable has changed. */
- unsigned int changed_flag;
-};
-
-
-static int wpa_global_config_parse_int(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- int val, *dst;
- char *end;
- bool same;
-
- dst = (int *) (((u8 *) config) + (long) data->param1);
- val = strtol(pos, &end, 0);
- if (*end) {
- wpa_printf(MSG_ERROR, "Line %d: invalid number \"%s\"",
- line, pos);
- return -1;
- }
- same = *dst == val;
- *dst = val;
-
- wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
-
- if (data->param2 && *dst < (long) data->param2) {
- wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
- "min_value=%ld)", line, data->name, *dst,
- (long) data->param2);
- *dst = (long) data->param2;
- return -1;
- }
-
- if (data->param3 && *dst > (long) data->param3) {
- wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
- "max_value=%ld)", line, data->name, *dst,
- (long) data->param3);
- *dst = (long) data->param3;
- return -1;
- }
-
- return same;
-}
-
-
-static int wpa_global_config_parse_str(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- size_t len, prev_len;
- char **dst, *tmp;
-
- len = os_strlen(pos);
- if (data->param2 && len < (size_t) data->param2) {
- wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
- "min_len=%ld)", line, data->name,
- (unsigned long) len, (long) data->param2);
- return -1;
- }
-
- if (data->param3 && len > (size_t) data->param3) {
- wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
- "max_len=%ld)", line, data->name,
- (unsigned long) len, (long) data->param3);
- return -1;
- }
-
- if (has_newline(pos)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid %s value with newline",
- line, data->name);
- return -1;
- }
-
- dst = (char **) (((u8 *) config) + (long) data->param1);
- if (*dst)
- prev_len = os_strlen(*dst);
- else
- prev_len = 0;
-
- /* No change to the previously configured value */
- if (*dst && prev_len == len && os_memcmp(*dst, pos, len) == 0)
- return 1;
-
- tmp = os_strdup(pos);
- if (tmp == NULL)
- return -1;
-
- os_free(*dst);
- *dst = tmp;
- wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
-
- return 0;
-}
-
-
-static int wpa_config_process_bgscan(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- size_t len;
- char *tmp;
- int res;
-
- tmp = wpa_config_parse_string(pos, &len);
- if (tmp == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to parse %s",
- line, data->name);
- return -1;
- }
-
- res = wpa_global_config_parse_str(data, config, line, tmp);
- os_free(tmp);
- return res;
-}
-
-
-static int wpa_global_config_parse_bin(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- struct wpabuf **dst, *tmp;
-
- tmp = wpabuf_parse_bin(pos);
- if (!tmp)
- return -1;
-
- dst = (struct wpabuf **) (((u8 *) config) + (long) data->param1);
- if (wpabuf_cmp(*dst, tmp) == 0) {
- wpabuf_free(tmp);
- return 1;
- }
- wpabuf_free(*dst);
- *dst = tmp;
- wpa_printf(MSG_DEBUG, "%s", data->name);
-
- return 0;
-}
-
-
-static int wpa_config_process_freq_list(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *value)
-{
- int *freqs;
-
- freqs = wpa_config_parse_int_array(value);
- if (freqs == NULL)
- return -1;
- if (freqs[0] == 0) {
- os_free(freqs);
- freqs = NULL;
- }
- os_free(config->freq_list);
- config->freq_list = freqs;
- return 0;
-}
-
-
-static int
-wpa_config_process_initial_freq_list(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *value)
-{
- int *freqs;
-
- freqs = wpa_config_parse_int_array(value);
- if (!freqs)
- return -1;
- if (freqs[0] == 0) {
- os_free(freqs);
- freqs = NULL;
- }
- os_free(config->initial_freq_list);
- config->initial_freq_list = freqs;
- return 0;
-}
-
-
-#ifdef CONFIG_P2P
-static int wpa_global_config_parse_ipv4(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- u32 *dst;
- struct hostapd_ip_addr addr;
-
- if (hostapd_parse_ip_addr(pos, &addr) < 0)
- return -1;
- if (addr.af != AF_INET)
- return -1;
-
- dst = (u32 *) (((u8 *) config) + (long) data->param1);
- if (os_memcmp(dst, &addr.u.v4.s_addr, 4) == 0)
- return 1;
- os_memcpy(dst, &addr.u.v4.s_addr, 4);
- wpa_printf(MSG_DEBUG, "%s = 0x%x", data->name,
- WPA_GET_BE32((u8 *) dst));
-
- return 0;
-}
-#endif /* CONFIG_P2P */
-
-
-static int wpa_config_process_country(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- if (!pos[0] || !pos[1]) {
- wpa_printf(MSG_DEBUG, "Invalid country set");
- return -1;
- }
- if (pos[0] == config->country[0] && pos[1] == config->country[1])
- return 1;
- config->country[0] = pos[0];
- config->country[1] = pos[1];
- wpa_printf(MSG_DEBUG, "country='%c%c'",
- config->country[0], config->country[1]);
- return 0;
-}
-
-
-static int wpa_config_process_load_dynamic_eap(
- const struct global_parse_data *data, struct wpa_config *config,
- int line, const char *so)
-{
- int ret;
- wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
- ret = eap_peer_method_load(so);
- if (ret == -2) {
- wpa_printf(MSG_DEBUG, "This EAP type was already loaded - not "
- "reloading.");
- } else if (ret) {
- wpa_printf(MSG_ERROR, "Line %d: Failed to load dynamic EAP "
- "method '%s'.", line, so);
- return -1;
- }
-
- return 0;
-}
-
-
-#ifdef CONFIG_WPS
-
-static int wpa_config_process_uuid(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- char buf[40];
- if (uuid_str2bin(pos, config->uuid)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
- return -1;
- }
- uuid_bin2str(config->uuid, buf, sizeof(buf));
- wpa_printf(MSG_DEBUG, "uuid=%s", buf);
- return 0;
-}
-
-
-static int wpa_config_process_device_type(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- return wps_dev_type_str2bin(pos, config->device_type);
-}
-
-
-static int wpa_config_process_os_version(const struct global_parse_data *data,
- struct wpa_config *config, int line,
- const char *pos)
-{
- if (hexstr2bin(pos, config->os_version, 4)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "os_version=%08x",
- WPA_GET_BE32(config->os_version));
- return 0;
-}
-
-
-static int wpa_config_process_wps_vendor_ext_m1(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- struct wpabuf *tmp;
- int len = os_strlen(pos) / 2;
- u8 *p;
-
- if (!len) {
- wpa_printf(MSG_ERROR, "Line %d: "
- "invalid wps_vendor_ext_m1", line);
- return -1;
- }
-
- tmp = wpabuf_alloc(len);
- if (tmp) {
- p = wpabuf_put(tmp, len);
-
- if (hexstr2bin(pos, p, len)) {
- wpa_printf(MSG_ERROR, "Line %d: "
- "invalid wps_vendor_ext_m1", line);
- wpabuf_free(tmp);
- return -1;
- }
-
- wpabuf_free(config->wps_vendor_ext_m1);
- config->wps_vendor_ext_m1 = tmp;
- } else {
- wpa_printf(MSG_ERROR, "Can not allocate "
- "memory for wps_vendor_ext_m1");
- return -1;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
-static int wpa_config_process_sec_device_type(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- int idx;
-
- if (config->num_sec_device_types >= MAX_SEC_DEVICE_TYPES) {
- wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type "
- "items", line);
- return -1;
- }
-
- idx = config->num_sec_device_types;
-
- if (wps_dev_type_str2bin(pos, config->sec_device_type[idx]))
- return -1;
-
- config->num_sec_device_types++;
- return 0;
-}
-
-
-static int wpa_config_process_p2p_pref_chan(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- struct p2p_channel *pref = NULL, *n;
- size_t num = 0;
- const char *pos2;
- u8 op_class, chan;
-
- /* format: class:chan,class:chan,... */
-
- while (*pos) {
- op_class = atoi(pos);
- pos2 = os_strchr(pos, ':');
- if (pos2 == NULL)
- goto fail;
- pos2++;
- chan = atoi(pos2);
-
- n = os_realloc_array(pref, num + 1,
- sizeof(struct p2p_channel));
- if (n == NULL)
- goto fail;
- pref = n;
- pref[num].op_class = op_class;
- pref[num].chan = chan;
- num++;
-
- pos = os_strchr(pos2, ',');
- if (pos == NULL)
- break;
- pos++;
- }
-
- os_free(config->p2p_pref_chan);
- config->p2p_pref_chan = pref;
- config->num_p2p_pref_chan = num;
- wpa_hexdump(MSG_DEBUG, "P2P: Preferred class/channel pairs",
- (u8 *) config->p2p_pref_chan,
- config->num_p2p_pref_chan * sizeof(struct p2p_channel));
-
- return 0;
-
-fail:
- os_free(pref);
- wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_pref_chan list", line);
- return -1;
-}
-
-
-static int wpa_config_process_p2p_no_go_freq(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- int ret;
-
- ret = freq_range_list_parse(&config->p2p_no_go_freq, pos);
- if (ret < 0) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_no_go_freq", line);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: p2p_no_go_freq with %u items",
- config->p2p_no_go_freq.num);
-
- return 0;
-}
-
-
-static int wpa_config_process_p2p_device_persistent_mac_addr(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- if (hwaddr_aton2(pos, config->p2p_device_persistent_mac_addr) < 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: Invalid p2p_device_persistent_mac_addr '%s'",
- line, pos);
- return -1;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_P2P */
-
-
-static int wpa_config_process_hessid(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- if (hwaddr_aton2(pos, config->hessid) < 0) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid hessid '%s'",
- line, pos);
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpa_config_process_sae_groups(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- int *groups = wpa_config_parse_int_array(pos);
- if (groups == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid sae_groups '%s'",
- line, pos);
- return -1;
- }
-
- os_free(config->sae_groups);
- config->sae_groups = groups;
-
- return 0;
-}
-
-
-static int wpa_config_process_ap_vendor_elements(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- struct wpabuf *tmp;
-
- if (!*pos) {
- wpabuf_free(config->ap_vendor_elements);
- config->ap_vendor_elements = NULL;
- return 0;
- }
-
- tmp = wpabuf_parse_bin(pos);
- if (!tmp) {
- wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
- line);
- return -1;
- }
- wpabuf_free(config->ap_vendor_elements);
- config->ap_vendor_elements = tmp;
-
- return 0;
-}
-
-
-static int wpa_config_process_ap_assocresp_elements(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- struct wpabuf *tmp;
-
- if (!*pos) {
- wpabuf_free(config->ap_assocresp_elements);
- config->ap_assocresp_elements = NULL;
- return 0;
- }
-
- tmp = wpabuf_parse_bin(pos);
- if (!tmp) {
- wpa_printf(MSG_ERROR, "Line %d: invalid ap_assocresp_elements",
- line);
- return -1;
- }
- wpabuf_free(config->ap_assocresp_elements);
- config->ap_assocresp_elements = tmp;
-
- return 0;
-}
-
-
-#ifdef CONFIG_CTRL_IFACE
-static int wpa_config_process_no_ctrl_interface(
- const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
-{
- wpa_printf(MSG_DEBUG, "no_ctrl_interface -> ctrl_interface=NULL");
- os_free(config->ctrl_interface);
- config->ctrl_interface = NULL;
- return 0;
-}
-#endif /* CONFIG_CTRL_IFACE */
-
-
-static int wpa_config_get_int(const char *name, struct wpa_config *config,
- long offset, char *buf, size_t buflen,
- int pretty_print)
-{
- int *val = (int *) (((u8 *) config) + (long) offset);
-
- if (pretty_print)
- return os_snprintf(buf, buflen, "%s=%d\n", name, *val);
- return os_snprintf(buf, buflen, "%d", *val);
-}
-
-
-static int wpa_config_get_str(const char *name, struct wpa_config *config,
- long offset, char *buf, size_t buflen,
- int pretty_print)
-{
- char **val = (char **) (((u8 *) config) + (long) offset);
- int res;
-
- if (pretty_print)
- res = os_snprintf(buf, buflen, "%s=%s\n", name,
- *val ? *val : "null");
- else if (!*val)
- return -1;
- else
- res = os_snprintf(buf, buflen, "%s", *val);
- if (os_snprintf_error(buflen, res))
- res = -1;
-
- return res;
-}
-
-
-#ifdef CONFIG_P2P
-static int wpa_config_get_ipv4(const char *name, struct wpa_config *config,
- long offset, char *buf, size_t buflen,
- int pretty_print)
-{
- void *val = ((u8 *) config) + (long) offset;
- int res;
- char addr[INET_ADDRSTRLEN];
-
- if (!val || !inet_ntop(AF_INET, val, addr, sizeof(addr)))
- return -1;
-
- if (pretty_print)
- res = os_snprintf(buf, buflen, "%s=%s\n", name, addr);
- else
- res = os_snprintf(buf, buflen, "%s", addr);
-
- if (os_snprintf_error(buflen, res))
- res = -1;
-
- return res;
-}
-#endif /* CONFIG_P2P */
-
-
-#ifdef OFFSET
-#undef OFFSET
-#endif /* OFFSET */
-/* OFFSET: Get offset of a variable within the wpa_config structure */
-#define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
-
-#define FUNC(f) #f, wpa_config_process_ ## f, NULL, OFFSET(f), NULL, NULL
-#define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL, NULL
-#define _INT(f) #f, wpa_global_config_parse_int, wpa_config_get_int, OFFSET(f)
-#define INT(f) _INT(f), NULL, NULL
-#define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
-#define _STR(f) #f, wpa_global_config_parse_str, wpa_config_get_str, OFFSET(f)
-#define STR(f) _STR(f), NULL, NULL
-#define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
-#define BIN(f) #f, wpa_global_config_parse_bin, NULL, OFFSET(f), NULL, NULL
-#define IPV4(f) #f, wpa_global_config_parse_ipv4, wpa_config_get_ipv4, \
- OFFSET(f), NULL, NULL
-
-static const struct global_parse_data global_fields[] = {
-#ifdef CONFIG_CTRL_IFACE
- { STR(ctrl_interface), 0 },
- { FUNC_NO_VAR(no_ctrl_interface), 0 },
- { STR(ctrl_interface_group), 0 } /* deprecated */,
-#endif /* CONFIG_CTRL_IFACE */
-#ifdef CONFIG_MACSEC
- { INT_RANGE(eapol_version, 1, 3), 0 },
-#else /* CONFIG_MACSEC */
- { INT_RANGE(eapol_version, 1, 2), 0 },
-#endif /* CONFIG_MACSEC */
- { INT(ap_scan), 0 },
- { FUNC(bgscan), CFG_CHANGED_BGSCAN },
-#ifdef CONFIG_MESH
- { INT(user_mpm), 0 },
- { INT_RANGE(max_peer_links, 0, 255), 0 },
- { INT(mesh_max_inactivity), 0 },
- { INT_RANGE(mesh_fwding, 0, 1), 0 },
- { INT(dot11RSNASAERetransPeriod), 0 },
-#endif /* CONFIG_MESH */
- { INT(disable_scan_offload), 0 },
- { INT(fast_reauth), 0 },
- { STR(opensc_engine_path), 0 },
- { STR(pkcs11_engine_path), 0 },
- { STR(pkcs11_module_path), 0 },
- { STR(openssl_ciphers), 0 },
- { STR(pcsc_reader), 0 },
- { STR(pcsc_pin), 0 },
- { INT(external_sim), 0 },
- { STR(driver_param), 0 },
- { INT(dot11RSNAConfigPMKLifetime), 0 },
- { INT(dot11RSNAConfigPMKReauthThreshold), 0 },
- { INT(dot11RSNAConfigSATimeout), 0 },
-#ifndef CONFIG_NO_CONFIG_WRITE
- { INT(update_config), 0 },
-#endif /* CONFIG_NO_CONFIG_WRITE */
- { FUNC_NO_VAR(load_dynamic_eap), 0 },
-#ifdef CONFIG_WPS
- { FUNC(uuid), CFG_CHANGED_UUID },
- { INT_RANGE(auto_uuid, 0, 1), 0 },
- { STR_RANGE(device_name, 0, WPS_DEV_NAME_MAX_LEN),
- CFG_CHANGED_DEVICE_NAME },
- { STR_RANGE(manufacturer, 0, 64), CFG_CHANGED_WPS_STRING },
- { STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING },
- { STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING },
- { STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING },
- { FUNC(device_type), CFG_CHANGED_DEVICE_TYPE },
- { FUNC(os_version), CFG_CHANGED_OS_VERSION },
- { STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
- { INT_RANGE(wps_cred_processing, 0, 2), 0 },
- { INT_RANGE(wps_cred_add_sae, 0, 1), 0 },
- { FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- { FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
- { INT(p2p_listen_reg_class), CFG_CHANGED_P2P_LISTEN_CHANNEL },
- { INT(p2p_listen_channel), CFG_CHANGED_P2P_LISTEN_CHANNEL },
- { INT(p2p_oper_reg_class), CFG_CHANGED_P2P_OPER_CHANNEL },
- { INT(p2p_oper_channel), CFG_CHANGED_P2P_OPER_CHANNEL },
- { INT_RANGE(p2p_go_intent, 0, 15), 0 },
- { STR(p2p_ssid_postfix), CFG_CHANGED_P2P_SSID_POSTFIX },
- { INT_RANGE(persistent_reconnect, 0, 1), 0 },
- { INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
- { INT(p2p_group_idle), 0 },
- { INT_RANGE(p2p_go_freq_change_policy, 0, P2P_GO_FREQ_MOVE_MAX), 0 },
- { INT_RANGE(p2p_passphrase_len, 8, 63),
- CFG_CHANGED_P2P_PASSPHRASE_LEN },
- { FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
- { FUNC(p2p_no_go_freq), CFG_CHANGED_P2P_PREF_CHAN },
- { INT_RANGE(p2p_add_cli_chan, 0, 1), 0 },
- { INT_RANGE(p2p_optimize_listen_chan, 0, 1), 0 },
- { INT(p2p_go_ht40), 0 },
- { INT(p2p_go_vht), 0 },
- { INT(p2p_go_he), 0 },
- { INT(p2p_go_edmg), 0 },
- { INT(p2p_disabled), 0 },
- { INT_RANGE(p2p_go_ctwindow, 0, 127), 0 },
- { INT(p2p_no_group_iface), 0 },
- { INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 },
- { IPV4(ip_addr_go), 0 },
- { IPV4(ip_addr_mask), 0 },
- { IPV4(ip_addr_start), 0 },
- { IPV4(ip_addr_end), 0 },
- { INT_RANGE(p2p_cli_probe, 0, 1), 0 },
- { INT(p2p_device_random_mac_addr), 0 },
- { FUNC(p2p_device_persistent_mac_addr), 0 },
- { INT(p2p_interface_random_mac_addr), 0 },
- { INT(p2p_6ghz_disable), 0 },
-#endif /* CONFIG_P2P */
- { FUNC(country), CFG_CHANGED_COUNTRY },
- { INT(bss_max_count), 0 },
- { INT(bss_expiration_age), 0 },
- { INT(bss_expiration_scan_count), 0 },
- { INT_RANGE(filter_ssids, 0, 1), 0 },
- { INT_RANGE(filter_rssi, -100, 0), 0 },
- { INT(max_num_sta), 0 },
- { INT_RANGE(ap_isolate, 0, 1), 0 },
- { INT_RANGE(disassoc_low_ack, 0, 1), 0 },
-#ifdef CONFIG_HS20
- { INT_RANGE(hs20, 0, 1), 0 },
-#endif /* CONFIG_HS20 */
- { INT_RANGE(interworking, 0, 1), 0 },
- { FUNC(hessid), 0 },
- { INT_RANGE(access_network_type, 0, 15), 0 },
- { INT_RANGE(go_interworking, 0, 1), 0 },
- { INT_RANGE(go_access_network_type, 0, 15), 0 },
- { INT_RANGE(go_internet, 0, 1), 0 },
- { INT_RANGE(go_venue_group, 0, 255), 0 },
- { INT_RANGE(go_venue_type, 0, 255), 0 },
- { INT_RANGE(pbc_in_m1, 0, 1), 0 },
- { STR(autoscan), 0 },
- { INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff),
- CFG_CHANGED_NFC_PASSWORD_TOKEN },
- { BIN(wps_nfc_dh_pubkey), CFG_CHANGED_NFC_PASSWORD_TOKEN },
- { BIN(wps_nfc_dh_privkey), CFG_CHANGED_NFC_PASSWORD_TOKEN },
- { BIN(wps_nfc_dev_pw), CFG_CHANGED_NFC_PASSWORD_TOKEN },
- { STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND },
- { INT(p2p_go_max_inactivity), 0 },
- { INT_RANGE(auto_interworking, 0, 1), 0 },
- { INT(okc), 0 },
- { INT(pmf), 0 },
- { FUNC(sae_groups), 0 },
- { INT_RANGE(sae_pwe, 0, 3), 0 },
- { INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
- { INT(dtim_period), 0 },
- { INT(beacon_int), 0 },
- { FUNC(ap_assocresp_elements), 0 },
- { FUNC(ap_vendor_elements), 0 },
- { INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
- { FUNC(freq_list), 0 },
- { FUNC(initial_freq_list), 0},
- { INT(scan_cur_freq), 0 },
- { INT(scan_res_valid_for_connect), 0},
- { INT(sched_scan_interval), 0 },
- { INT(sched_scan_start_delay), 0 },
- { INT(tdls_external_control), 0},
- { STR(osu_dir), 0 },
- { STR(wowlan_triggers), CFG_CHANGED_WOWLAN_TRIGGERS },
- { INT(p2p_search_delay), 0},
- { INT(mac_addr), 0 },
- { INT(rand_addr_lifetime), 0 },
- { INT(preassoc_mac_addr), 0 },
- { INT(key_mgmt_offload), 0},
- { INT(passive_scan), 0 },
- { INT(reassoc_same_bss_optim), 0 },
- { INT(wps_priority), 0},
-#ifdef CONFIG_FST
- { STR_RANGE(fst_group_id, 1, FST_MAX_GROUP_ID_LEN), 0 },
- { INT_RANGE(fst_priority, 1, FST_MAX_PRIO_VALUE), 0 },
- { INT_RANGE(fst_llt, 1, FST_MAX_LLT_MS), 0 },
-#endif /* CONFIG_FST */
- { INT_RANGE(cert_in_cb, 0, 1), 0 },
- { INT_RANGE(wpa_rsc_relaxation, 0, 1), 0 },
- { STR(sched_scan_plans), CFG_CHANGED_SCHED_SCAN_PLANS },
-#ifdef CONFIG_MBO
- { STR(non_pref_chan), 0 },
- { INT_RANGE(mbo_cell_capa, MBO_CELL_CAPA_AVAILABLE,
- MBO_CELL_CAPA_NOT_SUPPORTED), 0 },
- { INT_RANGE(disassoc_imminent_rssi_threshold, -120, 0), 0 },
- { INT_RANGE(oce, 0, 3), 0 },
-#endif /* CONFIG_MBO */
- { INT(gas_address3), 0 },
- { INT_RANGE(ftm_responder, 0, 1), 0 },
- { INT_RANGE(ftm_initiator, 0, 1), 0 },
- { INT(gas_rand_addr_lifetime), 0 },
- { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
-#ifdef CONFIG_DPP
- { INT_RANGE(dpp_config_processing, 0, 2), 0 },
- { STR(dpp_name), 0 },
- { STR(dpp_mud_url), 0 },
-#endif /* CONFIG_DPP */
- { INT_RANGE(coloc_intf_reporting, 0, 1), 0 },
-#ifdef CONFIG_WNM
- { INT_RANGE(disable_btm, 0, 1), CFG_CHANGED_DISABLE_BTM },
- { INT_RANGE(extended_key_id, 0, 1), 0 },
-#endif /* CONFIG_WNM */
- { INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0},
-#ifdef CONFIG_PASN
-#ifdef CONFIG_TESTING_OPTIONS
- { INT_RANGE(force_kdk_derivation, 0, 1), 0 },
- { INT_RANGE(pasn_corrupt_mic, 0, 1), 0 },
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_PASN */
-};
-
-#undef FUNC
-#undef _INT
-#undef INT
-#undef INT_RANGE
-#undef _STR
-#undef STR
-#undef STR_RANGE
-#undef BIN
-#undef IPV4
-#define NUM_GLOBAL_FIELDS ARRAY_SIZE(global_fields)
-
-
-int wpa_config_dump_values(struct wpa_config *config, char *buf, size_t buflen)
-{
- int result = 0;
- size_t i;
-
- for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
- const struct global_parse_data *field = &global_fields[i];
- int tmp;
-
- if (!field->get)
- continue;
-
- tmp = field->get(field->name, config, (long) field->param1,
- buf, buflen, 1);
- if (tmp < 0)
- return -1;
- buf += tmp;
- buflen -= tmp;
- result += tmp;
- }
- return result;
-}
-
-
-int wpa_config_get_value(const char *name, struct wpa_config *config,
- char *buf, size_t buflen)
-{
- size_t i;
-
- for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
- const struct global_parse_data *field = &global_fields[i];
-
- if (os_strcmp(name, field->name) != 0)
- continue;
- if (!field->get)
- break;
- return field->get(name, config, (long) field->param1,
- buf, buflen, 0);
- }
-
- return -1;
-}
-
-
-int wpa_config_get_num_global_field_names(void)
-{
- return NUM_GLOBAL_FIELDS;
-}
-
-
-const char * wpa_config_get_global_field_name(unsigned int i, int *no_var)
-{
- if (i >= NUM_GLOBAL_FIELDS)
- return NULL;
-
- if (no_var)
- *no_var = !global_fields[i].param1;
- return global_fields[i].name;
-}
-
-
-/**
- * wpa_config_process_global - Set a variable in global configuration
- * @config: Pointer to global configuration data
- * @pos: Name and value in the format "{name}={value}"
- * @line: Line number in configuration file or 0 if not used
- * Returns: 0 on success with a possible change in value, 1 on success with no
- * change to previously configured value, or -1 on failure
- *
- * This function can be used to set global configuration variables based on
- * both the configuration file and management interface input. The value
- * parameter must be in the same format as the text-based configuration file is
- * using. For example, strings are using double quotation marks.
- */
-int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
-{
- size_t i;
- int ret = 0;
-
- for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
- const struct global_parse_data *field = &global_fields[i];
- size_t flen = os_strlen(field->name);
- if (os_strncmp(pos, field->name, flen) != 0 ||
- pos[flen] != '=')
- continue;
-
- ret = field->parser(field, config, line, pos + flen + 1);
- if (ret < 0) {
- wpa_printf(MSG_ERROR, "Line %d: failed to "
- "parse '%s'.", line, pos);
- ret = -1;
- }
- if (ret == 1)
- break;
- if (field->changed_flag == CFG_CHANGED_NFC_PASSWORD_TOKEN)
- config->wps_nfc_pw_from_config = 1;
- config->changed_parameters |= field->changed_flag;
- break;
- }
- if (i == NUM_GLOBAL_FIELDS) {
-#ifdef CONFIG_AP
- if (os_strncmp(pos, "tx_queue_", 9) == 0) {
- char *tmp = os_strchr(pos, '=');
-
- if (!tmp) {
- if (line < 0)
- wpa_printf(MSG_ERROR,
- "Line %d: invalid line %s",
- line, pos);
- return -1;
- }
- *tmp++ = '\0';
- if (hostapd_config_tx_queue(config->tx_queue, pos,
- tmp)) {
- wpa_printf(MSG_ERROR,
- "Line %d: invalid TX queue item",
- line);
- return -1;
- }
- }
-
- if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
- char *tmp = os_strchr(pos, '=');
- if (tmp == NULL) {
- if (line < 0)
- return -1;
- wpa_printf(MSG_ERROR, "Line %d: invalid line "
- "'%s'", line, pos);
- return -1;
- }
- *tmp++ = '\0';
- if (hostapd_config_wmm_ac(config->wmm_ac_params, pos,
- tmp)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
- "AC item", line);
- return -1;
- }
- return ret;
- }
-#endif /* CONFIG_AP */
- if (line < 0)
- return -1;
- wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
- line, pos);
- ret = -1;
- }
-
- return ret;
-}
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
deleted file mode 100644
index d22ef05fb8ba..000000000000
--- a/wpa_supplicant/config.h
+++ /dev/null
@@ -1,1797 +0,0 @@
-/*
- * WPA Supplicant / Configuration file structures
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#define DEFAULT_EAPOL_VERSION 1
-#ifdef CONFIG_NO_SCAN_PROCESSING
-#define DEFAULT_AP_SCAN 2
-#else /* CONFIG_NO_SCAN_PROCESSING */
-#define DEFAULT_AP_SCAN 1
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-#define DEFAULT_USER_MPM 1
-#define DEFAULT_MAX_PEER_LINKS 99
-#define DEFAULT_MESH_MAX_INACTIVITY 300
-#define DEFAULT_MESH_FWDING 1
-/*
- * The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
- * but use 1000 ms in practice to avoid issues on low power CPUs.
- */
-#define DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD 1000
-#define DEFAULT_FAST_REAUTH 1
-#define DEFAULT_P2P_GO_INTENT 7
-#define DEFAULT_P2P_INTRA_BSS 1
-#define DEFAULT_P2P_GO_MAX_INACTIVITY (5 * 60)
-#define DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN 0
-#define DEFAULT_BSS_MAX_COUNT 200
-#define DEFAULT_BSS_EXPIRATION_AGE 180
-#define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
-#define DEFAULT_MAX_NUM_STA 128
-#define DEFAULT_AP_ISOLATE 0
-#define DEFAULT_ACCESS_NETWORK_TYPE 15
-#define DEFAULT_SCAN_CUR_FREQ 0
-#define DEFAULT_P2P_SEARCH_DELAY 500
-#define DEFAULT_RAND_ADDR_LIFETIME 60
-#define DEFAULT_KEY_MGMT_OFFLOAD 1
-#define DEFAULT_CERT_IN_CB 1
-#define DEFAULT_P2P_GO_CTWINDOW 0
-#define DEFAULT_WPA_RSC_RELAXATION 1
-#define DEFAULT_MBO_CELL_CAPA MBO_CELL_CAPA_NOT_SUPPORTED
-#define DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD -75
-#define DEFAULT_OCE_SUPPORT OCE_STA
-#define DEFAULT_EXTENDED_KEY_ID 0
-#define DEFAULT_SCAN_RES_VALID_FOR_CONNECT 5
-
-#include "config_ssid.h"
-#include "wps/wps.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-
-
-#define MAX_ROAMING_CONS 36
-#define MAX_ROAMING_CONS_OI_LEN 15
-
-struct wpa_cred {
- /**
- * next - Next credential in the list
- *
- * This pointer can be used to iterate over all credentials. The head
- * of this list is stored in the cred field of struct wpa_config.
- */
- struct wpa_cred *next;
-
- /**
- * id - Unique id for the credential
- *
- * This identifier is used as a unique identifier for each credential
- * block when using the control interface. Each credential is allocated
- * an id when it is being created, either when reading the
- * configuration file or when a new credential is added through the
- * control interface.
- */
- int id;
-
- /**
- * temporary - Whether this credential is temporary and not to be saved
- */
- int temporary;
-
- /**
- * priority - Priority group
- *
- * By default, all networks and credentials get the same priority group
- * (0). This field can be used to give higher priority for credentials
- * (and similarly in struct wpa_ssid for network blocks) to change the
- * Interworking automatic networking selection behavior. The matching
- * network (based on either an enabled network block or a credential)
- * with the highest priority value will be selected.
- */
- int priority;
-
- /**
- * pcsc - Use PC/SC and SIM/USIM card
- */
- int pcsc;
-
- /**
- * realm - Home Realm for Interworking
- */
- char *realm;
-
- /**
- * username - Username for Interworking network selection
- */
- char *username;
-
- /**
- * password - Password for Interworking network selection
- */
- char *password;
-
- /**
- * ext_password - Whether password is a name for external storage
- */
- int ext_password;
-
- /**
- * ca_cert - CA certificate for Interworking network selection
- */
- char *ca_cert;
-
- /**
- * client_cert - File path to client certificate file (PEM/DER)
- *
- * This field is used with Interworking networking selection for a case
- * where client certificate/private key is used for authentication
- * (EAP-TLS). Full path to the file should be used since working
- * directory may change when wpa_supplicant is run in the background.
- *
- * Alternatively, a named configuration blob can be used by setting
- * this to blob://blob_name.
- */
- char *client_cert;
-
- /**
- * private_key - File path to client private key file (PEM/DER/PFX)
- *
- * When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
- * commented out. Both the private key and certificate will be read
- * from the PKCS#12 file in this case. Full path to the file should be
- * used since working directory may change when wpa_supplicant is run
- * in the background.
- *
- * Windows certificate store can be used by leaving client_cert out and
- * configuring private_key in one of the following formats:
- *
- * cert://substring_to_match
- *
- * hash://certificate_thumbprint_in_hex
- *
- * For example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
- *
- * Note that when running wpa_supplicant as an application, the user
- * certificate store (My user account) is used, whereas computer store
- * (Computer account) is used when running wpasvc as a service.
- *
- * Alternatively, a named configuration blob can be used by setting
- * this to blob://blob_name.
- */
- char *private_key;
-
- /**
- * private_key_passwd - Password for private key file
- */
- char *private_key_passwd;
-
- /**
- * imsi - IMSI in <MCC> | <MNC> | '-' | <MSIN> format
- */
- char *imsi;
-
- /**
- * milenage - Milenage parameters for SIM/USIM simulator in
- * <Ki>:<OPc>:<SQN> format
- */
- char *milenage;
-
- /**
- * engine - Use an engine for private key operations
- */
- int engine;
-
- /**
- * engine_id - String identifying the engine to use
- */
- char *engine_id;
-
- /**
- * ca_cert_id - The CA certificate identifier when using an engine
- */
- char *ca_cert_id;
-
- /**
- * cert_id - The certificate identifier when using an engine
- */
- char *cert_id;
-
- /**
- * key_id - The private key identifier when using an engine
- */
- char *key_id;
-
- /**
- * domain_suffix_match - Constraint for server domain name
- *
- * If set, this FQDN is used as a suffix match requirement for the AAA
- * server certificate in SubjectAltName dNSName element(s). If a
- * matching dNSName is found, this constraint is met. If no dNSName
- * values are present, this constraint is matched against SubjectName CN
- * using same suffix match comparison. Suffix match here means that the
- * host/domain name is compared one label at a time starting from the
- * top-level domain and all the labels in @domain_suffix_match shall be
- * included in the certificate. The certificate may include additional
- * sub-level labels in addition to the required labels.
- *
- * For example, domain_suffix_match=example.com would match
- * test.example.com but would not match test-example.com.
- */
- char *domain_suffix_match;
-
- /**
- * domain - Home service provider FQDN(s)
- *
- * This is used to compare against the Domain Name List to figure out
- * whether the AP is operated by the Home SP. Multiple domain entries
- * can be used to configure alternative FQDNs that will be considered
- * home networks.
- */
- char **domain;
-
- /**
- * num_domain - Number of FQDNs in the domain array
- */
- size_t num_domain;
-
- /**
- * roaming_consortium - Roaming Consortium OI
- *
- * If roaming_consortium_len is non-zero, this field contains the
- * Roaming Consortium OI that can be used to determine which access
- * points support authentication with this credential. This is an
- * alternative to the use of the realm parameter. When using Roaming
- * Consortium to match the network, the EAP parameters need to be
- * pre-configured with the credential since the NAI Realm information
- * may not be available or fetched.
- */
- u8 roaming_consortium[15];
-
- /**
- * roaming_consortium_len - Length of roaming_consortium
- */
- size_t roaming_consortium_len;
-
- /**
- * required_roaming_consortium - Required Roaming Consortium OI
- *
- * If required_roaming_consortium_len is non-zero, this field contains
- * the Roaming Consortium OI that is required to be advertised by the AP
- * for the credential to be considered matching.
- */
- u8 required_roaming_consortium[15];
-
- /**
- * required_roaming_consortium_len - Length of required_roaming_consortium
- */
- size_t required_roaming_consortium_len;
-
- /**
- * roaming_consortiums - Roaming Consortium OI(s) memberships
- *
- * This field contains one or more OIs identifying the roaming
- * consortiums of which the provider is a member. The list is sorted
- * from the most preferred one to the least preferred one. A match
- * between the Roaming Consortium OIs advertised by an AP and the OIs
- * in this list indicates that successful authentication is possible.
- * (Hotspot 2.0 PerProviderSubscription/<X+>/HomeSP/RoamingConsortiumOI)
- */
- u8 roaming_consortiums[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN];
-
- /**
- * roaming_consortiums_len - Length on roaming_consortiums[i]
- */
- size_t roaming_consortiums_len[MAX_ROAMING_CONS];
-
- /**
- * num_roaming_consortiums - Number of entries in roaming_consortiums
- */
- unsigned int num_roaming_consortiums;
-
- /**
- * eap_method - EAP method to use
- *
- * Pre-configured EAP method to use with this credential or %NULL to
- * indicate no EAP method is selected, i.e., the method will be
- * selected automatically based on ANQP information.
- */
- struct eap_method_type *eap_method;
-
- /**
- * phase1 - Phase 1 (outer authentication) parameters
- *
- * Pre-configured EAP parameters or %NULL.
- */
- char *phase1;
-
- /**
- * phase2 - Phase 2 (inner authentication) parameters
- *
- * Pre-configured EAP parameters or %NULL.
- */
- char *phase2;
-
- struct excluded_ssid {
- u8 ssid[SSID_MAX_LEN];
- size_t ssid_len;
- } *excluded_ssid;
- size_t num_excluded_ssid;
-
- struct roaming_partner {
- char fqdn[128];
- int exact_match;
- u8 priority;
- char country[3];
- } *roaming_partner;
- size_t num_roaming_partner;
-
- int update_identifier;
-
- /**
- * provisioning_sp - FQDN of the SP that provisioned the credential
- */
- char *provisioning_sp;
-
- /**
- * sp_priority - Credential priority within a provisioning SP
- *
- * This is the priority of the credential among all credentials
- * provisionined by the same SP (i.e., for entries that have identical
- * provisioning_sp value). The range of this priority is 0-255 with 0
- * being the highest and 255 the lower priority.
- */
- int sp_priority;
-
- unsigned int min_dl_bandwidth_home;
- unsigned int min_ul_bandwidth_home;
- unsigned int min_dl_bandwidth_roaming;
- unsigned int min_ul_bandwidth_roaming;
-
- /**
- * max_bss_load - Maximum BSS Load Channel Utilization (1..255)
- * This value is used as the maximum channel utilization for network
- * selection purposes for home networks. If the AP does not advertise
- * BSS Load or if the limit would prevent any connection, this
- * constraint will be ignored.
- */
- unsigned int max_bss_load;
-
- size_t num_req_conn_capab;
- u8 *req_conn_capab_proto;
- int **req_conn_capab_port;
-
- /**
- * ocsp - Whether to use/require OCSP to check server certificate
- *
- * 0 = do not use OCSP stapling (TLS certificate status extension)
- * 1 = try to use OCSP stapling, but not require response
- * 2 = require valid OCSP stapling response
- */
- int ocsp;
-
- /**
- * sim_num - User selected SIM identifier
- *
- * This variable is used for identifying which SIM is used if the system
- * has more than one.
- */
- int sim_num;
-};
-
-
-#define CFG_CHANGED_DEVICE_NAME BIT(0)
-#define CFG_CHANGED_CONFIG_METHODS BIT(1)
-#define CFG_CHANGED_DEVICE_TYPE BIT(2)
-#define CFG_CHANGED_OS_VERSION BIT(3)
-#define CFG_CHANGED_UUID BIT(4)
-#define CFG_CHANGED_COUNTRY BIT(5)
-#define CFG_CHANGED_SEC_DEVICE_TYPE BIT(6)
-#define CFG_CHANGED_P2P_SSID_POSTFIX BIT(7)
-#define CFG_CHANGED_WPS_STRING BIT(8)
-#define CFG_CHANGED_P2P_INTRA_BSS BIT(9)
-#define CFG_CHANGED_VENDOR_EXTENSION BIT(10)
-#define CFG_CHANGED_P2P_LISTEN_CHANNEL BIT(11)
-#define CFG_CHANGED_P2P_OPER_CHANNEL BIT(12)
-#define CFG_CHANGED_P2P_PREF_CHAN BIT(13)
-#define CFG_CHANGED_EXT_PW_BACKEND BIT(14)
-#define CFG_CHANGED_NFC_PASSWORD_TOKEN BIT(15)
-#define CFG_CHANGED_P2P_PASSPHRASE_LEN BIT(16)
-#define CFG_CHANGED_SCHED_SCAN_PLANS BIT(17)
-#define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18)
-#define CFG_CHANGED_DISABLE_BTM BIT(19)
-#define CFG_CHANGED_BGSCAN BIT(20)
-
-/**
- * struct wpa_config - wpa_supplicant configuration data
- *
- * This data structure is presents the per-interface (radio) configuration
- * data. In many cases, there is only one struct wpa_config instance, but if
- * more than one network interface is being controlled, one instance is used
- * for each.
- */
-struct wpa_config {
- /**
- * ssid - Head of the global network list
- *
- * This is the head for the list of all the configured networks.
- */
- struct wpa_ssid *ssid;
-
- /**
- * pssid - Per-priority network lists (in priority order)
- */
- struct wpa_ssid **pssid;
-
- /**
- * num_prio - Number of different priorities used in the pssid lists
- *
- * This indicates how many per-priority network lists are included in
- * pssid.
- */
- size_t num_prio;
-
- /**
- * cred - Head of the credential list
- *
- * This is the head for the list of all the configured credentials.
- */
- struct wpa_cred *cred;
-
- /**
- * eapol_version - IEEE 802.1X/EAPOL version number
- *
- * wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which
- * defines EAPOL version 2. However, there are many APs that do not
- * handle the new version number correctly (they seem to drop the
- * frames completely). In order to make wpa_supplicant interoperate
- * with these APs, the version number is set to 1 by default. This
- * configuration value can be used to set it to the new version (2).
- */
- int eapol_version;
-
- /**
- * ap_scan - AP scanning/selection
- *
- * By default, wpa_supplicant requests driver to perform AP
- * scanning and then uses the scan results to select a
- * suitable AP. Another alternative is to allow the driver to
- * take care of AP scanning and selection and use
- * wpa_supplicant just to process EAPOL frames based on IEEE
- * 802.11 association information from the driver.
- *
- * 1: wpa_supplicant initiates scanning and AP selection (default).
- *
- * 0: Driver takes care of scanning, AP selection, and IEEE 802.11
- * association parameters (e.g., WPA IE generation); this mode can
- * also be used with non-WPA drivers when using IEEE 802.1X mode;
- * do not try to associate with APs (i.e., external program needs
- * to control association). This mode must also be used when using
- * wired Ethernet drivers.
- *
- * 2: like 0, but associate with APs using security policy and SSID
- * (but not BSSID); this can be used, e.g., with ndiswrapper and NDIS
- * drivers to enable operation with hidden SSIDs and optimized roaming;
- * in this mode, the network blocks in the configuration are tried
- * one by one until the driver reports successful association; each
- * network block should have explicit security policy (i.e., only one
- * option in the lists) for key_mgmt, pairwise, group, proto variables.
- *
- * Note: ap_scan=2 should not be used with the nl80211 driver interface
- * (the current Linux interface). ap_scan=1 is optimized work working
- * with nl80211. For finding networks using hidden SSID, scan_ssid=1 in
- * the network block can be used with nl80211.
- */
- int ap_scan;
-
- /**
- * bgscan - Background scan and roaming parameters or %NULL if none
- *
- * This is an optional set of parameters for background scanning and
- * roaming within a network (ESS). For more detailed information see
- * ssid block documentation.
- *
- * The variable defines default bgscan behavior for all BSS station
- * networks except for those which have their own bgscan configuration.
- */
- char *bgscan;
-
- /**
- * disable_scan_offload - Disable automatic offloading of scan requests
- *
- * By default, %wpa_supplicant tries to offload scanning if the driver
- * indicates support for this (sched_scan). This configuration
- * parameter can be used to disable this offloading mechanism.
- */
- int disable_scan_offload;
-
- /**
- * ctrl_interface - Parameters for the control interface
- *
- * If this is specified, %wpa_supplicant will open a control interface
- * that is available for external programs to manage %wpa_supplicant.
- * The meaning of this string depends on which control interface
- * mechanism is used. For all cases, the existence of this parameter
- * in configuration is used to determine whether the control interface
- * is enabled.
- *
- * For UNIX domain sockets (default on Linux and BSD): This is a
- * directory that will be created for UNIX domain sockets for listening
- * to requests from external programs (CLI/GUI, etc.) for status
- * information and configuration. The socket file will be named based
- * on the interface name, so multiple %wpa_supplicant processes can be
- * run at the same time if more than one interface is used.
- * /var/run/wpa_supplicant is the recommended directory for sockets and
- * by default, wpa_cli will use it when trying to connect with
- * %wpa_supplicant.
- *
- * Access control for the control interface can be configured
- * by setting the directory to allow only members of a group
- * to use sockets. This way, it is possible to run
- * %wpa_supplicant as root (since it needs to change network
- * configuration and open raw sockets) and still allow GUI/CLI
- * components to be run as non-root users. However, since the
- * control interface can be used to change the network
- * configuration, this access needs to be protected in many
- * cases. By default, %wpa_supplicant is configured to use gid
- * 0 (root). If you want to allow non-root users to use the
- * control interface, add a new group and change this value to
- * match with that group. Add users that should have control
- * interface access to this group.
- *
- * When configuring both the directory and group, use following format:
- * DIR=/var/run/wpa_supplicant GROUP=wheel
- * DIR=/var/run/wpa_supplicant GROUP=0
- * (group can be either group name or gid)
- *
- * For UDP connections (default on Windows): The value will be ignored.
- * This variable is just used to select that the control interface is
- * to be created. The value can be set to, e.g., udp
- * (ctrl_interface=udp).
- *
- * For Windows Named Pipe: This value can be used to set the security
- * descriptor for controlling access to the control interface. Security
- * descriptor can be set using Security Descriptor String Format (see
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/security_descriptor_string_format.asp).
- * The descriptor string needs to be prefixed with SDDL=. For example,
- * ctrl_interface=SDDL=D: would set an empty DACL (which will reject
- * all connections).
- */
- char *ctrl_interface;
-
- /**
- * ctrl_interface_group - Control interface group (DEPRECATED)
- *
- * This variable is only used for backwards compatibility. Group for
- * UNIX domain sockets should now be specified using GROUP=group in
- * ctrl_interface variable.
- */
- char *ctrl_interface_group;
-
- /**
- * fast_reauth - EAP fast re-authentication (session resumption)
- *
- * By default, fast re-authentication is enabled for all EAP methods
- * that support it. This variable can be used to disable fast
- * re-authentication (by setting fast_reauth=0). Normally, there is no
- * need to disable fast re-authentication.
- */
- int fast_reauth;
-
- /**
- * opensc_engine_path - Path to the OpenSSL engine for opensc
- *
- * This is an OpenSSL specific configuration option for loading OpenSC
- * engine (engine_opensc.so); if %NULL, this engine is not loaded.
- */
- char *opensc_engine_path;
-
- /**
- * pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
- *
- * This is an OpenSSL specific configuration option for loading PKCS#11
- * engine (engine_pkcs11.so); if %NULL, this engine is not loaded.
- */
- char *pkcs11_engine_path;
-
- /**
- * pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
- *
- * This is an OpenSSL specific configuration option for configuring
- * path to OpenSC/PKCS#11 engine (opensc-pkcs11.so); if %NULL, this
- * module is not loaded.
- */
- char *pkcs11_module_path;
-
- /**
- * openssl_ciphers - OpenSSL cipher string
- *
- * This is an OpenSSL specific configuration option for configuring the
- * default ciphers. If not set, "DEFAULT:!EXP:!LOW" is used as the
- * default.
- */
- char *openssl_ciphers;
-
- /**
- * pcsc_reader - PC/SC reader name prefix
- *
- * If not %NULL, PC/SC reader with a name that matches this prefix is
- * initialized for SIM/USIM access. Empty string can be used to match
- * the first available reader.
- */
- char *pcsc_reader;
-
- /**
- * pcsc_pin - PIN for USIM, GSM SIM, and smartcards
- *
- * This field is used to configure PIN for SIM/USIM for EAP-SIM and
- * EAP-AKA. If left out, this will be asked through control interface.
- */
- char *pcsc_pin;
-
- /**
- * external_sim - Use external processing for SIM/USIM operations
- */
- int external_sim;
-
- /**
- * driver_param - Driver interface parameters
- *
- * This text string is passed to the selected driver interface with the
- * optional struct wpa_driver_ops::set_param() handler. This can be
- * used to configure driver specific options without having to add new
- * driver interface functionality.
- */
- char *driver_param;
-
- /**
- * dot11RSNAConfigPMKLifetime - Maximum lifetime of a PMK
- *
- * dot11 MIB variable for the maximum lifetime of a PMK in the PMK
- * cache (unit: seconds).
- */
- unsigned int dot11RSNAConfigPMKLifetime;
-
- /**
- * dot11RSNAConfigPMKReauthThreshold - PMK re-authentication threshold
- *
- * dot11 MIB variable for the percentage of the PMK lifetime
- * that should expire before an IEEE 802.1X reauthentication occurs.
- */
- unsigned int dot11RSNAConfigPMKReauthThreshold;
-
- /**
- * dot11RSNAConfigSATimeout - Security association timeout
- *
- * dot11 MIB variable for the maximum time a security association
- * shall take to set up (unit: seconds).
- */
- unsigned int dot11RSNAConfigSATimeout;
-
- /**
- * update_config - Is wpa_supplicant allowed to update configuration
- *
- * This variable control whether wpa_supplicant is allow to re-write
- * its configuration with wpa_config_write(). If this is zero,
- * configuration data is only changed in memory and the external data
- * is not overridden. If this is non-zero, wpa_supplicant will update
- * the configuration data (e.g., a file) whenever configuration is
- * changed. This update may replace the old configuration which can
- * remove comments from it in case of a text file configuration.
- */
- int update_config;
-
- /**
- * blobs - Configuration blobs
- */
- struct wpa_config_blob *blobs;
-
- /**
- * uuid - Universally Unique IDentifier (UUID; see RFC 4122) for WPS
- */
- u8 uuid[16];
-
- /**
- * auto_uuid - Automatic UUID behavior
- * 0 = generate static value based on the local MAC address (default)
- * 1 = generate a random UUID every time wpa_supplicant starts
- */
- int auto_uuid;
-
- /**
- * device_name - Device Name (WPS)
- * User-friendly description of device; up to 32 octets encoded in
- * UTF-8
- */
- char *device_name;
-
- /**
- * manufacturer - Manufacturer (WPS)
- * The manufacturer of the device (up to 64 ASCII characters)
- */
- char *manufacturer;
-
- /**
- * model_name - Model Name (WPS)
- * Model of the device (up to 32 ASCII characters)
- */
- char *model_name;
-
- /**
- * model_number - Model Number (WPS)
- * Additional device description (up to 32 ASCII characters)
- */
- char *model_number;
-
- /**
- * serial_number - Serial Number (WPS)
- * Serial number of the device (up to 32 characters)
- */
- char *serial_number;
-
- /**
- * device_type - Primary Device Type (WPS)
- */
- u8 device_type[WPS_DEV_TYPE_LEN];
-
- /**
- * config_methods - Config Methods
- *
- * This is a space-separated list of supported WPS configuration
- * methods. For example, "label virtual_display virtual_push_button
- * keypad".
- * Available methods: usba ethernet label display ext_nfc_token
- * int_nfc_token nfc_interface push_button keypad
- * virtual_display physical_display
- * virtual_push_button physical_push_button.
- */
- char *config_methods;
-
- /**
- * os_version - OS Version (WPS)
- * 4-octet operating system version number
- */
- u8 os_version[4];
-
- /**
- * country - Country code
- *
- * This is the ISO/IEC alpha2 country code for which we are operating
- * in
- */
- char country[2];
-
- /**
- * wps_cred_processing - Credential processing
- *
- * 0 = process received credentials internally
- * 1 = do not process received credentials; just pass them over
- * ctrl_iface to external program(s)
- * 2 = process received credentials internally and pass them over
- * ctrl_iface to external program(s)
- */
- int wps_cred_processing;
-
- /**
- * wps_cred_add_sae - Whether to enable SAE automatically for WPS
- *
- * 0 = only add the explicitly listed WPA2-PSK configuration
- * 1 = add both the WPA2-PSK and SAE configuration and enable PMF so
- * that the station gets configured in WPA3-Personal transition mode
- * (supports both WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
- */
- int wps_cred_add_sae;
-
-#define MAX_SEC_DEVICE_TYPES 5
- /**
- * sec_device_types - Secondary Device Types (P2P)
- */
- u8 sec_device_type[MAX_SEC_DEVICE_TYPES][WPS_DEV_TYPE_LEN];
- int num_sec_device_types;
-
- int p2p_listen_reg_class;
- int p2p_listen_channel;
- int p2p_oper_reg_class;
- int p2p_oper_channel;
- int p2p_go_intent;
- char *p2p_ssid_postfix;
- int persistent_reconnect;
- int p2p_intra_bss;
- unsigned int num_p2p_pref_chan;
- struct p2p_channel *p2p_pref_chan;
- struct wpa_freq_range_list p2p_no_go_freq;
- int p2p_add_cli_chan;
- int p2p_ignore_shared_freq;
- int p2p_optimize_listen_chan;
-
- int p2p_6ghz_disable;
-
- struct wpabuf *wps_vendor_ext_m1;
-
-#define MAX_WPS_VENDOR_EXT 10
- /**
- * wps_vendor_ext - Vendor extension attributes in WPS
- */
- struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXT];
-
- /**
- * p2p_group_idle - Maximum idle time in seconds for P2P group
- *
- * This value controls how long a P2P group is maintained after there
- * is no other members in the group. As a GO, this means no associated
- * stations in the group. As a P2P client, this means no GO seen in
- * scan results. The maximum idle time is specified in seconds with 0
- * indicating no time limit, i.e., the P2P group remains in active
- * state indefinitely until explicitly removed. As a P2P client, the
- * maximum idle time of P2P_MAX_CLIENT_IDLE seconds is enforced, i.e.,
- * this parameter is mainly meant for GO use and for P2P client, it can
- * only be used to reduce the default timeout to smaller value. A
- * special value -1 can be used to configure immediate removal of the
- * group for P2P client role on any disconnection after the data
- * connection has been established.
- */
- int p2p_group_idle;
-
- /**
- * p2p_go_freq_change_policy - The GO frequency change policy
- *
- * This controls the behavior of the GO when there is a change in the
- * map of the currently used frequencies in case more than one channel
- * is supported.
- *
- * @P2P_GO_FREQ_MOVE_SCM: Prefer working in a single channel mode if
- * possible. In case the GO is the only interface using its frequency
- * and there are other station interfaces on other frequencies, the GO
- * will migrate to one of these frequencies.
- *
- * @P2P_GO_FREQ_MOVE_SCM_PEER_SUPPORTS: Same as P2P_GO_FREQ_MOVE_SCM,
- * but a transition is possible only in case one of the other used
- * frequencies is one of the frequencies in the intersection of the
- * frequency list of the local device and the peer device.
- *
- * @P2P_GO_FREQ_MOVE_STAY: Prefer to stay on the current frequency.
- *
- * @P2P_GO_FREQ_MOVE_SCM_ECSA: Same as
- * P2P_GO_FREQ_MOVE_SCM_PEER_SUPPORTS but a transition is possible only
- * if all the group members advertise eCSA support.
- */
- enum {
- P2P_GO_FREQ_MOVE_SCM = 0,
- P2P_GO_FREQ_MOVE_SCM_PEER_SUPPORTS = 1,
- P2P_GO_FREQ_MOVE_STAY = 2,
- P2P_GO_FREQ_MOVE_SCM_ECSA = 3,
- P2P_GO_FREQ_MOVE_MAX = P2P_GO_FREQ_MOVE_SCM_ECSA,
- } p2p_go_freq_change_policy;
-
-#define DEFAULT_P2P_GO_FREQ_MOVE P2P_GO_FREQ_MOVE_STAY
-
- /**
- * p2p_passphrase_len - Passphrase length (8..63) for P2P GO
- *
- * This parameter controls the length of the random passphrase that is
- * generated at the GO.
- */
- unsigned int p2p_passphrase_len;
-
- /**
- * bss_max_count - Maximum number of BSS entries to keep in memory
- */
- unsigned int bss_max_count;
-
- /**
- * bss_expiration_age - BSS entry age after which it can be expired
- *
- * This value controls the time in seconds after which a BSS entry
- * gets removed if it has not been updated or is not in use.
- */
- unsigned int bss_expiration_age;
-
- /**
- * bss_expiration_scan_count - Expire BSS after number of scans
- *
- * If the BSS entry has not been seen in this many scans, it will be
- * removed. A value of 1 means that entry is removed after the first
- * scan in which the BSSID is not seen. Larger values can be used
- * to avoid BSS entries disappearing if they are not visible in
- * every scan (e.g., low signal quality or interference).
- */
- unsigned int bss_expiration_scan_count;
-
- /**
- * filter_ssids - SSID-based scan result filtering
- *
- * 0 = do not filter scan results
- * 1 = only include configured SSIDs in scan results/BSS table
- */
- int filter_ssids;
-
- /**
- * filter_rssi - RSSI-based scan result filtering
- *
- * 0 = do not filter scan results
- * -n = filter scan results below -n dBm
- */
- int filter_rssi;
-
- /**
- * max_num_sta - Maximum number of STAs in an AP/P2P GO
- */
- unsigned int max_num_sta;
-
- /**
- * ap_isolate - Whether to use client isolation feature
- *
- * Client isolation can be used to prevent low-level bridging of
- * frames between associated stations in the BSS. By default,
- * this bridging is allowed (ap_isolate=0); except in P2P GO case,
- * where p2p_intra_bss parameter is used to determine whether to allow
- * intra-BSS forwarding (ap_isolate = !p2p_intra_bss).
- *
- * 0 = do not enable AP isolation
- * 1 = enable AP isolation
- */
- int ap_isolate;
-
- /**
- * freq_list - Array of allowed scan frequencies or %NULL for all
- *
- * This is an optional zero-terminated array of frequencies in
- * megahertz (MHz) to allow for narrowing scanning range.
- */
- int *freq_list;
-
- /**
- * initial_freq_list - like freq_list but for initial scan
- *
- * This is an optional zero-terminated array of frequencies in
- * megahertz (MHz) to allow for narrowing scanning range when
- * the application is started.
- *
- * This can be used to speed up initial connection time if the
- * channel is known ahead of time, without limiting the scanned
- * frequencies during normal use.
- */
- int *initial_freq_list;
-
- /**
- * scan_cur_freq - Whether to scan only the current channel
- *
- * If true, attempt to scan only the current channel if any other
- * VIFs on this radio are already associated on a particular channel.
- */
- int scan_cur_freq;
-
- /**
- * scan_res_valid_for_connect - Seconds scans are valid for association
- *
- * This configures the number of seconds old scan results are considered
- * valid for association. When scan results are older than this value
- * a new scan is triggered prior to the association.
- */
- int scan_res_valid_for_connect;
-
- /**
- * changed_parameters - Bitmap of changed parameters since last update
- */
- unsigned int changed_parameters;
-
- /**
- * disassoc_low_ack - Disassociate stations with massive packet loss
- */
- int disassoc_low_ack;
-
- /**
- * interworking - Whether Interworking (IEEE 802.11u) is enabled
- */
- int interworking;
-
- /**
- * access_network_type - Access Network Type
- *
- * When Interworking is enabled, scans will be limited to APs that
- * advertise the specified Access Network Type (0..15; with 15
- * indicating wildcard match).
- */
- int access_network_type;
-
- /**
- * go_interworking - Whether Interworking for P2P GO is enabled
- */
- int go_interworking;
-
- /**
- * go_access_network_type - P2P GO Access Network Type
- *
- * This indicates which access network type to advertise if Interworking
- * is enabled for P2P GO.
- */
- int go_access_network_type;
-
- /**
- * go_internet - Interworking: Internet connectivity (0 or 1)
- */
- int go_internet;
-
- /**
- * go_venue_group - Interworking: Venue group
- */
- int go_venue_group;
-
- /**
- * go_venue_type: Interworking: Venue type
- */
- int go_venue_type;
-
- /**
- * hessid - Homogeneous ESS identifier
- *
- * If this is set (any octet is non-zero), scans will be used to
- * request response only from BSSes belonging to the specified
- * Homogeneous ESS. This is used only if interworking is enabled.
- */
- u8 hessid[ETH_ALEN];
-
- /**
- * hs20 - Hotspot 2.0
- */
- int hs20;
-
- /**
- * pbc_in_m1 - AP mode WPS probing workaround for PBC with Windows 7
- *
- * Windows 7 uses incorrect way of figuring out AP's WPS capabilities
- * by acting as a Registrar and using M1 from the AP. The config
- * methods attribute in that message is supposed to indicate only the
- * configuration method supported by the AP in Enrollee role, i.e., to
- * add an external Registrar. For that case, PBC shall not be used and
- * as such, the PushButton config method is removed from M1 by default.
- * If pbc_in_m1=1 is included in the configuration file, the PushButton
- * config method is left in M1 (if included in config_methods
- * parameter) to allow Windows 7 to use PBC instead of PIN (e.g., from
- * a label in the AP).
- */
- int pbc_in_m1;
-
- /**
- * autoscan - Automatic scan parameters or %NULL if none
- *
- * This is an optional set of parameters for automatic scanning
- * within an interface in following format:
- * <autoscan module name>:<module parameters>
- */
- char *autoscan;
-
- /**
- * wps_nfc_pw_from_config - NFC Device Password was read from config
- *
- * This parameter can be determined whether the NFC Device Password was
- * included in the configuration (1) or generated dynamically (0). Only
- * the former case is re-written back to the configuration file.
- */
- int wps_nfc_pw_from_config;
-
- /**
- * wps_nfc_dev_pw_id - NFC Device Password ID for password token
- */
- int wps_nfc_dev_pw_id;
-
- /**
- * wps_nfc_dh_pubkey - NFC DH Public Key for password token
- */
- struct wpabuf *wps_nfc_dh_pubkey;
-
- /**
- * wps_nfc_dh_privkey - NFC DH Private Key for password token
- */
- struct wpabuf *wps_nfc_dh_privkey;
-
- /**
- * wps_nfc_dev_pw - NFC Device Password for password token
- */
- struct wpabuf *wps_nfc_dev_pw;
-
- /**
- * ext_password_backend - External password backend or %NULL if none
- *
- * format: <backend name>[:<optional backend parameters>]
- */
- char *ext_password_backend;
-
- /*
- * p2p_go_max_inactivity - Timeout in seconds to detect STA inactivity
- *
- * This timeout value is used in P2P GO mode to clean up
- * inactive stations.
- * By default: 300 seconds.
- */
- int p2p_go_max_inactivity;
-
- struct hostapd_wmm_ac_params wmm_ac_params[4];
- struct hostapd_tx_queue_params tx_queue[4];
-
- /**
- * auto_interworking - Whether to use network selection automatically
- *
- * 0 = do not automatically go through Interworking network selection
- * (i.e., require explicit interworking_select command for this)
- * 1 = perform Interworking network selection if one or more
- * credentials have been configured and scan did not find a
- * matching network block
- */
- int auto_interworking;
-
- /**
- * p2p_go_ht40 - Default mode for HT40 enable when operating as GO.
- *
- * This will take effect for p2p_group_add, p2p_connect, and p2p_invite.
- * Note that regulatory constraints and driver capabilities are
- * consulted anyway, so setting it to 1 can't do real harm.
- * By default: 0 (disabled)
- */
- int p2p_go_ht40;
-
- /**
- * p2p_go_vht - Default mode for VHT enable when operating as GO
- *
- * This will take effect for p2p_group_add, p2p_connect, and p2p_invite.
- * Note that regulatory constraints and driver capabilities are
- * consulted anyway, so setting it to 1 can't do real harm.
- * By default: 0 (disabled)
- */
- int p2p_go_vht;
-
- /**
- * p2p_go_edmg - Default mode for EDMG enable when operating as GO
- *
- * This will take effect for p2p_group_add, p2p_connect, and p2p_invite.
- * Note that regulatory constraints and driver capabilities are
- * consulted anyway, so setting it to 1 can't do real harm.
- * By default: 0 (disabled)
- */
- int p2p_go_edmg;
-
- /**
- * p2p_go_he - Default mode for 11ax HE enable when operating as GO
- *
- * This will take effect for p2p_group_add, p2p_connect, and p2p_invite.
- * Note that regulatory constraints and driver capabilities are
- * consulted anyway, so setting it to 1 can't do real harm.
- * By default: 0 (disabled)
- */
- int p2p_go_he;
-
- /**
- * p2p_go_ctwindow - CTWindow to use when operating as GO
- *
- * By default: 0 (no CTWindow). Values 0-127 can be used to indicate
- * the length of the CTWindow in TUs.
- */
- int p2p_go_ctwindow;
-
- /**
- * p2p_disabled - Whether P2P operations are disabled for this interface
- */
- int p2p_disabled;
-
- /**
- * p2p_no_group_iface - Whether group interfaces can be used
- *
- * By default, wpa_supplicant will create a separate interface for P2P
- * group operations if the driver supports this. This functionality can
- * be disabled by setting this parameter to 1. In that case, the same
- * interface that was used for the P2P management operations is used
- * also for the group operation.
- */
- int p2p_no_group_iface;
-
- /**
- * p2p_cli_probe - Enable/disable P2P CLI probe request handling
- *
- * If this parameter is set to 1, a connected P2P Client will receive
- * and handle Probe Request frames. Setting this parameter to 0
- * disables this option. Default value: 0.
- *
- * Note: Setting this property at run time takes effect on the following
- * interface state transition to/from the WPA_COMPLETED state.
- */
- int p2p_cli_probe;
-
- /**
- * okc - Whether to enable opportunistic key caching by default
- *
- * By default, OKC is disabled unless enabled by the per-network
- * proactive_key_caching=1 parameter. okc=1 can be used to change this
- * default behavior.
- */
- int okc;
-
- /**
- * pmf - Whether to enable/require PMF by default
- *
- * By default, PMF is disabled unless enabled by the per-network
- * ieee80211w=1 or ieee80211w=2 parameter. pmf=1/2 can be used to change
- * this default behavior for RSN network (this is not applicable for
- * non-RSN cases).
- */
- enum mfp_options pmf;
-
- /**
- * sae_groups - Preference list of enabled groups for SAE
- *
- * By default (if this parameter is not set), the mandatory group 19
- * (ECC group defined over a 256-bit prime order field) is preferred,
- * but other groups are also enabled. If this parameter is set, the
- * groups will be tried in the indicated order.
- */
- int *sae_groups;
-
- /**
- * sae_pwe - SAE mechanism for PWE derivation
- * 0 = hunting-and-pecking loop only
- * 1 = hash-to-element only
- * 2 = both hunting-and-pecking loop and hash-to-element enabled
- */
- int sae_pwe;
-
- /**
- * sae_pmkid_in_assoc - Whether to include PMKID in SAE Assoc Req
- */
- int sae_pmkid_in_assoc;
-
- /**
- * dtim_period - Default DTIM period in Beacon intervals
- *
- * This parameter can be used to set the default value for network
- * blocks that do not specify dtim_period.
- */
- int dtim_period;
-
- /**
- * beacon_int - Default Beacon interval in TU
- *
- * This parameter can be used to set the default value for network
- * blocks that do not specify beacon_int.
- */
- int beacon_int;
-
- /**
- * ap_vendor_elements: Vendor specific elements for Beacon/ProbeResp
- *
- * This parameter can be used to define additional vendor specific
- * elements for Beacon and Probe Response frames in AP/P2P GO mode. The
- * format for these element(s) is a hexdump of the raw information
- * elements (id+len+payload for one or more elements).
- */
- struct wpabuf *ap_vendor_elements;
-
- /**
- * ap_assocresp_elements: Vendor specific elements for (Re)Association
- * Response frames
- *
- * This parameter can be used to define additional vendor specific
- * elements for (Re)Association Response frames in AP/P2P GO mode. The
- * format for these element(s) is a hexdump of the raw information
- * elements (id+len+payload for one or more elements).
- */
- struct wpabuf *ap_assocresp_elements;
-
- /**
- * ignore_old_scan_res - Ignore scan results older than request
- *
- * The driver may have a cache of scan results that makes it return
- * information that is older than our scan trigger. This parameter can
- * be used to configure such old information to be ignored instead of
- * allowing it to update the internal BSS table.
- */
- int ignore_old_scan_res;
-
- /**
- * sched_scan_interval - schedule scan interval
- */
- unsigned int sched_scan_interval;
-
- /**
- * sched_scan_start_delay - Schedule scan start delay before first scan
- *
- * Delay (in seconds) before scheduling first scan plan cycle. The
- * driver may ignore this parameter and start immediately (or at any
- * other time), if this feature is not supported.
- */
- unsigned int sched_scan_start_delay;
-
- /**
- * tdls_external_control - External control for TDLS setup requests
- *
- * Enable TDLS mode where external programs are given the control
- * to specify the TDLS link to get established to the driver. The
- * driver requests the TDLS setup to the supplicant only for the
- * specified TDLS peers.
- */
- int tdls_external_control;
-
- u8 ip_addr_go[4];
- u8 ip_addr_mask[4];
- u8 ip_addr_start[4];
- u8 ip_addr_end[4];
-
- /**
- * osu_dir - OSU provider information directory
- *
- * If set, allow FETCH_OSU control interface command to be used to fetch
- * OSU provider information into all APs and store the results in this
- * directory.
- */
- char *osu_dir;
-
- /**
- * wowlan_triggers - Wake-on-WLAN triggers
- *
- * If set, these wowlan triggers will be configured.
- */
- char *wowlan_triggers;
-
- /**
- * p2p_search_delay - Extra delay between concurrent search iterations
- *
- * Add extra delay (in milliseconds) between search iterations when
- * there is a concurrent operation to make p2p_find friendlier to
- * concurrent operations by avoiding it from taking 100% of radio
- * resources.
- */
- unsigned int p2p_search_delay;
-
- /**
- * mac_addr - MAC address policy default
- *
- * 0 = use permanent MAC address
- * 1 = use random MAC address for each ESS connection
- * 2 = like 1, but maintain OUI (with local admin bit set)
- *
- * By default, permanent MAC address is used unless policy is changed by
- * the per-network mac_addr parameter. Global mac_addr=1 can be used to
- * change this default behavior.
- */
- int mac_addr;
-
- /**
- * rand_addr_lifetime - Lifetime of random MAC address in seconds
- */
- unsigned int rand_addr_lifetime;
-
- /**
- * preassoc_mac_addr - Pre-association MAC address policy
- *
- * 0 = use permanent MAC address
- * 1 = use random MAC address
- * 2 = like 1, but maintain OUI (with local admin bit set)
- */
- int preassoc_mac_addr;
-
- /**
- * key_mgmt_offload - Use key management offload
- *
- * Key management offload should be used if the device supports it.
- * Key management offload is the capability of a device operating as
- * a station to do the exchange necessary to establish temporal keys
- * during initial RSN connection, after roaming, or during a PTK
- * rekeying operation.
- */
- int key_mgmt_offload;
-
- /**
- * user_mpm - MPM residency
- *
- * 0: MPM lives in driver.
- * 1: wpa_supplicant handles peering and station allocation.
- *
- * If AMPE or SAE is enabled, the MPM is always in userspace.
- */
- int user_mpm;
-
- /**
- * max_peer_links - Maximum number of peer links
- *
- * Maximum number of mesh peering currently maintained by the STA.
- */
- int max_peer_links;
-
- /**
- * cert_in_cb - Whether to include a peer certificate dump in events
- *
- * This controls whether peer certificates for authentication server and
- * its certificate chain are included in EAP peer certificate events.
- */
- int cert_in_cb;
-
- /**
- * mesh_max_inactivity - Timeout in seconds to detect STA inactivity
- *
- * This timeout value is used in mesh STA to clean up inactive stations.
- * By default: 300 seconds.
- */
- int mesh_max_inactivity;
-
- /**
- * mesh_fwding - Mesh network layer-2 forwarding (dot11MeshForwarding)
- *
- * This controls whether to enable layer-2 forwarding.
- * By default: 1: enabled
- */
- int mesh_fwding;
-
- /**
- * dot11RSNASAERetransPeriod - Timeout to retransmit SAE Auth frame
- *
- * This timeout value is used in mesh STA to retransmit
- * SAE Authentication frame.
- * By default: 1000 milliseconds.
- */
- int dot11RSNASAERetransPeriod;
-
- /**
- * passive_scan - Whether to force passive scan for network connection
- *
- * This parameter can be used to force only passive scanning to be used
- * for network connection cases. It should be noted that this will slow
- * down scan operations and reduce likelihood of finding the AP. In
- * addition, some use cases will override this due to functional
- * requirements, e.g., for finding an AP that uses hidden SSID
- * (scan_ssid=1) or P2P device discovery.
- */
- int passive_scan;
-
- /**
- * reassoc_same_bss_optim - Whether to optimize reassoc-to-same-BSS
- */
- int reassoc_same_bss_optim;
-
- /**
- * wps_priority - Priority for the networks added through WPS
- *
- * This priority value will be set to each network profile that is added
- * by executing the WPS protocol.
- */
- int wps_priority;
-
- /**
- * fst_group_id - FST group ID
- */
- char *fst_group_id;
-
- /**
- * fst_priority - priority of the interface within the FST group
- */
- int fst_priority;
-
- /**
- * fst_llt - default FST LLT (Link-Lost Timeout) to be used for the
- * interface.
- */
- int fst_llt;
-
- /**
- * wpa_rsc_relaxation - RSC relaxation on GTK installation
- *
- * Values:
- * 0 - use the EAPOL-Key RSC value on GTK installation
- * 1 - use the null RSC if a bogus RSC value is detected in message 3
- * of 4-Way Handshake or message 1 of Group Key Handshake.
- */
- int wpa_rsc_relaxation;
-
- /**
- * sched_scan_plans - Scan plans for scheduled scan
- *
- * Each scan plan specifies the interval between scans and the number of
- * iterations. The last scan plan only specifies the scan interval and
- * will be run infinitely.
- *
- * format: <interval:iterations> <interval2:iterations2> ... <interval>
- */
- char *sched_scan_plans;
-
-#ifdef CONFIG_MBO
- /**
- * non_pref_chan - Non-preferred channels list, separated by spaces.
- *
- * format: op_class:chan:preference:reason<:detail>
- * Detail is optional.
- */
- char *non_pref_chan;
-
- /**
- * mbo_cell_capa - Cellular capabilities for MBO
- */
- enum mbo_cellular_capa mbo_cell_capa;
-
- /**
- * disassoc_imminent_rssi_threshold - RSSI threshold of candidate AP
- * when disassociation imminent is set.
- */
- int disassoc_imminent_rssi_threshold;
-
- /**
- * oce - Enable OCE in STA and/or STA-CFON mode
- * - Set BIT(0) to enable OCE in non-AP STA mode
- * - Set BIT(1) to enable OCE in STA-CFON mode
- */
- unsigned int oce;
-#endif /* CONFIG_MBO */
-
- /**
- * gas_address3 - GAS Address3 field behavior
- *
- * Values:
- * 0 - P2P specification (Address3 = AP BSSID)
- * 1 = IEEE 802.11 standard compliant (Address3 = Wildcard BSSID when
- * sent to not-associated AP; if associated, AP BSSID)
- */
- int gas_address3;
-
- /**
- * ftm_responder - Publish FTM (fine timing measurement)
- * responder functionality
- *
- * Values:
- * 0 - do not publish FTM responder functionality (Default)
- * 1 - publish FTM responder functionality in
- * bit 70 of Extended Capabilities element
- * Note, actual FTM responder operation is managed outside
- * wpa_supplicant.
- */
- int ftm_responder;
-
- /**
- * ftm_initiator - Publish FTM (fine timing measurement)
- * initiator functionality
- *
- * Values:
- * 0 - do not publish FTM initiator functionality (Default)
- * 1 - publish FTM initiator functionality in
- * bit 71 of Extended Capabilities element
- * Note, actual FTM initiator operation is managed outside
- * wpa_supplicant.
- */
- int ftm_initiator;
-
- /**
- * gas_rand_addr_lifetime - Lifetime of random MAC address for ANQP in
- * seconds
- */
- unsigned int gas_rand_addr_lifetime;
-
- /**
- * gas_rand_mac_addr - GAS MAC address policy
- *
- * 0 = use permanent MAC address
- * 1 = use random MAC address
- * 2 = like 1, but maintain OUI (with local admin bit set)
- */
- int gas_rand_mac_addr;
-
- /**
- * dpp_config_processing - How to process DPP configuration
- *
- * 0 = report received configuration to an external program for
- * processing; do not generate any network profile internally
- * 1 = report received configuration to an external program and generate
- * a network profile internally, but do not automatically connect
- * to the created (disabled) profile; the network profile id is
- * reported to external programs
- * 2 = report received configuration to an external program, generate
- * a network profile internally, try to connect to the created
- * profile automatically
- */
- int dpp_config_processing;
-
- /**
- * dpp_name - Name for Enrollee's DPP Configuration Request
- */
- char *dpp_name;
-
- /**
- * dpp_mud_url - MUD URL for Enrollee's DPP Configuration Request
- */
- char *dpp_mud_url;
-
- /**
- * coloc_intf_reporting - Colocated interference reporting
- *
- * dot11CoLocIntfReportingActivated
- * 0 = disabled (false)
- * 1 = enabled (true)
- */
- int coloc_intf_reporting;
-
- /**
- * p2p_device_random_mac_addr - P2P Device MAC address policy default
- *
- * 0 = use permanent MAC address (the one set by default by the device
- * driver). Notice that, if the device driver is configured to
- * always use random MAC addresses, this flag breaks reinvoking a
- * persistent group, so flags 1 or 2 should be used instead with
- * such drivers if persistent groups are used.
- * 1 = use random MAC address on creating the interface if there is no
- * persistent group. Besides, if a persistent group is created,
- * p2p_device_persistent_mac_addr is set to the MAC address of the
- * P2P Device interface, so that this address will be subsequently
- * used to change the MAC address of the P2P Device interface. With
- * no persistent group, the random MAC address is created by
- * wpa_supplicant, changing the one set by the device driver.
- * The device driver shall support SIOCGIFFLAGS/SIOCSIFFLAGS ioctl
- * interface control operations.
- * 2 = this flag should be used when the device driver uses random MAC
- * addresses by default when a P2P Device interface is created.
- * If p2p_device_persistent_mac_addr is set, use this MAC address
- * on creating the P2P Device interface. If not set, use the
- * default method adopted by the device driver (e.g., random MAC
- * address). Besides, if a persistent group is created,
- * p2p_device_persistent_mac_addr is set to the MAC address of the
- * P2P Device interface, so that this address will be subsequently
- * used in place of the default address set by the device driver.
- * (This option does not need support of SIOCGIFFLAGS/SIOCSIFFLAGS
- * ioctl interface control operations and uses NL80211_ATTR_MAC).
- *
- * By default, permanent MAC address is used.
- */
- int p2p_device_random_mac_addr;
-
- /**
- * p2p_device_persistent_mac_addr - Record last used MAC address
- *
- * If there are saved persistent groups, P2P cannot generate another
- * random MAC address, and need to restore to last used MAC address.
- */
- u8 p2p_device_persistent_mac_addr[ETH_ALEN];
-
- /**
- * p2p_interface_random_mac_addr - P2P Interface MAC address policy default
- *
- * 0 = use permanent MAC address
- * 1 = use random MAC address on creating the interface.
- *
- * By default, permanent MAC address is used.
- */
- int p2p_interface_random_mac_addr;
-
- /**
- * disable_btm - Disable BSS transition management in STA
- * - Set to 0 to enable BSS transition management
- * - Set to 1 to disable BSS transition management
- *
- * By default BSS transition management is enabled
- */
- int disable_btm;
-
- /**
- * extended_key_id - Extended Key ID support
- *
- * IEEE Std 802.11-2016 optionally allows to use Key ID 0 and 1 for PTK
- * keys with Extended Key ID.
- *
- * 0 = don't use Extended Key ID
- * 1 = use Extended Key ID when possible
- */
- int extended_key_id;
-
- /**
- * wowlan_disconnect_on_deinit - Trigger disconnect on wpa_supplicant
- * interface deinit even if the driver has enabled WoWLAN.
- *
- * 0 = Do not disconnect
- * 1 = Trigger disconnection
- */
- int wowlan_disconnect_on_deinit;
-
-#ifdef CONFIG_PASN
-#ifdef CONFIG_TESTING_OPTIONS
- /*
- * Normally, KDK should be derived if and only if both sides support
- * secure LTF. Allow forcing KDK derivation for testing purposes.
- */
- int force_kdk_derivation;
-
- /* If set, corrupt the MIC in the 3rd Authentication frame of PASN */
- int pasn_corrupt_mic;
-
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_PASN*/
-};
-
-
-/* Prototypes for common functions from config.c */
-
-void wpa_config_free(struct wpa_config *ssid);
-void wpa_config_free_ssid(struct wpa_ssid *ssid);
-void wpa_config_foreach_network(struct wpa_config *config,
- void (*func)(void *, struct wpa_ssid *),
- void *arg);
-struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id);
-struct wpa_ssid * wpa_config_add_network(struct wpa_config *config);
-int wpa_config_remove_network(struct wpa_config *config, int id);
-void wpa_config_set_network_defaults(struct wpa_ssid *ssid);
-int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
- int line);
-int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
- const char *value);
-int wpa_config_dump_values(struct wpa_config *config, char *buf,
- size_t buflen);
-int wpa_config_get_value(const char *name, struct wpa_config *config,
- char *buf, size_t buflen);
-
-char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys);
-char * wpa_config_get(struct wpa_ssid *ssid, const char *var);
-char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var);
-void wpa_config_update_psk(struct wpa_ssid *ssid);
-int wpa_config_add_prio_network(struct wpa_config *config,
- struct wpa_ssid *ssid);
-int wpa_config_update_prio_list(struct wpa_config *config);
-const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
- const char *name);
-void wpa_config_set_blob(struct wpa_config *config,
- struct wpa_config_blob *blob);
-void wpa_config_free_blob(struct wpa_config_blob *blob);
-int wpa_config_remove_blob(struct wpa_config *config, const char *name);
-void wpa_config_flush_blobs(struct wpa_config *config);
-
-struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id);
-struct wpa_cred * wpa_config_add_cred(struct wpa_config *config);
-int wpa_config_remove_cred(struct wpa_config *config, int id);
-void wpa_config_free_cred(struct wpa_cred *cred);
-int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
- const char *value, int line);
-char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var);
-
-struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
- const char *driver_param);
-#ifndef CONFIG_NO_STDOUT_DEBUG
-void wpa_config_debug_dump_networks(struct wpa_config *config);
-#else /* CONFIG_NO_STDOUT_DEBUG */
-#define wpa_config_debug_dump_networks(c) do { } while (0)
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
-
-/* Prototypes for common functions from config.c */
-int wpa_config_process_global(struct wpa_config *config, char *pos, int line);
-
-int wpa_config_get_num_global_field_names(void);
-
-const char * wpa_config_get_global_field_name(unsigned int i, int *no_var);
-
-/* Prototypes for backend specific functions from the selected config_*.c */
-
-/**
- * wpa_config_read - Read and parse configuration database
- * @name: Name of the configuration (e.g., path and file name for the
- * configuration file)
- * @cfgp: Pointer to previously allocated configuration data or %NULL if none
- * Returns: Pointer to allocated configuration data or %NULL on failure
- *
- * This function reads configuration data, parses its contents, and allocates
- * data structures needed for storing configuration information. The allocated
- * data can be freed with wpa_config_free().
- *
- * Each configuration backend needs to implement this function.
- */
-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp);
-
-/**
- * wpa_config_write - Write or update configuration data
- * @name: Name of the configuration (e.g., path and file name for the
- * configuration file)
- * @config: Configuration data from wpa_config_read()
- * Returns: 0 on success, -1 on failure
- *
- * This function write all configuration data into an external database (e.g.,
- * a text file) in a format that can be read with wpa_config_read(). This can
- * be used to allow wpa_supplicant to update its configuration, e.g., when a
- * new network is added or a password is changed.
- *
- * Each configuration backend needs to implement this function.
- */
-int wpa_config_write(const char *name, struct wpa_config *config);
-
-#endif /* CONFIG_H */
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
deleted file mode 100644
index 6db5010db3a7..000000000000
--- a/wpa_supplicant/config_file.c
+++ /dev/null
@@ -1,1656 +0,0 @@
-/*
- * WPA Supplicant / Configuration backend: text file
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * This file implements a configuration backend for text files. All the
- * configuration information is stored in a text file that uses a format
- * described in the sample configuration file, wpa_supplicant.conf.
- */
-
-#include "includes.h"
-#ifdef ANDROID
-#include <sys/stat.h>
-#endif /* ANDROID */
-
-#include "common.h"
-#include "config.h"
-#include "base64.h"
-#include "uuid.h"
-#include "common/ieee802_1x_defs.h"
-#include "p2p/p2p.h"
-#include "eap_peer/eap_methods.h"
-#include "eap_peer/eap.h"
-#include "utils/config.h"
-
-
-static int wpa_config_validate_network(struct wpa_ssid *ssid, int line)
-{
- int errors = 0;
-
- if (ssid->passphrase) {
- if (ssid->psk_set) {
- wpa_printf(MSG_ERROR, "Line %d: both PSK and "
- "passphrase configured.", line);
- errors++;
- }
- wpa_config_update_psk(ssid);
- }
-
- if (ssid->disabled == 2)
- ssid->p2p_persistent_group = 1;
-
- if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
- !(ssid->pairwise_cipher & (WPA_CIPHER_CCMP | WPA_CIPHER_CCMP_256 |
- WPA_CIPHER_GCMP | WPA_CIPHER_GCMP_256 |
- WPA_CIPHER_NONE))) {
- /* Group cipher cannot be stronger than the pairwise cipher. */
- wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher"
- " list since it was not allowed for pairwise "
- "cipher", line);
- ssid->group_cipher &= ~WPA_CIPHER_CCMP;
- }
-
- if (ssid->mode == WPAS_MODE_MESH &&
- (ssid->key_mgmt != WPA_KEY_MGMT_NONE &&
- ssid->key_mgmt != WPA_KEY_MGMT_SAE)) {
- wpa_printf(MSG_ERROR,
- "Line %d: key_mgmt for mesh network should be open or SAE",
- line);
- errors++;
- }
-
-#ifdef CONFIG_OCV
- if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
- wpa_printf(MSG_ERROR,
- "Line %d: PMF needs to be enabled whenever using OCV",
- line);
- errors++;
- }
-#endif /* CONFIG_OCV */
-
- return errors;
-}
-
-
-static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id)
-{
- struct wpa_ssid *ssid;
- int errors = 0, end = 0;
- char buf[2000], *pos, *pos2;
-
- wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block",
- *line);
- ssid = os_zalloc(sizeof(*ssid));
- if (ssid == NULL)
- return NULL;
- dl_list_init(&ssid->psk_list);
- ssid->id = id;
-
- wpa_config_set_network_defaults(ssid);
-
- while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
- if (os_strcmp(pos, "}") == 0) {
- end = 1;
- break;
- }
-
- pos2 = os_strchr(pos, '=');
- if (pos2 == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line "
- "'%s'.", *line, pos);
- errors++;
- continue;
- }
-
- *pos2++ = '\0';
- if (*pos2 == '"') {
- if (os_strchr(pos2 + 1, '"') == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "quotation '%s'.", *line, pos2);
- errors++;
- continue;
- }
- }
-
- if (wpa_config_set(ssid, pos, pos2, *line) < 0) {
-#ifndef CONFIG_WEP
- if (os_strcmp(pos, "wep_key0") == 0 ||
- os_strcmp(pos, "wep_key1") == 0 ||
- os_strcmp(pos, "wep_key2") == 0 ||
- os_strcmp(pos, "wep_key3") == 0 ||
- os_strcmp(pos, "wep_tx_keyidx") == 0) {
- wpa_printf(MSG_ERROR,
- "Line %d: unsupported WEP parameter",
- *line);
- ssid->disabled = 1;
- continue;
- }
-#endif /* CONFIG_WEP */
- errors++;
- }
- }
-
- if (!end) {
- wpa_printf(MSG_ERROR, "Line %d: network block was not "
- "terminated properly.", *line);
- errors++;
- }
-
- errors += wpa_config_validate_network(ssid, *line);
-
- if (errors) {
- wpa_config_free_ssid(ssid);
- ssid = NULL;
- }
-
- return ssid;
-}
-
-
-static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id)
-{
- struct wpa_cred *cred;
- int errors = 0, end = 0;
- char buf[256], *pos, *pos2;
-
- wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line);
- cred = os_zalloc(sizeof(*cred));
- if (cred == NULL)
- return NULL;
- cred->id = id;
- cred->sim_num = DEFAULT_USER_SELECTED_SIM;
-
- while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
- if (os_strcmp(pos, "}") == 0) {
- end = 1;
- break;
- }
-
- pos2 = os_strchr(pos, '=');
- if (pos2 == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid cred line "
- "'%s'.", *line, pos);
- errors++;
- continue;
- }
-
- *pos2++ = '\0';
- if (*pos2 == '"') {
- if (os_strchr(pos2 + 1, '"') == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "quotation '%s'.", *line, pos2);
- errors++;
- continue;
- }
- }
-
- if (wpa_config_set_cred(cred, pos, pos2, *line) < 0)
- errors++;
- }
-
- if (!end) {
- wpa_printf(MSG_ERROR, "Line %d: cred block was not "
- "terminated properly.", *line);
- errors++;
- }
-
- if (errors) {
- wpa_config_free_cred(cred);
- cred = NULL;
- }
-
- return cred;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
- const char *name)
-{
- struct wpa_config_blob *blob;
- char buf[256], *pos;
- char *encoded = NULL, *nencoded;
- int end = 0;
- size_t encoded_len = 0, len;
-
- wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'",
- *line, name);
-
- while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
- if (os_strcmp(pos, "}") == 0) {
- end = 1;
- break;
- }
-
- len = os_strlen(pos);
- nencoded = os_realloc(encoded, encoded_len + len);
- if (nencoded == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: not enough memory for "
- "blob", *line);
- os_free(encoded);
- return NULL;
- }
- encoded = nencoded;
- os_memcpy(encoded + encoded_len, pos, len);
- encoded_len += len;
- }
-
- if (!end || !encoded) {
- wpa_printf(MSG_ERROR, "Line %d: blob was not terminated "
- "properly", *line);
- os_free(encoded);
- return NULL;
- }
-
- blob = os_zalloc(sizeof(*blob));
- if (blob == NULL) {
- os_free(encoded);
- return NULL;
- }
- blob->name = os_strdup(name);
- blob->data = base64_decode(encoded, encoded_len, &blob->len);
- os_free(encoded);
-
- if (blob->name == NULL || blob->data == NULL) {
- wpa_config_free_blob(blob);
- return NULL;
- }
-
- return blob;
-}
-
-
-static int wpa_config_process_blob(struct wpa_config *config, FILE *f,
- int *line, char *bname)
-{
- char *name_end;
- struct wpa_config_blob *blob;
-
- name_end = os_strchr(bname, '=');
- if (name_end == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: no blob name terminator",
- *line);
- return -1;
- }
- *name_end = '\0';
-
- blob = wpa_config_read_blob(f, line, bname);
- if (blob == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to read blob %s",
- *line, bname);
- return -1;
- }
- wpa_config_set_blob(config, blob);
- return 0;
-}
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
-{
- FILE *f;
- char buf[512], *pos;
- int errors = 0, line = 0;
- struct wpa_ssid *ssid, *tail, *head;
- struct wpa_cred *cred, *cred_tail, *cred_head;
- struct wpa_config *config;
- int id = 0;
- int cred_id = 0;
-
- if (name == NULL)
- return NULL;
- if (cfgp)
- config = cfgp;
- else
- config = wpa_config_alloc_empty(NULL, NULL);
- if (config == NULL) {
- wpa_printf(MSG_ERROR, "Failed to allocate config file "
- "structure");
- return NULL;
- }
- tail = head = config->ssid;
- while (tail && tail->next)
- tail = tail->next;
- cred_tail = cred_head = config->cred;
- while (cred_tail && cred_tail->next)
- cred_tail = cred_tail->next;
-
- wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name);
- f = fopen(name, "r");
- if (f == NULL) {
- wpa_printf(MSG_ERROR, "Failed to open config file '%s', "
- "error: %s", name, strerror(errno));
- if (config != cfgp)
- os_free(config);
- return NULL;
- }
-
- while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
- if (os_strcmp(pos, "network={") == 0) {
- ssid = wpa_config_read_network(f, &line, id++);
- if (ssid == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to "
- "parse network block.", line);
- errors++;
- continue;
- }
- if (head == NULL) {
- head = tail = ssid;
- } else {
- tail->next = ssid;
- tail = ssid;
- }
- if (wpa_config_add_prio_network(config, ssid)) {
- wpa_printf(MSG_ERROR, "Line %d: failed to add "
- "network block to priority list.",
- line);
- errors++;
- continue;
- }
- } else if (os_strcmp(pos, "cred={") == 0) {
- cred = wpa_config_read_cred(f, &line, cred_id++);
- if (cred == NULL) {
- wpa_printf(MSG_ERROR, "Line %d: failed to "
- "parse cred block.", line);
- errors++;
- continue;
- }
- if (cred_head == NULL) {
- cred_head = cred_tail = cred;
- } else {
- cred_tail->next = cred;
- cred_tail = cred;
- }
-#ifndef CONFIG_NO_CONFIG_BLOBS
- } else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
- if (wpa_config_process_blob(config, f, &line, pos + 12)
- < 0) {
- wpa_printf(MSG_ERROR, "Line %d: failed to "
- "process blob.", line);
- errors++;
- continue;
- }
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- } else if (wpa_config_process_global(config, pos, line) < 0) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
- "line '%s'.", line, pos);
- errors++;
- continue;
- }
- }
-
- fclose(f);
-
- config->ssid = head;
- wpa_config_debug_dump_networks(config);
- config->cred = cred_head;
-
-#ifndef WPA_IGNORE_CONFIG_ERRORS
- if (errors) {
- if (config != cfgp)
- wpa_config_free(config);
- config = NULL;
- head = NULL;
- }
-#endif /* WPA_IGNORE_CONFIG_ERRORS */
-
- return config;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-
-static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, field);
- if (value == NULL)
- return;
- fprintf(f, "\t%s=%s\n", field, value);
- str_clear_free(value);
-}
-
-
-static void write_int(FILE *f, const char *field, int value, int def)
-{
- if (value == def)
- return;
- fprintf(f, "\t%s=%d\n", field, value);
-}
-
-
-static void write_bssid(FILE *f, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "bssid");
- if (value == NULL)
- return;
- fprintf(f, "\tbssid=%s\n", value);
- os_free(value);
-}
-
-
-static void write_bssid_hint(FILE *f, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "bssid_hint");
-
- if (!value)
- return;
- fprintf(f, "\tbssid_hint=%s\n", value);
- os_free(value);
-}
-
-
-static void write_psk(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->mem_only_psk)
- return;
-
- value = wpa_config_get(ssid, "psk");
- if (value == NULL)
- return;
- fprintf(f, "\tpsk=%s\n", value);
- os_free(value);
-}
-
-
-static void write_proto(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->proto == DEFAULT_PROTO)
- return;
-
- value = wpa_config_get(ssid, "proto");
- if (value == NULL)
- return;
- if (value[0])
- fprintf(f, "\tproto=%s\n", value);
- os_free(value);
-}
-
-
-static void write_key_mgmt(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
- return;
-
- value = wpa_config_get(ssid, "key_mgmt");
- if (value == NULL)
- return;
- if (value[0])
- fprintf(f, "\tkey_mgmt=%s\n", value);
- os_free(value);
-}
-
-
-static void write_pairwise(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
- return;
-
- value = wpa_config_get(ssid, "pairwise");
- if (value == NULL)
- return;
- if (value[0])
- fprintf(f, "\tpairwise=%s\n", value);
- os_free(value);
-}
-
-
-static void write_group(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->group_cipher == DEFAULT_GROUP)
- return;
-
- value = wpa_config_get(ssid, "group");
- if (value == NULL)
- return;
- if (value[0])
- fprintf(f, "\tgroup=%s\n", value);
- os_free(value);
-}
-
-
-static void write_group_mgmt(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (!ssid->group_mgmt_cipher)
- return;
-
- value = wpa_config_get(ssid, "group_mgmt");
- if (!value)
- return;
- if (value[0])
- fprintf(f, "\tgroup_mgmt=%s\n", value);
- os_free(value);
-}
-
-
-static void write_auth_alg(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->auth_alg == 0)
- return;
-
- value = wpa_config_get(ssid, "auth_alg");
- if (value == NULL)
- return;
- if (value[0])
- fprintf(f, "\tauth_alg=%s\n", value);
- os_free(value);
-}
-
-
-#ifdef IEEE8021X_EAPOL
-static void write_eap(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- value = wpa_config_get(ssid, "eap");
- if (value == NULL)
- return;
-
- if (value[0])
- fprintf(f, "\teap=%s\n", value);
- os_free(value);
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-#ifdef CONFIG_WEP
-static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
-{
- char field[20], *value;
- int res;
-
- res = os_snprintf(field, sizeof(field), "wep_key%d", idx);
- if (os_snprintf_error(sizeof(field), res))
- return;
- value = wpa_config_get(ssid, field);
- if (value) {
- fprintf(f, "\t%s=%s\n", field, value);
- os_free(value);
- }
-}
-#endif /* CONFIG_WEP */
-
-
-#ifdef CONFIG_P2P
-
-static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "go_p2p_dev_addr");
- if (value == NULL)
- return;
- fprintf(f, "\tgo_p2p_dev_addr=%s\n", value);
- os_free(value);
-}
-
-static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "p2p_client_list");
- if (value == NULL)
- return;
- fprintf(f, "\tp2p_client_list=%s\n", value);
- os_free(value);
-}
-
-
-static void write_psk_list(FILE *f, struct wpa_ssid *ssid)
-{
- struct psk_list_entry *psk;
- char hex[32 * 2 + 1];
-
- dl_list_for_each(psk, &ssid->psk_list, struct psk_list_entry, list) {
- wpa_snprintf_hex(hex, sizeof(hex), psk->psk, sizeof(psk->psk));
- fprintf(f, "\tpsk_list=%s" MACSTR "-%s\n",
- psk->p2p ? "P2P-" : "", MAC2STR(psk->addr), hex);
- }
-}
-
-#endif /* CONFIG_P2P */
-
-
-#ifdef CONFIG_MACSEC
-
-static void write_mka_cak(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK))
- return;
-
- value = wpa_config_get(ssid, "mka_cak");
- if (!value)
- return;
- fprintf(f, "\tmka_cak=%s\n", value);
- os_free(value);
-}
-
-
-static void write_mka_ckn(FILE *f, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN))
- return;
-
- value = wpa_config_get(ssid, "mka_ckn");
- if (!value)
- return;
- fprintf(f, "\tmka_ckn=%s\n", value);
- os_free(value);
-}
-
-#endif /* CONFIG_MACSEC */
-
-
-static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
-{
-#define STR(t) write_str(f, #t, ssid)
-#define INT(t) write_int(f, #t, ssid->t, 0)
-#define INTe(t, m) write_int(f, #t, ssid->eap.m, 0)
-#define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
-#define INT_DEFe(t, m, def) write_int(f, #t, ssid->eap.m, def)
-
- STR(ssid);
- INT(scan_ssid);
- write_bssid(f, ssid);
- write_bssid_hint(f, ssid);
- write_str(f, "bssid_ignore", ssid);
- write_str(f, "bssid_accept", ssid);
- write_psk(f, ssid);
- INT(mem_only_psk);
- STR(sae_password);
- STR(sae_password_id);
- write_int(f, "sae_pwe", ssid->sae_pwe, DEFAULT_SAE_PWE);
- write_proto(f, ssid);
- write_key_mgmt(f, ssid);
- INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
- write_pairwise(f, ssid);
- write_group(f, ssid);
- write_group_mgmt(f, ssid);
- write_auth_alg(f, ssid);
- STR(bgscan);
- STR(autoscan);
- STR(scan_freq);
-#ifdef IEEE8021X_EAPOL
- write_eap(f, ssid);
- STR(identity);
- STR(anonymous_identity);
- STR(imsi_identity);
- STR(machine_identity);
- STR(password);
- STR(machine_password);
- STR(ca_cert);
- STR(ca_path);
- STR(client_cert);
- STR(private_key);
- STR(private_key_passwd);
- STR(dh_file);
- STR(subject_match);
- STR(check_cert_subject);
- STR(altsubject_match);
- STR(domain_suffix_match);
- STR(domain_match);
- STR(ca_cert2);
- STR(ca_path2);
- STR(client_cert2);
- STR(private_key2);
- STR(private_key2_passwd);
- STR(dh_file2);
- STR(subject_match2);
- STR(check_cert_subject2);
- STR(altsubject_match2);
- STR(domain_suffix_match2);
- STR(domain_match2);
- STR(machine_ca_cert);
- STR(machine_ca_path);
- STR(machine_client_cert);
- STR(machine_private_key);
- STR(machine_private_key_passwd);
- STR(machine_dh_file);
- STR(machine_subject_match);
- STR(machine_check_cert_subject);
- STR(machine_altsubject_match);
- STR(machine_domain_suffix_match);
- STR(machine_domain_match);
- STR(phase1);
- STR(phase2);
- STR(machine_phase2);
- STR(pcsc);
- STR(pin);
- STR(engine_id);
- STR(key_id);
- STR(cert_id);
- STR(ca_cert_id);
- STR(key2_id);
- STR(pin2);
- STR(engine2_id);
- STR(cert2_id);
- STR(ca_cert2_id);
- INTe(engine, cert.engine);
- INTe(engine2, phase2_cert.engine);
- INTe(machine_engine, machine_cert.engine);
- INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
- STR(openssl_ciphers);
- INTe(erp, erp);
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_WEP
- {
- int i;
-
- for (i = 0; i < 4; i++)
- write_wep_key(f, i, ssid);
- INT(wep_tx_keyidx);
- }
-#endif /* CONFIG_WEP */
- INT(priority);
-#ifdef IEEE8021X_EAPOL
- INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
- STR(pac_file);
- INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
- INTe(ocsp, cert.ocsp);
- INTe(ocsp2, phase2_cert.ocsp);
- INTe(machine_ocsp, machine_cert.ocsp);
- INT_DEFe(sim_num, sim_num, DEFAULT_USER_SELECTED_SIM);
-#endif /* IEEE8021X_EAPOL */
- INT(mode);
- INT(no_auto_peer);
- INT(mesh_fwding);
- INT(frequency);
- INT(enable_edmg);
- INT(edmg_channel);
- INT(fixed_freq);
-#ifdef CONFIG_ACS
- INT(acs);
-#endif /* CONFIG_ACS */
- write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
- INT(disabled);
- INT(mixed_cell);
- INT_DEF(vht, 1);
- INT_DEF(ht, 1);
- INT(ht40);
- INT_DEF(he, 1);
- INT_DEF(max_oper_chwidth, DEFAULT_MAX_OPER_CHWIDTH);
- INT(vht_center_freq1);
- INT(vht_center_freq2);
- INT(pbss);
- INT(wps_disabled);
- INT(fils_dh_group);
- write_int(f, "ieee80211w", ssid->ieee80211w,
- MGMT_FRAME_PROTECTION_DEFAULT);
- STR(id_str);
-#ifdef CONFIG_P2P
- write_go_p2p_dev_addr(f, ssid);
- write_p2p_client_list(f, ssid);
- write_psk_list(f, ssid);
-#endif /* CONFIG_P2P */
- INT(ap_max_inactivity);
- INT(dtim_period);
- INT(beacon_int);
-#ifdef CONFIG_MACSEC
- INT(macsec_policy);
- write_mka_cak(f, ssid);
- write_mka_ckn(f, ssid);
- INT(macsec_integ_only);
- INT(macsec_replay_protect);
- INT(macsec_replay_window);
- INT(macsec_port);
- INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER);
-#endif /* CONFIG_MACSEC */
-#ifdef CONFIG_HS20
- INT(update_identifier);
- STR(roaming_consortium_selection);
-#endif /* CONFIG_HS20 */
- write_int(f, "mac_addr", ssid->mac_addr, -1);
-#ifdef CONFIG_MESH
- STR(mesh_basic_rates);
- INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
- INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT);
- INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT);
- INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT);
- INT_DEF(mesh_rssi_threshold, DEFAULT_MESH_RSSI_THRESHOLD);
-#endif /* CONFIG_MESH */
- INT(wpa_ptk_rekey);
- INT(wpa_deny_ptk0_rekey);
- INT(group_rekey);
- INT(ignore_broadcast_ssid);
-#ifdef CONFIG_DPP
- STR(dpp_connector);
- STR(dpp_netaccesskey);
- INT(dpp_netaccesskey_expiry);
- STR(dpp_csign);
- STR(dpp_pp_key);
- INT(dpp_pfs);
-#endif /* CONFIG_DPP */
- INT(owe_group);
- INT(owe_only);
- INT(owe_ptk_workaround);
- INT(multi_ap_backhaul_sta);
- INT(ft_eap_pmksa_caching);
- INT(beacon_prot);
- INT(transition_disable);
- INT(sae_pk);
-#ifdef CONFIG_HT_OVERRIDES
- INT_DEF(disable_ht, DEFAULT_DISABLE_HT);
- INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40);
- INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI);
- INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC);
- INT(ht40_intolerant);
- INT_DEF(tx_stbc, DEFAULT_TX_STBC);
- INT_DEF(rx_stbc, DEFAULT_RX_STBC);
- INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU);
- INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR);
- INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY);
- STR(ht_mcs);
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- INT(disable_vht);
- INT(vht_capa);
- INT(vht_capa_mask);
- INT_DEF(vht_rx_mcs_nss_1, -1);
- INT_DEF(vht_rx_mcs_nss_2, -1);
- INT_DEF(vht_rx_mcs_nss_3, -1);
- INT_DEF(vht_rx_mcs_nss_4, -1);
- INT_DEF(vht_rx_mcs_nss_5, -1);
- INT_DEF(vht_rx_mcs_nss_6, -1);
- INT_DEF(vht_rx_mcs_nss_7, -1);
- INT_DEF(vht_rx_mcs_nss_8, -1);
- INT_DEF(vht_tx_mcs_nss_1, -1);
- INT_DEF(vht_tx_mcs_nss_2, -1);
- INT_DEF(vht_tx_mcs_nss_3, -1);
- INT_DEF(vht_tx_mcs_nss_4, -1);
- INT_DEF(vht_tx_mcs_nss_5, -1);
- INT_DEF(vht_tx_mcs_nss_6, -1);
- INT_DEF(vht_tx_mcs_nss_7, -1);
- INT_DEF(vht_tx_mcs_nss_8, -1);
-#endif /* CONFIG_VHT_OVERRIDES */
-#ifdef CONFIG_HE_OVERRIDES
- INT(disable_he);
-#endif /* CONFIG_HE_OVERRIDES */
-
-#undef STR
-#undef INT
-#undef INT_DEF
-}
-
-
-static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
-{
- size_t i;
-
- if (cred->priority)
- fprintf(f, "\tpriority=%d\n", cred->priority);
- if (cred->pcsc)
- fprintf(f, "\tpcsc=%d\n", cred->pcsc);
- if (cred->realm)
- fprintf(f, "\trealm=\"%s\"\n", cred->realm);
- if (cred->username)
- fprintf(f, "\tusername=\"%s\"\n", cred->username);
- if (cred->password && cred->ext_password)
- fprintf(f, "\tpassword=ext:%s\n", cred->password);
- else if (cred->password)
- fprintf(f, "\tpassword=\"%s\"\n", cred->password);
- if (cred->ca_cert)
- fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert);
- if (cred->client_cert)
- fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert);
- if (cred->private_key)
- fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key);
- if (cred->private_key_passwd)
- fprintf(f, "\tprivate_key_passwd=\"%s\"\n",
- cred->private_key_passwd);
- if (cred->imsi)
- fprintf(f, "\timsi=\"%s\"\n", cred->imsi);
- if (cred->milenage)
- fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage);
- for (i = 0; i < cred->num_domain; i++)
- fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]);
- if (cred->domain_suffix_match)
- fprintf(f, "\tdomain_suffix_match=\"%s\"\n",
- cred->domain_suffix_match);
- if (cred->roaming_consortium_len) {
- fprintf(f, "\troaming_consortium=");
- for (i = 0; i < cred->roaming_consortium_len; i++)
- fprintf(f, "%02x", cred->roaming_consortium[i]);
- fprintf(f, "\n");
- }
- if (cred->eap_method) {
- const char *name;
- name = eap_get_name(cred->eap_method[0].vendor,
- cred->eap_method[0].method);
- if (name)
- fprintf(f, "\teap=%s\n", name);
- }
- if (cred->phase1)
- fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
- if (cred->phase2)
- fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
- if (cred->excluded_ssid) {
- size_t j;
- for (i = 0; i < cred->num_excluded_ssid; i++) {
- struct excluded_ssid *e = &cred->excluded_ssid[i];
- fprintf(f, "\texcluded_ssid=");
- for (j = 0; j < e->ssid_len; j++)
- fprintf(f, "%02x", e->ssid[j]);
- fprintf(f, "\n");
- }
- }
- if (cred->roaming_partner) {
- for (i = 0; i < cred->num_roaming_partner; i++) {
- struct roaming_partner *p = &cred->roaming_partner[i];
- fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n",
- p->fqdn, p->exact_match, p->priority,
- p->country);
- }
- }
- if (cred->update_identifier)
- fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier);
-
- if (cred->provisioning_sp)
- fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp);
- if (cred->sp_priority)
- fprintf(f, "\tsp_priority=%d\n", cred->sp_priority);
-
- if (cred->min_dl_bandwidth_home)
- fprintf(f, "\tmin_dl_bandwidth_home=%u\n",
- cred->min_dl_bandwidth_home);
- if (cred->min_ul_bandwidth_home)
- fprintf(f, "\tmin_ul_bandwidth_home=%u\n",
- cred->min_ul_bandwidth_home);
- if (cred->min_dl_bandwidth_roaming)
- fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n",
- cred->min_dl_bandwidth_roaming);
- if (cred->min_ul_bandwidth_roaming)
- fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n",
- cred->min_ul_bandwidth_roaming);
-
- if (cred->max_bss_load)
- fprintf(f, "\tmax_bss_load=%u\n",
- cred->max_bss_load);
-
- if (cred->ocsp)
- fprintf(f, "\tocsp=%d\n", cred->ocsp);
-
- if (cred->num_req_conn_capab) {
- for (i = 0; i < cred->num_req_conn_capab; i++) {
- int *ports;
-
- fprintf(f, "\treq_conn_capab=%u",
- cred->req_conn_capab_proto[i]);
- ports = cred->req_conn_capab_port[i];
- if (ports) {
- int j;
- for (j = 0; ports[j] != -1; j++) {
- fprintf(f, "%s%d", j > 0 ? "," : ":",
- ports[j]);
- }
- }
- fprintf(f, "\n");
- }
- }
-
- if (cred->required_roaming_consortium_len) {
- fprintf(f, "\trequired_roaming_consortium=");
- for (i = 0; i < cred->required_roaming_consortium_len; i++)
- fprintf(f, "%02x",
- cred->required_roaming_consortium[i]);
- fprintf(f, "\n");
- }
-
- if (cred->num_roaming_consortiums) {
- size_t j;
-
- fprintf(f, "\troaming_consortiums=\"");
- for (i = 0; i < cred->num_roaming_consortiums; i++) {
- if (i > 0)
- fprintf(f, ",");
- for (j = 0; j < cred->roaming_consortiums_len[i]; j++)
- fprintf(f, "%02x",
- cred->roaming_consortiums[i][j]);
- }
- fprintf(f, "\"\n");
- }
-
- if (cred->sim_num != DEFAULT_USER_SELECTED_SIM)
- fprintf(f, "\tsim_num=%d\n", cred->sim_num);
-
- if (cred->engine)
- fprintf(f, "\tengine=%d\n", cred->engine);
- if (cred->engine_id)
- fprintf(f, "\tengine_id=\"%s\"\n", cred->engine_id);
- if (cred->key_id)
- fprintf(f, "\tkey_id=\"%s\"\n", cred->key_id);
- if (cred->cert_id)
- fprintf(f, "\tcert_id=\"%s\"\n", cred->cert_id);
- if (cred->ca_cert_id)
- fprintf(f, "\tca_cert_id=\"%s\"\n", cred->ca_cert_id);
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob)
-{
- char *encoded;
-
- encoded = base64_encode(blob->data, blob->len, NULL);
- if (encoded == NULL)
- return -1;
-
- fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded);
- os_free(encoded);
- return 0;
-}
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-static void write_global_bin(FILE *f, const char *field,
- const struct wpabuf *val)
-{
- size_t i;
- const u8 *pos;
-
- if (val == NULL)
- return;
-
- fprintf(f, "%s=", field);
- pos = wpabuf_head(val);
- for (i = 0; i < wpabuf_len(val); i++)
- fprintf(f, "%02X", *pos++);
- fprintf(f, "\n");
-}
-
-
-static void wpa_config_write_global(FILE *f, struct wpa_config *config)
-{
-#ifdef CONFIG_CTRL_IFACE
- if (config->ctrl_interface)
- fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface);
- if (config->ctrl_interface_group)
- fprintf(f, "ctrl_interface_group=%s\n",
- config->ctrl_interface_group);
-#endif /* CONFIG_CTRL_IFACE */
- if (config->eapol_version != DEFAULT_EAPOL_VERSION)
- fprintf(f, "eapol_version=%d\n", config->eapol_version);
- if (config->ap_scan != DEFAULT_AP_SCAN)
- fprintf(f, "ap_scan=%d\n", config->ap_scan);
- if (config->disable_scan_offload)
- fprintf(f, "disable_scan_offload=%d\n",
- config->disable_scan_offload);
- if (config->fast_reauth != DEFAULT_FAST_REAUTH)
- fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
- if (config->opensc_engine_path)
- fprintf(f, "opensc_engine_path=%s\n",
- config->opensc_engine_path);
- if (config->pkcs11_engine_path)
- fprintf(f, "pkcs11_engine_path=%s\n",
- config->pkcs11_engine_path);
- if (config->pkcs11_module_path)
- fprintf(f, "pkcs11_module_path=%s\n",
- config->pkcs11_module_path);
- if (config->openssl_ciphers)
- fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers);
- if (config->pcsc_reader)
- fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader);
- if (config->pcsc_pin)
- fprintf(f, "pcsc_pin=%s\n", config->pcsc_pin);
- if (config->driver_param)
- fprintf(f, "driver_param=%s\n", config->driver_param);
- if (config->dot11RSNAConfigPMKLifetime)
- fprintf(f, "dot11RSNAConfigPMKLifetime=%u\n",
- config->dot11RSNAConfigPMKLifetime);
- if (config->dot11RSNAConfigPMKReauthThreshold)
- fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%u\n",
- config->dot11RSNAConfigPMKReauthThreshold);
- if (config->dot11RSNAConfigSATimeout)
- fprintf(f, "dot11RSNAConfigSATimeout=%u\n",
- config->dot11RSNAConfigSATimeout);
- if (config->update_config)
- fprintf(f, "update_config=%d\n", config->update_config);
-#ifdef CONFIG_WPS
- if (!is_nil_uuid(config->uuid)) {
- char buf[40];
- uuid_bin2str(config->uuid, buf, sizeof(buf));
- fprintf(f, "uuid=%s\n", buf);
- }
- if (config->auto_uuid)
- fprintf(f, "auto_uuid=%d\n", config->auto_uuid);
- if (config->device_name)
- fprintf(f, "device_name=%s\n", config->device_name);
- if (config->manufacturer)
- fprintf(f, "manufacturer=%s\n", config->manufacturer);
- if (config->model_name)
- fprintf(f, "model_name=%s\n", config->model_name);
- if (config->model_number)
- fprintf(f, "model_number=%s\n", config->model_number);
- if (config->serial_number)
- fprintf(f, "serial_number=%s\n", config->serial_number);
- {
- char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
- buf = wps_dev_type_bin2str(config->device_type,
- _buf, sizeof(_buf));
- if (os_strcmp(buf, "0-00000000-0") != 0)
- fprintf(f, "device_type=%s\n", buf);
- }
- if (WPA_GET_BE32(config->os_version))
- fprintf(f, "os_version=%08x\n",
- WPA_GET_BE32(config->os_version));
- if (config->config_methods)
- fprintf(f, "config_methods=%s\n", config->config_methods);
- if (config->wps_cred_processing)
- fprintf(f, "wps_cred_processing=%d\n",
- config->wps_cred_processing);
- if (config->wps_cred_add_sae)
- fprintf(f, "wps_cred_add_sae=%d\n",
- config->wps_cred_add_sae);
- if (config->wps_vendor_ext_m1) {
- int i, len = wpabuf_len(config->wps_vendor_ext_m1);
- const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
- if (len > 0) {
- fprintf(f, "wps_vendor_ext_m1=");
- for (i = 0; i < len; i++)
- fprintf(f, "%02x", *p++);
- fprintf(f, "\n");
- }
- }
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- {
- int i;
- char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
-
- for (i = 0; i < config->num_sec_device_types; i++) {
- buf = wps_dev_type_bin2str(config->sec_device_type[i],
- _buf, sizeof(_buf));
- if (buf)
- fprintf(f, "sec_device_type=%s\n", buf);
- }
- }
- if (config->p2p_listen_reg_class)
- fprintf(f, "p2p_listen_reg_class=%d\n",
- config->p2p_listen_reg_class);
- if (config->p2p_listen_channel)
- fprintf(f, "p2p_listen_channel=%d\n",
- config->p2p_listen_channel);
- if (config->p2p_oper_reg_class)
- fprintf(f, "p2p_oper_reg_class=%d\n",
- config->p2p_oper_reg_class);
- if (config->p2p_oper_channel)
- fprintf(f, "p2p_oper_channel=%d\n", config->p2p_oper_channel);
- if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT)
- fprintf(f, "p2p_go_intent=%d\n", config->p2p_go_intent);
- if (config->p2p_ssid_postfix)
- fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix);
- if (config->persistent_reconnect)
- fprintf(f, "persistent_reconnect=%d\n",
- config->persistent_reconnect);
- if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS)
- fprintf(f, "p2p_intra_bss=%d\n", config->p2p_intra_bss);
- if (config->p2p_group_idle)
- fprintf(f, "p2p_group_idle=%d\n", config->p2p_group_idle);
- if (config->p2p_passphrase_len)
- fprintf(f, "p2p_passphrase_len=%u\n",
- config->p2p_passphrase_len);
- if (config->p2p_pref_chan) {
- unsigned int i;
- fprintf(f, "p2p_pref_chan=");
- for (i = 0; i < config->num_p2p_pref_chan; i++) {
- fprintf(f, "%s%u:%u", i > 0 ? "," : "",
- config->p2p_pref_chan[i].op_class,
- config->p2p_pref_chan[i].chan);
- }
- fprintf(f, "\n");
- }
- if (config->p2p_no_go_freq.num) {
- char *val = freq_range_list_str(&config->p2p_no_go_freq);
- if (val) {
- fprintf(f, "p2p_no_go_freq=%s\n", val);
- os_free(val);
- }
- }
- if (config->p2p_add_cli_chan)
- fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan);
- if (config->p2p_optimize_listen_chan !=
- DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN)
- fprintf(f, "p2p_optimize_listen_chan=%d\n",
- config->p2p_optimize_listen_chan);
- if (config->p2p_go_ht40)
- fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40);
- if (config->p2p_go_vht)
- fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht);
- if (config->p2p_go_he)
- fprintf(f, "p2p_go_he=%d\n", config->p2p_go_he);
- if (config->p2p_go_edmg)
- fprintf(f, "p2p_go_edmg=%d\n", config->p2p_go_edmg);
- if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW)
- fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow);
- if (config->p2p_disabled)
- fprintf(f, "p2p_disabled=%d\n", config->p2p_disabled);
- if (config->p2p_no_group_iface)
- fprintf(f, "p2p_no_group_iface=%d\n",
- config->p2p_no_group_iface);
- if (config->p2p_ignore_shared_freq)
- fprintf(f, "p2p_ignore_shared_freq=%d\n",
- config->p2p_ignore_shared_freq);
- if (config->p2p_cli_probe)
- fprintf(f, "p2p_cli_probe=%d\n", config->p2p_cli_probe);
- if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE)
- fprintf(f, "p2p_go_freq_change_policy=%u\n",
- config->p2p_go_freq_change_policy);
-
- if (config->p2p_6ghz_disable)
- fprintf(f, "p2p_6ghz_disable=%d\n", config->p2p_6ghz_disable);
-
- if (WPA_GET_BE32(config->ip_addr_go))
- fprintf(f, "ip_addr_go=%u.%u.%u.%u\n",
- config->ip_addr_go[0], config->ip_addr_go[1],
- config->ip_addr_go[2], config->ip_addr_go[3]);
- if (WPA_GET_BE32(config->ip_addr_mask))
- fprintf(f, "ip_addr_mask=%u.%u.%u.%u\n",
- config->ip_addr_mask[0], config->ip_addr_mask[1],
- config->ip_addr_mask[2], config->ip_addr_mask[3]);
- if (WPA_GET_BE32(config->ip_addr_start))
- fprintf(f, "ip_addr_start=%u.%u.%u.%u\n",
- config->ip_addr_start[0], config->ip_addr_start[1],
- config->ip_addr_start[2], config->ip_addr_start[3]);
- if (WPA_GET_BE32(config->ip_addr_end))
- fprintf(f, "ip_addr_end=%u.%u.%u.%u\n",
- config->ip_addr_end[0], config->ip_addr_end[1],
- config->ip_addr_end[2], config->ip_addr_end[3]);
-#endif /* CONFIG_P2P */
- if (config->country[0] && config->country[1]) {
- fprintf(f, "country=%c%c\n",
- config->country[0], config->country[1]);
- }
- if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
- fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
- if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE)
- fprintf(f, "bss_expiration_age=%u\n",
- config->bss_expiration_age);
- if (config->bss_expiration_scan_count !=
- DEFAULT_BSS_EXPIRATION_SCAN_COUNT)
- fprintf(f, "bss_expiration_scan_count=%u\n",
- config->bss_expiration_scan_count);
- if (config->filter_ssids)
- fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
- if (config->filter_rssi)
- fprintf(f, "filter_rssi=%d\n", config->filter_rssi);
- if (config->max_num_sta != DEFAULT_MAX_NUM_STA)
- fprintf(f, "max_num_sta=%u\n", config->max_num_sta);
- if (config->ap_isolate != DEFAULT_AP_ISOLATE)
- fprintf(f, "ap_isolate=%u\n", config->ap_isolate);
- if (config->disassoc_low_ack)
- fprintf(f, "disassoc_low_ack=%d\n", config->disassoc_low_ack);
-#ifdef CONFIG_HS20
- if (config->hs20)
- fprintf(f, "hs20=1\n");
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_INTERWORKING
- if (config->interworking)
- fprintf(f, "interworking=%d\n", config->interworking);
- if (!is_zero_ether_addr(config->hessid))
- fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid));
- if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE)
- fprintf(f, "access_network_type=%d\n",
- config->access_network_type);
- if (config->go_interworking)
- fprintf(f, "go_interworking=%d\n", config->go_interworking);
- if (config->go_access_network_type)
- fprintf(f, "go_access_network_type=%d\n",
- config->go_access_network_type);
- if (config->go_internet)
- fprintf(f, "go_internet=%d\n", config->go_internet);
- if (config->go_venue_group)
- fprintf(f, "go_venue_group=%d\n", config->go_venue_group);
- if (config->go_venue_type)
- fprintf(f, "go_venue_type=%d\n", config->go_venue_type);
-#endif /* CONFIG_INTERWORKING */
- if (config->pbc_in_m1)
- fprintf(f, "pbc_in_m1=%d\n", config->pbc_in_m1);
- if (config->wps_nfc_pw_from_config) {
- if (config->wps_nfc_dev_pw_id)
- fprintf(f, "wps_nfc_dev_pw_id=%d\n",
- config->wps_nfc_dev_pw_id);
- write_global_bin(f, "wps_nfc_dh_pubkey",
- config->wps_nfc_dh_pubkey);
- write_global_bin(f, "wps_nfc_dh_privkey",
- config->wps_nfc_dh_privkey);
- write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw);
- }
-
- if (config->ext_password_backend)
- fprintf(f, "ext_password_backend=%s\n",
- config->ext_password_backend);
- if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY)
- fprintf(f, "p2p_go_max_inactivity=%d\n",
- config->p2p_go_max_inactivity);
- if (config->auto_interworking)
- fprintf(f, "auto_interworking=%d\n",
- config->auto_interworking);
- if (config->okc)
- fprintf(f, "okc=%d\n", config->okc);
- if (config->pmf)
- fprintf(f, "pmf=%d\n", config->pmf);
- if (config->dtim_period)
- fprintf(f, "dtim_period=%d\n", config->dtim_period);
- if (config->beacon_int)
- fprintf(f, "beacon_int=%d\n", config->beacon_int);
-
- if (config->sae_groups) {
- int i;
- fprintf(f, "sae_groups=");
- for (i = 0; config->sae_groups[i] > 0; i++) {
- fprintf(f, "%s%d", i > 0 ? " " : "",
- config->sae_groups[i]);
- }
- fprintf(f, "\n");
- }
-
- if (config->sae_pwe)
- fprintf(f, "sae_pwe=%d\n", config->sae_pwe);
-
- if (config->sae_pmkid_in_assoc)
- fprintf(f, "sae_pmkid_in_assoc=%d\n",
- config->sae_pmkid_in_assoc);
-
- if (config->ap_vendor_elements) {
- int i, len = wpabuf_len(config->ap_vendor_elements);
- const u8 *p = wpabuf_head_u8(config->ap_vendor_elements);
- if (len > 0) {
- fprintf(f, "ap_vendor_elements=");
- for (i = 0; i < len; i++)
- fprintf(f, "%02x", *p++);
- fprintf(f, "\n");
- }
- }
-
- if (config->ap_assocresp_elements) {
- int i, len = wpabuf_len(config->ap_assocresp_elements);
- const u8 *p = wpabuf_head_u8(config->ap_assocresp_elements);
-
- if (len > 0) {
- fprintf(f, "ap_assocresp_elements=");
- for (i = 0; i < len; i++)
- fprintf(f, "%02x", *p++);
- fprintf(f, "\n");
- }
- }
-
- if (config->ignore_old_scan_res)
- fprintf(f, "ignore_old_scan_res=%d\n",
- config->ignore_old_scan_res);
-
- if (config->freq_list && config->freq_list[0]) {
- int i;
- fprintf(f, "freq_list=");
- for (i = 0; config->freq_list[i]; i++) {
- fprintf(f, "%s%d", i > 0 ? " " : "",
- config->freq_list[i]);
- }
- fprintf(f, "\n");
- }
- if (config->initial_freq_list && config->initial_freq_list[0]) {
- int i;
- fprintf(f, "initial_freq_list=");
- for (i = 0; config->initial_freq_list[i]; i++) {
- fprintf(f, "%s%d", i > 0 ? " " : "",
- config->initial_freq_list[i]);
- }
- fprintf(f, "\n");
- }
- if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ)
- fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq);
-
- if (config->scan_res_valid_for_connect !=
- DEFAULT_SCAN_RES_VALID_FOR_CONNECT)
- fprintf(f, "scan_res_valid_for_connect=%d\n",
- config->scan_res_valid_for_connect);
-
- if (config->sched_scan_interval)
- fprintf(f, "sched_scan_interval=%u\n",
- config->sched_scan_interval);
-
- if (config->sched_scan_start_delay)
- fprintf(f, "sched_scan_start_delay=%u\n",
- config->sched_scan_start_delay);
-
- if (config->external_sim)
- fprintf(f, "external_sim=%d\n", config->external_sim);
-
- if (config->tdls_external_control)
- fprintf(f, "tdls_external_control=%d\n",
- config->tdls_external_control);
-
- if (config->wowlan_triggers)
- fprintf(f, "wowlan_triggers=%s\n",
- config->wowlan_triggers);
-
- if (config->bgscan)
- fprintf(f, "bgscan=\"%s\"\n", config->bgscan);
-
- if (config->autoscan)
- fprintf(f, "autoscan=%s\n", config->autoscan);
-
- if (config->p2p_search_delay != DEFAULT_P2P_SEARCH_DELAY)
- fprintf(f, "p2p_search_delay=%u\n",
- config->p2p_search_delay);
-
- if (config->mac_addr)
- fprintf(f, "mac_addr=%d\n", config->mac_addr);
-
- if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
- fprintf(f, "rand_addr_lifetime=%u\n",
- config->rand_addr_lifetime);
-
- if (config->preassoc_mac_addr)
- fprintf(f, "preassoc_mac_addr=%d\n", config->preassoc_mac_addr);
-
- if (config->key_mgmt_offload != DEFAULT_KEY_MGMT_OFFLOAD)
- fprintf(f, "key_mgmt_offload=%d\n", config->key_mgmt_offload);
-
- if (config->user_mpm != DEFAULT_USER_MPM)
- fprintf(f, "user_mpm=%d\n", config->user_mpm);
-
- if (config->max_peer_links != DEFAULT_MAX_PEER_LINKS)
- fprintf(f, "max_peer_links=%d\n", config->max_peer_links);
-
- if (config->cert_in_cb != DEFAULT_CERT_IN_CB)
- fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb);
-
- if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY)
- fprintf(f, "mesh_max_inactivity=%d\n",
- config->mesh_max_inactivity);
-
- if (config->mesh_fwding != DEFAULT_MESH_FWDING)
- fprintf(f, "mesh_fwding=%d\n", config->mesh_fwding);
-
- if (config->dot11RSNASAERetransPeriod !=
- DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD)
- fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
- config->dot11RSNASAERetransPeriod);
-
- if (config->passive_scan)
- fprintf(f, "passive_scan=%d\n", config->passive_scan);
-
- if (config->reassoc_same_bss_optim)
- fprintf(f, "reassoc_same_bss_optim=%d\n",
- config->reassoc_same_bss_optim);
-
- if (config->wps_priority)
- fprintf(f, "wps_priority=%d\n", config->wps_priority);
-
- if (config->wpa_rsc_relaxation != DEFAULT_WPA_RSC_RELAXATION)
- fprintf(f, "wpa_rsc_relaxation=%d\n",
- config->wpa_rsc_relaxation);
-
- if (config->sched_scan_plans)
- fprintf(f, "sched_scan_plans=%s\n", config->sched_scan_plans);
-
-#ifdef CONFIG_MBO
- if (config->non_pref_chan)
- fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan);
- if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA)
- fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa);
- if (config->disassoc_imminent_rssi_threshold !=
- DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD)
- fprintf(f, "disassoc_imminent_rssi_threshold=%d\n",
- config->disassoc_imminent_rssi_threshold);
- if (config->oce != DEFAULT_OCE_SUPPORT)
- fprintf(f, "oce=%u\n", config->oce);
-#endif /* CONFIG_MBO */
-
- if (config->gas_address3)
- fprintf(f, "gas_address3=%d\n", config->gas_address3);
-
- if (config->ftm_responder)
- fprintf(f, "ftm_responder=%d\n", config->ftm_responder);
- if (config->ftm_initiator)
- fprintf(f, "ftm_initiator=%d\n", config->ftm_initiator);
-
- if (config->osu_dir)
- fprintf(f, "osu_dir=%s\n", config->osu_dir);
-
- if (config->fst_group_id)
- fprintf(f, "fst_group_id=%s\n", config->fst_group_id);
- if (config->fst_priority)
- fprintf(f, "fst_priority=%d\n", config->fst_priority);
- if (config->fst_llt)
- fprintf(f, "fst_llt=%d\n", config->fst_llt);
-
- if (config->gas_rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
- fprintf(f, "gas_rand_addr_lifetime=%u\n",
- config->gas_rand_addr_lifetime);
- if (config->gas_rand_mac_addr)
- fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr);
- if (config->dpp_config_processing)
- fprintf(f, "dpp_config_processing=%d\n",
- config->dpp_config_processing);
- if (config->coloc_intf_reporting)
- fprintf(f, "coloc_intf_reporting=%d\n",
- config->coloc_intf_reporting);
- if (config->p2p_device_random_mac_addr)
- fprintf(f, "p2p_device_random_mac_addr=%d\n",
- config->p2p_device_random_mac_addr);
- if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr))
- fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n",
- MAC2STR(config->p2p_device_persistent_mac_addr));
- if (config->p2p_interface_random_mac_addr)
- fprintf(f, "p2p_interface_random_mac_addr=%d\n",
- config->p2p_interface_random_mac_addr);
- if (config->disable_btm)
- fprintf(f, "disable_btm=1\n");
- if (config->extended_key_id != DEFAULT_EXTENDED_KEY_ID)
- fprintf(f, "extended_key_id=%d\n",
- config->extended_key_id);
- if (config->wowlan_disconnect_on_deinit)
- fprintf(f, "wowlan_disconnect_on_deinit=%d\n",
- config->wowlan_disconnect_on_deinit);
-}
-
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-int wpa_config_write(const char *name, struct wpa_config *config)
-{
-#ifndef CONFIG_NO_CONFIG_WRITE
- FILE *f;
- struct wpa_ssid *ssid;
- struct wpa_cred *cred;
-#ifndef CONFIG_NO_CONFIG_BLOBS
- struct wpa_config_blob *blob;
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- int ret = 0;
- const char *orig_name = name;
- int tmp_len;
- char *tmp_name;
-
- if (!name) {
- wpa_printf(MSG_ERROR, "No configuration file for writing");
- return -1;
- }
-
- tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */
- tmp_name = os_malloc(tmp_len);
- if (tmp_name) {
- os_snprintf(tmp_name, tmp_len, "%s.tmp", name);
- name = tmp_name;
- }
-
- wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
-
- f = fopen(name, "w");
- if (f == NULL) {
- wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name);
- os_free(tmp_name);
- return -1;
- }
-
- wpa_config_write_global(f, config);
-
- for (cred = config->cred; cred; cred = cred->next) {
- if (cred->temporary)
- continue;
- fprintf(f, "\ncred={\n");
- wpa_config_write_cred(f, cred);
- fprintf(f, "}\n");
- }
-
- for (ssid = config->ssid; ssid; ssid = ssid->next) {
- if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary)
- continue; /* do not save temporary networks */
- if (wpa_key_mgmt_wpa_psk_no_sae(ssid->key_mgmt) &&
- !ssid->psk_set && !ssid->passphrase)
- continue; /* do not save invalid network */
- if (wpa_key_mgmt_sae(ssid->key_mgmt) &&
- !ssid->passphrase && !ssid->sae_password)
- continue; /* do not save invalid network */
- fprintf(f, "\nnetwork={\n");
- wpa_config_write_network(f, ssid);
- fprintf(f, "}\n");
- }
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
- for (blob = config->blobs; blob; blob = blob->next) {
- ret = wpa_config_write_blob(f, blob);
- if (ret)
- break;
- }
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
- os_fdatasync(f);
-
- fclose(f);
-
- if (tmp_name) {
- int chmod_ret = 0;
-
-#ifdef ANDROID
- chmod_ret = chmod(tmp_name,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-#endif /* ANDROID */
- if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0)
- ret = -1;
-
- os_free(tmp_name);
- }
-
- wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
- orig_name, ret ? "un" : "");
- return ret;
-#else /* CONFIG_NO_CONFIG_WRITE */
- return -1;
-#endif /* CONFIG_NO_CONFIG_WRITE */
-}
diff --git a/wpa_supplicant/config_none.c b/wpa_supplicant/config_none.c
deleted file mode 100644
index 0bc977e3961b..000000000000
--- a/wpa_supplicant/config_none.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * WPA Supplicant / Configuration backend: empty starting point
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * This file implements stub example of a configuration backend. None of the
- * functions are actually implemented so this can be used as a simple
- * compilation test or a starting point for a new configuration backend.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "config.h"
-#include "base64.h"
-
-
-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
-{
- struct wpa_config *config;
-
- if (name == NULL)
- return NULL;
- if (cfgp)
- config = cfgp;
- else
- config = wpa_config_alloc_empty(NULL, NULL);
- if (config == NULL)
- return NULL;
- /* TODO: fill in configuration data */
- return config;
-}
-
-
-int wpa_config_write(const char *name, struct wpa_config *config)
-{
- struct wpa_ssid *ssid;
- struct wpa_config_blob *blob;
-
- wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
-
- /* TODO: write global config parameters */
-
-
- for (ssid = config->ssid; ssid; ssid = ssid->next) {
- /* TODO: write networks */
- }
-
- for (blob = config->blobs; blob; blob = blob->next) {
- /* TODO: write blobs */
- }
-
- return 0;
-}
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
deleted file mode 100644
index 724534dd0123..000000000000
--- a/wpa_supplicant/config_ssid.h
+++ /dev/null
@@ -1,1182 +0,0 @@
-/*
- * WPA Supplicant / Network configuration structures
- * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CONFIG_SSID_H
-#define CONFIG_SSID_H
-
-#include "common/defs.h"
-#include "utils/list.h"
-#include "eap_peer/eap_config.h"
-
-
-#define DEFAULT_EAP_WORKAROUND ((unsigned int) -1)
-#define DEFAULT_EAPOL_FLAGS (EAPOL_FLAG_REQUIRE_KEY_UNICAST | \
- EAPOL_FLAG_REQUIRE_KEY_BROADCAST)
-#define DEFAULT_PROTO (WPA_PROTO_WPA | WPA_PROTO_RSN)
-#define DEFAULT_KEY_MGMT (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X)
-#ifdef CONFIG_NO_TKIP
-#define DEFAULT_PAIRWISE (WPA_CIPHER_CCMP)
-#define DEFAULT_GROUP (WPA_CIPHER_CCMP)
-#else /* CONFIG_NO_TKIP */
-#define DEFAULT_PAIRWISE (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP)
-#define DEFAULT_GROUP (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP)
-#endif /* CONFIG_NO_TKIP */
-#define DEFAULT_FRAGMENT_SIZE 1398
-
-#define DEFAULT_BG_SCAN_PERIOD -1
-#define DEFAULT_MESH_MAX_RETRIES 2
-#define DEFAULT_MESH_RETRY_TIMEOUT 40
-#define DEFAULT_MESH_CONFIRM_TIMEOUT 40
-#define DEFAULT_MESH_HOLDING_TIMEOUT 40
-#define DEFAULT_MESH_RSSI_THRESHOLD 1 /* no change */
-#define DEFAULT_DISABLE_HT 0
-#define DEFAULT_DISABLE_HT40 0
-#define DEFAULT_DISABLE_SGI 0
-#define DEFAULT_DISABLE_LDPC 0
-#define DEFAULT_TX_STBC -1 /* no change */
-#define DEFAULT_RX_STBC -1 /* no change */
-#define DEFAULT_DISABLE_MAX_AMSDU -1 /* no change */
-#define DEFAULT_AMPDU_FACTOR -1 /* no change */
-#define DEFAULT_AMPDU_DENSITY -1 /* no change */
-#define DEFAULT_USER_SELECTED_SIM 1
-#define DEFAULT_MAX_OPER_CHWIDTH -1
-
-/* Consider global sae_pwe for SAE mechanism for PWE derivation */
-#define DEFAULT_SAE_PWE 4
-
-struct psk_list_entry {
- struct dl_list list;
- u8 addr[ETH_ALEN];
- u8 psk[32];
- u8 p2p;
-};
-
-enum wpas_mode {
- WPAS_MODE_INFRA = 0,
- WPAS_MODE_IBSS = 1,
- WPAS_MODE_AP = 2,
- WPAS_MODE_P2P_GO = 3,
- WPAS_MODE_P2P_GROUP_FORMATION = 4,
- WPAS_MODE_MESH = 5,
-};
-
-enum sae_pk_mode {
- SAE_PK_MODE_AUTOMATIC = 0,
- SAE_PK_MODE_ONLY = 1,
- SAE_PK_MODE_DISABLED = 2,
-};
-
-/**
- * struct wpa_ssid - Network configuration data
- *
- * This structure includes all the configuration variables for a network. This
- * data is included in the per-interface configuration data as an element of
- * the network list, struct wpa_config::ssid. Each network block in the
- * configuration is mapped to a struct wpa_ssid instance.
- */
-struct wpa_ssid {
- /**
- * next - Next network in global list
- *
- * This pointer can be used to iterate over all networks. The head of
- * this list is stored in the ssid field of struct wpa_config.
- */
- struct wpa_ssid *next;
-
- /**
- * pnext - Next network in per-priority list
- *
- * This pointer can be used to iterate over all networks in the same
- * priority class. The heads of these list are stored in the pssid
- * fields of struct wpa_config.
- */
- struct wpa_ssid *pnext;
-
- /**
- * id - Unique id for the network
- *
- * This identifier is used as a unique identifier for each network
- * block when using the control interface. Each network is allocated an
- * id when it is being created, either when reading the configuration
- * file or when a new network is added through the control interface.
- */
- int id;
-
- /**
- * priority - Priority group
- *
- * By default, all networks will get same priority group (0). If some
- * of the networks are more desirable, this field can be used to change
- * the order in which wpa_supplicant goes through the networks when
- * selecting a BSS. The priority groups will be iterated in decreasing
- * priority (i.e., the larger the priority value, the sooner the
- * network is matched against the scan results). Within each priority
- * group, networks will be selected based on security policy, signal
- * strength, etc.
- *
- * Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are
- * not using this priority to select the order for scanning. Instead,
- * they try the networks in the order that used in the configuration
- * file.
- */
- int priority;
-
- /**
- * ssid - Service set identifier (network name)
- *
- * This is the SSID for the network. For wireless interfaces, this is
- * used to select which network will be used. If set to %NULL (or
- * ssid_len=0), any SSID can be used. For wired interfaces, this must
- * be set to %NULL. Note: SSID may contain any characters, even nul
- * (ASCII 0) and as such, this should not be assumed to be a nul
- * terminated string. ssid_len defines how many characters are valid
- * and the ssid field is not guaranteed to be nul terminated.
- */
- u8 *ssid;
-
- /**
- * ssid_len - Length of the SSID
- */
- size_t ssid_len;
-
- /**
- * bssid - BSSID
- *
- * If set, this network block is used only when associating with the AP
- * using the configured BSSID
- *
- * If this is a persistent P2P group (disabled == 2), this is the GO
- * Device Address.
- */
- u8 bssid[ETH_ALEN];
-
- /**
- * bssid_ignore - List of inacceptable BSSIDs
- */
- u8 *bssid_ignore;
- size_t num_bssid_ignore;
-
- /**
- * bssid_accept - List of acceptable BSSIDs
- */
- u8 *bssid_accept;
- size_t num_bssid_accept;
-
- /**
- * bssid_set - Whether BSSID is configured for this network
- */
- int bssid_set;
-
- /**
- * bssid_hint - BSSID hint
- *
- * If set, this is configured to the driver as a preferred initial BSSID
- * while connecting to this network.
- */
- u8 bssid_hint[ETH_ALEN];
-
- /**
- * bssid_hint_set - Whether BSSID hint is configured for this network
- */
- int bssid_hint_set;
-
- /**
- * go_p2p_dev_addr - GO's P2P Device Address or all zeros if not set
- */
- u8 go_p2p_dev_addr[ETH_ALEN];
-
- /**
- * psk - WPA pre-shared key (256 bits)
- */
- u8 psk[32];
-
- /**
- * psk_set - Whether PSK field is configured
- */
- int psk_set;
-
- /**
- * passphrase - WPA ASCII passphrase
- *
- * If this is set, psk will be generated using the SSID and passphrase
- * configured for the network. ASCII passphrase must be between 8 and
- * 63 characters (inclusive).
- */
- char *passphrase;
-
- /**
- * sae_password - SAE password
- *
- * This parameter can be used to set a password for SAE. By default, the
- * passphrase value is used if this separate parameter is not used, but
- * passphrase follows the WPA-PSK constraints (8..63 characters) even
- * though SAE passwords do not have such constraints.
- */
- char *sae_password;
-
- /**
- * sae_password_id - SAE password identifier
- *
- * This parameter can be used to identify a specific SAE password. If
- * not included, the default SAE password is used instead.
- */
- char *sae_password_id;
-
- struct sae_pt *pt;
-
- /**
- * ext_psk - PSK/passphrase name in external storage
- *
- * If this is set, PSK/passphrase will be fetched from external storage
- * when requesting association with the network.
- */
- char *ext_psk;
-
- /**
- * mem_only_psk - Whether to keep PSK/passphrase only in memory
- *
- * 0 = allow psk/passphrase to be stored to the configuration file
- * 1 = do not store psk/passphrase to the configuration file
- */
- int mem_only_psk;
-
- /**
- * pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
- */
- int pairwise_cipher;
-
- /**
- * group_cipher - Bitfield of allowed group ciphers, WPA_CIPHER_*
- */
- int group_cipher;
-
- /**
- * group_mgmt_cipher - Bitfield of allowed group management ciphers
- *
- * This is a bitfield of WPA_CIPHER_AES_128_CMAC and WPA_CIPHER_BIP_*
- * values. If 0, no constraint is used for the cipher, i.e., whatever
- * the AP uses is accepted.
- */
- int group_mgmt_cipher;
-
- /**
- * key_mgmt - Bitfield of allowed key management protocols
- *
- * WPA_KEY_MGMT_*
- */
- int key_mgmt;
-
- /**
- * bg_scan_period - Background scan period in seconds, 0 to disable, or
- * -1 to indicate no change to default driver configuration
- */
- int bg_scan_period;
-
- /**
- * proto - Bitfield of allowed protocols, WPA_PROTO_*
- */
- int proto;
-
- /**
- * auth_alg - Bitfield of allowed authentication algorithms
- *
- * WPA_AUTH_ALG_*
- */
- int auth_alg;
-
- /**
- * scan_ssid - Scan this SSID with Probe Requests
- *
- * scan_ssid can be used to scan for APs using hidden SSIDs.
- * Note: Many drivers do not support this. ap_mode=2 can be used with
- * such drivers to use hidden SSIDs. Note2: Most nl80211-based drivers
- * do support scan_ssid=1 and that should be used with them instead of
- * ap_scan=2.
- */
- int scan_ssid;
-
-#ifdef IEEE8021X_EAPOL
-#define EAPOL_FLAG_REQUIRE_KEY_UNICAST BIT(0)
-#define EAPOL_FLAG_REQUIRE_KEY_BROADCAST BIT(1)
- /**
- * eapol_flags - Bit field of IEEE 802.1X/EAPOL options (EAPOL_FLAG_*)
- */
- int eapol_flags;
-
- /**
- * eap - EAP peer configuration for this network
- */
- struct eap_peer_config eap;
-#endif /* IEEE8021X_EAPOL */
-
-#ifdef CONFIG_WEP
-#define NUM_WEP_KEYS 4
-#define MAX_WEP_KEY_LEN 16
- /**
- * wep_key - WEP keys
- */
- u8 wep_key[NUM_WEP_KEYS][MAX_WEP_KEY_LEN];
-
- /**
- * wep_key_len - WEP key lengths
- */
- size_t wep_key_len[NUM_WEP_KEYS];
-
- /**
- * wep_tx_keyidx - Default key index for TX frames using WEP
- */
- int wep_tx_keyidx;
-#endif /* CONFIG_WEP */
-
- /**
- * proactive_key_caching - Enable proactive key caching
- *
- * This field can be used to enable proactive key caching which is also
- * known as opportunistic PMKSA caching for WPA2. This is disabled (0)
- * by default unless default value is changed with the global okc=1
- * parameter. Enable by setting this to 1.
- *
- * Proactive key caching is used to make supplicant assume that the APs
- * are using the same PMK and generate PMKSA cache entries without
- * doing RSN pre-authentication. This requires support from the AP side
- * and is normally used with wireless switches that co-locate the
- * authenticator.
- *
- * Internally, special value -1 is used to indicate that the parameter
- * was not specified in the configuration (i.e., default behavior is
- * followed).
- */
- int proactive_key_caching;
-
- /**
- * mixed_cell - Whether mixed cells are allowed
- *
- * This option can be used to configure whether so called mixed cells,
- * i.e., networks that use both plaintext and encryption in the same
- * SSID, are allowed. This is disabled (0) by default. Enable by
- * setting this to 1.
- */
- int mixed_cell;
-
-#ifdef IEEE8021X_EAPOL
-
- /**
- * leap - Number of EAP methods using LEAP
- *
- * This field should be set to 1 if LEAP is enabled. This is used to
- * select IEEE 802.11 authentication algorithm.
- */
- int leap;
-
- /**
- * non_leap - Number of EAP methods not using LEAP
- *
- * This field should be set to >0 if any EAP method other than LEAP is
- * enabled. This is used to select IEEE 802.11 authentication
- * algorithm.
- */
- int non_leap;
-
- /**
- * eap_workaround - EAP workarounds enabled
- *
- * wpa_supplicant supports number of "EAP workarounds" to work around
- * interoperability issues with incorrectly behaving authentication
- * servers. This is recommended to be enabled by default because some
- * of the issues are present in large number of authentication servers.
- *
- * Strict EAP conformance mode can be configured by disabling
- * workarounds with eap_workaround = 0.
- */
- unsigned int eap_workaround;
-
-#endif /* IEEE8021X_EAPOL */
-
- /**
- * mode - IEEE 802.11 operation mode (Infrastucture/IBSS)
- *
- * 0 = infrastructure (Managed) mode, i.e., associate with an AP.
- *
- * 1 = IBSS (ad-hoc, peer-to-peer)
- *
- * 2 = AP (access point)
- *
- * 3 = P2P Group Owner (can be set in the configuration file)
- *
- * 4 = P2P Group Formation (used internally; not in configuration
- * files)
- *
- * 5 = Mesh
- *
- * Note: IBSS can only be used with key_mgmt NONE (plaintext and static
- * WEP) and WPA-PSK (with proto=RSN). In addition, key_mgmt=WPA-NONE
- * (fixed group key TKIP/CCMP) is available for backwards compatibility,
- * but its use is deprecated. WPA-None requires following network block
- * options: proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or
- * CCMP, but not both), and psk must also be set (either directly or
- * using ASCII passphrase).
- */
- enum wpas_mode mode;
-
- /**
- * pbss - Whether to use PBSS. Relevant to DMG networks only.
- * 0 = do not use PBSS
- * 1 = use PBSS
- * 2 = don't care (not allowed in AP mode)
- * Used together with mode configuration. When mode is AP, it
- * means to start a PCP instead of a regular AP. When mode is INFRA it
- * means connect to a PCP instead of AP. In this mode you can also
- * specify 2 (don't care) meaning connect to either AP or PCP.
- * P2P_GO and P2P_GROUP_FORMATION modes must use PBSS in DMG network.
- */
- int pbss;
-
- /**
- * disabled - Whether this network is currently disabled
- *
- * 0 = this network can be used (default).
- * 1 = this network block is disabled (can be enabled through
- * ctrl_iface, e.g., with wpa_cli or wpa_gui).
- * 2 = this network block includes parameters for a persistent P2P
- * group (can be used with P2P ctrl_iface commands)
- */
- int disabled;
-
- /**
- * disabled_for_connect - Whether this network was temporarily disabled
- *
- * This flag is used to reenable all the temporarily disabled networks
- * after either the success or failure of a WPS connection.
- */
- int disabled_for_connect;
-
- /**
- * id_str - Network identifier string for external scripts
- *
- * This value is passed to external ctrl_iface monitors in
- * WPA_EVENT_CONNECTED event and wpa_cli sets this as WPA_ID_STR
- * environment variable for action scripts.
- */
- char *id_str;
-
- /**
- * ieee80211w - Whether management frame protection is enabled
- *
- * This value is used to configure policy for management frame
- * protection (IEEE 802.11w). 0 = disabled, 1 = optional, 2 = required.
- * This is disabled by default unless the default value has been changed
- * with the global pmf=1/2 parameter.
- *
- * Internally, special value 3 is used to indicate that the parameter
- * was not specified in the configuration (i.e., default behavior is
- * followed).
- */
- enum mfp_options ieee80211w;
-
-#ifdef CONFIG_OCV
- /**
- * ocv - Enable/disable operating channel validation
- *
- * If this parameter is set to 1, stations will exchange OCI element
- * to cryptographically verify the operating channel. Setting this
- * parameter to 0 disables this option. Default value: 0.
- */
- int ocv;
-#endif /* CONFIG_OCV */
-
- /**
- * frequency - Channel frequency in megahertz (MHz) for IBSS
- *
- * This value is used to configure the initial channel for IBSS (adhoc)
- * networks, e.g., 2412 = IEEE 802.11b/g channel 1. It is ignored in
- * the infrastructure mode. In addition, this value is only used by the
- * station that creates the IBSS. If an IBSS network with the
- * configured SSID is already present, the frequency of the network
- * will be used instead of this configured value.
- */
- int frequency;
-
- /**
- * enable_edmg - Enable EDMG feature in STA/AP mode
- *
- * This flag is used for enabling the EDMG capability in STA/AP mode.
- */
- int enable_edmg;
-
- /**
- * edmg_channel - EDMG channel number
- *
- * This value is used to configure the EDMG channel bonding feature.
- * In AP mode it defines the EDMG channel to start the AP on.
- * in STA mode it defines the EDMG channel to use for connection
- * (if supported by AP).
- */
- u8 edmg_channel;
-
- /**
- * fixed_freq - Use fixed frequency for IBSS
- */
- int fixed_freq;
-
-#ifdef CONFIG_ACS
- /**
- * ACS - Automatic Channel Selection for AP mode
- *
- * If present, it will be handled together with frequency.
- * frequency will be used to determine hardware mode only, when it is
- * used for both hardware mode and channel when used alone. This will
- * force the channel to be set to 0, thus enabling ACS.
- */
- int acs;
-#endif /* CONFIG_ACS */
-
- /**
- * mesh_basic_rates - BSS Basic rate set for mesh network
- *
- */
- int *mesh_basic_rates;
-
- /**
- * Mesh network plink parameters
- */
- int dot11MeshMaxRetries;
- int dot11MeshRetryTimeout; /* msec */
- int dot11MeshConfirmTimeout; /* msec */
- int dot11MeshHoldingTimeout; /* msec */
-
- /**
- * Mesh network layer-2 forwarding (dot11MeshForwarding)
- */
- int mesh_fwding;
-
- int ht;
- int ht40;
-
- int vht;
-
- int he;
-
- int max_oper_chwidth;
-
- unsigned int vht_center_freq1;
- unsigned int vht_center_freq2;
-
- /**
- * wpa_ptk_rekey - Maximum lifetime for PTK in seconds
- *
- * This value can be used to enforce rekeying of PTK to mitigate some
- * attacks against TKIP deficiencies.
- */
- int wpa_ptk_rekey;
-
- /** wpa_deny_ptk0_rekey - Control PTK0 rekeying
- *
- * Rekeying a pairwise key using only keyid 0 (PTK0 rekey) has many
- * broken implementations and should be avoided when using or
- * interacting with one.
- *
- * 0 = always rekey when configured/instructed
- * 1 = only rekey when the local driver is explicitly indicating it can
- * perform this operation without issues
- * 2 = never allow PTK0 rekeys
- */
- enum ptk0_rekey_handling wpa_deny_ptk0_rekey;
-
- /**
- * group_rekey - Group rekeying time in seconds
- *
- * This value, if non-zero, is used as the dot11RSNAConfigGroupRekeyTime
- * parameter when operating in Authenticator role in IBSS.
- */
- int group_rekey;
-
- /**
- * scan_freq - Array of frequencies to scan or %NULL for all
- *
- * This is an optional zero-terminated array of frequencies in
- * megahertz (MHz) to include in scan requests when searching for this
- * network. This can be used to speed up scanning when the network is
- * known to not use all possible channels.
- */
- int *scan_freq;
-
- /**
- * bgscan - Background scan and roaming parameters or %NULL if none
- *
- * This is an optional set of parameters for background scanning and
- * roaming within a network (ESS) in following format:
- * <bgscan module name>:<module parameters>
- */
- char *bgscan;
-
- /**
- * ignore_broadcast_ssid - Hide SSID in AP mode
- *
- * Send empty SSID in beacons and ignore probe request frames that do
- * not specify full SSID, i.e., require stations to know SSID.
- * default: disabled (0)
- * 1 = send empty (length=0) SSID in beacon and ignore probe request
- * for broadcast SSID
- * 2 = clear SSID (ASCII 0), but keep the original length (this may be
- * required with some clients that do not support empty SSID) and
- * ignore probe requests for broadcast SSID
- */
- int ignore_broadcast_ssid;
-
- /**
- * freq_list - Array of allowed frequencies or %NULL for all
- *
- * This is an optional zero-terminated array of frequencies in
- * megahertz (MHz) to allow for selecting the BSS. If set, scan results
- * that do not match any of the specified frequencies are not
- * considered when selecting a BSS.
- */
- int *freq_list;
-
- /**
- * p2p_client_list - List of P2P Clients in a persistent group (GO)
- *
- * This is a list of P2P Clients (P2P Device Address) that have joined
- * the persistent group. This is maintained on the GO for persistent
- * group entries (disabled == 2).
- */
- u8 *p2p_client_list;
-
- /**
- * num_p2p_clients - Number of entries in p2p_client_list
- */
- size_t num_p2p_clients;
-
-#ifndef P2P_MAX_STORED_CLIENTS
-#define P2P_MAX_STORED_CLIENTS 100
-#endif /* P2P_MAX_STORED_CLIENTS */
-
- /**
- * psk_list - Per-client PSKs (struct psk_list_entry)
- */
- struct dl_list psk_list;
-
- /**
- * p2p_group - Network generated as a P2P group (used internally)
- */
- int p2p_group;
-
- /**
- * p2p_persistent_group - Whether this is a persistent group
- */
- int p2p_persistent_group;
-
- /**
- * temporary - Whether this network is temporary and not to be saved
- */
- int temporary;
-
- /**
- * export_keys - Whether keys may be exported
- *
- * This attribute will be set when keys are determined through
- * WPS or similar so that they may be exported.
- */
- int export_keys;
-
-#ifdef CONFIG_HT_OVERRIDES
- /**
- * disable_ht - Disable HT (IEEE 802.11n) for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_ht;
-
- /**
- * disable_ht40 - Disable HT40 for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_ht40;
-
- /**
- * disable_sgi - Disable SGI (Short Guard Interval) for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_sgi;
-
- /**
- * disable_ldpc - Disable LDPC for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_ldpc;
-
- /**
- * ht40_intolerant - Indicate 40 MHz intolerant for this network
- */
- int ht40_intolerant;
-
- /**
- * disable_max_amsdu - Disable MAX A-MSDU
- *
- * A-MDSU will be 3839 bytes when disabled, or 7935
- * when enabled (assuming it is otherwise supported)
- * -1 (default) means do not apply any settings to the kernel.
- */
- int disable_max_amsdu;
-
- /**
- * ampdu_factor - Maximum A-MPDU Length Exponent
- *
- * Value: 0-3, see 7.3.2.56.3 in IEEE Std 802.11n-2009.
- */
- int ampdu_factor;
-
- /**
- * ampdu_density - Minimum A-MPDU Start Spacing
- *
- * Value: 0-7, see 7.3.2.56.3 in IEEE Std 802.11n-2009.
- */
- int ampdu_density;
-
- /**
- * ht_mcs - Allowed HT-MCS rates, in ASCII hex: ffff0000...
- *
- * By default (empty string): Use whatever the OS has configured.
- */
- char *ht_mcs;
-
- /**
- * tx_stbc - Indicate STBC support for TX streams
- *
- * Value: -1..1, by default (-1): use whatever the OS or card has
- * configured. See IEEE Std 802.11-2016, 9.4.2.56.2.
- */
- int tx_stbc;
-
- /**
- * rx_stbc - Indicate STBC support for RX streams
- *
- * Value: -1..3, by default (-1): use whatever the OS or card has
- * configured. See IEEE Std 802.11-2016, 9.4.2.56.2.
- */
- int rx_stbc;
-#endif /* CONFIG_HT_OVERRIDES */
-
-#ifdef CONFIG_VHT_OVERRIDES
- /**
- * disable_vht - Disable VHT (IEEE 802.11ac) for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_vht;
-
- /**
- * vht_capa - VHT capabilities to use
- */
- unsigned int vht_capa;
-
- /**
- * vht_capa_mask - mask for VHT capabilities
- */
- unsigned int vht_capa_mask;
-
- int vht_rx_mcs_nss_1, vht_rx_mcs_nss_2,
- vht_rx_mcs_nss_3, vht_rx_mcs_nss_4,
- vht_rx_mcs_nss_5, vht_rx_mcs_nss_6,
- vht_rx_mcs_nss_7, vht_rx_mcs_nss_8;
- int vht_tx_mcs_nss_1, vht_tx_mcs_nss_2,
- vht_tx_mcs_nss_3, vht_tx_mcs_nss_4,
- vht_tx_mcs_nss_5, vht_tx_mcs_nss_6,
- vht_tx_mcs_nss_7, vht_tx_mcs_nss_8;
-#endif /* CONFIG_VHT_OVERRIDES */
-
-#ifdef CONFIG_HE_OVERRIDES
- /**
- * disable_he - Disable HE (IEEE 802.11ax) for this network
- *
- * By default, use it if it is available, but this can be configured
- * to 1 to have it disabled.
- */
- int disable_he;
-#endif /* CONFIG_HE_OVERRIDES */
-
- /**
- * ap_max_inactivity - Timeout in seconds to detect STA's inactivity
- *
- * This timeout value is used in AP mode to clean up inactive stations.
- * By default: 300 seconds.
- */
- int ap_max_inactivity;
-
- /**
- * dtim_period - DTIM period in Beacon intervals
- * By default: 2
- */
- int dtim_period;
-
- /**
- * beacon_int - Beacon interval (default: 100 TU)
- */
- int beacon_int;
-
- /**
- * auth_failures - Number of consecutive authentication failures
- */
- unsigned int auth_failures;
-
- /**
- * disabled_until - Network block disabled until this time if non-zero
- */
- struct os_reltime disabled_until;
-
- /**
- * parent_cred - Pointer to parent wpa_cred entry
- *
- * This pointer can be used to delete temporary networks when a wpa_cred
- * that was used to create them is removed. This pointer should not be
- * dereferences since it may not be updated in all cases.
- */
- void *parent_cred;
-
-#ifdef CONFIG_MACSEC
- /**
- * macsec_policy - Determines the policy for MACsec secure session
- *
- * 0: MACsec not in use (default)
- * 1: MACsec enabled - Should secure, accept key server's advice to
- * determine whether to use a secure session or not.
- */
- int macsec_policy;
-
- /**
- * macsec_integ_only - Determines how MACsec are transmitted
- *
- * This setting applies only when MACsec is in use, i.e.,
- * - macsec_policy is enabled
- * - the key server has decided to enable MACsec
- *
- * 0: Encrypt traffic (default)
- * 1: Integrity only
- */
- int macsec_integ_only;
-
- /**
- * macsec_replay_protect - Enable MACsec replay protection
- *
- * This setting applies only when MACsec is in use, i.e.,
- * - macsec_policy is enabled
- * - the key server has decided to enable MACsec
- *
- * 0: Replay protection disabled (default)
- * 1: Replay protection enabled
- */
- int macsec_replay_protect;
-
- /**
- * macsec_replay_window - MACsec replay protection window
- *
- * A window in which replay is tolerated, to allow receipt of frames
- * that have been misordered by the network.
- *
- * This setting applies only when MACsec replay protection active, i.e.,
- * - macsec_replay_protect is enabled
- * - the key server has decided to enable MACsec
- *
- * 0: No replay window, strict check (default)
- * 1..2^32-1: number of packets that could be misordered
- */
- u32 macsec_replay_window;
-
- /**
- * macsec_port - MACsec port (in SCI)
- *
- * Port component of the SCI.
- *
- * Range: 1-65534 (default: 1)
- */
- int macsec_port;
-
- /**
- * mka_priority - Priority of MKA Actor
- *
- * Range: 0-255 (default: 255)
- */
- int mka_priority;
-
- /**
- * mka_ckn - MKA pre-shared CKN
- */
-#define MACSEC_CKN_MAX_LEN 32
- size_t mka_ckn_len;
- u8 mka_ckn[MACSEC_CKN_MAX_LEN];
-
- /**
- * mka_cak - MKA pre-shared CAK
- */
-#define MACSEC_CAK_MAX_LEN 32
- size_t mka_cak_len;
- u8 mka_cak[MACSEC_CAK_MAX_LEN];
-
-#define MKA_PSK_SET_CKN BIT(0)
-#define MKA_PSK_SET_CAK BIT(1)
-#define MKA_PSK_SET (MKA_PSK_SET_CKN | MKA_PSK_SET_CAK)
- /**
- * mka_psk_set - Whether mka_ckn and mka_cak are set
- */
- u8 mka_psk_set;
-#endif /* CONFIG_MACSEC */
-
-#ifdef CONFIG_HS20
- int update_identifier;
-
- /**
- * roaming_consortium_selection - Roaming Consortium Selection
- *
- * The matching Roaming Consortium OI that was used to generate this
- * network profile.
- */
- u8 *roaming_consortium_selection;
-
- /**
- * roaming_consortium_selection_len - roaming_consortium_selection len
- */
- size_t roaming_consortium_selection_len;
-#endif /* CONFIG_HS20 */
-
- unsigned int wps_run;
-
- /**
- * mac_addr - MAC address policy
- *
- * 0 = use permanent MAC address
- * 1 = use random MAC address for each ESS connection
- * 2 = like 1, but maintain OUI (with local admin bit set)
- *
- * Internally, special value -1 is used to indicate that the parameter
- * was not specified in the configuration (i.e., default behavior is
- * followed).
- */
- int mac_addr;
-
- /**
- * no_auto_peer - Do not automatically peer with compatible mesh peers
- *
- * When unset, the reception of a beacon from a another mesh peer in
- * this MBSS will trigger a peering attempt.
- */
- int no_auto_peer;
-
- /**
- * mesh_rssi_threshold - Set mesh parameter mesh_rssi_threshold (dBm)
- *
- * -255..-1 = threshold value in dBm
- * 0 = not using RSSI threshold
- * 1 = do not change driver default
- */
- int mesh_rssi_threshold;
-
- /**
- * wps_disabled - WPS disabled in AP mode
- *
- * 0 = WPS enabled and configured (default)
- * 1 = WPS disabled
- */
- int wps_disabled;
-
- /**
- * fils_dh_group - FILS DH Group
- *
- * 0 = PFS disabled with FILS shared key authentication
- * 1-65535 DH Group to use for FILS PFS
- */
- int fils_dh_group;
-
- /**
- * dpp_connector - DPP Connector (signedConnector as string)
- */
- char *dpp_connector;
-
- /**
- * dpp_netaccesskey - DPP netAccessKey (own private key)
- */
- u8 *dpp_netaccesskey;
-
- /**
- * dpp_netaccesskey_len - DPP netAccessKey length in octets
- */
- size_t dpp_netaccesskey_len;
-
- /**
- * net_access_key_expiry - DPP netAccessKey expiry in UNIX time stamp
- *
- * 0 indicates no expiration.
- */
- unsigned int dpp_netaccesskey_expiry;
-
- /**
- * dpp_csign - C-sign-key (Configurator public key)
- */
- u8 *dpp_csign;
-
- /**
- * dpp_csign_len - C-sign-key length in octets
- */
- size_t dpp_csign_len;
-
- /**
- * dpp_pp_key - ppKey (Configurator privacy protection public key)
- */
- u8 *dpp_pp_key;
-
- /**
- * dpp_pp_key_len - ppKey length in octets
- */
- size_t dpp_pp_key_len;
-
- /**
- * dpp_pfs - DPP PFS
- * 0: allow PFS to be used or not used
- * 1: require PFS to be used (note: not compatible with DPP R1)
- * 2: do not allow PFS to be used
- */
- int dpp_pfs;
-
- /**
- * dpp_pfs_fallback - DPP PFS fallback selection
- *
- * This is an internally used variable (i.e., not used in external
- * configuration) to track state of the DPP PFS fallback mechanism.
- */
- int dpp_pfs_fallback;
-
- /**
- * owe_group - OWE DH Group
- *
- * 0 = use default (19) first and then try all supported groups one by
- * one if AP rejects the selected group
- * 1-65535 DH Group to use for OWE
- *
- * Groups 19 (NIST P-256), 20 (NIST P-384), and 21 (NIST P-521) are
- * currently supported.
- */
- int owe_group;
-
- /**
- * owe_only - OWE-only mode (disable transition mode)
- *
- * 0 = enable transition mode (allow connection to either OWE or open
- * BSS)
- * 1 = disable transition mode (allow connection only with OWE)
- */
- int owe_only;
-
- /**
- * owe_ptk_workaround - OWE PTK derivation workaround
- *
- * Initial OWE implementation used SHA256 when deriving the PTK for all
- * OWE groups. This was supposed to change to SHA384 for group 20 and
- * SHA512 for group 21. This parameter can be used to enable older
- * behavior mainly for testing purposes. There is no impact to group 19
- * behavior, but if enabled, this will make group 20 and 21 cases use
- * SHA256-based PTK derivation which will not work with the updated
- * OWE implementation on the AP side.
- */
- int owe_ptk_workaround;
-
- /**
- * owe_transition_bss_select_count - OWE transition BSS select count
- *
- * This is an internally used variable (i.e., not used in external
- * configuration) to track the number of selection attempts done for
- * OWE BSS in transition mode. This allows fallback to an open BSS if
- * the selection attempts for OWE BSS exceed the configured threshold.
- */
- int owe_transition_bss_select_count;
-
- /**
- * multi_ap_backhaul_sta - Multi-AP backhaul STA
- * 0 = normal (non-Multi-AP) station
- * 1 = Multi-AP backhaul station
- */
- int multi_ap_backhaul_sta;
-
- /**
- * ft_eap_pmksa_caching - Whether FT-EAP PMKSA caching is allowed
- * 0 = do not try to use PMKSA caching with FT-EAP
- * 1 = try to use PMKSA caching with FT-EAP
- *
- * This controls whether to try to use PMKSA caching with FT-EAP for the
- * FT initial mobility domain association.
- */
- int ft_eap_pmksa_caching;
-
- /**
- * beacon_prot - Whether Beacon protection is enabled
- *
- * This depends on management frame protection (ieee80211w) being
- * enabled.
- */
- int beacon_prot;
-
- /**
- * transition_disable - Transition Disable indication
- * The AP can notify authenticated stations to disable transition mode
- * in their network profiles when the network has completed transition
- * steps, i.e., once sufficiently large number of APs in the ESS have
- * been updated to support the more secure alternative. When this
- * indication is used, the stations are expected to automatically
- * disable transition mode and less secure security options. This
- * includes use of WEP, TKIP (including use of TKIP as the group
- * cipher), and connections without PMF.
- * Bitmap bits:
- * bit 0 (0x01): WPA3-Personal (i.e., disable WPA2-Personal = WPA-PSK
- * and only allow SAE to be used)
- * bit 1 (0x02): SAE-PK (disable SAE without use of SAE-PK)
- * bit 2 (0x04): WPA3-Enterprise (move to requiring PMF)
- * bit 3 (0x08): Enhanced Open (disable use of open network; require
- * OWE)
- */
- u8 transition_disable;
-
- /**
- * sae_pk - SAE-PK mode
- * 0 = automatic SAE/SAE-PK selection based on password; enable
- * transition mode (allow SAE authentication without SAE-PK)
- * 1 = SAE-PK only (disable transition mode; allow SAE authentication
- * only with SAE-PK)
- * 2 = disable SAE-PK (allow SAE authentication only without SAE-PK)
- */
- enum sae_pk_mode sae_pk;
-
- /**
- * was_recently_reconfigured - Whether this SSID config has been changed
- * recently
- *
- * This is an internally used variable, i.e., not used in external
- * configuration.
- */
- bool was_recently_reconfigured;
-
- /**
- * sae_pwe - SAE mechanism for PWE derivation
- *
- * Internally, special value 4 (DEFAULT_SAE_PWE) is used to indicate
- * that the parameter is not set and the global sae_pwe value needs to
- * be considered.
- *
- * 0 = hunting-and-pecking loop only
- * 1 = hash-to-element only
- * 2 = both hunting-and-pecking loop and hash-to-element enabled
- */
- int sae_pwe;
-};
-
-#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
deleted file mode 100644
index 1b7f96ed2fb1..000000000000
--- a/wpa_supplicant/config_winreg.c
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*
- * WPA Supplicant / Configuration backend: Windows registry
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * This file implements a configuration backend for Windows registry. All the
- * configuration information is stored in the registry and the format for
- * network configuration fields is same as described in the sample
- * configuration file, wpa_supplicant.conf.
- *
- * Configuration data is in
- * \a HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant\\configs
- * key. Each configuration profile has its own key under this. In terms of text
- * files, each profile would map to a separate text file with possibly multiple
- * networks. Under each profile, there is a networks key that lists all
- * networks as a subkey. Each network has set of values in the same way as
- * network block in the configuration file. In addition, blobs subkey has
- * possible blobs as values.
- *
- * Example network configuration block:
- * \verbatim
-HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000
- ssid="example"
- key_mgmt=WPA-PSK
-\endverbatim
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "uuid.h"
-#include "config.h"
-
-#ifndef WPA_KEY_ROOT
-#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
-#endif
-#ifndef WPA_KEY_PREFIX
-#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
-#endif
-
-#ifdef UNICODE
-#define TSTR "%S"
-#else /* UNICODE */
-#define TSTR "%s"
-#endif /* UNICODE */
-
-
-static int wpa_config_read_blobs(struct wpa_config *config, HKEY hk)
-{
- struct wpa_config_blob *blob;
- int errors = 0;
- HKEY bhk;
- LONG ret;
- DWORD i;
-
- ret = RegOpenKeyEx(hk, TEXT("blobs"), 0, KEY_QUERY_VALUE, &bhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
- "blobs key");
- return 0; /* assume no blobs */
- }
-
- for (i = 0; ; i++) {
-#define TNAMELEN 255
- TCHAR name[TNAMELEN];
- char data[4096];
- DWORD namelen, datalen, type;
-
- namelen = TNAMELEN;
- datalen = sizeof(data);
- ret = RegEnumValue(bhk, i, name, &namelen, NULL, &type,
- (LPBYTE) data, &datalen);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "RegEnumValue failed: 0x%x",
- (unsigned int) ret);
- break;
- }
-
- if (namelen >= TNAMELEN)
- namelen = TNAMELEN - 1;
- name[namelen] = TEXT('\0');
- wpa_unicode2ascii_inplace(name);
-
- if (datalen >= sizeof(data))
- datalen = sizeof(data) - 1;
-
- wpa_printf(MSG_MSGDUMP, "blob %d: field='%s' len %d",
- (int) i, name, (int) datalen);
-
- blob = os_zalloc(sizeof(*blob));
- if (blob == NULL) {
- errors++;
- break;
- }
- blob->name = os_strdup((char *) name);
- blob->data = os_memdup(data, datalen);
- if (blob->name == NULL || blob->data == NULL) {
- wpa_config_free_blob(blob);
- errors++;
- break;
- }
- blob->len = datalen;
-
- wpa_config_set_blob(config, blob);
- }
-
- RegCloseKey(bhk);
-
- return errors ? -1 : 0;
-}
-
-
-static int wpa_config_read_reg_dword(HKEY hk, const TCHAR *name, int *_val)
-{
- DWORD val, buflen;
- LONG ret;
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
- wpa_printf(MSG_DEBUG, TSTR "=%d", name, (int) val);
- *_val = val;
- return 0;
- }
-
- return -1;
-}
-
-
-static char * wpa_config_read_reg_string(HKEY hk, const TCHAR *name)
-{
- DWORD buflen;
- LONG ret;
- TCHAR *val;
-
- buflen = 0;
- ret = RegQueryValueEx(hk, name, NULL, NULL, NULL, &buflen);
- if (ret != ERROR_SUCCESS)
- return NULL;
- val = os_malloc(buflen);
- if (val == NULL)
- return NULL;
-
- ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) val, &buflen);
- if (ret != ERROR_SUCCESS) {
- os_free(val);
- return NULL;
- }
-
- wpa_unicode2ascii_inplace(val);
- wpa_printf(MSG_DEBUG, TSTR "=%s", name, (char *) val);
- return (char *) val;
-}
-
-
-#ifdef CONFIG_WPS
-static int wpa_config_read_global_uuid(struct wpa_config *config, HKEY hk)
-{
- char *str;
- int ret = 0;
-
- str = wpa_config_read_reg_string(hk, TEXT("uuid"));
- if (str == NULL)
- return 0;
-
- if (uuid_str2bin(str, config->uuid))
- ret = -1;
-
- os_free(str);
-
- return ret;
-}
-
-
-static int wpa_config_read_global_os_version(struct wpa_config *config,
- HKEY hk)
-{
- char *str;
- int ret = 0;
-
- str = wpa_config_read_reg_string(hk, TEXT("os_version"));
- if (str == NULL)
- return 0;
-
- if (hexstr2bin(str, config->os_version, 4))
- ret = -1;
-
- os_free(str);
-
- return ret;
-}
-#endif /* CONFIG_WPS */
-
-
-static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
-{
- int errors = 0;
- int val;
-
- wpa_config_read_reg_dword(hk, TEXT("ap_scan"), &config->ap_scan);
- wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
- &config->fast_reauth);
- wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
- (int *) &config->dot11RSNAConfigPMKLifetime);
- wpa_config_read_reg_dword(hk,
- TEXT("dot11RSNAConfigPMKReauthThreshold"),
- (int *)
- &config->dot11RSNAConfigPMKReauthThreshold);
- wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
- (int *) &config->dot11RSNAConfigSATimeout);
- wpa_config_read_reg_dword(hk, TEXT("update_config"),
- &config->update_config);
-
- if (wpa_config_read_reg_dword(hk, TEXT("eapol_version"),
- &config->eapol_version) == 0) {
- if (config->eapol_version < 1 ||
- config->eapol_version > 2) {
- wpa_printf(MSG_ERROR, "Invalid EAPOL version (%d)",
- config->eapol_version);
- errors++;
- }
- }
-
- config->ctrl_interface = wpa_config_read_reg_string(
- hk, TEXT("ctrl_interface"));
-
-#ifdef CONFIG_WPS
- if (wpa_config_read_global_uuid(config, hk))
- errors++;
- wpa_config_read_reg_dword(hk, TEXT("auto_uuid"), &config->auto_uuid);
- config->device_name = wpa_config_read_reg_string(
- hk, TEXT("device_name"));
- config->manufacturer = wpa_config_read_reg_string(
- hk, TEXT("manufacturer"));
- config->model_name = wpa_config_read_reg_string(
- hk, TEXT("model_name"));
- config->serial_number = wpa_config_read_reg_string(
- hk, TEXT("serial_number"));
- {
- char *t = wpa_config_read_reg_string(
- hk, TEXT("device_type"));
- if (t && wps_dev_type_str2bin(t, config->device_type))
- errors++;
- os_free(t);
- }
- config->config_methods = wpa_config_read_reg_string(
- hk, TEXT("config_methods"));
- if (wpa_config_read_global_os_version(config, hk))
- errors++;
- wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
- &config->wps_cred_processing);
- wpa_config_read_reg_dword(hk, TEXT("wps_cred_add_sae"),
- &config->wps_cred_add_sae);
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- config->p2p_ssid_postfix = wpa_config_read_reg_string(
- hk, TEXT("p2p_ssid_postfix"));
- wpa_config_read_reg_dword(hk, TEXT("p2p_group_idle"),
- (int *) &config->p2p_group_idle);
-#endif /* CONFIG_P2P */
-
- wpa_config_read_reg_dword(hk, TEXT("bss_max_count"),
- (int *) &config->bss_max_count);
- wpa_config_read_reg_dword(hk, TEXT("filter_ssids"),
- &config->filter_ssids);
- wpa_config_read_reg_dword(hk, TEXT("max_num_sta"),
- (int *) &config->max_num_sta);
- wpa_config_read_reg_dword(hk, TEXT("disassoc_low_ack"),
- (int *) &config->disassoc_low_ack);
-
- wpa_config_read_reg_dword(hk, TEXT("okc"), &config->okc);
- wpa_config_read_reg_dword(hk, TEXT("pmf"), &val);
- config->pmf = val;
- if (wpa_config_read_reg_dword(hk, TEXT("extended_key_id"),
- &val) == 0) {
- if (val < 0 || val > 1) {
- wpa_printf(MSG_ERROR,
- "Invalid Extended Key ID setting (%d)", val);
- errors++;
- }
- config->extended_key_id = val;
- }
-
- return errors ? -1 : 0;
-}
-
-
-static struct wpa_ssid * wpa_config_read_network(HKEY hk, const TCHAR *netw,
- int id)
-{
- HKEY nhk;
- LONG ret;
- DWORD i;
- struct wpa_ssid *ssid;
- int errors = 0;
-
- ret = RegOpenKeyEx(hk, netw, 0, KEY_QUERY_VALUE, &nhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
- "network '" TSTR "'", netw);
- return NULL;
- }
-
- wpa_printf(MSG_MSGDUMP, "Start of a new network '" TSTR "'", netw);
- ssid = os_zalloc(sizeof(*ssid));
- if (ssid == NULL) {
- RegCloseKey(nhk);
- return NULL;
- }
- dl_list_init(&ssid->psk_list);
- ssid->id = id;
-
- wpa_config_set_network_defaults(ssid);
-
- for (i = 0; ; i++) {
- TCHAR name[255], data[1024];
- DWORD namelen, datalen, type;
-
- namelen = 255;
- datalen = sizeof(data);
- ret = RegEnumValue(nhk, i, name, &namelen, NULL, &type,
- (LPBYTE) data, &datalen);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "RegEnumValue failed: 0x%x",
- (unsigned int) ret);
- break;
- }
-
- if (namelen >= 255)
- namelen = 255 - 1;
- name[namelen] = TEXT('\0');
-
- if (datalen >= 1024)
- datalen = 1024 - 1;
- data[datalen] = TEXT('\0');
-
- wpa_unicode2ascii_inplace(name);
- wpa_unicode2ascii_inplace(data);
- if (wpa_config_set(ssid, (char *) name, (char *) data, 0) < 0)
- errors++;
- }
-
- RegCloseKey(nhk);
-
- if (ssid->passphrase) {
- if (ssid->psk_set) {
- wpa_printf(MSG_ERROR, "Both PSK and passphrase "
- "configured for network '" TSTR "'.", netw);
- errors++;
- }
- wpa_config_update_psk(ssid);
- }
-
- if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
- !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
- !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) {
- /* Group cipher cannot be stronger than the pairwise cipher. */
- wpa_printf(MSG_DEBUG, "Removed CCMP from group cipher "
- "list since it was not allowed for pairwise "
- "cipher for network '" TSTR "'.", netw);
- ssid->group_cipher &= ~WPA_CIPHER_CCMP;
- }
-
- if (errors) {
- wpa_config_free_ssid(ssid);
- ssid = NULL;
- }
-
- return ssid;
-}
-
-
-static int wpa_config_read_networks(struct wpa_config *config, HKEY hk)
-{
- HKEY nhk;
- struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
- int errors = 0;
- LONG ret;
- DWORD i;
-
- ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_ENUMERATE_SUB_KEYS,
- &nhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "Could not open wpa_supplicant networks "
- "registry key");
- return -1;
- }
-
- for (i = 0; ; i++) {
- TCHAR name[255];
- DWORD namelen;
-
- namelen = 255;
- ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
- NULL);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x",
- (unsigned int) ret);
- break;
- }
-
- if (namelen >= 255)
- namelen = 255 - 1;
- name[namelen] = '\0';
-
- ssid = wpa_config_read_network(nhk, name, i);
- if (ssid == NULL) {
- wpa_printf(MSG_ERROR, "Failed to parse network "
- "profile '%s'.", name);
- errors++;
- continue;
- }
- if (head == NULL) {
- head = tail = ssid;
- } else {
- tail->next = ssid;
- tail = ssid;
- }
- if (wpa_config_add_prio_network(config, ssid)) {
- wpa_printf(MSG_ERROR, "Failed to add network profile "
- "'%s' to priority list.", name);
- errors++;
- continue;
- }
- }
-
- RegCloseKey(nhk);
-
- config->ssid = head;
-
- return errors ? -1 : 0;
-}
-
-
-struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp)
-{
- TCHAR buf[256];
- int errors = 0;
- struct wpa_config *config;
- HKEY hk;
- LONG ret;
-
- if (name == NULL)
- return NULL;
- if (cfgp)
- config = cfgp;
- else
- config = wpa_config_alloc_empty(NULL, NULL);
- if (config == NULL)
- return NULL;
- wpa_printf(MSG_DEBUG, "Reading configuration profile '%s'", name);
-
-#ifdef UNICODE
- _snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
-#else /* UNICODE */
- os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
-#endif /* UNICODE */
-
- ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_QUERY_VALUE, &hk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
- "configuration registry HKLM\\" TSTR, buf);
- os_free(config);
- return NULL;
- }
-
- if (wpa_config_read_global(config, hk))
- errors++;
-
- if (wpa_config_read_networks(config, hk))
- errors++;
-
- if (wpa_config_read_blobs(config, hk))
- errors++;
-
- wpa_config_debug_dump_networks(config);
-
- RegCloseKey(hk);
-
- if (errors) {
- wpa_config_free(config);
- config = NULL;
- }
-
- return config;
-}
-
-
-static int wpa_config_write_reg_dword(HKEY hk, const TCHAR *name, int val,
- int def)
-{
- LONG ret;
- DWORD _val = val;
-
- if (val == def) {
- RegDeleteValue(hk, name);
- return 0;
- }
-
- ret = RegSetValueEx(hk, name, 0, REG_DWORD, (LPBYTE) &_val,
- sizeof(_val));
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "WINREG: Failed to set %s=%d: error %d",
- name, val, (int) GetLastError());
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpa_config_write_reg_string(HKEY hk, const char *name,
- const char *val)
-{
- LONG ret;
- TCHAR *_name, *_val;
-
- _name = wpa_strdup_tchar(name);
- if (_name == NULL)
- return -1;
-
- if (val == NULL) {
- RegDeleteValue(hk, _name);
- os_free(_name);
- return 0;
- }
-
- _val = wpa_strdup_tchar(val);
- if (_val == NULL) {
- os_free(_name);
- return -1;
- }
- ret = RegSetValueEx(hk, _name, 0, REG_SZ, (BYTE *) _val,
- (os_strlen(val) + 1) * sizeof(TCHAR));
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "WINREG: Failed to set %s='%s': "
- "error %d", name, val, (int) GetLastError());
- os_free(_name);
- os_free(_val);
- return -1;
- }
-
- os_free(_name);
- os_free(_val);
- return 0;
-}
-
-
-static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
-{
-#ifdef CONFIG_CTRL_IFACE
- wpa_config_write_reg_string(hk, "ctrl_interface",
- config->ctrl_interface);
-#endif /* CONFIG_CTRL_IFACE */
-
- wpa_config_write_reg_dword(hk, TEXT("eapol_version"),
- config->eapol_version,
- DEFAULT_EAPOL_VERSION);
- wpa_config_write_reg_dword(hk, TEXT("ap_scan"), config->ap_scan,
- DEFAULT_AP_SCAN);
- wpa_config_write_reg_dword(hk, TEXT("fast_reauth"),
- config->fast_reauth, DEFAULT_FAST_REAUTH);
- wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
- config->dot11RSNAConfigPMKLifetime, 0);
- wpa_config_write_reg_dword(hk,
- TEXT("dot11RSNAConfigPMKReauthThreshold"),
- config->dot11RSNAConfigPMKReauthThreshold,
- 0);
- wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
- config->dot11RSNAConfigSATimeout, 0);
- wpa_config_write_reg_dword(hk, TEXT("update_config"),
- config->update_config,
- 0);
-#ifdef CONFIG_WPS
- if (!is_nil_uuid(config->uuid)) {
- char buf[40];
- uuid_bin2str(config->uuid, buf, sizeof(buf));
- wpa_config_write_reg_string(hk, "uuid", buf);
- }
- wpa_config_write_reg_dword(hk, TEXT("auto_uuid"), config->auto_uuid,
- 0);
- wpa_config_write_reg_string(hk, "device_name", config->device_name);
- wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
- wpa_config_write_reg_string(hk, "model_name", config->model_name);
- wpa_config_write_reg_string(hk, "model_number", config->model_number);
- wpa_config_write_reg_string(hk, "serial_number",
- config->serial_number);
- {
- char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
- buf = wps_dev_type_bin2str(config->device_type,
- _buf, sizeof(_buf));
- wpa_config_write_reg_string(hk, "device_type", buf);
- }
- wpa_config_write_reg_string(hk, "config_methods",
- config->config_methods);
- if (WPA_GET_BE32(config->os_version)) {
- char vbuf[10];
- os_snprintf(vbuf, sizeof(vbuf), "%08x",
- WPA_GET_BE32(config->os_version));
- wpa_config_write_reg_string(hk, "os_version", vbuf);
- }
- wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
- config->wps_cred_processing, 0);
- wpa_config_write_reg_dword(hk, TEXT("wps_cred_add_sae"),
- config->wps_cred_add_sae, 0);
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- wpa_config_write_reg_string(hk, "p2p_ssid_postfix",
- config->p2p_ssid_postfix);
- wpa_config_write_reg_dword(hk, TEXT("p2p_group_idle"),
- config->p2p_group_idle, 0);
-#endif /* CONFIG_P2P */
-
- wpa_config_write_reg_dword(hk, TEXT("bss_max_count"),
- config->bss_max_count,
- DEFAULT_BSS_MAX_COUNT);
- wpa_config_write_reg_dword(hk, TEXT("filter_ssids"),
- config->filter_ssids, 0);
- wpa_config_write_reg_dword(hk, TEXT("max_num_sta"),
- config->max_num_sta, DEFAULT_MAX_NUM_STA);
- wpa_config_write_reg_dword(hk, TEXT("ap_isolate"),
- config->ap_isolate, DEFAULT_AP_ISOLATE);
- wpa_config_write_reg_dword(hk, TEXT("disassoc_low_ack"),
- config->disassoc_low_ack, 0);
-
- wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
- wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
-
- wpa_config_write_reg_dword(hk, TEXT("external_sim"),
- config->external_sim, 0);
-
- return 0;
-}
-
-
-static int wpa_config_delete_subkeys(HKEY hk, const TCHAR *key)
-{
- HKEY nhk;
- int i, errors = 0;
- LONG ret;
-
- ret = RegOpenKeyEx(hk, key, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &nhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "WINREG: Could not open key '" TSTR
- "' for subkey deletion: error 0x%x (%d)", key,
- (unsigned int) ret, (int) GetLastError());
- return 0;
- }
-
- for (i = 0; ; i++) {
- TCHAR name[255];
- DWORD namelen;
-
- namelen = 255;
- ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
- NULL);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x (%d)",
- (unsigned int) ret, (int) GetLastError());
- break;
- }
-
- if (namelen >= 255)
- namelen = 255 - 1;
- name[namelen] = TEXT('\0');
-
- ret = RegDeleteKey(nhk, name);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "RegDeleteKey failed: 0x%x (%d)",
- (unsigned int) ret, (int) GetLastError());
- errors++;
- }
- }
-
- RegCloseKey(nhk);
-
- return errors ? -1 : 0;
-}
-
-
-static void write_str(HKEY hk, const char *field, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, field);
- if (value == NULL)
- return;
- wpa_config_write_reg_string(hk, field, value);
- os_free(value);
-}
-
-
-static void write_int(HKEY hk, const char *field, int value, int def)
-{
- char val[20];
- if (value == def)
- return;
- os_snprintf(val, sizeof(val), "%d", value);
- wpa_config_write_reg_string(hk, field, val);
-}
-
-
-static void write_bssid(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "bssid");
- if (value == NULL)
- return;
- wpa_config_write_reg_string(hk, "bssid", value);
- os_free(value);
-}
-
-
-static void write_psk(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value = wpa_config_get(ssid, "psk");
- if (value == NULL)
- return;
- wpa_config_write_reg_string(hk, "psk", value);
- os_free(value);
-}
-
-
-static void write_proto(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->proto == DEFAULT_PROTO)
- return;
-
- value = wpa_config_get(ssid, "proto");
- if (value == NULL)
- return;
- if (value[0])
- wpa_config_write_reg_string(hk, "proto", value);
- os_free(value);
-}
-
-
-static void write_key_mgmt(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
- return;
-
- value = wpa_config_get(ssid, "key_mgmt");
- if (value == NULL)
- return;
- if (value[0])
- wpa_config_write_reg_string(hk, "key_mgmt", value);
- os_free(value);
-}
-
-
-static void write_pairwise(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
- return;
-
- value = wpa_config_get(ssid, "pairwise");
- if (value == NULL)
- return;
- if (value[0])
- wpa_config_write_reg_string(hk, "pairwise", value);
- os_free(value);
-}
-
-
-static void write_group(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->group_cipher == DEFAULT_GROUP)
- return;
-
- value = wpa_config_get(ssid, "group");
- if (value == NULL)
- return;
- if (value[0])
- wpa_config_write_reg_string(hk, "group", value);
- os_free(value);
-}
-
-
-static void write_auth_alg(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- if (ssid->auth_alg == 0)
- return;
-
- value = wpa_config_get(ssid, "auth_alg");
- if (value == NULL)
- return;
- if (value[0])
- wpa_config_write_reg_string(hk, "auth_alg", value);
- os_free(value);
-}
-
-
-#ifdef IEEE8021X_EAPOL
-static void write_eap(HKEY hk, struct wpa_ssid *ssid)
-{
- char *value;
-
- value = wpa_config_get(ssid, "eap");
- if (value == NULL)
- return;
-
- if (value[0])
- wpa_config_write_reg_string(hk, "eap", value);
- os_free(value);
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-#ifdef CONFIG_WEP
-static void write_wep_key(HKEY hk, int idx, struct wpa_ssid *ssid)
-{
- char field[20], *value;
-
- os_snprintf(field, sizeof(field), "wep_key%d", idx);
- value = wpa_config_get(ssid, field);
- if (value) {
- wpa_config_write_reg_string(hk, field, value);
- os_free(value);
- }
-}
-#endif /* CONFIG_WEP */
-
-
-static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
-{
- int errors = 0;
- HKEY nhk, netw;
- LONG ret;
- TCHAR name[5];
-
- ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_CREATE_SUB_KEY, &nhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "WINREG: Could not open networks key "
- "for subkey addition: error 0x%x (%d)",
- (unsigned int) ret, (int) GetLastError());
- return 0;
- }
-
-#ifdef UNICODE
- wsprintf(name, L"%04d", id);
-#else /* UNICODE */
- os_snprintf(name, sizeof(name), "%04d", id);
-#endif /* UNICODE */
- ret = RegCreateKeyEx(nhk, name, 0, NULL, 0, KEY_WRITE, NULL, &netw,
- NULL);
- RegCloseKey(nhk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "WINREG: Could not add network key '%s':"
- " error 0x%x (%d)",
- name, (unsigned int) ret, (int) GetLastError());
- return -1;
- }
-
-#define STR(t) write_str(netw, #t, ssid)
-#define INT(t) write_int(netw, #t, ssid->t, 0)
-#define INTe(t, m) write_int(netw, #t, ssid->eap.m, 0)
-#define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
-#define INT_DEFe(t, m, def) write_int(netw, #t, ssid->eap.m, def)
-
- STR(ssid);
- INT(scan_ssid);
- write_bssid(netw, ssid);
- write_psk(netw, ssid);
- STR(sae_password);
- STR(sae_password_id);
- write_proto(netw, ssid);
- write_key_mgmt(netw, ssid);
- write_pairwise(netw, ssid);
- write_group(netw, ssid);
- write_auth_alg(netw, ssid);
-#ifdef IEEE8021X_EAPOL
- write_eap(netw, ssid);
- STR(identity);
- STR(anonymous_identity);
- STR(imsi_identity);
- STR(password);
- STR(ca_cert);
- STR(ca_path);
- STR(client_cert);
- STR(private_key);
- STR(private_key_passwd);
- STR(dh_file);
- STR(subject_match);
- STR(check_cert_subject);
- STR(altsubject_match);
- STR(ca_cert2);
- STR(ca_path2);
- STR(client_cert2);
- STR(private_key2);
- STR(private_key2_passwd);
- STR(dh_file2);
- STR(subject_match2);
- STR(check_cert_subject2);
- STR(altsubject_match2);
- STR(phase1);
- STR(phase2);
- STR(pcsc);
- STR(pin);
- STR(engine_id);
- STR(key_id);
- STR(cert_id);
- STR(ca_cert_id);
- STR(key2_id);
- STR(pin2);
- STR(engine2_id);
- STR(cert2_id);
- STR(ca_cert2_id);
- INTe(engine, cert.engine);
- INTe(engine2, phase2_cert.engine);
- INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_WEP
- {
- int i;
-
- for (i = 0; i < 4; i++)
- write_wep_key(netw, i, ssid);
- INT(wep_tx_keyidx);
- }
-#endif /* CONFIG_WEP */
- INT(priority);
-#ifdef IEEE8021X_EAPOL
- INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
- STR(pac_file);
- INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
-#endif /* IEEE8021X_EAPOL */
- INT(mode);
- write_int(netw, "proactive_key_caching", ssid->proactive_key_caching,
- -1);
- INT(disabled);
- write_int(netw, "ieee80211w", ssid->ieee80211w,
- MGMT_FRAME_PROTECTION_DEFAULT);
- STR(id_str);
-#ifdef CONFIG_HS20
- INT(update_identifier);
-#endif /* CONFIG_HS20 */
- INT(group_rekey);
- INT(ft_eap_pmksa_caching);
-
-#undef STR
-#undef INT
-#undef INT_DEF
-
- RegCloseKey(netw);
-
- return errors ? -1 : 0;
-}
-
-
-static int wpa_config_write_blob(HKEY hk, struct wpa_config_blob *blob)
-{
- HKEY bhk;
- LONG ret;
- TCHAR *name;
-
- ret = RegCreateKeyEx(hk, TEXT("blobs"), 0, NULL, 0, KEY_WRITE, NULL,
- &bhk, NULL);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_DEBUG, "WINREG: Could not add blobs key: "
- "error 0x%x (%d)",
- (unsigned int) ret, (int) GetLastError());
- return -1;
- }
-
- name = wpa_strdup_tchar(blob->name);
- ret = RegSetValueEx(bhk, name, 0, REG_BINARY, blob->data,
- blob->len);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "WINREG: Failed to set blob %s': "
- "error 0x%x (%d)", blob->name, (unsigned int) ret,
- (int) GetLastError());
- RegCloseKey(bhk);
- os_free(name);
- return -1;
- }
- os_free(name);
-
- RegCloseKey(bhk);
-
- return 0;
-}
-
-
-int wpa_config_write(const char *name, struct wpa_config *config)
-{
- TCHAR buf[256];
- HKEY hk;
- LONG ret;
- int errors = 0;
- struct wpa_ssid *ssid;
- struct wpa_config_blob *blob;
- int id;
-
- wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
-
-#ifdef UNICODE
- _snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
-#else /* UNICODE */
- os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
-#endif /* UNICODE */
-
- ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_SET_VALUE | DELETE, &hk);
- if (ret != ERROR_SUCCESS) {
- wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
- "configuration registry %s: error %d", buf,
- (int) GetLastError());
- return -1;
- }
-
- if (wpa_config_write_global(config, hk)) {
- wpa_printf(MSG_ERROR, "Failed to write global configuration "
- "data");
- errors++;
- }
-
- wpa_config_delete_subkeys(hk, TEXT("networks"));
- for (ssid = config->ssid, id = 0; ssid; ssid = ssid->next, id++) {
- if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
- continue; /* do not save temporary WPS networks */
- if (wpa_config_write_network(hk, ssid, id))
- errors++;
- }
-
- RegDeleteKey(hk, TEXT("blobs"));
- for (blob = config->blobs; blob; blob = blob->next) {
- if (wpa_config_write_blob(hk, blob))
- errors++;
- }
-
- RegCloseKey(hk);
-
- wpa_printf(MSG_DEBUG, "Configuration '%s' written %ssuccessfully",
- name, errors ? "un" : "");
- return errors ? -1 : 0;
-}
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
deleted file mode 100644
index bcd67fca3e12..000000000000
--- a/wpa_supplicant/ctrl_iface.c
+++ /dev/null
@@ -1,13103 +0,0 @@
-/*
- * WPA Supplicant / Control interface (shared code for all backends)
- * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#ifdef CONFIG_TESTING_OPTIONS
-#include <netinet/ip.h>
-#endif /* CONFIG_TESTING_OPTIONS */
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/uuid.h"
-#include "utils/module_tests.h"
-#include "common/version.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/wpa_ctrl.h"
-#ifdef CONFIG_DPP
-#include "common/dpp.h"
-#endif /* CONFIG_DPP */
-#include "common/ptksa_cache.h"
-#include "crypto/tls.h"
-#include "ap/hostapd.h"
-#include "eap_peer/eap.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/preauth.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "l2_packet/l2_packet.h"
-#include "wps/wps.h"
-#include "fst/fst.h"
-#include "fst/fst_ctrl_iface.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "wps_supplicant.h"
-#include "ibss_rsn.h"
-#include "wpas_glue.h"
-#include "ap.h"
-#include "p2p_supplicant.h"
-#include "p2p/p2p.h"
-#include "hs20_supplicant.h"
-#include "wifi_display.h"
-#include "notify.h"
-#include "bss.h"
-#include "scan.h"
-#include "ctrl_iface.h"
-#include "interworking.h"
-#include "bssid_ignore.h"
-#include "autoscan.h"
-#include "wnm_sta.h"
-#include "offchannel.h"
-#include "drivers/driver.h"
-#include "mesh.h"
-#include "dpp_supplicant.h"
-#include "sme.h"
-
-#ifdef __NetBSD__
-#include <net/if_ether.h>
-#elif !defined(__CYGWIN__) && !defined(CONFIG_NATIVE_WINDOWS)
-#include <net/ethernet.h>
-#endif
-
-static int wpa_supplicant_global_iface_list(struct wpa_global *global,
- char *buf, int len);
-static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
- const char *input,
- char *buf, int len);
-static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s,
- char *val);
-
-
-static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
-{
- char *pos;
- u8 addr[ETH_ALEN], *filter = NULL, *n;
- size_t count = 0;
-
- pos = val;
- while (pos) {
- if (*pos == '\0')
- break;
- if (hwaddr_aton(pos, addr)) {
- os_free(filter);
- return -1;
- }
- n = os_realloc_array(filter, count + 1, ETH_ALEN);
- if (n == NULL) {
- os_free(filter);
- return -1;
- }
- filter = n;
- os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN);
- count++;
-
- pos = os_strchr(pos, ' ');
- if (pos)
- pos++;
- }
-
- wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN);
- os_free(wpa_s->bssid_filter);
- wpa_s->bssid_filter = filter;
- wpa_s->bssid_filter_count = count;
-
- return 0;
-}
-
-
-static int set_disallow_aps(struct wpa_supplicant *wpa_s, char *val)
-{
- char *pos;
- u8 addr[ETH_ALEN], *bssid = NULL, *n;
- struct wpa_ssid_value *ssid = NULL, *ns;
- size_t count = 0, ssid_count = 0;
- struct wpa_ssid *c;
-
- /*
- * disallow_list ::= <ssid_spec> | <bssid_spec> | <disallow_list> | ""
- * SSID_SPEC ::= ssid <SSID_HEX>
- * BSSID_SPEC ::= bssid <BSSID_HEX>
- */
-
- pos = val;
- while (pos) {
- if (*pos == '\0')
- break;
- if (os_strncmp(pos, "bssid ", 6) == 0) {
- int res;
- pos += 6;
- res = hwaddr_aton2(pos, addr);
- if (res < 0) {
- os_free(ssid);
- os_free(bssid);
- wpa_printf(MSG_DEBUG, "Invalid disallow_aps "
- "BSSID value '%s'", pos);
- return -1;
- }
- pos += res;
- n = os_realloc_array(bssid, count + 1, ETH_ALEN);
- if (n == NULL) {
- os_free(ssid);
- os_free(bssid);
- return -1;
- }
- bssid = n;
- os_memcpy(bssid + count * ETH_ALEN, addr, ETH_ALEN);
- count++;
- } else if (os_strncmp(pos, "ssid ", 5) == 0) {
- char *end;
- pos += 5;
-
- end = pos;
- while (*end) {
- if (*end == '\0' || *end == ' ')
- break;
- end++;
- }
-
- ns = os_realloc_array(ssid, ssid_count + 1,
- sizeof(struct wpa_ssid_value));
- if (ns == NULL) {
- os_free(ssid);
- os_free(bssid);
- return -1;
- }
- ssid = ns;
-
- if ((end - pos) & 0x01 ||
- end - pos > 2 * SSID_MAX_LEN ||
- hexstr2bin(pos, ssid[ssid_count].ssid,
- (end - pos) / 2) < 0) {
- os_free(ssid);
- os_free(bssid);
- wpa_printf(MSG_DEBUG, "Invalid disallow_aps "
- "SSID value '%s'", pos);
- return -1;
- }
- ssid[ssid_count].ssid_len = (end - pos) / 2;
- wpa_hexdump_ascii(MSG_DEBUG, "disallow_aps SSID",
- ssid[ssid_count].ssid,
- ssid[ssid_count].ssid_len);
- ssid_count++;
- pos = end;
- } else {
- wpa_printf(MSG_DEBUG, "Unexpected disallow_aps value "
- "'%s'", pos);
- os_free(ssid);
- os_free(bssid);
- return -1;
- }
-
- pos = os_strchr(pos, ' ');
- if (pos)
- pos++;
- }
-
- wpa_hexdump(MSG_DEBUG, "disallow_aps_bssid", bssid, count * ETH_ALEN);
- os_free(wpa_s->disallow_aps_bssid);
- wpa_s->disallow_aps_bssid = bssid;
- wpa_s->disallow_aps_bssid_count = count;
-
- wpa_printf(MSG_DEBUG, "disallow_aps_ssid_count %d", (int) ssid_count);
- os_free(wpa_s->disallow_aps_ssid);
- wpa_s->disallow_aps_ssid = ssid;
- wpa_s->disallow_aps_ssid_count = ssid_count;
-
- if (!wpa_s->current_ssid || wpa_s->wpa_state < WPA_AUTHENTICATING)
- return 0;
-
- c = wpa_s->current_ssid;
- if (c->mode != WPAS_MODE_INFRA && c->mode != WPAS_MODE_IBSS)
- return 0;
-
- if (!disallowed_bssid(wpa_s, wpa_s->bssid) &&
- !disallowed_ssid(wpa_s, c->ssid, c->ssid_len))
- return 0;
-
- wpa_printf(MSG_DEBUG, "Disconnect and try to find another network "
- "because current AP was marked disallowed");
-
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- wpa_s->reassociate = 1;
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-
- return 0;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-static int wpas_ctrl_set_blob(struct wpa_supplicant *wpa_s, char *pos)
-{
- char *name = pos;
- struct wpa_config_blob *blob;
- size_t len;
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- len = os_strlen(pos);
- if (len & 1)
- return -1;
-
- wpa_printf(MSG_DEBUG, "CTRL: Set blob '%s'", name);
- blob = os_zalloc(sizeof(*blob));
- if (blob == NULL)
- return -1;
- blob->name = os_strdup(name);
- blob->data = os_malloc(len / 2);
- if (blob->name == NULL || blob->data == NULL) {
- wpa_config_free_blob(blob);
- return -1;
- }
-
- if (hexstr2bin(pos, blob->data, len / 2) < 0) {
- wpa_printf(MSG_DEBUG, "CTRL: Invalid blob hex data");
- wpa_config_free_blob(blob);
- return -1;
- }
- blob->len = len / 2;
-
- wpa_config_set_blob(wpa_s->conf, blob);
-
- return 0;
-}
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-static int wpas_ctrl_pno(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *params;
- char *pos;
- int *freqs = NULL;
- int ret;
-
- if (atoi(cmd)) {
- params = os_strchr(cmd, ' ');
- os_free(wpa_s->manual_sched_scan_freqs);
- if (params) {
- params++;
- pos = os_strstr(params, "freq=");
- if (pos)
- freqs = freq_range_to_channel_list(wpa_s,
- pos + 5);
- }
- wpa_s->manual_sched_scan_freqs = freqs;
- ret = wpas_start_pno(wpa_s);
- } else {
- ret = wpas_stop_pno(wpa_s);
- }
- return ret;
-}
-
-
-static int wpas_ctrl_set_band(struct wpa_supplicant *wpa_s, char *bands)
-{
- union wpa_event_data event;
- u32 setband_mask = WPA_SETBAND_AUTO;
-
- /*
- * For example:
- * SET setband 2G,6G
- * SET setband 5G
- * SET setband AUTO
- */
- if (!os_strstr(bands, "AUTO")) {
- if (os_strstr(bands, "5G"))
- setband_mask |= WPA_SETBAND_5G;
- if (os_strstr(bands, "6G"))
- setband_mask |= WPA_SETBAND_6G;
- if (os_strstr(bands, "2G"))
- setband_mask |= WPA_SETBAND_2G;
- if (setband_mask == WPA_SETBAND_AUTO)
- return -1;
- }
-
- wpa_s->setband_mask = setband_mask;
- if (wpa_drv_setband(wpa_s, wpa_s->setband_mask) == 0) {
- os_memset(&event, 0, sizeof(event));
- event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
- event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
- wpa_supplicant_event(wpa_s, EVENT_CHANNEL_LIST_CHANGED, &event);
- }
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_set_lci(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- struct wpabuf *lci;
-
- if (*cmd == '\0' || os_strcmp(cmd, "\"\"") == 0) {
- wpabuf_free(wpa_s->lci);
- wpa_s->lci = NULL;
- return 0;
- }
-
- lci = wpabuf_parse_bin(cmd);
- if (!lci)
- return -1;
-
- if (os_get_reltime(&wpa_s->lci_time)) {
- wpabuf_free(lci);
- return -1;
- }
-
- wpabuf_free(wpa_s->lci);
- wpa_s->lci = lci;
-
- return 0;
-}
-
-
-static int
-wpas_ctrl_set_relative_rssi(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- int relative_rssi;
-
- if (os_strcmp(cmd, "disable") == 0) {
- wpa_s->srp.relative_rssi_set = 0;
- return 0;
- }
-
- relative_rssi = atoi(cmd);
- if (relative_rssi < 0 || relative_rssi > 100)
- return -1;
- wpa_s->srp.relative_rssi = relative_rssi;
- wpa_s->srp.relative_rssi_set = 1;
- return 0;
-}
-
-
-static int wpas_ctrl_set_relative_band_adjust(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- char *pos;
- int adjust_rssi;
-
- /* <band>:adjust_value */
- pos = os_strchr(cmd, ':');
- if (!pos)
- return -1;
- pos++;
- adjust_rssi = atoi(pos);
- if (adjust_rssi < -100 || adjust_rssi > 100)
- return -1;
-
- if (os_strncmp(cmd, "2G", 2) == 0)
- wpa_s->srp.relative_adjust_band = WPA_SETBAND_2G;
- else if (os_strncmp(cmd, "5G", 2) == 0)
- wpa_s->srp.relative_adjust_band = WPA_SETBAND_5G;
- else
- return -1;
-
- wpa_s->srp.relative_adjust_rssi = adjust_rssi;
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_set_ric_ies(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- struct wpabuf *ric_ies;
-
- if (*cmd == '\0' || os_strcmp(cmd, "\"\"") == 0) {
- wpabuf_free(wpa_s->ric_ies);
- wpa_s->ric_ies = NULL;
- return 0;
- }
-
- ric_ies = wpabuf_parse_bin(cmd);
- if (!ric_ies)
- return -1;
-
- wpabuf_free(wpa_s->ric_ies);
- wpa_s->ric_ies = ric_ies;
-
- return 0;
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-static int wpas_ctrl_iface_set_dso(struct wpa_supplicant *wpa_s,
- const char *val)
-{
- u8 bssid[ETH_ALEN];
- const char *pos = val;
- struct driver_signal_override *dso = NULL, *tmp, parsed;
-
- if (hwaddr_aton(pos, bssid))
- return -1;
- pos = os_strchr(pos, ' ');
-
- dl_list_for_each(tmp, &wpa_s->drv_signal_override,
- struct driver_signal_override, list) {
- if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
- dso = tmp;
- break;
- }
- }
-
- if (!pos) {
- /* Remove existing entry */
- if (dso) {
- dl_list_del(&dso->list);
- os_free(dso);
- }
- return 0;
- }
- pos++;
-
- /* Update an existing entry or add a new one */
- os_memset(&parsed, 0, sizeof(parsed));
- if (sscanf(pos, "%d %d %d %d %d",
- &parsed.si_current_signal,
- &parsed.si_avg_signal,
- &parsed.si_avg_beacon_signal,
- &parsed.si_current_noise,
- &parsed.scan_level) != 5)
- return -1;
-
- if (!dso) {
- dso = os_zalloc(sizeof(*dso));
- if (!dso)
- return -1;
- os_memcpy(dso->bssid, bssid, ETH_ALEN);
- dl_list_add(&wpa_s->drv_signal_override, &dso->list);
- }
- dso->si_current_signal = parsed.si_current_signal;
- dso->si_avg_signal = parsed.si_avg_signal;
- dso->si_avg_beacon_signal = parsed.si_avg_beacon_signal;
- dso->si_current_noise = parsed.si_current_noise;
- dso->scan_level = parsed.scan_level;
-
- return 0;
-}
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *value;
- int ret = 0;
-
- value = os_strchr(cmd, ' ');
- if (value == NULL)
- return -1;
- *value++ = '\0';
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
- if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
- eapol_sm_configure(wpa_s->eapol,
- atoi(value), -1, -1, -1);
- } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
- eapol_sm_configure(wpa_s->eapol,
- -1, atoi(value), -1, -1);
- } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
- eapol_sm_configure(wpa_s->eapol,
- -1, -1, atoi(value), -1);
- } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
- eapol_sm_configure(wpa_s->eapol,
- -1, -1, -1, atoi(value));
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strcasecmp(cmd, "EAPOL::portControl") == 0) {
- if (os_strcmp(value, "Auto") == 0)
- eapol_sm_notify_portControl(wpa_s->eapol, Auto);
- else if (os_strcmp(value, "ForceUnauthorized") == 0)
- eapol_sm_notify_portControl(wpa_s->eapol,
- ForceUnauthorized);
- else if (os_strcmp(value, "ForceAuthorized") == 0)
- eapol_sm_notify_portControl(wpa_s->eapol,
- ForceAuthorized);
- else
- ret = -1;
-#endif /* CONFIG_TESTING_OPTIONS */
- } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
- if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
- atoi(value))) {
- ret = -1;
- } else {
- value[-1] = '=';
- wpa_config_process_global(wpa_s->conf, cmd, -1);
- }
- } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
- 0) {
- if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
- atoi(value))) {
- ret = -1;
- } else {
- value[-1] = '=';
- wpa_config_process_global(wpa_s->conf, cmd, -1);
- }
- } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
- if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
- atoi(value))) {
- ret = -1;
- } else {
- value[-1] = '=';
- wpa_config_process_global(wpa_s->conf, cmd, -1);
- }
- } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
- wpa_s->wps_fragment_size = atoi(value);
-#ifdef CONFIG_WPS_TESTING
- } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
- long int val;
- val = strtol(value, NULL, 0);
- if (val < 0 || val > 0xff) {
- ret = -1;
- wpa_printf(MSG_DEBUG, "WPS: Invalid "
- "wps_version_number %ld", val);
- } else {
- wps_version_number = val;
- wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
- "version %u.%u",
- (wps_version_number & 0xf0) >> 4,
- wps_version_number & 0x0f);
- }
- } else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
- wps_testing_stub_cred = atoi(value);
- wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
- wps_testing_stub_cred);
- } else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
- wps_corrupt_pkhash = atoi(value);
- wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
- wps_corrupt_pkhash);
- } else if (os_strcasecmp(cmd, "wps_force_auth_types") == 0) {
- if (value[0] == '\0') {
- wps_force_auth_types_in_use = 0;
- } else {
- wps_force_auth_types = strtol(value, NULL, 0);
- wps_force_auth_types_in_use = 1;
- }
- } else if (os_strcasecmp(cmd, "wps_force_encr_types") == 0) {
- if (value[0] == '\0') {
- wps_force_encr_types_in_use = 0;
- } else {
- wps_force_encr_types = strtol(value, NULL, 0);
- wps_force_encr_types_in_use = 1;
- }
-#endif /* CONFIG_WPS_TESTING */
- } else if (os_strcasecmp(cmd, "ampdu") == 0) {
- if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
- ret = -1;
-#ifdef CONFIG_TDLS
-#ifdef CONFIG_TDLS_TESTING
- } else if (os_strcasecmp(cmd, "tdls_testing") == 0) {
- tdls_testing = strtol(value, NULL, 0);
- wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing);
-#endif /* CONFIG_TDLS_TESTING */
- } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) {
- int disabled = atoi(value);
- wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled);
- if (disabled) {
- if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0)
- ret = -1;
- } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0)
- ret = -1;
- wpa_tdls_enable(wpa_s->wpa, !disabled);
-#endif /* CONFIG_TDLS */
- } else if (os_strcasecmp(cmd, "pno") == 0) {
- ret = wpas_ctrl_pno(wpa_s, value);
- } else if (os_strcasecmp(cmd, "radio_disabled") == 0) {
- int disabled = atoi(value);
- if (wpa_drv_radio_disable(wpa_s, disabled) < 0)
- ret = -1;
- else if (disabled)
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
- } else if (os_strcasecmp(cmd, "uapsd") == 0) {
- if (os_strcmp(value, "disable") == 0)
- wpa_s->set_sta_uapsd = 0;
- else {
- int be, bk, vi, vo;
- char *pos;
- /* format: BE,BK,VI,VO;max SP Length */
- be = atoi(value);
- pos = os_strchr(value, ',');
- if (pos == NULL)
- return -1;
- pos++;
- bk = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- vi = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- vo = atoi(pos);
- /* ignore max SP Length for now */
-
- wpa_s->set_sta_uapsd = 1;
- wpa_s->sta_uapsd = 0;
- if (be)
- wpa_s->sta_uapsd |= BIT(0);
- if (bk)
- wpa_s->sta_uapsd |= BIT(1);
- if (vi)
- wpa_s->sta_uapsd |= BIT(2);
- if (vo)
- wpa_s->sta_uapsd |= BIT(3);
- }
- } else if (os_strcasecmp(cmd, "ps") == 0) {
- ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
-#ifdef CONFIG_WIFI_DISPLAY
- } else if (os_strcasecmp(cmd, "wifi_display") == 0) {
- int enabled = !!atoi(value);
- if (enabled && !wpa_s->global->p2p)
- ret = -1;
- else
- wifi_display_enable(wpa_s->global, enabled);
-#endif /* CONFIG_WIFI_DISPLAY */
- } else if (os_strcasecmp(cmd, "bssid_filter") == 0) {
- ret = set_bssid_filter(wpa_s, value);
- } else if (os_strcasecmp(cmd, "disallow_aps") == 0) {
- ret = set_disallow_aps(wpa_s, value);
- } else if (os_strcasecmp(cmd, "no_keep_alive") == 0) {
- wpa_s->no_keep_alive = !!atoi(value);
-#ifdef CONFIG_DPP
- } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
- os_free(wpa_s->dpp_configurator_params);
- wpa_s->dpp_configurator_params = os_strdup(value);
- } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
- wpa_s->dpp_init_max_tries = atoi(value);
- } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
- wpa_s->dpp_init_retry_time = atoi(value);
- } else if (os_strcasecmp(cmd, "dpp_resp_wait_time") == 0) {
- wpa_s->dpp_resp_wait_time = atoi(value);
- } else if (os_strcasecmp(cmd, "dpp_resp_max_tries") == 0) {
- wpa_s->dpp_resp_max_tries = atoi(value);
- } else if (os_strcasecmp(cmd, "dpp_resp_retry_time") == 0) {
- wpa_s->dpp_resp_retry_time = atoi(value);
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strcasecmp(cmd, "dpp_pkex_own_mac_override") == 0) {
- if (hwaddr_aton(value, dpp_pkex_own_mac_override))
- ret = -1;
- } else if (os_strcasecmp(cmd, "dpp_pkex_peer_mac_override") == 0) {
- if (hwaddr_aton(value, dpp_pkex_peer_mac_override))
- ret = -1;
- } else if (os_strcasecmp(cmd, "dpp_pkex_ephemeral_key_override") == 0) {
- size_t hex_len = os_strlen(value);
-
- if (hex_len >
- 2 * sizeof(dpp_pkex_ephemeral_key_override))
- ret = -1;
- else if (hexstr2bin(value, dpp_pkex_ephemeral_key_override,
- hex_len / 2))
- ret = -1;
- else
- dpp_pkex_ephemeral_key_override_len = hex_len / 2;
- } else if (os_strcasecmp(cmd, "dpp_protocol_key_override") == 0) {
- size_t hex_len = os_strlen(value);
-
- if (hex_len > 2 * sizeof(dpp_protocol_key_override))
- ret = -1;
- else if (hexstr2bin(value, dpp_protocol_key_override,
- hex_len / 2))
- ret = -1;
- else
- dpp_protocol_key_override_len = hex_len / 2;
- } else if (os_strcasecmp(cmd, "dpp_nonce_override") == 0) {
- size_t hex_len = os_strlen(value);
-
- if (hex_len > 2 * sizeof(dpp_nonce_override))
- ret = -1;
- else if (hexstr2bin(value, dpp_nonce_override, hex_len / 2))
- ret = -1;
- else
- dpp_nonce_override_len = hex_len / 2;
- } else if (os_strcasecmp(cmd, "dpp_version_override") == 0) {
- dpp_version_override = atoi(value);
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_DPP */
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
- wpa_s->ext_mgmt_frame_handling = !!atoi(value);
- } else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
- wpa_s->ext_eapol_frame_io = !!atoi(value);
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_s->ap_iface->bss[0]->ext_eapol_frame_io =
- wpa_s->ext_eapol_frame_io;
- }
-#endif /* CONFIG_AP */
- } else if (os_strcasecmp(cmd, "extra_roc_dur") == 0) {
- wpa_s->extra_roc_dur = atoi(value);
- } else if (os_strcasecmp(cmd, "test_failure") == 0) {
- wpa_s->test_failure = atoi(value);
- } else if (os_strcasecmp(cmd, "p2p_go_csa_on_inv") == 0) {
- wpa_s->p2p_go_csa_on_inv = !!atoi(value);
- } else if (os_strcasecmp(cmd, "ignore_auth_resp") == 0) {
- wpa_s->ignore_auth_resp = !!atoi(value);
- } else if (os_strcasecmp(cmd, "ignore_assoc_disallow") == 0) {
- wpa_s->ignore_assoc_disallow = !!atoi(value);
- wpa_drv_ignore_assoc_disallow(wpa_s,
- wpa_s->ignore_assoc_disallow);
- } else if (os_strcasecmp(cmd, "disable_sa_query") == 0) {
- wpa_s->disable_sa_query = !!atoi(value);
- } else if (os_strcasecmp(cmd, "ignore_sae_h2e_only") == 0) {
- wpa_s->ignore_sae_h2e_only = !!atoi(value);
- } else if (os_strcasecmp(cmd, "extra_sae_rejected_groups") == 0) {
- char *pos;
-
- os_free(wpa_s->extra_sae_rejected_groups);
- wpa_s->extra_sae_rejected_groups = NULL;
- pos = value;
- while (pos && pos[0]) {
- int group;
-
- group = atoi(pos);
- wpa_printf(MSG_DEBUG,
- "TESTING: Extra rejection of SAE group %d",
- group);
- if (group)
- int_array_add_unique(
- &wpa_s->extra_sae_rejected_groups,
- group);
- pos = os_strchr(pos, ' ');
- if (!pos)
- break;
- pos++;
- }
- } else if (os_strcasecmp(cmd, "ft_rsnxe_used") == 0) {
- wpa_s->ft_rsnxe_used = atoi(value);
- } else if (os_strcasecmp(cmd, "oci_freq_override_eapol") == 0) {
- wpa_s->oci_freq_override_eapol = atoi(value);
- } else if (os_strcasecmp(cmd, "oci_freq_override_saquery_req") == 0) {
- wpa_s->oci_freq_override_saquery_req = atoi(value);
- } else if (os_strcasecmp(cmd, "oci_freq_override_saquery_resp") == 0) {
- wpa_s->oci_freq_override_saquery_resp = atoi(value);
- } else if (os_strcasecmp(cmd, "oci_freq_override_eapol_g2") == 0) {
- wpa_s->oci_freq_override_eapol_g2 = atoi(value);
- /* Populate value to wpa_sm if already associated. */
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_EAPOL_G2,
- wpa_s->oci_freq_override_eapol_g2);
- } else if (os_strcasecmp(cmd, "oci_freq_override_ft_assoc") == 0) {
- wpa_s->oci_freq_override_ft_assoc = atoi(value);
- /* Populate value to wpa_sm if already associated. */
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_FT_ASSOC,
- wpa_s->oci_freq_override_ft_assoc);
- } else if (os_strcasecmp(cmd, "oci_freq_override_fils_assoc") == 0) {
- wpa_s->oci_freq_override_fils_assoc = atoi(value);
- } else if (os_strcasecmp(cmd, "oci_freq_override_wnm_sleep") == 0) {
- wpa_s->oci_freq_override_wnm_sleep = atoi(value);
- } else if (os_strcasecmp(cmd, "rsne_override_eapol") == 0) {
- wpabuf_free(wpa_s->rsne_override_eapol);
- if (os_strcmp(value, "NULL") == 0)
- wpa_s->rsne_override_eapol = NULL;
- else
- wpa_s->rsne_override_eapol = wpabuf_parse_bin(value);
- } else if (os_strcasecmp(cmd, "rsnxe_override_assoc") == 0) {
- wpabuf_free(wpa_s->rsnxe_override_assoc);
- if (os_strcmp(value, "NULL") == 0)
- wpa_s->rsnxe_override_assoc = NULL;
- else
- wpa_s->rsnxe_override_assoc = wpabuf_parse_bin(value);
- } else if (os_strcasecmp(cmd, "rsnxe_override_eapol") == 0) {
- wpabuf_free(wpa_s->rsnxe_override_eapol);
- if (os_strcmp(value, "NULL") == 0)
- wpa_s->rsnxe_override_eapol = NULL;
- else
- wpa_s->rsnxe_override_eapol = wpabuf_parse_bin(value);
- } else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) {
- wpa_s->reject_btm_req_reason = atoi(value);
- } else if (os_strcasecmp(cmd, "get_pref_freq_list_override") == 0) {
- os_free(wpa_s->get_pref_freq_list_override);
- if (!value[0])
- wpa_s->get_pref_freq_list_override = NULL;
- else
- wpa_s->get_pref_freq_list_override = os_strdup(value);
- } else if (os_strcasecmp(cmd, "sae_commit_override") == 0) {
- wpabuf_free(wpa_s->sae_commit_override);
- if (value[0] == '\0')
- wpa_s->sae_commit_override = NULL;
- else
- wpa_s->sae_commit_override = wpabuf_parse_bin(value);
- } else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
- ret = wpas_ctrl_iface_set_dso(wpa_s, value);
- } else if (os_strcasecmp(cmd, "disable_scs_support") == 0) {
- wpa_s->disable_scs_support = !!atoi(value);
- } else if (os_strcasecmp(cmd, "disable_mscs_support") == 0) {
- wpa_s->disable_mscs_support = !!atoi(value);
-#ifdef CONFIG_DPP
- } else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
- os_free(wpa_s->dpp_config_obj_override);
- if (value[0] == '\0')
- wpa_s->dpp_config_obj_override = NULL;
- else
- wpa_s->dpp_config_obj_override = os_strdup(value);
- } else if (os_strcasecmp(cmd, "dpp_discovery_override") == 0) {
- os_free(wpa_s->dpp_discovery_override);
- if (value[0] == '\0')
- wpa_s->dpp_discovery_override = NULL;
- else
- wpa_s->dpp_discovery_override = os_strdup(value);
- } else if (os_strcasecmp(cmd, "dpp_groups_override") == 0) {
- os_free(wpa_s->dpp_groups_override);
- if (value[0] == '\0')
- wpa_s->dpp_groups_override = NULL;
- else
- wpa_s->dpp_groups_override = os_strdup(value);
- } else if (os_strcasecmp(cmd,
- "dpp_ignore_netaccesskey_mismatch") == 0) {
- wpa_s->dpp_ignore_netaccesskey_mismatch = atoi(value);
- } else if (os_strcasecmp(cmd, "dpp_test") == 0) {
- dpp_test = atoi(value);
-#endif /* CONFIG_DPP */
-#endif /* CONFIG_TESTING_OPTIONS */
-#ifdef CONFIG_FILS
- } else if (os_strcasecmp(cmd, "disable_fils") == 0) {
- wpa_s->disable_fils = !!atoi(value);
- wpa_drv_disable_fils(wpa_s, wpa_s->disable_fils);
- wpa_supplicant_set_default_scan_ies(wpa_s);
-#endif /* CONFIG_FILS */
-#ifndef CONFIG_NO_CONFIG_BLOBS
- } else if (os_strcmp(cmd, "blob") == 0) {
- ret = wpas_ctrl_set_blob(wpa_s, value);
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- } else if (os_strcasecmp(cmd, "setband") == 0) {
- ret = wpas_ctrl_set_band(wpa_s, value);
-#ifdef CONFIG_MBO
- } else if (os_strcasecmp(cmd, "non_pref_chan") == 0) {
- ret = wpas_mbo_update_non_pref_chan(wpa_s, value);
- if (ret == 0) {
- value[-1] = '=';
- wpa_config_process_global(wpa_s->conf, cmd, -1);
- }
- } else if (os_strcasecmp(cmd, "mbo_cell_capa") == 0) {
- wpas_mbo_update_cell_capa(wpa_s, atoi(value));
- } else if (os_strcasecmp(cmd, "oce") == 0) {
- wpa_s->conf->oce = atoi(value);
- if (wpa_s->conf->oce) {
- if ((wpa_s->conf->oce & OCE_STA) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
- wpa_s->enable_oce = OCE_STA;
-
- if ((wpa_s->conf->oce & OCE_STA_CFON) &&
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_OCE_STA_CFON)) {
- /* TODO: Need to add STA-CFON support */
- wpa_printf(MSG_ERROR,
- "OCE STA-CFON feature is not yet supported");
- return -1;
- }
- } else {
- wpa_s->enable_oce = 0;
- }
- wpa_supplicant_set_default_scan_ies(wpa_s);
-#endif /* CONFIG_MBO */
- } else if (os_strcasecmp(cmd, "lci") == 0) {
- ret = wpas_ctrl_iface_set_lci(wpa_s, value);
- } else if (os_strcasecmp(cmd, "tdls_trigger_control") == 0) {
- ret = wpa_drv_set_tdls_mode(wpa_s, atoi(value));
- } else if (os_strcasecmp(cmd, "relative_rssi") == 0) {
- ret = wpas_ctrl_set_relative_rssi(wpa_s, value);
- } else if (os_strcasecmp(cmd, "relative_band_adjust") == 0) {
- ret = wpas_ctrl_set_relative_band_adjust(wpa_s, value);
- } else if (os_strcasecmp(cmd, "ric_ies") == 0) {
- ret = wpas_ctrl_iface_set_ric_ies(wpa_s, value);
- } else if (os_strcasecmp(cmd, "roaming") == 0) {
- ret = wpa_drv_roaming(wpa_s, atoi(value), NULL);
-#ifdef CONFIG_WNM
- } else if (os_strcasecmp(cmd, "coloc_intf_elems") == 0) {
- struct wpabuf *elems;
-
- elems = wpabuf_parse_bin(value);
- if (!elems)
- return -1;
- wnm_set_coloc_intf_elems(wpa_s, elems);
-#endif /* CONFIG_WNM */
- } else if (os_strcasecmp(cmd, "enable_dscp_policy_capa") == 0) {
- wpa_s->enable_dscp_policy_capa = !!atoi(value);
- } else {
- value[-1] = '=';
- ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
- if (ret == 0)
- wpa_supplicant_update_config(wpa_s);
- else if (ret == 1)
- ret = 0;
- }
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf, size_t buflen)
-{
- int res = -1;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
-
- if (os_strcmp(cmd, "version") == 0) {
- res = os_snprintf(buf, buflen, "%s", VERSION_STR);
- } else if (os_strcasecmp(cmd, "max_command_len") == 0) {
- res = os_snprintf(buf, buflen, "%u", CTRL_IFACE_MAX_LEN);
- } else if (os_strcasecmp(cmd, "country") == 0) {
- if (wpa_s->conf->country[0] && wpa_s->conf->country[1])
- res = os_snprintf(buf, buflen, "%c%c",
- wpa_s->conf->country[0],
- wpa_s->conf->country[1]);
-#ifdef CONFIG_WIFI_DISPLAY
- } else if (os_strcasecmp(cmd, "wifi_display") == 0) {
- int enabled;
- if (wpa_s->global->p2p == NULL ||
- wpa_s->global->p2p_disabled)
- enabled = 0;
- else
- enabled = wpa_s->global->wifi_display;
- res = os_snprintf(buf, buflen, "%d", enabled);
-#endif /* CONFIG_WIFI_DISPLAY */
-#ifdef CONFIG_TESTING_GET_GTK
- } else if (os_strcmp(cmd, "gtk") == 0) {
- if (wpa_s->last_gtk_len == 0)
- return -1;
- res = wpa_snprintf_hex(buf, buflen, wpa_s->last_gtk,
- wpa_s->last_gtk_len);
- return res;
-#endif /* CONFIG_TESTING_GET_GTK */
- } else if (os_strcmp(cmd, "tls_library") == 0) {
- res = tls_get_library_version(buf, buflen);
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strcmp(cmd, "anonce") == 0) {
- return wpa_snprintf_hex(buf, buflen,
- wpa_sm_get_anonce(wpa_s->wpa),
- WPA_NONCE_LEN);
- } else if (os_strcasecmp(cmd, "last_tk_key_idx") == 0) {
- res = os_snprintf(buf, buflen, "%d", wpa_s->last_tk_key_idx);
-#endif /* CONFIG_TESTING_OPTIONS */
- } else {
- res = wpa_config_get_value(cmd, wpa_s->conf, buf, buflen);
- }
-
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
-}
-
-
-#ifdef IEEE8021X_EAPOL
-static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
- char *addr)
-{
- u8 bssid[ETH_ALEN];
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (hwaddr_aton(addr, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
- "'%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
- rsn_preauth_deinit(wpa_s->wpa);
- if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
- return -1;
-
- return 0;
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-#ifdef CONFIG_TDLS
-
-static int wpa_supplicant_ctrl_iface_tdls_discover(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 peer[ETH_ALEN];
- int ret;
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
- MAC2STR(peer));
-
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_tdls_setup(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 peer[ETH_ALEN];
- int ret;
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
- MAC2STR(peer));
-
- if ((wpa_s->conf->tdls_external_control) &&
- wpa_tdls_is_external_setup(wpa_s->wpa))
- return wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
-
- wpa_tdls_remove(wpa_s->wpa, peer);
-
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_start(wpa_s->wpa, peer);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_tdls_teardown(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 peer[ETH_ALEN];
- int ret;
-
- if (os_strcmp(addr, "*") == 0) {
- /* remove everyone */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN *");
- wpa_tdls_teardown_peers(wpa_s->wpa);
- return 0;
- }
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
- MAC2STR(peer));
-
- if ((wpa_s->conf->tdls_external_control) &&
- wpa_tdls_is_external_setup(wpa_s->wpa))
- return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
-
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_teardown_link(
- wpa_s->wpa, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
-
- return ret;
-}
-
-
-static int ctrl_iface_get_capability_tdls(
- struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
-{
- int ret;
-
- ret = os_snprintf(buf, buflen, "%s\n",
- wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT ?
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP ?
- "EXTERNAL" : "INTERNAL") : "UNSUPPORTED");
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_tdls_chan_switch(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 peer[ETH_ALEN];
- struct hostapd_freq_params freq_params;
- u8 oper_class;
- char *pos, *end;
-
- if (!wpa_tdls_is_external_setup(wpa_s->wpa)) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Only supported with external setup");
- return -1;
- }
-
- os_memset(&freq_params, 0, sizeof(freq_params));
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- oper_class = strtol(pos, &end, 10);
- if (pos == end) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Invalid op class provided");
- return -1;
- }
-
- pos = end;
- freq_params.freq = atoi(pos);
- if (freq_params.freq == 0) {
- wpa_printf(MSG_INFO, "tdls_chanswitch: Invalid freq provided");
- return -1;
- }
-
-#define SET_FREQ_SETTING(str) \
- do { \
- const char *pos2 = os_strstr(pos, " " #str "="); \
- if (pos2) { \
- pos2 += sizeof(" " #str "=") - 1; \
- freq_params.str = atoi(pos2); \
- } \
- } while (0)
-
- SET_FREQ_SETTING(center_freq1);
- SET_FREQ_SETTING(center_freq2);
- SET_FREQ_SETTING(bandwidth);
- SET_FREQ_SETTING(sec_channel_offset);
-#undef SET_FREQ_SETTING
-
- freq_params.ht_enabled = !!os_strstr(pos, " ht");
- freq_params.vht_enabled = !!os_strstr(pos, " vht");
-
- if (hwaddr_aton(cmd, peer)) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE TDLS_CHAN_SWITCH: Invalid address '%s'",
- cmd);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_CHAN_SWITCH " MACSTR
- " OP CLASS %d FREQ %d CENTER1 %d CENTER2 %d BW %d SEC_OFFSET %d%s%s",
- MAC2STR(peer), oper_class, freq_params.freq,
- freq_params.center_freq1, freq_params.center_freq2,
- freq_params.bandwidth, freq_params.sec_channel_offset,
- freq_params.ht_enabled ? " HT" : "",
- freq_params.vht_enabled ? " VHT" : "");
-
- return wpa_tdls_enable_chan_switch(wpa_s->wpa, peer, oper_class,
- &freq_params);
-}
-
-
-static int wpa_supplicant_ctrl_iface_tdls_cancel_chan_switch(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 peer[ETH_ALEN];
-
- if (!wpa_tdls_is_external_setup(wpa_s->wpa)) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Only supported with external setup");
- return -1;
- }
-
- if (hwaddr_aton(cmd, peer)) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE TDLS_CANCEL_CHAN_SWITCH: Invalid address '%s'",
- cmd);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_CANCEL_CHAN_SWITCH " MACSTR,
- MAC2STR(peer));
-
- return wpa_tdls_disable_chan_switch(wpa_s->wpa, peer);
-}
-
-
-static int wpa_supplicant_ctrl_iface_tdls_link_status(
- struct wpa_supplicant *wpa_s, const char *addr,
- char *buf, size_t buflen)
-{
- u8 peer[ETH_ALEN];
- const char *tdls_status;
- int ret;
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE TDLS_LINK_STATUS: Invalid address '%s'",
- addr);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_LINK_STATUS " MACSTR,
- MAC2STR(peer));
-
- tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_LINK_STATUS: %s", tdls_status);
- ret = os_snprintf(buf, buflen, "TDLS link status: %s\n", tdls_status);
- if (os_snprintf_error(buflen, ret))
- return -1;
-
- return ret;
-}
-
-#endif /* CONFIG_TDLS */
-
-
-static int wmm_ac_ctrl_addts(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *token, *context = NULL;
- struct wmm_ac_ts_setup_params params = {
- .tsid = 0xff,
- .direction = 0xff,
- };
-
- while ((token = str_token(cmd, " ", &context))) {
- if (sscanf(token, "tsid=%i", &params.tsid) == 1 ||
- sscanf(token, "up=%i", &params.user_priority) == 1 ||
- sscanf(token, "nominal_msdu_size=%i",
- &params.nominal_msdu_size) == 1 ||
- sscanf(token, "mean_data_rate=%i",
- &params.mean_data_rate) == 1 ||
- sscanf(token, "min_phy_rate=%i",
- &params.minimum_phy_rate) == 1 ||
- sscanf(token, "sba=%i",
- &params.surplus_bandwidth_allowance) == 1)
- continue;
-
- if (os_strcasecmp(token, "downlink") == 0) {
- params.direction = WMM_TSPEC_DIRECTION_DOWNLINK;
- } else if (os_strcasecmp(token, "uplink") == 0) {
- params.direction = WMM_TSPEC_DIRECTION_UPLINK;
- } else if (os_strcasecmp(token, "bidi") == 0) {
- params.direction = WMM_TSPEC_DIRECTION_BI_DIRECTIONAL;
- } else if (os_strcasecmp(token, "fixed_nominal_msdu") == 0) {
- params.fixed_nominal_msdu = 1;
- } else {
- wpa_printf(MSG_DEBUG,
- "CTRL: Invalid WMM_AC_ADDTS parameter: '%s'",
- token);
- return -1;
- }
-
- }
-
- return wpas_wmm_ac_addts(wpa_s, &params);
-}
-
-
-static int wmm_ac_ctrl_delts(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 tsid = atoi(cmd);
-
- return wpas_wmm_ac_delts(wpa_s, tsid);
-}
-
-
-#ifdef CONFIG_IEEE80211R
-static int wpa_supplicant_ctrl_iface_ft_ds(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 target_ap[ETH_ALEN];
- struct wpa_bss *bss;
- const u8 *mdie;
-
- if (hwaddr_aton(addr, target_ap)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
-
- bss = wpa_bss_get_bssid(wpa_s, target_ap);
- if (bss)
- mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
- else
- mdie = NULL;
-
- return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-#ifdef CONFIG_WPS
-static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- u8 bssid[ETH_ALEN], *_bssid = bssid;
-#ifdef CONFIG_P2P
- u8 p2p_dev_addr[ETH_ALEN];
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_AP
- u8 *_p2p_dev_addr = NULL;
-#endif /* CONFIG_AP */
- char *pos;
- int multi_ap = 0;
-
- if (!cmd || os_strcmp(cmd, "any") == 0 ||
- os_strncmp(cmd, "any ", 4) == 0) {
- _bssid = NULL;
-#ifdef CONFIG_P2P
- } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
- if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
- "P2P Device Address '%s'",
- cmd + 13);
- return -1;
- }
- _p2p_dev_addr = p2p_dev_addr;
-#endif /* CONFIG_P2P */
- } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
- _bssid = NULL;
- multi_ap = atoi(cmd + 9);
- } else if (hwaddr_aton(cmd, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
- cmd);
- return -1;
- }
-
- if (cmd) {
- pos = os_strstr(cmd, " multi_ap=");
- if (pos) {
- pos += 10;
- multi_ap = atoi(pos);
- }
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface)
- return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
-#endif /* CONFIG_AP */
-
- return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf,
- size_t buflen)
-{
- u8 bssid[ETH_ALEN], *_bssid = bssid;
- char *pin;
- int ret;
-
- pin = os_strchr(cmd, ' ');
- if (pin)
- *pin++ = '\0';
-
- if (os_strcmp(cmd, "any") == 0)
- _bssid = NULL;
- else if (os_strcmp(cmd, "get") == 0) {
- if (wps_generate_pin((unsigned int *) &ret) < 0)
- return -1;
- goto done;
- } else if (hwaddr_aton(cmd, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
- cmd);
- return -1;
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- int timeout = 0;
- char *pos;
-
- if (pin) {
- pos = os_strchr(pin, ' ');
- if (pos) {
- *pos++ = '\0';
- timeout = atoi(pos);
- }
- }
-
- return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
- buf, buflen, timeout);
- }
-#endif /* CONFIG_AP */
-
- if (pin) {
- ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
- DEV_PW_DEFAULT);
- if (ret < 0)
- return -1;
- ret = os_snprintf(buf, buflen, "%s", pin);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
- }
-
- ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
- if (ret < 0)
- return -1;
-
-done:
- /* Return the generated PIN */
- ret = os_snprintf(buf, buflen, "%08d", ret);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_check_pin(
- struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
-{
- char pin[9];
- size_t len;
- char *pos;
- int ret;
-
- wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
- (u8 *) cmd, os_strlen(cmd));
- for (pos = cmd, len = 0; *pos != '\0'; pos++) {
- if (*pos < '0' || *pos > '9')
- continue;
- pin[len++] = *pos;
- if (len == 9) {
- wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
- return -1;
- }
- }
- if (len != 4 && len != 8) {
- wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
- return -1;
- }
- pin[len] = '\0';
-
- if (len == 8) {
- unsigned int pin_val;
- pin_val = atoi(pin);
- if (!wps_pin_valid(pin_val)) {
- wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
- ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
- }
- }
-
- ret = os_snprintf(buf, buflen, "%s", pin);
- if (os_snprintf_error(buflen, ret))
- return -1;
-
- return ret;
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- u8 bssid[ETH_ALEN], *_bssid = bssid;
-
- if (cmd == NULL || cmd[0] == '\0')
- _bssid = NULL;
- else if (hwaddr_aton(cmd, bssid))
- return -1;
-
- return wpas_wps_start_nfc(wpa_s, NULL, _bssid, NULL, 0, 0, NULL, NULL,
- 0, 0);
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
- struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
-{
- int ndef;
- struct wpabuf *buf;
- int res;
- char *pos;
-
- pos = os_strchr(cmd, ' ');
- if (pos)
- *pos++ = '\0';
- if (os_strcmp(cmd, "WPS") == 0)
- ndef = 0;
- else if (os_strcmp(cmd, "NDEF") == 0)
- ndef = 1;
- else
- return -1;
-
- buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_nfc_token(
- struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
-{
- int ndef;
- struct wpabuf *buf;
- int res;
-
- if (os_strcmp(cmd, "WPS") == 0)
- ndef = 0;
- else if (os_strcmp(cmd, "NDEF") == 0)
- ndef = 1;
- else
- return -1;
-
- buf = wpas_wps_nfc_token(wpa_s, ndef);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read(
- struct wpa_supplicant *wpa_s, char *pos)
-{
- size_t len;
- struct wpabuf *buf;
- int ret;
- char *freq;
- int forced_freq = 0;
-
- freq = strstr(pos, " freq=");
- if (freq) {
- *freq = '\0';
- freq += 6;
- forced_freq = atoi(freq);
- }
-
- len = os_strlen(pos);
- if (len & 0x01)
- return -1;
- len /= 2;
-
- buf = wpabuf_alloc(len);
- if (buf == NULL)
- return -1;
- if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
- wpabuf_free(buf);
- return -1;
- }
-
- ret = wpas_wps_nfc_tag_read(wpa_s, buf, forced_freq);
- wpabuf_free(buf);
-
- return ret;
-}
-
-
-static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s,
- char *reply, size_t max_len,
- int ndef)
-{
- struct wpabuf *buf;
- int res;
-
- buf = wpas_wps_nfc_handover_req(wpa_s, ndef);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-
-
-#ifdef CONFIG_P2P
-static int wpas_ctrl_nfc_get_handover_req_p2p(struct wpa_supplicant *wpa_s,
- char *reply, size_t max_len,
- int ndef)
-{
- struct wpabuf *buf;
- int res;
-
- buf = wpas_p2p_nfc_handover_req(wpa_s, ndef);
- if (buf == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Could not generate NFC handover request");
- return -1;
- }
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-#endif /* CONFIG_P2P */
-
-
-static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
- char *cmd, char *reply,
- size_t max_len)
-{
- char *pos;
- int ndef;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "WPS") == 0)
- ndef = 0;
- else if (os_strcmp(cmd, "NDEF") == 0)
- ndef = 1;
- else
- return -1;
-
- if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
- if (!ndef)
- return -1;
- return wpas_ctrl_nfc_get_handover_req_wps(
- wpa_s, reply, max_len, ndef);
- }
-
-#ifdef CONFIG_P2P
- if (os_strcmp(pos, "P2P-CR") == 0) {
- return wpas_ctrl_nfc_get_handover_req_p2p(
- wpa_s, reply, max_len, ndef);
- }
-#endif /* CONFIG_P2P */
-
- return -1;
-}
-
-
-static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
- char *reply, size_t max_len,
- int ndef, int cr, char *uuid)
-{
- struct wpabuf *buf;
- int res;
-
- buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-
-
-#ifdef CONFIG_P2P
-static int wpas_ctrl_nfc_get_handover_sel_p2p(struct wpa_supplicant *wpa_s,
- char *reply, size_t max_len,
- int ndef, int tag)
-{
- struct wpabuf *buf;
- int res;
-
- buf = wpas_p2p_nfc_handover_sel(wpa_s, ndef, tag);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-#endif /* CONFIG_P2P */
-
-
-static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
- char *cmd, char *reply,
- size_t max_len)
-{
- char *pos, *pos2;
- int ndef;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "WPS") == 0)
- ndef = 0;
- else if (os_strcmp(cmd, "NDEF") == 0)
- ndef = 1;
- else
- return -1;
-
- pos2 = os_strchr(pos, ' ');
- if (pos2)
- *pos2++ = '\0';
- if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
- if (!ndef)
- return -1;
- return wpas_ctrl_nfc_get_handover_sel_wps(
- wpa_s, reply, max_len, ndef,
- os_strcmp(pos, "WPS-CR") == 0, pos2);
- }
-
-#ifdef CONFIG_P2P
- if (os_strcmp(pos, "P2P-CR") == 0) {
- return wpas_ctrl_nfc_get_handover_sel_p2p(
- wpa_s, reply, max_len, ndef, 0);
- }
-
- if (os_strcmp(pos, "P2P-CR-TAG") == 0) {
- return wpas_ctrl_nfc_get_handover_sel_p2p(
- wpa_s, reply, max_len, ndef, 1);
- }
-#endif /* CONFIG_P2P */
-
- return -1;
-}
-
-
-static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- size_t len;
- struct wpabuf *req, *sel;
- int ret;
- char *pos, *role, *type, *pos2;
-#ifdef CONFIG_P2P
- char *freq;
- int forced_freq = 0;
-
- freq = strstr(cmd, " freq=");
- if (freq) {
- *freq = '\0';
- freq += 6;
- forced_freq = atoi(freq);
- }
-#endif /* CONFIG_P2P */
-
- role = cmd;
- pos = os_strchr(role, ' ');
- if (pos == NULL) {
- wpa_printf(MSG_DEBUG, "NFC: Missing type in handover report");
- return -1;
- }
- *pos++ = '\0';
-
- type = pos;
- pos = os_strchr(type, ' ');
- if (pos == NULL) {
- wpa_printf(MSG_DEBUG, "NFC: Missing request message in handover report");
- return -1;
- }
- *pos++ = '\0';
-
- pos2 = os_strchr(pos, ' ');
- if (pos2 == NULL) {
- wpa_printf(MSG_DEBUG, "NFC: Missing select message in handover report");
- return -1;
- }
- *pos2++ = '\0';
-
- len = os_strlen(pos);
- if (len & 0x01) {
- wpa_printf(MSG_DEBUG, "NFC: Invalid request message length in handover report");
- return -1;
- }
- len /= 2;
-
- req = wpabuf_alloc(len);
- if (req == NULL) {
- wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for request message");
- return -1;
- }
- if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) {
- wpa_printf(MSG_DEBUG, "NFC: Invalid request message hexdump in handover report");
- wpabuf_free(req);
- return -1;
- }
-
- len = os_strlen(pos2);
- if (len & 0x01) {
- wpa_printf(MSG_DEBUG, "NFC: Invalid select message length in handover report");
- wpabuf_free(req);
- return -1;
- }
- len /= 2;
-
- sel = wpabuf_alloc(len);
- if (sel == NULL) {
- wpa_printf(MSG_DEBUG, "NFC: Failed to allocate memory for select message");
- wpabuf_free(req);
- return -1;
- }
- if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) {
- wpa_printf(MSG_DEBUG, "NFC: Invalid select message hexdump in handover report");
- wpabuf_free(req);
- wpabuf_free(sel);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "NFC: Connection handover reported - role=%s type=%s req_len=%d sel_len=%d",
- role, type, (int) wpabuf_len(req), (int) wpabuf_len(sel));
-
- if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) {
- ret = wpas_wps_nfc_report_handover(wpa_s, req, sel);
-#ifdef CONFIG_AP
- } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "WPS") == 0)
- {
- ret = wpas_ap_wps_nfc_report_handover(wpa_s, req, sel);
- if (ret < 0)
- ret = wpas_er_wps_nfc_report_handover(wpa_s, req, sel);
-#endif /* CONFIG_AP */
-#ifdef CONFIG_P2P
- } else if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "P2P") == 0)
- {
- ret = wpas_p2p_nfc_report_handover(wpa_s, 1, req, sel, 0);
- } else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "P2P") == 0)
- {
- ret = wpas_p2p_nfc_report_handover(wpa_s, 0, req, sel,
- forced_freq);
-#endif /* CONFIG_P2P */
- } else {
- wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover "
- "reported: role=%s type=%s", role, type);
- ret = -1;
- }
- wpabuf_free(req);
- wpabuf_free(sel);
-
- if (ret)
- wpa_printf(MSG_DEBUG, "NFC: Failed to process reported handover messages");
-
- return ret;
-}
-
-#endif /* CONFIG_WPS_NFC */
-
-
-static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- u8 bssid[ETH_ALEN];
- char *pin;
- char *new_ssid;
- char *new_auth;
- char *new_encr;
- char *new_key;
- struct wps_new_ap_settings ap;
-
- pin = os_strchr(cmd, ' ');
- if (pin == NULL)
- return -1;
- *pin++ = '\0';
-
- if (hwaddr_aton(cmd, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
- cmd);
- return -1;
- }
-
- new_ssid = os_strchr(pin, ' ');
- if (new_ssid == NULL)
- return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
- *new_ssid++ = '\0';
-
- new_auth = os_strchr(new_ssid, ' ');
- if (new_auth == NULL)
- return -1;
- *new_auth++ = '\0';
-
- new_encr = os_strchr(new_auth, ' ');
- if (new_encr == NULL)
- return -1;
- *new_encr++ = '\0';
-
- new_key = os_strchr(new_encr, ' ');
- if (new_key == NULL)
- return -1;
- *new_key++ = '\0';
-
- os_memset(&ap, 0, sizeof(ap));
- ap.ssid_hex = new_ssid;
- ap.auth = new_auth;
- ap.encr = new_encr;
- ap.key_hex = new_key;
- return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
-}
-
-
-#ifdef CONFIG_AP
-static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf,
- size_t buflen)
-{
- int timeout = 300;
- char *pos;
- const char *pin_txt;
-
- if (!wpa_s->ap_iface)
- return -1;
-
- pos = os_strchr(cmd, ' ');
- if (pos)
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "disable") == 0) {
- wpas_wps_ap_pin_disable(wpa_s);
- return os_snprintf(buf, buflen, "OK\n");
- }
-
- if (os_strcmp(cmd, "random") == 0) {
- if (pos)
- timeout = atoi(pos);
- pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
- if (pin_txt == NULL)
- return -1;
- return os_snprintf(buf, buflen, "%s", pin_txt);
- }
-
- if (os_strcmp(cmd, "get") == 0) {
- pin_txt = wpas_wps_ap_pin_get(wpa_s);
- if (pin_txt == NULL)
- return -1;
- return os_snprintf(buf, buflen, "%s", pin_txt);
- }
-
- if (os_strcmp(cmd, "set") == 0) {
- char *pin;
- if (pos == NULL)
- return -1;
- pin = pos;
- pos = os_strchr(pos, ' ');
- if (pos) {
- *pos++ = '\0';
- timeout = atoi(pos);
- }
- if (os_strlen(pin) > buflen)
- return -1;
- if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
- return -1;
- return os_snprintf(buf, buflen, "%s", pin);
- }
-
- return -1;
-}
-#endif /* CONFIG_AP */
-
-
-#ifdef CONFIG_WPS_ER
-static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *uuid = cmd, *pin, *pos;
- u8 addr_buf[ETH_ALEN], *addr = NULL;
- pin = os_strchr(uuid, ' ');
- if (pin == NULL)
- return -1;
- *pin++ = '\0';
- pos = os_strchr(pin, ' ');
- if (pos) {
- *pos++ = '\0';
- if (hwaddr_aton(pos, addr_buf) == 0)
- addr = addr_buf;
- }
- return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *uuid = cmd, *pin;
- pin = os_strchr(uuid, ' ');
- if (pin == NULL)
- return -1;
- *pin++ = '\0';
- return wpas_wps_er_learn(wpa_s, uuid, pin);
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_er_set_config(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *uuid = cmd, *id;
- id = os_strchr(uuid, ' ');
- if (id == NULL)
- return -1;
- *id++ = '\0';
- return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
-}
-
-
-static int wpa_supplicant_ctrl_iface_wps_er_config(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pin;
- char *new_ssid;
- char *new_auth;
- char *new_encr;
- char *new_key;
- struct wps_new_ap_settings ap;
-
- pin = os_strchr(cmd, ' ');
- if (pin == NULL)
- return -1;
- *pin++ = '\0';
-
- new_ssid = os_strchr(pin, ' ');
- if (new_ssid == NULL)
- return -1;
- *new_ssid++ = '\0';
-
- new_auth = os_strchr(new_ssid, ' ');
- if (new_auth == NULL)
- return -1;
- *new_auth++ = '\0';
-
- new_encr = os_strchr(new_auth, ' ');
- if (new_encr == NULL)
- return -1;
- *new_encr++ = '\0';
-
- new_key = os_strchr(new_encr, ' ');
- if (new_key == NULL)
- return -1;
- *new_key++ = '\0';
-
- os_memset(&ap, 0, sizeof(ap));
- ap.ssid_hex = new_ssid;
- ap.auth = new_auth;
- ap.encr = new_encr;
- ap.key_hex = new_key;
- return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
-}
-
-
-#ifdef CONFIG_WPS_NFC
-static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
- struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
-{
- int ndef;
- struct wpabuf *buf;
- int res;
- char *uuid;
-
- uuid = os_strchr(cmd, ' ');
- if (uuid == NULL)
- return -1;
- *uuid++ = '\0';
-
- if (os_strcmp(cmd, "WPS") == 0)
- ndef = 0;
- else if (os_strcmp(cmd, "NDEF") == 0)
- ndef = 1;
- else
- return -1;
-
- buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid);
- if (buf == NULL)
- return -1;
-
- res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
- wpabuf_len(buf));
- reply[res++] = '\n';
- reply[res] = '\0';
-
- wpabuf_free(buf);
-
- return res;
-}
-#endif /* CONFIG_WPS_NFC */
-#endif /* CONFIG_WPS_ER */
-
-#endif /* CONFIG_WPS */
-
-
-#ifdef CONFIG_IBSS_RSN
-static int wpa_supplicant_ctrl_iface_ibss_rsn(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 peer[ETH_ALEN];
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
- MAC2STR(peer));
-
- return ibss_rsn_start(wpa_s->ibss_rsn, peer);
-}
-#endif /* CONFIG_IBSS_RSN */
-
-
-static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
- char *rsp)
-{
-#ifdef IEEE8021X_EAPOL
- char *pos, *id_pos;
- int id;
- struct wpa_ssid *ssid;
-
- pos = os_strchr(rsp, '-');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- id_pos = pos;
- pos = os_strchr(pos, ':');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- id = atoi(id_pos);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
- wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
- (u8 *) pos, os_strlen(pos));
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
- "to update", id);
- return -1;
- }
-
- return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp,
- pos);
-#else /* IEEE8021X_EAPOL */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
- return -1;
-#endif /* IEEE8021X_EAPOL */
-}
-
-
-static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
- const char *params,
- char *buf, size_t buflen)
-{
- char *pos, *end, tmp[30];
- int res, verbose, wps, ret;
-#ifdef CONFIG_HS20
- const u8 *hs20;
-#endif /* CONFIG_HS20 */
- const u8 *sess_id;
- size_t sess_id_len;
-
- if (os_strcmp(params, "-DRIVER") == 0)
- return wpa_drv_status(wpa_s, buf, buflen);
- verbose = os_strcmp(params, "-VERBOSE") == 0;
- wps = os_strcmp(params, "-WPS") == 0;
- pos = buf;
- end = buf + buflen;
- if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
- MAC2STR(wpa_s->bssid));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- ret = os_snprintf(pos, end - pos, "freq=%u\n",
- wpa_s->assoc_freq);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- if (ssid) {
- u8 *_ssid = ssid->ssid;
- size_t ssid_len = ssid->ssid_len;
- u8 ssid_buf[SSID_MAX_LEN];
- if (ssid_len == 0) {
- int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
- if (_res < 0)
- ssid_len = 0;
- else
- ssid_len = _res;
- _ssid = ssid_buf;
- }
- ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
- wpa_ssid_txt(_ssid, ssid_len),
- ssid->id);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- if (wps && ssid->passphrase &&
- wpa_key_mgmt_wpa_psk(ssid->key_mgmt) &&
- (ssid->mode == WPAS_MODE_AP ||
- ssid->mode == WPAS_MODE_P2P_GO)) {
- ret = os_snprintf(pos, end - pos,
- "passphrase=%s\n",
- ssid->passphrase);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- if (ssid->id_str) {
- ret = os_snprintf(pos, end - pos,
- "id_str=%s\n",
- ssid->id_str);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- switch (ssid->mode) {
- case WPAS_MODE_INFRA:
- ret = os_snprintf(pos, end - pos,
- "mode=station\n");
- break;
- case WPAS_MODE_IBSS:
- ret = os_snprintf(pos, end - pos,
- "mode=IBSS\n");
- break;
- case WPAS_MODE_AP:
- ret = os_snprintf(pos, end - pos,
- "mode=AP\n");
- break;
- case WPAS_MODE_P2P_GO:
- ret = os_snprintf(pos, end - pos,
- "mode=P2P GO\n");
- break;
- case WPAS_MODE_P2P_GROUP_FORMATION:
- ret = os_snprintf(pos, end - pos,
- "mode=P2P GO - group "
- "formation\n");
- break;
- case WPAS_MODE_MESH:
- ret = os_snprintf(pos, end - pos,
- "mode=mesh\n");
- break;
- default:
- ret = 0;
- break;
- }
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (wpa_s->connection_set &&
- (wpa_s->connection_ht || wpa_s->connection_vht ||
- wpa_s->connection_he)) {
- ret = os_snprintf(pos, end - pos,
- "wifi_generation=%u\n",
- wpa_s->connection_he ? 6 :
- (wpa_s->connection_vht ? 5 : 4));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
- end - pos,
- verbose);
- } else
-#endif /* CONFIG_AP */
- pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
- }
-#ifdef CONFIG_SME
-#ifdef CONFIG_SAE
- if (wpa_s->wpa_state >= WPA_ASSOCIATED &&
-#ifdef CONFIG_AP
- !wpa_s->ap_iface &&
-#endif /* CONFIG_AP */
- wpa_s->sme.sae.state == SAE_ACCEPTED) {
- ret = os_snprintf(pos, end - pos, "sae_group=%d\n"
- "sae_h2e=%d\n"
- "sae_pk=%d\n",
- wpa_s->sme.sae.group,
- wpa_s->sme.sae.h2e,
- wpa_s->sme.sae.pk);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SAE */
-#endif /* CONFIG_SME */
- ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
- wpa_supplicant_state_txt(wpa_s->wpa_state));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- if (wpa_s->l2 &&
- l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
- ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p) {
- ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
- "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_P2P */
-
- ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
- MAC2STR(wpa_s->own_addr));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
-#ifdef CONFIG_HS20
- if (wpa_s->current_bss &&
- (hs20 = wpa_bss_get_vendor_ie(wpa_s->current_bss,
- HS20_IE_VENDOR_TYPE)) &&
- wpa_s->wpa_proto == WPA_PROTO_RSN &&
- wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
- int release = 1;
- if (hs20[1] >= 5) {
- u8 rel_num = (hs20[6] & 0xf0) >> 4;
- release = rel_num + 1;
- }
- ret = os_snprintf(pos, end - pos, "hs20=%d\n", release);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (wpa_s->current_ssid) {
- struct wpa_cred *cred;
- char *type;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- size_t i;
-
- if (wpa_s->current_ssid->parent_cred != cred)
- continue;
-
- if (cred->provisioning_sp) {
- ret = os_snprintf(pos, end - pos,
- "provisioning_sp=%s\n",
- cred->provisioning_sp);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (!cred->domain)
- goto no_domain;
-
- i = 0;
- if (wpa_s->current_bss && wpa_s->current_bss->anqp) {
- struct wpabuf *names =
- wpa_s->current_bss->anqp->domain_name;
- for (i = 0; names && i < cred->num_domain; i++)
- {
- if (domain_name_list_contains(
- names, cred->domain[i], 1))
- break;
- }
- if (i == cred->num_domain)
- i = 0; /* show first entry by default */
- }
- ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
- cred->domain[i]);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- no_domain:
- if (wpa_s->current_bss == NULL ||
- wpa_s->current_bss->anqp == NULL)
- res = -1;
- else
- res = interworking_home_sp_cred(
- wpa_s, cred,
- wpa_s->current_bss->anqp->domain_name);
- if (res > 0)
- type = "home";
- else if (res == 0)
- type = "roaming";
- else
- type = "unknown";
-
- ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- break;
- }
- }
-#endif /* CONFIG_HS20 */
-
- if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
- verbose);
- if (res >= 0)
- pos += res;
- }
-
-#ifdef CONFIG_MACSEC
- res = ieee802_1x_kay_get_status(wpa_s->kay, pos, end - pos);
- if (res > 0)
- pos += res;
-#endif /* CONFIG_MACSEC */
-
- sess_id = eapol_sm_get_session_id(wpa_s->eapol, &sess_id_len);
- if (sess_id) {
- char *start = pos;
-
- ret = os_snprintf(pos, end - pos, "eap_session_id=");
- if (os_snprintf_error(end - pos, ret))
- return start - buf;
- pos += ret;
- ret = wpa_snprintf_hex(pos, end - pos, sess_id, sess_id_len);
- if (ret <= 0)
- return start - buf;
- pos += ret;
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return start - buf;
- pos += ret;
- }
-
- res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
- if (res >= 0)
- pos += res;
-
-#ifdef CONFIG_WPS
- {
- char uuid_str[100];
- uuid_bin2str(wpa_s->wps->uuid, uuid_str, sizeof(uuid_str));
- ret = os_snprintf(pos, end - pos, "uuid=%s\n", uuid_str);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_WPS */
-
- if (wpa_s->ieee80211ac) {
- ret = os_snprintf(pos, end - pos, "ieee80211ac=1\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef ANDROID
- /*
- * Allow using the STATUS command with default behavior, say for debug,
- * i.e., don't generate a "fake" CONNECTION and SUPPLICANT_STATE_CHANGE
- * events with STATUS-NO_EVENTS.
- */
- if (os_strcmp(params, "-NO_EVENTS")) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
- "id=%d state=%d BSSID=" MACSTR " SSID=%s",
- wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
- wpa_s->wpa_state,
- MAC2STR(wpa_s->bssid),
- wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
- wpa_ssid_txt(wpa_s->current_ssid->ssid,
- wpa_s->current_ssid->ssid_len) : "");
- if (wpa_s->wpa_state == WPA_COMPLETED) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED
- "- connection to " MACSTR
- " completed %s [id=%d id_str=%s]",
- MAC2STR(wpa_s->bssid), "(auth)",
- ssid ? ssid->id : -1,
- ssid && ssid->id_str ? ssid->id_str : "");
- }
- }
-#endif /* ANDROID */
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *pos;
- int id;
- struct wpa_ssid *ssid;
- u8 bssid[ETH_ALEN];
-
- /* cmd: "<network id> <BSSID>" */
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
- if (hwaddr_aton(pos, bssid)) {
- wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
- return -1;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
- "to update", id);
- return -1;
- }
-
- os_memcpy(ssid->bssid, bssid, ETH_ALEN);
- ssid->bssid_set = !is_zero_ether_addr(bssid);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_bssid_ignore(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf,
- size_t buflen)
-{
- u8 bssid[ETH_ALEN];
- struct wpa_bssid_ignore *e;
- char *pos, *end;
- int ret;
-
- /* cmd: "BSSID_IGNORE [<BSSID>]" */
- if (*cmd == '\0') {
- pos = buf;
- end = buf + buflen;
- e = wpa_s->bssid_ignore;
- while (e) {
- ret = os_snprintf(pos, end - pos, MACSTR "\n",
- MAC2STR(e->bssid));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- e = e->next;
- }
- return pos - buf;
- }
-
- cmd++;
- if (os_strncmp(cmd, "clear", 5) == 0) {
- wpa_bssid_ignore_clear(wpa_s);
- os_memcpy(buf, "OK\n", 3);
- return 3;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: BSSID_IGNORE bssid='%s'", cmd);
- if (hwaddr_aton(cmd, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
- return -1;
- }
-
- /*
- * Add the BSSID twice, so its count will be 2, causing it to be
- * skipped when processing scan results.
- */
- ret = wpa_bssid_ignore_add(wpa_s, bssid);
- if (ret < 0)
- return -1;
- ret = wpa_bssid_ignore_add(wpa_s, bssid);
- if (ret < 0)
- return -1;
- os_memcpy(buf, "OK\n", 3);
- return 3;
-}
-
-
-static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf,
- size_t buflen)
-{
- char *pos, *end, *stamp;
- int ret;
-
- /* cmd: "LOG_LEVEL [<level>]" */
- if (*cmd == '\0') {
- pos = buf;
- end = buf + buflen;
- ret = os_snprintf(pos, end - pos, "Current level: %s\n"
- "Timestamp: %d\n",
- debug_level_str(wpa_debug_level),
- wpa_debug_timestamp);
- if (os_snprintf_error(end - pos, ret))
- ret = 0;
-
- return ret;
- }
-
- while (*cmd == ' ')
- cmd++;
-
- stamp = os_strchr(cmd, ' ');
- if (stamp) {
- *stamp++ = '\0';
- while (*stamp == ' ') {
- stamp++;
- }
- }
-
- if (os_strlen(cmd)) {
- int level = str_to_debug_level(cmd);
- if (level < 0)
- return -1;
- wpa_debug_level = level;
- }
-
- if (stamp && os_strlen(stamp))
- wpa_debug_timestamp = atoi(stamp);
-
- os_memcpy(buf, "OK\n", 3);
- return 3;
-}
-
-
-static int wpa_supplicant_ctrl_iface_list_networks(
- struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
-{
- char *pos, *end, *prev;
- struct wpa_ssid *ssid;
- int ret;
-
- pos = buf;
- end = buf + buflen;
- ret = os_snprintf(pos, end - pos,
- "network id / ssid / bssid / flags\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- ssid = wpa_s->conf->ssid;
-
- /* skip over ssids until we find next one */
- if (cmd != NULL && os_strncmp(cmd, "LAST_ID=", 8) == 0) {
- int last_id = atoi(cmd + 8);
- if (last_id != -1) {
- while (ssid != NULL && ssid->id <= last_id) {
- ssid = ssid->next;
- }
- }
- }
-
- while (ssid) {
- prev = pos;
- ret = os_snprintf(pos, end - pos, "%d\t%s",
- ssid->id,
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- if (os_snprintf_error(end - pos, ret))
- return prev - buf;
- pos += ret;
- if (ssid->bssid_set) {
- ret = os_snprintf(pos, end - pos, "\t" MACSTR,
- MAC2STR(ssid->bssid));
- } else {
- ret = os_snprintf(pos, end - pos, "\tany");
- }
- if (os_snprintf_error(end - pos, ret))
- return prev - buf;
- pos += ret;
- ret = os_snprintf(pos, end - pos, "\t%s%s%s%s",
- ssid == wpa_s->current_ssid ?
- "[CURRENT]" : "",
- ssid->disabled ? "[DISABLED]" : "",
- ssid->disabled_until.sec ?
- "[TEMP-DISABLED]" : "",
- ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
- "");
- if (os_snprintf_error(end - pos, ret))
- return prev - buf;
- pos += ret;
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return prev - buf;
- pos += ret;
-
- ssid = ssid->next;
- }
-
- return pos - buf;
-}
-
-
-static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
-{
- int ret;
- ret = os_snprintf(pos, end - pos, "-");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- ret = wpa_write_ciphers(pos, end, cipher, "+");
- if (ret < 0)
- return pos;
- pos += ret;
- return pos;
-}
-
-
-static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
- const u8 *ie, size_t ie_len)
-{
- struct wpa_ie_data data;
- char *start;
- int ret;
-
- ret = os_snprintf(pos, end - pos, "[%s-", proto);
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
-
- if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
- ret = os_snprintf(pos, end - pos, "?]");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- return pos;
- }
-
- start = pos;
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
- ret = os_snprintf(pos, end - pos, "%sEAP",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
- ret = os_snprintf(pos, end - pos, "%sPSK",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
- ret = os_snprintf(pos, end - pos, "%sNone",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_SAE) {
- ret = os_snprintf(pos, end - pos, "%sSAE",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#ifdef CONFIG_IEEE80211R
- if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
- ret = os_snprintf(pos, end - pos, "%sFT/EAP",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
- ret = os_snprintf(pos, end - pos, "%sFT/PSK",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE) {
- ret = os_snprintf(pos, end - pos, "%sFT/SAE",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_IEEE80211R */
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-
-#ifdef CONFIG_SUITEB
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
- ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_SUITEB */
-
-#ifdef CONFIG_SUITEB192
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
- ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B-192",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_SUITEB192 */
-
-#ifdef CONFIG_FILS
- if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sFILS-SHA256",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, "%sFILS-SHA384",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#ifdef CONFIG_IEEE80211R
- if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA256",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
- if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA384",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_OWE
- if (data.key_mgmt & WPA_KEY_MGMT_OWE) {
- ret = os_snprintf(pos, end - pos, "%sOWE",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_DPP
- if (data.key_mgmt & WPA_KEY_MGMT_DPP) {
- ret = os_snprintf(pos, end - pos, "%sDPP",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-#endif /* CONFIG_DPP */
-
- if (data.key_mgmt & WPA_KEY_MGMT_OSEN) {
- ret = os_snprintf(pos, end - pos, "%sOSEN",
- pos == start ? "" : "+");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-
- pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
-
- if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
- ret = os_snprintf(pos, end - pos, "-preauth");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "]");
- if (os_snprintf_error(end - pos, ret))
- return pos;
- pos += ret;
-
- return pos;
-}
-
-
-#ifdef CONFIG_WPS
-static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
- char *pos, char *end,
- struct wpabuf *wps_ie)
-{
- int ret;
- const char *txt;
-
- if (wps_ie == NULL)
- return pos;
- if (wps_is_selected_pbc_registrar(wps_ie))
- txt = "[WPS-PBC]";
- else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
- txt = "[WPS-AUTH]";
- else if (wps_is_selected_pin_registrar(wps_ie))
- txt = "[WPS-PIN]";
- else
- txt = "[WPS]";
-
- ret = os_snprintf(pos, end - pos, "%s", txt);
- if (!os_snprintf_error(end - pos, ret))
- pos += ret;
- wpabuf_free(wps_ie);
- return pos;
-}
-#endif /* CONFIG_WPS */
-
-
-static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
- char *pos, char *end,
- const struct wpa_bss *bss)
-{
-#ifdef CONFIG_WPS
- struct wpabuf *wps_ie;
- wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
-#else /* CONFIG_WPS */
- return pos;
-#endif /* CONFIG_WPS */
-}
-
-
-/* Format one result on one text line into a buffer. */
-static int wpa_supplicant_ctrl_iface_scan_result(
- struct wpa_supplicant *wpa_s,
- const struct wpa_bss *bss, char *buf, size_t buflen)
-{
- char *pos, *end;
- int ret;
- const u8 *ie, *ie2, *osen_ie, *p2p, *mesh, *owe, *rsnxe;
-
- mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
- p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
- if (!p2p)
- p2p = wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE);
- if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
- os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
- 0)
- return 0; /* Do not show P2P listen discovery results here */
-
- pos = buf;
- end = buf + buflen;
-
- ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
- MAC2STR(bss->bssid), bss->freq, bss->level);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- if (ie)
- pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
- ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (ie2) {
- pos = wpa_supplicant_ie_txt(pos, end, mesh ? "RSN" : "WPA2",
- ie2, 2 + ie2[1]);
- }
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
- ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
- ret = os_snprintf(pos, end - pos, "[SAE-PK]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- if (osen_ie)
- pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
- osen_ie, 2 + osen_ie[1]);
- owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (owe) {
- ret = os_snprintf(pos, end - pos,
- ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
- if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) {
- ret = os_snprintf(pos, end - pos, "[WEP]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- if (mesh) {
- ret = os_snprintf(pos, end - pos, "[MESH]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- if (bss_is_dmg(bss)) {
- const char *s;
-
- if (wpa_bss_get_ie_ext(bss, WLAN_EID_EXT_EDMG_OPERATION)) {
- ret = os_snprintf(pos, end - pos, "[EDMG]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "[DMG]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- switch (bss->caps & IEEE80211_CAP_DMG_MASK) {
- case IEEE80211_CAP_DMG_IBSS:
- s = "[IBSS]";
- break;
- case IEEE80211_CAP_DMG_AP:
- s = "[ESS]";
- break;
- case IEEE80211_CAP_DMG_PBSS:
- s = "[PBSS]";
- break;
- default:
- s = "";
- break;
- }
- ret = os_snprintf(pos, end - pos, "%s", s);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- } else {
- if (bss->caps & IEEE80211_CAP_IBSS) {
- ret = os_snprintf(pos, end - pos, "[IBSS]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- if (bss->caps & IEEE80211_CAP_ESS) {
- ret = os_snprintf(pos, end - pos, "[ESS]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- }
- if (p2p) {
- ret = os_snprintf(pos, end - pos, "[P2P]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-#ifdef CONFIG_HS20
- if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) {
- ret = os_snprintf(pos, end - pos, "[HS20]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_FILS
- if (wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION)) {
- ret = os_snprintf(pos, end - pos, "[FILS]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_FST
- if (wpa_bss_get_ie(bss, WLAN_EID_MULTI_BAND)) {
- ret = os_snprintf(pos, end - pos, "[FST]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-#endif /* CONFIG_FST */
- if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) {
- ret = os_snprintf(pos, end - pos, "[UTF-8]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\t%s",
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_ctrl_iface_scan_results(
- struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
-{
- char *pos, *end;
- struct wpa_bss *bss;
- int ret;
-
- pos = buf;
- end = buf + buflen;
- ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
- "flags / ssid\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
- ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
- end - pos);
- if (ret < 0 || ret >= end - pos)
- return pos - buf;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-#ifdef CONFIG_MESH
-
-static int wpa_supplicant_ctrl_iface_mesh_interface_add(
- struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
-{
- char *pos, ifname[IFNAMSIZ + 1];
-
- ifname[0] = '\0';
-
- pos = os_strstr(cmd, "ifname=");
- if (pos) {
- pos += 7;
- os_strlcpy(ifname, pos, sizeof(ifname));
- }
-
- if (wpas_mesh_add_interface(wpa_s, ifname, sizeof(ifname)) < 0)
- return -1;
-
- os_strlcpy(reply, ifname, max_len);
- return os_strlen(ifname);
-}
-
-
-static int wpa_supplicant_ctrl_iface_mesh_group_add(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id;
- struct wpa_ssid *ssid;
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: MESH_GROUP_ADD id=%d", id);
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: Could not find network id=%d", id);
- return -1;
- }
- if (ssid->mode != WPAS_MODE_MESH) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: Cannot use MESH_GROUP_ADD on a non mesh network");
- return -1;
- }
- if (ssid->key_mgmt != WPA_KEY_MGMT_NONE &&
- ssid->key_mgmt != WPA_KEY_MGMT_SAE) {
- wpa_printf(MSG_ERROR,
- "CTRL_IFACE: key_mgmt for mesh network should be open or SAE");
- return -1;
- }
-
- /*
- * TODO: If necessary write our own group_add function,
- * for now we can reuse select_network
- */
- wpa_supplicant_select_network(wpa_s, ssid);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_mesh_group_remove(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- struct wpa_supplicant *orig;
- struct wpa_global *global;
- int found = 0;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: MESH_GROUP_REMOVE ifname=%s", cmd);
-
- global = wpa_s->global;
- orig = wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_strcmp(wpa_s->ifname, cmd) == 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- wpa_printf(MSG_ERROR,
- "CTRL_IFACE: MESH_GROUP_REMOVE ifname=%s not found",
- cmd);
- return -1;
- }
- if (wpa_s->mesh_if_created && wpa_s == orig) {
- wpa_printf(MSG_ERROR,
- "CTRL_IFACE: MESH_GROUP_REMOVE can't remove itself");
- return -1;
- }
-
- wpa_s->reassociate = 0;
- wpa_s->disconnected = 1;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
-
- /*
- * TODO: If necessary write our own group_remove function,
- * for now we can reuse deauthenticate
- */
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-
- if (wpa_s->mesh_if_created)
- wpa_supplicant_remove_iface(global, wpa_s, 0);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_mesh_peer_remove(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
-
- if (hwaddr_aton(cmd, addr) < 0)
- return -1;
-
- return wpas_mesh_peer_remove(wpa_s, addr);
-}
-
-
-static int wpa_supplicant_ctrl_iface_mesh_peer_add(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
- int duration;
- char *pos;
-
- pos = os_strstr(cmd, " duration=");
- if (pos) {
- *pos = '\0';
- duration = atoi(pos + 10);
- } else {
- duration = -1;
- }
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- return wpas_mesh_peer_add(wpa_s, addr, duration);
-}
-
-
-static int wpa_supplicant_ctrl_iface_mesh_link_probe(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- struct ether_header *eth;
- u8 addr[ETH_ALEN];
- u8 *buf;
- char *pos;
- size_t payload_len = 0, len;
- int ret = -1;
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- pos = os_strstr(cmd, " payload=");
- if (pos) {
- pos = pos + 9;
- payload_len = os_strlen(pos);
- if (payload_len & 1)
- return -1;
-
- payload_len /= 2;
- }
-
- len = ETH_HLEN + payload_len;
- buf = os_malloc(len);
- if (!buf)
- return -1;
-
- eth = (struct ether_header *) buf;
- os_memcpy(eth->ether_dhost, addr, ETH_ALEN);
- os_memcpy(eth->ether_shost, wpa_s->own_addr, ETH_ALEN);
- eth->ether_type = htons(ETH_P_802_3);
-
- if (payload_len && hexstr2bin(pos, buf + ETH_HLEN, payload_len) < 0)
- goto fail;
-
- ret = wpa_drv_mesh_link_probe(wpa_s, addr, buf, len);
-fail:
- os_free(buf);
- return -ret;
-}
-
-#endif /* CONFIG_MESH */
-
-
-static int wpa_supplicant_ctrl_iface_select_network(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id;
- struct wpa_ssid *ssid;
- char *pos;
-
- /* cmd: "<network id>" or "any" */
- if (os_strncmp(cmd, "any", 3) == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
- ssid = NULL;
- } else {
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "network id=%d", id);
- return -1;
- }
- if (ssid->disabled == 2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
- "SELECT_NETWORK with persistent P2P group");
- return -1;
- }
- }
-
- pos = os_strstr(cmd, " freq=");
- if (pos) {
- int *freqs = freq_range_to_channel_list(wpa_s, pos + 6);
- if (freqs) {
- os_free(wpa_s->select_network_scan_freqs);
- wpa_s->select_network_scan_freqs = freqs;
- }
- }
-
- wpa_s->scan_min_time.sec = 0;
- wpa_s->scan_min_time.usec = 0;
- wpa_supplicant_select_network(wpa_s, ssid);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_enable_network(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id;
- struct wpa_ssid *ssid;
-
- /* cmd: "<network id>" or "all" */
- if (os_strcmp(cmd, "all") == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
- ssid = NULL;
- } else {
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "network id=%d", id);
- return -1;
- }
- if (ssid->disabled == 2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
- "ENABLE_NETWORK with persistent P2P group");
- return -1;
- }
-
- if (os_strstr(cmd, " no-connect")) {
- ssid->disabled = 0;
- return 0;
- }
- }
- wpa_s->scan_min_time.sec = 0;
- wpa_s->scan_min_time.usec = 0;
- wpa_supplicant_enable_network(wpa_s, ssid);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_disable_network(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id;
- struct wpa_ssid *ssid;
-
- /* cmd: "<network id>" or "all" */
- if (os_strcmp(cmd, "all") == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
- ssid = NULL;
- } else {
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "network id=%d", id);
- return -1;
- }
- if (ssid->disabled == 2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
- "DISABLE_NETWORK with persistent P2P "
- "group");
- return -1;
- }
- }
- wpa_supplicant_disable_network(wpa_s, ssid);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_add_network(
- struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
-{
- struct wpa_ssid *ssid;
- int ret;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
-
- ssid = wpa_supplicant_add_network(wpa_s);
- if (ssid == NULL)
- return -1;
-
- ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_remove_network(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id;
- int result;
-
- /* cmd: "<network id>" or "all" */
- if (os_strcmp(cmd, "all") == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
- return wpa_supplicant_remove_all_networks(wpa_s);
- }
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
-
- result = wpa_supplicant_remove_network(wpa_s, id);
- if (result == -1) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
- "id=%d", id);
- return -1;
- }
- if (result == -2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the "
- "network id=%d", id);
- return -1;
- }
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_update_network(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- char *name, char *value)
-{
- int ret;
-
- ret = wpa_config_set(ssid, name, value, 0);
- if (ret < 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
- "variable '%s'", name);
- return -1;
- }
- if (ret == 1)
- return 0; /* No change to the previously configured value */
-
-#ifdef CONFIG_BGSCAN
- if (os_strcmp(name, "bgscan") == 0) {
- /*
- * Reset the bgscan parameters for the current network and
- * return. There's no need to flush caches for bgscan parameter
- * changes.
- */
- if (wpa_s->current_ssid == ssid &&
- wpa_s->wpa_state == WPA_COMPLETED)
- wpa_supplicant_reset_bgscan(wpa_s);
- return 0;
- }
-#endif /* CONFIG_BGSCAN */
-
- if (os_strcmp(name, "bssid") != 0 &&
- os_strcmp(name, "bssid_hint") != 0 &&
- os_strcmp(name, "priority") != 0) {
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
-
- if (wpa_s->current_ssid == ssid ||
- wpa_s->current_ssid == NULL) {
- /*
- * Invalidate the EAP session cache if anything in the
- * current or previously used configuration changes.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
- }
-
- if ((os_strcmp(name, "psk") == 0 &&
- value[0] == '"' && ssid->ssid_len) ||
- (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
- wpa_config_update_psk(ssid);
- else if (os_strcmp(name, "priority") == 0)
- wpa_config_update_prio_list(wpa_s->conf);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_set_network(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int id, ret, prev_bssid_set, prev_disabled;
- struct wpa_ssid *ssid;
- char *name, *value;
- u8 prev_bssid[ETH_ALEN];
-
- /* cmd: "<network id> <variable name> <value>" */
- name = os_strchr(cmd, ' ');
- if (name == NULL)
- return -1;
- *name++ = '\0';
-
- value = os_strchr(name, ' ');
- if (value == NULL)
- return -1;
- *value++ = '\0';
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
- id, name);
- wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
- (u8 *) value, os_strlen(value));
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
- "id=%d", id);
- return -1;
- }
-
- prev_bssid_set = ssid->bssid_set;
- prev_disabled = ssid->disabled;
- os_memcpy(prev_bssid, ssid->bssid, ETH_ALEN);
- ret = wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid, name,
- value);
- if (ret == 0 &&
- (ssid->bssid_set != prev_bssid_set ||
- os_memcmp(ssid->bssid, prev_bssid, ETH_ALEN) != 0))
- wpas_notify_network_bssid_set_changed(wpa_s, ssid);
-
- if (prev_disabled != ssid->disabled &&
- (prev_disabled == 2 || ssid->disabled == 2))
- wpas_notify_network_type_changed(wpa_s, ssid);
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_get_network(
- struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
-{
- int id;
- size_t res;
- struct wpa_ssid *ssid;
- char *name, *value;
-
- /* cmd: "<network id> <variable name>" */
- name = os_strchr(cmd, ' ');
- if (name == NULL || buflen == 0)
- return -1;
- *name++ = '\0';
-
- id = atoi(cmd);
- wpa_printf(MSG_EXCESSIVE, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
- id, name);
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- wpa_printf(MSG_EXCESSIVE, "CTRL_IFACE: Could not find network "
- "id=%d", id);
- return -1;
- }
-
- value = wpa_config_get_no_key(ssid, name);
- if (value == NULL) {
- wpa_printf(MSG_EXCESSIVE, "CTRL_IFACE: Failed to get network "
- "variable '%s'", name);
- return -1;
- }
-
- res = os_strlcpy(buf, value, buflen);
- if (res >= buflen) {
- os_free(value);
- return -1;
- }
-
- os_free(value);
-
- return res;
-}
-
-
-static int wpa_supplicant_ctrl_iface_dup_network(
- struct wpa_supplicant *wpa_s, char *cmd,
- struct wpa_supplicant *dst_wpa_s)
-{
- struct wpa_ssid *ssid_s, *ssid_d;
- char *name, *id, *value;
- int id_s, id_d, ret;
-
- /* cmd: "<src network id> <dst network id> <variable name>" */
- id = os_strchr(cmd, ' ');
- if (id == NULL)
- return -1;
- *id++ = '\0';
-
- name = os_strchr(id, ' ');
- if (name == NULL)
- return -1;
- *name++ = '\0';
-
- id_s = atoi(cmd);
- id_d = atoi(id);
-
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: DUP_NETWORK ifname=%s->%s id=%d->%d name='%s'",
- wpa_s->ifname, dst_wpa_s->ifname, id_s, id_d, name);
-
- ssid_s = wpa_config_get_network(wpa_s->conf, id_s);
- if (ssid_s == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "network id=%d", id_s);
- return -1;
- }
-
- ssid_d = wpa_config_get_network(dst_wpa_s->conf, id_d);
- if (ssid_d == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "network id=%d", id_d);
- return -1;
- }
-
- value = wpa_config_get(ssid_s, name);
- if (value == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
- "variable '%s'", name);
- return -1;
- }
-
- ret = wpa_supplicant_ctrl_iface_update_network(dst_wpa_s, ssid_d, name,
- value);
-
- os_free(value);
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- char *pos, *end;
- struct wpa_cred *cred;
- int ret;
-
- pos = buf;
- end = buf + buflen;
- ret = os_snprintf(pos, end - pos,
- "cred id / realm / username / domain / imsi\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- cred = wpa_s->conf->cred;
- while (cred) {
- ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
- cred->id, cred->realm ? cred->realm : "",
- cred->username ? cred->username : "",
- cred->domain ? cred->domain[0] : "",
- cred->imsi ? cred->imsi : "");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- cred = cred->next;
- }
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- struct wpa_cred *cred;
- int ret;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED");
-
- cred = wpa_config_add_cred(wpa_s->conf);
- if (cred == NULL)
- return -1;
-
- wpa_msg(wpa_s, MSG_INFO, CRED_ADDED "%d", cred->id);
-
- ret = os_snprintf(buf, buflen, "%d\n", cred->id);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- int id;
- struct wpa_cred *cred, *prev;
-
- /* cmd: "<cred id>", "all", "sp_fqdn=<FQDN>", or
- * "provisioning_sp=<FQDN> */
- if (os_strcmp(cmd, "all") == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
- return wpas_remove_all_creds(wpa_s);
- }
-
- if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED SP FQDN '%s'",
- cmd + 8);
- cred = wpa_s->conf->cred;
- while (cred) {
- prev = cred;
- cred = cred->next;
- if (prev->domain) {
- size_t i;
- for (i = 0; i < prev->num_domain; i++) {
- if (os_strcmp(prev->domain[i], cmd + 8)
- != 0)
- continue;
- wpas_remove_cred(wpa_s, prev);
- break;
- }
- }
- }
- return 0;
- }
-
- if (os_strncmp(cmd, "provisioning_sp=", 16) == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED provisioning SP FQDN '%s'",
- cmd + 16);
- cred = wpa_s->conf->cred;
- while (cred) {
- prev = cred;
- cred = cred->next;
- if (prev->provisioning_sp &&
- os_strcmp(prev->provisioning_sp, cmd + 16) == 0)
- wpas_remove_cred(wpa_s, prev);
- }
- return 0;
- }
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
-
- cred = wpa_config_get_cred(wpa_s->conf, id);
- return wpas_remove_cred(wpa_s, cred);
-}
-
-
-static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- int id;
- struct wpa_cred *cred;
- char *name, *value;
-
- /* cmd: "<cred id> <variable name> <value>" */
- name = os_strchr(cmd, ' ');
- if (name == NULL)
- return -1;
- *name++ = '\0';
-
- value = os_strchr(name, ' ');
- if (value == NULL)
- return -1;
- *value++ = '\0';
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'",
- id, name);
- wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
- (u8 *) value, os_strlen(value));
-
- cred = wpa_config_get_cred(wpa_s->conf, id);
- if (cred == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
- id);
- return -1;
- }
-
- if (wpa_config_set_cred(cred, name, value, 0) < 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred "
- "variable '%s'", name);
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_INFO, CRED_MODIFIED "%d %s", cred->id, name);
-
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_get_cred(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf,
- size_t buflen)
-{
- int id;
- size_t res;
- struct wpa_cred *cred;
- char *name, *value;
-
- /* cmd: "<cred id> <variable name>" */
- name = os_strchr(cmd, ' ');
- if (name == NULL)
- return -1;
- *name++ = '\0';
-
- id = atoi(cmd);
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CRED id=%d name='%s'",
- id, name);
-
- cred = wpa_config_get_cred(wpa_s->conf, id);
- if (cred == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
- id);
- return -1;
- }
-
- value = wpa_config_get_cred_no_key(cred, name);
- if (value == NULL) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get cred variable '%s'",
- name);
- return -1;
- }
-
- res = os_strlcpy(buf, value, buflen);
- if (res >= buflen) {
- os_free(value);
- return -1;
- }
-
- os_free(value);
-
- return res;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
-{
- int ret;
-
- if (!wpa_s->conf->update_config) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
- "to update configuration (update_config=0)");
- return -1;
- }
-
- ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
- if (ret) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
- "update configuration");
- } else {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
- " updated");
- }
-
- return ret;
-}
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-struct cipher_info {
- unsigned int capa;
- const char *name;
- int group_only;
-};
-
-static const struct cipher_info ciphers[] = {
- { WPA_DRIVER_CAPA_ENC_CCMP_256, "CCMP-256", 0 },
- { WPA_DRIVER_CAPA_ENC_GCMP_256, "GCMP-256", 0 },
- { WPA_DRIVER_CAPA_ENC_CCMP, "CCMP", 0 },
- { WPA_DRIVER_CAPA_ENC_GCMP, "GCMP", 0 },
-#ifndef CONFIG_NO_TKIP
- { WPA_DRIVER_CAPA_ENC_TKIP, "TKIP", 0 },
-#endif /* CONFIG_NO_TKIP */
- { WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE, "NONE", 0 },
-#ifdef CONFIG_WEP
- { WPA_DRIVER_CAPA_ENC_WEP104, "WEP104", 1 },
- { WPA_DRIVER_CAPA_ENC_WEP40, "WEP40", 1 }
-#endif /* CONFIG_WEP */
-};
-
-static const struct cipher_info ciphers_group_mgmt[] = {
- { WPA_DRIVER_CAPA_ENC_BIP, "AES-128-CMAC", 1 },
- { WPA_DRIVER_CAPA_ENC_BIP_GMAC_128, "BIP-GMAC-128", 1 },
- { WPA_DRIVER_CAPA_ENC_BIP_GMAC_256, "BIP-GMAC-256", 1 },
- { WPA_DRIVER_CAPA_ENC_BIP_CMAC_256, "BIP-CMAC-256", 1 },
-};
-
-
-static int ctrl_iface_get_capability_pairwise(int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- size_t len;
- unsigned int i;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
-#ifdef CONFIG_NO_TKIP
- len = os_strlcpy(buf, "CCMP NONE", buflen);
-#else /* CONFIG_NO_TKIP */
- len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
-#endif /* CONFIG_NO_TKIP */
- if (len >= buflen)
- return -1;
- return len;
- }
-
- for (i = 0; i < ARRAY_SIZE(ciphers); i++) {
- if (!ciphers[i].group_only && capa->enc & ciphers[i].capa) {
- ret = os_snprintf(pos, end - pos, "%s%s",
- pos == buf ? "" : " ",
- ciphers[i].name);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- }
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_group(int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- size_t len;
- unsigned int i;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
-#ifdef CONFIG_WEP
-#ifdef CONFIG_NO_TKIP
- len = os_strlcpy(buf, "CCMP WEP104 WEP40", buflen);
-#else /* CONFIG_NO_TKIP */
- len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
-#endif /* CONFIG_NO_TKIP */
-#else /* CONFIG_WEP */
-#ifdef CONFIG_NO_TKIP
- len = os_strlcpy(buf, "CCMP", buflen);
-#else /* CONFIG_NO_TKIP */
- len = os_strlcpy(buf, "CCMP TKIP", buflen);
-#endif /* CONFIG_NO_TKIP */
-#endif /* CONFIG_WEP */
- if (len >= buflen)
- return -1;
- return len;
- }
-
- for (i = 0; i < ARRAY_SIZE(ciphers); i++) {
- if (capa->enc & ciphers[i].capa) {
- ret = os_snprintf(pos, end - pos, "%s%s",
- pos == buf ? "" : " ",
- ciphers[i].name);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- }
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_group_mgmt(int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- unsigned int i;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0)
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(ciphers_group_mgmt); i++) {
- if (capa->enc & ciphers_group_mgmt[i].capa) {
- ret = os_snprintf(pos, end - pos, "%s%s",
- pos == buf ? "" : " ",
- ciphers_group_mgmt[i].name);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- }
-
- return pos - buf;
-}
-
-
-static int iftype_str_to_index(const char *iftype_str)
-{
- if (!iftype_str)
- return WPA_IF_MAX;
-
- if (os_strcmp(iftype_str, "STATION") == 0)
- return WPA_IF_STATION;
-
- if (os_strcmp(iftype_str, "AP_VLAN") == 0)
- return WPA_IF_AP_VLAN;
-
- if (os_strcmp(iftype_str, "AP") == 0)
- return WPA_IF_AP_BSS;
-
- if (os_strcmp(iftype_str, "P2P_GO") == 0)
- return WPA_IF_P2P_GO;
-
- if (os_strcmp(iftype_str, "P2P_CLIENT") == 0)
- return WPA_IF_P2P_CLIENT;
-
- if (os_strcmp(iftype_str, "P2P_DEVICE") == 0)
- return WPA_IF_P2P_DEVICE;
-
- if (os_strcmp(iftype_str, "MESH") == 0)
- return WPA_IF_MESH;
-
- if (os_strcmp(iftype_str, "IBSS") == 0)
- return WPA_IF_IBSS;
-
- if (os_strcmp(iftype_str, "NAN") == 0)
- return WPA_IF_NAN;
-
- return WPA_IF_MAX;
-}
-
-
-static int ctrl_iface_get_capability_key_mgmt(int res, bool strict,
- struct wpa_driver_capa *capa,
- const char *iftype_str,
- char *buf, size_t buflen)
-{
- int ret;
- unsigned int key_mgmt;
- char *pos, *end;
- size_t len;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
- len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
- "NONE", buflen);
- if (len >= buflen)
- return -1;
- return len;
- }
-
- if (iftype_str) {
- enum wpa_driver_if_type iftype;
-
- iftype = iftype_str_to_index(iftype_str);
- if (iftype == WPA_IF_MAX)
- return -1;
- key_mgmt = capa->key_mgmt_iftype[iftype];
- } else {
- key_mgmt = capa->key_mgmt;
- }
-
- ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
- ret = os_snprintf(pos, end - pos, " WPA-EAP");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
- ret = os_snprintf(pos, end - pos, " WPA-PSK");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
- ret = os_snprintf(pos, end - pos, " WPA-NONE");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WAPI_PSK) {
- ret = os_snprintf(pos, end - pos, " WAPI-PSK");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_TPK_HANDSHAKE) {
- ret = os_snprintf(pos, end - pos, " TPK-HANDSHAKE");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_CCKM) {
- ret = os_snprintf(pos, end - pos, " CCKM");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_SUITEB
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B) {
- ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SUITEB */
-#ifdef CONFIG_SUITEB192
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
- ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B-192");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SUITEB192 */
-#ifdef CONFIG_OWE
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
- ret = os_snprintf(pos, end - pos, " OWE");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_OWE */
-#ifdef CONFIG_DPP
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
- ret = os_snprintf(pos, end - pos, " DPP");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_DPP */
-#ifdef CONFIG_FILS
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, " FILS-SHA256");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, " FILS-SHA384");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#ifdef CONFIG_IEEE80211R
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
- ret = os_snprintf(pos, end - pos, " FT-FILS-SHA256");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
- ret = os_snprintf(pos, end - pos, " FT-FILS-SHA384");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_IEEE80211R
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
- ret = os_snprintf(pos, end - pos, " FT-PSK");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT) {
- ret = os_snprintf(pos, end - pos, " FT-EAP");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#ifdef CONFIG_SAE
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE) {
- ret = os_snprintf(pos, end - pos, " FT-SAE");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_SHA384
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384) {
- ret = os_snprintf(pos, end - pos, " FT-EAP-SHA384");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SHA384 */
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_SAE
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
- ret = os_snprintf(pos, end - pos, " SAE");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_SHA256
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256) {
- ret = os_snprintf(pos, end - pos, " WPA-EAP-SHA256");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256) {
- ret = os_snprintf(pos, end - pos, " WPA-PSK-SHA256");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SHA256 */
-#ifdef CONFIG_HS20
- if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OSEN) {
- ret = os_snprintf(pos, end - pos, " OSEN");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_HS20 */
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_proto(int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- size_t len;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
- len = os_strlcpy(buf, "RSN WPA", buflen);
- if (len >= buflen)
- return -1;
- return len;
- }
-
- if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
- ret = os_snprintf(pos, end - pos, "%sRSN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
- ret = os_snprintf(pos, end - pos, "%sWPA",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_auth_alg(struct wpa_supplicant *wpa_s,
- int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- size_t len;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
- len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
- if (len >= buflen)
- return -1;
- return len;
- }
-
- if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
- ret = os_snprintf(pos, end - pos, "%sOPEN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
- ret = os_snprintf(pos, end - pos, "%sSHARED",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
- ret = os_snprintf(pos, end - pos, "%sLEAP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_SAE
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
- ret = os_snprintf(pos, end - pos, "%sSAE",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_FILS
- if (wpa_is_fils_supported(wpa_s)) {
- ret = os_snprintf(pos, end - pos, "%sFILS_SK_WITHOUT_PFS",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_FILS_SK_PFS
- if (wpa_is_fils_sk_pfs_supported(wpa_s)) {
- ret = os_snprintf(pos, end - pos, "%sFILS_SK_WITH_PFS",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_FILS_SK_PFS */
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_PASN
- ret = os_snprintf(pos, end - pos, "%sPASN",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
-#endif /* CONFIG_PASN */
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_modes(int res, bool strict,
- struct wpa_driver_capa *capa,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *end;
- size_t len;
-
- pos = buf;
- end = pos + buflen;
-
- if (res < 0) {
- if (strict)
- return 0;
- len = os_strlcpy(buf, "IBSS AP", buflen);
- if (len >= buflen)
- return -1;
- return len;
- }
-
- if (capa->flags & WPA_DRIVER_FLAGS_IBSS) {
- ret = os_snprintf(pos, end - pos, "%sIBSS",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- if (capa->flags & WPA_DRIVER_FLAGS_AP) {
- ret = os_snprintf(pos, end - pos, "%sAP",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
-#ifdef CONFIG_MESH
- if (capa->flags & WPA_DRIVER_FLAGS_MESH) {
- ret = os_snprintf(pos, end - pos, "%sMESH",
- pos == buf ? "" : " ");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_MESH */
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- struct hostapd_channel_data *chnl;
- int ret, i, j;
- char *pos, *end, *hmode;
-
- pos = buf;
- end = pos + buflen;
-
- for (j = 0; j < wpa_s->hw.num_modes; j++) {
- switch (wpa_s->hw.modes[j].mode) {
- case HOSTAPD_MODE_IEEE80211B:
- hmode = "B";
- break;
- case HOSTAPD_MODE_IEEE80211G:
- hmode = "G";
- break;
- case HOSTAPD_MODE_IEEE80211A:
- hmode = "A";
- break;
- case HOSTAPD_MODE_IEEE80211AD:
- hmode = "AD";
- break;
- default:
- continue;
- }
- ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:", hmode);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- chnl = wpa_s->hw.modes[j].channels;
- for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) {
- if (chnl[i].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- ret = os_snprintf(pos, end - pos, " %d", chnl[i].chan);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int ctrl_iface_get_capability_freq(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- struct hostapd_channel_data *chnl;
- int ret, i, j;
- char *pos, *end, *hmode;
-
- pos = buf;
- end = pos + buflen;
-
- for (j = 0; j < wpa_s->hw.num_modes; j++) {
- switch (wpa_s->hw.modes[j].mode) {
- case HOSTAPD_MODE_IEEE80211B:
- hmode = "B";
- break;
- case HOSTAPD_MODE_IEEE80211G:
- hmode = "G";
- break;
- case HOSTAPD_MODE_IEEE80211A:
- hmode = "A";
- break;
- case HOSTAPD_MODE_IEEE80211AD:
- hmode = "AD";
- break;
- default:
- continue;
- }
- ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:\n",
- hmode);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- chnl = wpa_s->hw.modes[j].channels;
- for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) {
- if (chnl[i].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- ret = os_snprintf(pos, end - pos, " %d = %d MHz%s%s\n",
- chnl[i].chan, chnl[i].freq,
- chnl[i].flag & HOSTAPD_CHAN_NO_IR ?
- " (NO_IR)" : "",
- chnl[i].flag & HOSTAPD_CHAN_RADAR ?
- " (DFS)" : "");
-
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_ctrl_iface_get_capability(
- struct wpa_supplicant *wpa_s, const char *_field, char *buf,
- size_t buflen)
-{
- struct wpa_driver_capa capa;
- int res;
- char *next_param, *curr_param, *iftype = NULL;
- bool strict = false;
- char field[50];
- size_t len;
-
- /* Determine whether or not strict checking was requested */
- len = os_strlcpy(field, _field, sizeof(field));
- if (len >= sizeof(field))
- return -1;
-
- next_param = os_strchr(field, ' ');
- while (next_param) {
- *next_param++ = '\0';
- curr_param = next_param;
- next_param = os_strchr(next_param, ' ');
-
- if (next_param)
- *next_param = '\0';
-
- if (os_strcmp(curr_param, "strict") == 0)
- strict = true;
- else if (os_strncmp(curr_param, "iftype=", 7) == 0)
- iftype = curr_param + 7;
- else
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s'%s%s%s",
- field, iftype ? " iftype=" : "", iftype ? iftype : "",
- strict ? " strict" : "");
-
- if (os_strcmp(field, "eap") == 0) {
- return eap_get_names(buf, buflen);
- }
-
- res = wpa_drv_get_capa(wpa_s, &capa);
-
- if (os_strcmp(field, "pairwise") == 0)
- return ctrl_iface_get_capability_pairwise(res, strict, &capa,
- buf, buflen);
-
- if (os_strcmp(field, "group") == 0)
- return ctrl_iface_get_capability_group(res, strict, &capa,
- buf, buflen);
-
- if (os_strcmp(field, "group_mgmt") == 0)
- return ctrl_iface_get_capability_group_mgmt(res, strict, &capa,
- buf, buflen);
-
- if (os_strcmp(field, "key_mgmt") == 0)
- return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
- iftype, buf, buflen);
-
- if (os_strcmp(field, "proto") == 0)
- return ctrl_iface_get_capability_proto(res, strict, &capa,
- buf, buflen);
-
- if (os_strcmp(field, "auth_alg") == 0)
- return ctrl_iface_get_capability_auth_alg(wpa_s, res, strict,
- &capa, buf, buflen);
-
- if (os_strcmp(field, "modes") == 0)
- return ctrl_iface_get_capability_modes(res, strict, &capa,
- buf, buflen);
-
- if (os_strcmp(field, "channels") == 0)
- return ctrl_iface_get_capability_channels(wpa_s, buf, buflen);
-
- if (os_strcmp(field, "freq") == 0)
- return ctrl_iface_get_capability_freq(wpa_s, buf, buflen);
-
-#ifdef CONFIG_TDLS
- if (os_strcmp(field, "tdls") == 0)
- return ctrl_iface_get_capability_tdls(wpa_s, buf, buflen);
-#endif /* CONFIG_TDLS */
-
-#ifdef CONFIG_ERP
- if (os_strcmp(field, "erp") == 0) {
- res = os_snprintf(buf, buflen, "ERP");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_EPR */
-
-#ifdef CONFIG_FIPS
- if (os_strcmp(field, "fips") == 0) {
- res = os_snprintf(buf, buflen, "FIPS");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_FIPS */
-
-#ifdef CONFIG_ACS
- if (os_strcmp(field, "acs") == 0) {
- res = os_snprintf(buf, buflen, "ACS");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_ACS */
-
-#ifdef CONFIG_FILS
- if (os_strcmp(field, "fils") == 0) {
-#ifdef CONFIG_FILS_SK_PFS
- if (wpa_is_fils_supported(wpa_s) &&
- wpa_is_fils_sk_pfs_supported(wpa_s)) {
- res = os_snprintf(buf, buflen, "FILS FILS-SK-PFS");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_FILS_SK_PFS */
-
- if (wpa_is_fils_supported(wpa_s)) {
- res = os_snprintf(buf, buflen, "FILS");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
- }
-#endif /* CONFIG_FILS */
-
- if (os_strcmp(field, "multibss") == 0 && wpa_s->multi_bss_support) {
- res = os_snprintf(buf, buflen, "MULTIBSS-STA");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-
-#ifdef CONFIG_DPP
- if (os_strcmp(field, "dpp") == 0) {
-#ifdef CONFIG_DPP3
- res = os_snprintf(buf, buflen, "DPP=3");
-#elif defined(CONFIG_DPP2)
- res = os_snprintf(buf, buflen, "DPP=2");
-#else /* CONFIG_DPP2 */
- res = os_snprintf(buf, buflen, "DPP=1");
-#endif /* CONFIG_DPP2 */
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_SAE
- if (os_strcmp(field, "sae") == 0 &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
-#ifdef CONFIG_SAE_PK
- res = os_snprintf(buf, buflen, "H2E PK");
-#else /* CONFIG_SAE_PK */
- res = os_snprintf(buf, buflen, "H2E");
-#endif /* CONFIG_SAE_PK */
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_OCV
- if (os_strcmp(field, "ocv") == 0) {
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
- (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV))
- res = os_snprintf(buf, buflen, "supported");
- else
- res = os_snprintf(buf, buflen, "not supported");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-#endif /* CONFIG_OCV */
-
- if (os_strcmp(field, "beacon_prot") == 0) {
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION) ||
- (wpa_s->drv_flags2 &
- WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT))
- res = os_snprintf(buf, buflen, "supported");
- else
- res = os_snprintf(buf, buflen, "not supported");
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
- field);
-
- return -1;
-}
-
-
-#ifdef CONFIG_INTERWORKING
-static char * anqp_add_hex(char *pos, char *end, const char *title,
- struct wpabuf *data)
-{
- char *start = pos;
- size_t i;
- int ret;
- const u8 *d;
-
- if (data == NULL)
- return start;
-
- ret = os_snprintf(pos, end - pos, "%s=", title);
- if (os_snprintf_error(end - pos, ret))
- return start;
- pos += ret;
-
- d = wpabuf_head_u8(data);
- for (i = 0; i < wpabuf_len(data); i++) {
- ret = os_snprintf(pos, end - pos, "%02x", *d++);
- if (os_snprintf_error(end - pos, ret))
- return start;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return start;
- pos += ret;
-
- return pos;
-}
-#endif /* CONFIG_INTERWORKING */
-
-
-#ifdef CONFIG_FILS
-static int print_fils_indication(struct wpa_bss *bss, char *pos, char *end)
-{
- char *start = pos;
- const u8 *ie, *ie_end;
- u16 info, realms;
- int ret;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
- if (!ie)
- return 0;
- ie_end = ie + 2 + ie[1];
- ie += 2;
- if (ie_end - ie < 2)
- return -1;
-
- info = WPA_GET_LE16(ie);
- ie += 2;
- ret = os_snprintf(pos, end - pos, "fils_info=%04x\n", info);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
-
- if (info & BIT(7)) {
- /* Cache Identifier Included */
- if (ie_end - ie < 2)
- return -1;
- ret = os_snprintf(pos, end - pos, "fils_cache_id=%02x%02x\n",
- ie[0], ie[1]);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- ie += 2;
- }
-
- if (info & BIT(8)) {
- /* HESSID Included */
- if (ie_end - ie < ETH_ALEN)
- return -1;
- ret = os_snprintf(pos, end - pos, "fils_hessid=" MACSTR "\n",
- MAC2STR(ie));
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- ie += ETH_ALEN;
- }
-
- realms = (info & (BIT(3) | BIT(4) | BIT(5))) >> 3;
- if (realms) {
- if (ie_end - ie < realms * 2)
- return -1;
- ret = os_snprintf(pos, end - pos, "fils_realms=");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
-
- ret = wpa_snprintf_hex(pos, end - pos, ie, realms * 2);
- if (ret <= 0)
- return 0;
- pos += ret;
- ie += realms * 2;
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- return pos - start;
-}
-#endif /* CONFIG_FILS */
-
-
-static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- unsigned long mask, char *buf, size_t buflen)
-{
- size_t i;
- int ret;
- char *pos, *end;
- const u8 *ie, *ie2, *osen_ie, *mesh, *owe, *rsnxe;
-
- pos = buf;
- end = buf + buflen;
-
- if (mask & WPA_BSS_MASK_ID) {
- ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_BSSID) {
- ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
- MAC2STR(bss->bssid));
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_FREQ) {
- ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_BEACON_INT) {
- ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
- bss->beacon_int);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_CAPABILITIES) {
- ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n",
- bss->caps);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_QUAL) {
- ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_NOISE) {
- ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_LEVEL) {
- ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_TSF) {
- ret = os_snprintf(pos, end - pos, "tsf=%016llu\n",
- (unsigned long long) bss->tsf);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_AGE) {
- struct os_reltime now;
-
- os_get_reltime(&now);
- ret = os_snprintf(pos, end - pos, "age=%d\n",
- (int) (now.sec - bss->last_update.sec));
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_IE) {
- ret = os_snprintf(pos, end - pos, "ie=");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
-
- ie = wpa_bss_ie_ptr(bss);
- for (i = 0; i < bss->ie_len; i++) {
- ret = os_snprintf(pos, end - pos, "%02x", *ie++);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_FLAGS) {
- ret = os_snprintf(pos, end - pos, "flags=");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
-
- mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
-
- ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- if (ie)
- pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
- 2 + ie[1]);
- ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (ie2)
- pos = wpa_supplicant_ie_txt(pos, end,
- mesh ? "RSN" : "WPA2", ie2,
- 2 + ie2[1]);
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
- ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
- ret = os_snprintf(pos, end - pos, "[SAE-PK]");
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- if (osen_ie)
- pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
- osen_ie, 2 + osen_ie[1]);
- owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (owe) {
- ret = os_snprintf(
- pos, end - pos,
- ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
- pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
- if (!ie && !ie2 && !osen_ie &&
- (bss->caps & IEEE80211_CAP_PRIVACY)) {
- ret = os_snprintf(pos, end - pos, "[WEP]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mesh) {
- ret = os_snprintf(pos, end - pos, "[MESH]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (bss_is_dmg(bss)) {
- const char *s;
- ret = os_snprintf(pos, end - pos, "[DMG]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- switch (bss->caps & IEEE80211_CAP_DMG_MASK) {
- case IEEE80211_CAP_DMG_IBSS:
- s = "[IBSS]";
- break;
- case IEEE80211_CAP_DMG_AP:
- s = "[ESS]";
- break;
- case IEEE80211_CAP_DMG_PBSS:
- s = "[PBSS]";
- break;
- default:
- s = "";
- break;
- }
- ret = os_snprintf(pos, end - pos, "%s", s);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- } else {
- if (bss->caps & IEEE80211_CAP_IBSS) {
- ret = os_snprintf(pos, end - pos, "[IBSS]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
- if (bss->caps & IEEE80211_CAP_ESS) {
- ret = os_snprintf(pos, end - pos, "[ESS]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
- }
- if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
- wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
- ret = os_snprintf(pos, end - pos, "[P2P]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-#ifdef CONFIG_HS20
- if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) {
- ret = os_snprintf(pos, end - pos, "[HS20]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_FILS
- if (wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION)) {
- ret = os_snprintf(pos, end - pos, "[FILS]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_FST
- if (wpa_bss_get_ie(bss, WLAN_EID_MULTI_BAND)) {
- ret = os_snprintf(pos, end - pos, "[FST]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-#endif /* CONFIG_FST */
- if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) {
- ret = os_snprintf(pos, end - pos, "[UTF-8]");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_SSID) {
- ret = os_snprintf(pos, end - pos, "ssid=%s\n",
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
-#ifdef CONFIG_WPS
- if (mask & WPA_BSS_MASK_WPS_SCAN) {
- ie = wpa_bss_ie_ptr(bss);
- ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
- if (ret >= end - pos)
- return 0;
- if (ret > 0)
- pos += ret;
- }
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
- if (mask & WPA_BSS_MASK_P2P_SCAN) {
- ie = wpa_bss_ie_ptr(bss);
- ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
- if (ret >= end - pos)
- return 0;
- if (ret > 0)
- pos += ret;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WIFI_DISPLAY
- if (mask & WPA_BSS_MASK_WIFI_DISPLAY) {
- struct wpabuf *wfd;
-
- ie = wpa_bss_ie_ptr(bss);
- wfd = ieee802_11_vendor_ie_concat(ie, bss->ie_len,
- WFD_IE_VENDOR_TYPE);
- if (wfd) {
- ret = os_snprintf(pos, end - pos, "wfd_subelems=");
- if (os_snprintf_error(end - pos, ret)) {
- wpabuf_free(wfd);
- return 0;
- }
- pos += ret;
-
- pos += wpa_snprintf_hex(pos, end - pos,
- wpabuf_head(wfd),
- wpabuf_len(wfd));
- wpabuf_free(wfd);
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
- }
-#endif /* CONFIG_WIFI_DISPLAY */
-
-#ifdef CONFIG_INTERWORKING
- if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) {
- struct wpa_bss_anqp *anqp = bss->anqp;
- struct wpa_bss_anqp_elem *elem;
-
- pos = anqp_add_hex(pos, end, "anqp_capability_list",
- anqp->capability_list);
- pos = anqp_add_hex(pos, end, "anqp_venue_name",
- anqp->venue_name);
- pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
- anqp->network_auth_type);
- pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
- anqp->roaming_consortium);
- pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
- anqp->ip_addr_type_availability);
- pos = anqp_add_hex(pos, end, "anqp_nai_realm",
- anqp->nai_realm);
- pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp);
- pos = anqp_add_hex(pos, end, "anqp_domain_name",
- anqp->domain_name);
- pos = anqp_add_hex(pos, end, "anqp_fils_realm_info",
- anqp->fils_realm_info);
-#ifdef CONFIG_HS20
- pos = anqp_add_hex(pos, end, "hs20_capability_list",
- anqp->hs20_capability_list);
- pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name",
- anqp->hs20_operator_friendly_name);
- pos = anqp_add_hex(pos, end, "hs20_wan_metrics",
- anqp->hs20_wan_metrics);
- pos = anqp_add_hex(pos, end, "hs20_connection_capability",
- anqp->hs20_connection_capability);
- pos = anqp_add_hex(pos, end, "hs20_operating_class",
- anqp->hs20_operating_class);
- pos = anqp_add_hex(pos, end, "hs20_osu_providers_list",
- anqp->hs20_osu_providers_list);
- pos = anqp_add_hex(pos, end, "hs20_operator_icon_metadata",
- anqp->hs20_operator_icon_metadata);
- pos = anqp_add_hex(pos, end, "hs20_osu_providers_nai_list",
- anqp->hs20_osu_providers_nai_list);
-#endif /* CONFIG_HS20 */
-
- dl_list_for_each(elem, &anqp->anqp_elems,
- struct wpa_bss_anqp_elem, list) {
- char title[20];
-
- os_snprintf(title, sizeof(title), "anqp[%u]",
- elem->infoid);
- pos = anqp_add_hex(pos, end, title, elem->payload);
- if (elem->protected_response) {
- ret = os_snprintf(pos, end - pos,
- "protected-anqp-info[%u]=1\n",
- elem->infoid);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
- }
- }
-#endif /* CONFIG_INTERWORKING */
-
-#ifdef CONFIG_MESH
- if (mask & WPA_BSS_MASK_MESH_SCAN) {
- ie = wpa_bss_ie_ptr(bss);
- ret = wpas_mesh_scan_result_text(ie, bss->ie_len, pos, end);
- if (ret >= end - pos)
- return 0;
- if (ret > 0)
- pos += ret;
- }
-#endif /* CONFIG_MESH */
-
- if (mask & WPA_BSS_MASK_SNR) {
- ret = os_snprintf(pos, end - pos, "snr=%d\n", bss->snr);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if (mask & WPA_BSS_MASK_EST_THROUGHPUT) {
- ret = os_snprintf(pos, end - pos, "est_throughput=%d\n",
- bss->est_throughput);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
-#ifdef CONFIG_FST
- if (mask & WPA_BSS_MASK_FST) {
- ret = fst_ctrl_iface_mb_info(bss->bssid, pos, end - pos);
- if (ret < 0 || ret >= end - pos)
- return 0;
- pos += ret;
- }
-#endif /* CONFIG_FST */
-
- if (mask & WPA_BSS_MASK_UPDATE_IDX) {
- ret = os_snprintf(pos, end - pos, "update_idx=%u\n",
- bss->last_update_idx);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- if ((mask & WPA_BSS_MASK_BEACON_IE) && bss->beacon_ie_len) {
- ret = os_snprintf(pos, end - pos, "beacon_ie=");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
-
- ie = wpa_bss_ie_ptr(bss);
- ie += bss->ie_len;
- for (i = 0; i < bss->beacon_ie_len; i++) {
- ret = os_snprintf(pos, end - pos, "%02x", *ie++);
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
-#ifdef CONFIG_FILS
- if (mask & WPA_BSS_MASK_FILS_INDICATION) {
- ret = print_fils_indication(bss, pos, end);
- if (ret < 0)
- return 0;
- pos += ret;
- }
-#endif /* CONFIG_FILS */
-
- if (mask & WPA_BSS_MASK_DELIM) {
- ret = os_snprintf(pos, end - pos, "====\n");
- if (os_snprintf_error(end - pos, ret))
- return 0;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
- const char *cmd, char *buf,
- size_t buflen)
-{
- u8 bssid[ETH_ALEN];
- size_t i;
- struct wpa_bss *bss;
- struct wpa_bss *bsslast = NULL;
- struct dl_list *next;
- int ret = 0;
- int len;
- char *ctmp, *end = buf + buflen;
- unsigned long mask = WPA_BSS_MASK_ALL;
-
- if (os_strncmp(cmd, "RANGE=", 6) == 0) {
- if (os_strncmp(cmd + 6, "ALL", 3) == 0) {
- bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss,
- list_id);
- bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss,
- list_id);
- } else { /* N1-N2 */
- unsigned int id1, id2;
-
- if ((ctmp = os_strchr(cmd + 6, '-')) == NULL) {
- wpa_printf(MSG_INFO, "Wrong BSS range "
- "format");
- return 0;
- }
-
- if (*(cmd + 6) == '-')
- id1 = 0;
- else
- id1 = atoi(cmd + 6);
- ctmp++;
- if (*ctmp >= '0' && *ctmp <= '9')
- id2 = atoi(ctmp);
- else
- id2 = (unsigned int) -1;
- bss = wpa_bss_get_id_range(wpa_s, id1, id2);
- if (id2 == (unsigned int) -1)
- bsslast = dl_list_last(&wpa_s->bss_id,
- struct wpa_bss,
- list_id);
- else {
- bsslast = wpa_bss_get_id(wpa_s, id2);
- if (bsslast == NULL && bss && id2 > id1) {
- struct wpa_bss *tmp = bss;
- for (;;) {
- next = tmp->list_id.next;
- if (next == &wpa_s->bss_id)
- break;
- tmp = dl_list_entry(
- next, struct wpa_bss,
- list_id);
- if (tmp->id > id2)
- break;
- bsslast = tmp;
- }
- }
- }
- }
- } else if (os_strncmp(cmd, "FIRST", 5) == 0)
- bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, list_id);
- else if (os_strncmp(cmd, "LAST", 4) == 0)
- bss = dl_list_last(&wpa_s->bss_id, struct wpa_bss, list_id);
- else if (os_strncmp(cmd, "ID-", 3) == 0) {
- i = atoi(cmd + 3);
- bss = wpa_bss_get_id(wpa_s, i);
- } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
- i = atoi(cmd + 5);
- bss = wpa_bss_get_id(wpa_s, i);
- if (bss) {
- next = bss->list_id.next;
- if (next == &wpa_s->bss_id)
- bss = NULL;
- else
- bss = dl_list_entry(next, struct wpa_bss,
- list_id);
- }
- } else if (os_strncmp(cmd, "CURRENT", 7) == 0) {
- bss = wpa_s->current_bss;
-#ifdef CONFIG_P2P
- } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
- if (hwaddr_aton(cmd + 13, bssid) == 0)
- bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
- else
- bss = NULL;
-#endif /* CONFIG_P2P */
- } else if (hwaddr_aton(cmd, bssid) == 0)
- bss = wpa_bss_get_bssid(wpa_s, bssid);
- else {
- struct wpa_bss *tmp;
- i = atoi(cmd);
- bss = NULL;
- dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
- {
- if (i == 0) {
- bss = tmp;
- break;
- }
- i--;
- }
- }
-
- if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) {
- mask = strtoul(ctmp + 5, NULL, 0x10);
- if (mask == 0)
- mask = WPA_BSS_MASK_ALL;
- }
-
- if (bss == NULL)
- return 0;
-
- if (bsslast == NULL)
- bsslast = bss;
- do {
- len = print_bss_info(wpa_s, bss, mask, buf, buflen);
- ret += len;
- buf += len;
- buflen -= len;
- if (bss == bsslast) {
- if ((mask & WPA_BSS_MASK_DELIM) && len &&
- (bss == dl_list_last(&wpa_s->bss_id,
- struct wpa_bss, list_id))) {
- int res;
-
- res = os_snprintf(buf - 5, end - buf + 5,
- "####\n");
- if (os_snprintf_error(end - buf + 5, res)) {
- wpa_printf(MSG_DEBUG,
- "Could not add end delim");
- }
- }
- break;
- }
- next = bss->list_id.next;
- if (next == &wpa_s->bss_id)
- break;
- bss = dl_list_entry(next, struct wpa_bss, list_id);
- } while (bss && len);
-
- return ret;
-}
-
-
-static int wpa_supplicant_ctrl_iface_ap_scan(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int ap_scan = atoi(cmd);
- return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
-}
-
-
-static int wpa_supplicant_ctrl_iface_scan_interval(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int scan_int = atoi(cmd);
- return wpa_supplicant_set_scan_interval(wpa_s, scan_int);
-}
-
-
-static int wpa_supplicant_ctrl_iface_bss_expire_age(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int expire_age = atoi(cmd);
- return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
-}
-
-
-static int wpa_supplicant_ctrl_iface_bss_expire_count(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int expire_count = atoi(cmd);
- return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
-}
-
-
-static void wpa_supplicant_ctrl_iface_bss_flush(
- struct wpa_supplicant *wpa_s, char *cmd)
-{
- int flush_age = atoi(cmd);
-
- if (flush_age == 0)
- wpa_bss_flush(wpa_s);
- else
- wpa_bss_flush_by_age(wpa_s, flush_age);
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
- /* MLME-DELETEKEYS.request */
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL,
- 0, KEY_FLAG_GROUP);
-
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
- 0, KEY_FLAG_PAIRWISE);
- if (wpa_sm_ext_key_id(wpa_s->wpa))
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 1, 0,
- NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE);
- /* MLME-SETPROTECTION.request(None) */
- wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
- MLME_SETPROTECTION_PROTECT_TYPE_NONE,
- MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
- wpa_sm_drop_sa(wpa_s->wpa);
-}
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
- char *addr)
-{
-#ifdef CONFIG_NO_SCAN_PROCESSING
- return -1;
-#else /* CONFIG_NO_SCAN_PROCESSING */
- u8 bssid[ETH_ALEN];
- struct wpa_bss *bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpa_radio_work *already_connecting;
-
- if (hwaddr_aton(addr, bssid)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
-
- if (!ssid) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
- "configuration known for the target AP");
- return -1;
- }
-
- bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
- "from BSS table");
- return -1;
- }
-
- /*
- * TODO: Find best network configuration block from configuration to
- * allow roaming to other networks
- */
-
- already_connecting = radio_work_pending(wpa_s, "sme-connect");
- wpa_s->reassociate = 1;
- wpa_supplicant_connect(wpa_s, bss, ssid);
-
- /*
- * Indicate that an explicitly requested roam is in progress so scan
- * results that come in before the 'sme-connect' radio work gets
- * executed do not override the original connection attempt.
- */
- if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
- wpa_s->roam_in_progress = true;
-
- return 0;
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-}
-
-
-#ifdef CONFIG_P2P
-static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
-{
- unsigned int timeout = atoi(cmd);
- enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
- u8 dev_id[ETH_ALEN], *_dev_id = NULL;
- u8 dev_type[WPS_DEV_TYPE_LEN], *_dev_type = NULL;
- char *pos;
- unsigned int search_delay;
- const char *_seek[P2P_MAX_QUERY_HASH + 1], **seek = NULL;
- u8 seek_count = 0;
- int freq = 0;
- bool include_6ghz = false;
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_dbg(wpa_s, MSG_INFO,
- "Reject P2P_FIND since interface is disabled");
- return -1;
- }
-
- if (os_strstr(cmd, " include_6ghz"))
- include_6ghz = true;
- if (os_strstr(cmd, "type=social"))
- type = P2P_FIND_ONLY_SOCIAL;
- else if (os_strstr(cmd, "type=progressive"))
- type = P2P_FIND_PROGRESSIVE;
-
- pos = os_strstr(cmd, "dev_id=");
- if (pos) {
- pos += 7;
- if (hwaddr_aton(pos, dev_id))
- return -1;
- _dev_id = dev_id;
- }
-
- pos = os_strstr(cmd, "dev_type=");
- if (pos) {
- pos += 9;
- if (wps_dev_type_str2bin(pos, dev_type) < 0)
- return -1;
- _dev_type = dev_type;
- }
-
- pos = os_strstr(cmd, "delay=");
- if (pos) {
- pos += 6;
- search_delay = atoi(pos);
- } else
- search_delay = wpas_p2p_search_delay(wpa_s);
-
- pos = os_strstr(cmd, "freq=");
- if (pos) {
- pos += 5;
- freq = atoi(pos);
- if (freq <= 0)
- return -1;
- }
-
- /* Must be searched for last, because it adds nul termination */
- pos = os_strstr(cmd, " seek=");
- if (pos)
- pos += 6;
- while (pos && seek_count < P2P_MAX_QUERY_HASH + 1) {
- char *term;
-
- _seek[seek_count++] = pos;
- seek = _seek;
- term = os_strchr(pos, ' ');
- if (!term)
- break;
- *term = '\0';
- pos = os_strstr(term + 1, "seek=");
- if (pos)
- pos += 5;
- }
- if (seek_count > P2P_MAX_QUERY_HASH) {
- seek[0] = NULL;
- seek_count = 1;
- }
-
- return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type,
- _dev_id, search_delay, seek_count, seek, freq,
- include_6ghz);
-}
-
-
-static int p2ps_ctrl_parse_cpt_priority(const char *pos, u8 *cpt)
-{
- const char *last = NULL;
- const char *token;
- long int token_len;
- unsigned int i;
-
- /* Expected predefined CPT names delimited by ':' */
- for (i = 0; (token = cstr_token(pos, ": \t", &last)); i++) {
- if (i >= P2PS_FEATURE_CAPAB_CPT_MAX) {
- wpa_printf(MSG_ERROR,
- "P2PS: CPT name list is too long, expected up to %d names",
- P2PS_FEATURE_CAPAB_CPT_MAX);
- cpt[0] = 0;
- return -1;
- }
-
- token_len = last - token;
-
- if (token_len == 3 &&
- os_memcmp(token, "UDP", token_len) == 0) {
- cpt[i] = P2PS_FEATURE_CAPAB_UDP_TRANSPORT;
- } else if (token_len == 3 &&
- os_memcmp(token, "MAC", token_len) == 0) {
- cpt[i] = P2PS_FEATURE_CAPAB_MAC_TRANSPORT;
- } else {
- wpa_printf(MSG_ERROR,
- "P2PS: Unsupported CPT name '%s'", token);
- cpt[0] = 0;
- return -1;
- }
-
- if (isblank((unsigned char) *last)) {
- i++;
- break;
- }
- }
- cpt[i] = 0;
- return 0;
-}
-
-
-static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
-{
- struct p2ps_provision *p2ps_prov;
- char *pos;
- size_t info_len = 0;
- char *info = NULL;
- u8 role = P2PS_SETUP_NONE;
- long long unsigned val;
- int i;
-
- pos = os_strstr(cmd, "info=");
- if (pos) {
- pos += 5;
- info_len = os_strlen(pos);
-
- if (info_len) {
- info = os_malloc(info_len + 1);
- if (info) {
- info_len = utf8_unescape(pos, info_len,
- info, info_len + 1);
- } else
- info_len = 0;
- }
- }
-
- p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + info_len + 1);
- if (p2ps_prov == NULL) {
- os_free(info);
- return NULL;
- }
-
- if (info) {
- os_memcpy(p2ps_prov->info, info, info_len);
- p2ps_prov->info[info_len] = '\0';
- os_free(info);
- }
-
- pos = os_strstr(cmd, "status=");
- if (pos)
- p2ps_prov->status = atoi(pos + 7);
- else
- p2ps_prov->status = -1;
-
- pos = os_strstr(cmd, "adv_id=");
- if (!pos || sscanf(pos + 7, "%llx", &val) != 1 || val > 0xffffffffULL)
- goto invalid_args;
- p2ps_prov->adv_id = val;
-
- pos = os_strstr(cmd, "method=");
- if (pos)
- p2ps_prov->method = strtol(pos + 7, NULL, 16);
- else
- p2ps_prov->method = 0;
-
- pos = os_strstr(cmd, "session=");
- if (!pos || sscanf(pos + 8, "%llx", &val) != 1 || val > 0xffffffffULL)
- goto invalid_args;
- p2ps_prov->session_id = val;
-
- pos = os_strstr(cmd, "adv_mac=");
- if (!pos || hwaddr_aton(pos + 8, p2ps_prov->adv_mac))
- goto invalid_args;
-
- pos = os_strstr(cmd, "session_mac=");
- if (!pos || hwaddr_aton(pos + 12, p2ps_prov->session_mac))
- goto invalid_args;
-
- pos = os_strstr(cmd, "cpt=");
- if (pos) {
- if (p2ps_ctrl_parse_cpt_priority(pos + 4,
- p2ps_prov->cpt_priority))
- goto invalid_args;
- } else {
- p2ps_prov->cpt_priority[0] = P2PS_FEATURE_CAPAB_UDP_TRANSPORT;
- }
-
- for (i = 0; p2ps_prov->cpt_priority[i]; i++)
- p2ps_prov->cpt_mask |= p2ps_prov->cpt_priority[i];
-
- /* force conncap with tstCap (no validity checks) */
- pos = os_strstr(cmd, "tstCap=");
- if (pos) {
- role = strtol(pos + 7, NULL, 16);
- } else {
- pos = os_strstr(cmd, "role=");
- if (pos) {
- role = strtol(pos + 5, NULL, 16);
- if (role != P2PS_SETUP_CLIENT &&
- role != P2PS_SETUP_GROUP_OWNER)
- role = P2PS_SETUP_NONE;
- }
- }
- p2ps_prov->role = role;
-
- return p2ps_prov;
-
-invalid_args:
- os_free(p2ps_prov);
- return NULL;
-}
-
-
-static int p2p_ctrl_asp_provision_resp(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
- struct p2ps_provision *p2ps_prov;
- char *pos;
-
- /* <addr> id=<adv_id> [role=<conncap>] [info=<infodata>] */
-
- wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- pos = cmd + 17;
- if (*pos != ' ')
- return -1;
-
- p2ps_prov = p2p_parse_asp_provision_cmd(pos);
- if (!p2ps_prov)
- return -1;
-
- if (p2ps_prov->status < 0) {
- os_free(p2ps_prov);
- return -1;
- }
-
- return wpas_p2p_prov_disc(wpa_s, addr, NULL, WPAS_P2P_PD_FOR_ASP,
- p2ps_prov);
-}
-
-
-static int p2p_ctrl_asp_provision(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
- struct p2ps_provision *p2ps_prov;
- char *pos;
-
- /* <addr> id=<adv_id> adv_mac=<adv_mac> conncap=<conncap>
- * session=<ses_id> mac=<ses_mac> [info=<infodata>]
- */
-
- wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- pos = cmd + 17;
- if (*pos != ' ')
- return -1;
-
- p2ps_prov = p2p_parse_asp_provision_cmd(pos);
- if (!p2ps_prov)
- return -1;
-
- p2ps_prov->pd_seeker = 1;
-
- return wpas_p2p_prov_disc(wpa_s, addr, NULL, WPAS_P2P_PD_FOR_ASP,
- p2ps_prov);
-}
-
-
-static int parse_freq(int chwidth, int freq2)
-{
- if (freq2 < 0)
- return -1;
- if (freq2)
- return CHANWIDTH_80P80MHZ;
-
- switch (chwidth) {
- case 0:
- case 20:
- case 40:
- return CHANWIDTH_USE_HT;
- case 80:
- return CHANWIDTH_80MHZ;
- case 160:
- return CHANWIDTH_160MHZ;
- default:
- wpa_printf(MSG_DEBUG, "Unknown max oper bandwidth: %d",
- chwidth);
- return -1;
- }
-}
-
-
-static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- u8 addr[ETH_ALEN];
- char *pos, *pos2;
- char *pin = NULL;
- enum p2p_wps_method wps_method;
- int new_pin;
- int ret;
- int persistent_group, persistent_id = -1;
- int join;
- int auth;
- int automatic;
- int go_intent = -1;
- int freq = 0;
- int pd;
- int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
- int edmg;
- u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL;
- size_t group_ssid_len = 0;
- int he;
- bool allow_6ghz;
-
- if (!wpa_s->global->p2p_init_wpa_s)
- return -1;
- if (wpa_s->global->p2p_init_wpa_s != wpa_s) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Direct P2P_CONNECT command to %s",
- wpa_s->global->p2p_init_wpa_s->ifname);
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- }
-
- /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad|p2ps]
- * [persistent|persistent=<network id>]
- * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
- * [ht40] [vht] [he] [edmg] [auto] [ssid=<hexdump>] */
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- pos = cmd + 17;
- if (*pos != ' ')
- return -1;
- pos++;
-
- persistent_group = os_strstr(pos, " persistent") != NULL;
- pos2 = os_strstr(pos, " persistent=");
- if (pos2) {
- struct wpa_ssid *ssid;
- persistent_id = atoi(pos2 + 12);
- ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
- if (ssid == NULL || ssid->disabled != 2 ||
- ssid->mode != WPAS_MODE_P2P_GO) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
- "SSID id=%d for persistent P2P group (GO)",
- persistent_id);
- return -1;
- }
- }
- join = os_strstr(pos, " join") != NULL;
- allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
- auth = os_strstr(pos, " auth") != NULL;
- automatic = os_strstr(pos, " auto") != NULL;
- pd = os_strstr(pos, " provdisc") != NULL;
- vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
- ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
- vht;
- he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he;
- edmg = (os_strstr(cmd, " edmg") != NULL) || wpa_s->conf->p2p_go_edmg;
-
- pos2 = os_strstr(pos, " go_intent=");
- if (pos2) {
- pos2 += 11;
- go_intent = atoi(pos2);
- if (go_intent < 0 || go_intent > 15)
- return -1;
- }
-
- pos2 = os_strstr(pos, " freq=");
- if (pos2) {
- pos2 += 6;
- freq = atoi(pos2);
- if (freq <= 0)
- return -1;
- }
-
- pos2 = os_strstr(pos, " freq2=");
- if (pos2)
- freq2 = atoi(pos2 + 7);
-
- pos2 = os_strstr(pos, " max_oper_chwidth=");
- if (pos2)
- chwidth = atoi(pos2 + 18);
-
- max_oper_chwidth = parse_freq(chwidth, freq2);
- if (max_oper_chwidth < 0)
- return -1;
-
- if (allow_6ghz && chwidth == 40)
- max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
-
- pos2 = os_strstr(pos, " ssid=");
- if (pos2) {
- char *end;
-
- pos2 += 6;
- end = os_strchr(pos2, ' ');
- if (!end)
- group_ssid_len = os_strlen(pos2) / 2;
- else
- group_ssid_len = (end - pos2) / 2;
- if (group_ssid_len == 0 || group_ssid_len > SSID_MAX_LEN ||
- hexstr2bin(pos2, _group_ssid, group_ssid_len) < 0)
- return -1;
- group_ssid = _group_ssid;
- }
-
- if (os_strncmp(pos, "pin", 3) == 0) {
- /* Request random PIN (to be displayed) and enable the PIN */
- wps_method = WPS_PIN_DISPLAY;
- } else if (os_strncmp(pos, "pbc", 3) == 0) {
- wps_method = WPS_PBC;
- } else if (os_strstr(pos, "p2ps") != NULL) {
- wps_method = WPS_P2PS;
- } else {
- pin = pos;
- pos = os_strchr(pin, ' ');
- wps_method = WPS_PIN_KEYPAD;
- if (pos) {
- *pos++ = '\0';
- if (os_strncmp(pos, "display", 7) == 0)
- wps_method = WPS_PIN_DISPLAY;
- }
- if (!wps_pin_str_valid(pin)) {
- os_memcpy(buf, "FAIL-INVALID-PIN\n", 17);
- return 17;
- }
- }
-
- new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
- persistent_group, automatic, join,
- auth, go_intent, freq, freq2, persistent_id,
- pd, ht40, vht, max_oper_chwidth, he, edmg,
- group_ssid, group_ssid_len, allow_6ghz);
- if (new_pin == -2) {
- os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
- return 25;
- }
- if (new_pin == -3) {
- os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
- return 25;
- }
- if (new_pin < 0)
- return -1;
- if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
- ret = os_snprintf(buf, buflen, "%08d", new_pin);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
- }
-
- os_memcpy(buf, "OK\n", 3);
- return 3;
-}
-
-
-static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
-{
- unsigned int timeout = atoi(cmd);
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_dbg(wpa_s, MSG_INFO,
- "Reject P2P_LISTEN since interface is disabled");
- return -1;
- }
- return wpas_p2p_listen(wpa_s, timeout);
-}
-
-
-static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
- char *pos;
- enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG;
-
- /* <addr> <config method> [join|auto] */
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- pos = cmd + 17;
- if (*pos != ' ')
- return -1;
- pos++;
-
- if (os_strstr(pos, " join") != NULL)
- use = WPAS_P2P_PD_FOR_JOIN;
- else if (os_strstr(pos, " auto") != NULL)
- use = WPAS_P2P_PD_AUTO;
-
- return wpas_p2p_prov_disc(wpa_s, addr, pos, use, NULL);
-}
-
-
-static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
- size_t buflen)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
- ssid->passphrase == NULL)
- return -1;
-
- os_strlcpy(buf, ssid->passphrase, buflen);
- return os_strlen(buf);
-}
-
-
-static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- u64 ref;
- int res;
- u8 dst_buf[ETH_ALEN], *dst;
- struct wpabuf *tlvs;
- char *pos;
- size_t len;
-
- if (hwaddr_aton(cmd, dst_buf))
- return -1;
- dst = dst_buf;
- if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
- dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
- dst = NULL;
- pos = cmd + 17;
- if (*pos != ' ')
- return -1;
- pos++;
-
- if (os_strncmp(pos, "upnp ", 5) == 0) {
- u8 version;
- pos += 5;
- if (hexstr2bin(pos, &version, 1) < 0)
- return -1;
- pos += 2;
- if (*pos != ' ')
- return -1;
- pos++;
- ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
-#ifdef CONFIG_WIFI_DISPLAY
- } else if (os_strncmp(pos, "wifi-display ", 13) == 0) {
- ref = wpas_p2p_sd_request_wifi_display(wpa_s, dst, pos + 13);
-#endif /* CONFIG_WIFI_DISPLAY */
- } else if (os_strncmp(pos, "asp ", 4) == 0) {
- char *svc_str;
- char *svc_info = NULL;
- u32 id;
-
- pos += 4;
- if (sscanf(pos, "%x", &id) != 1 || id > 0xff)
- return -1;
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL || pos[1] == '\0' || pos[1] == ' ')
- return -1;
-
- svc_str = pos + 1;
-
- pos = os_strchr(svc_str, ' ');
-
- if (pos)
- *pos++ = '\0';
-
- /* All remaining data is the svc_info string */
- if (pos && pos[0] && pos[0] != ' ') {
- len = os_strlen(pos);
-
- /* Unescape in place */
- len = utf8_unescape(pos, len, pos, len);
- if (len > 0xff)
- return -1;
-
- svc_info = pos;
- }
-
- ref = wpas_p2p_sd_request_asp(wpa_s, dst, (u8) id,
- svc_str, svc_info);
- } else {
- len = os_strlen(pos);
- if (len & 1)
- return -1;
- len /= 2;
- tlvs = wpabuf_alloc(len);
- if (tlvs == NULL)
- return -1;
- if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
- wpabuf_free(tlvs);
- return -1;
- }
-
- ref = wpas_p2p_sd_request(wpa_s, dst, tlvs);
- wpabuf_free(tlvs);
- }
- if (ref == 0)
- return -1;
- res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
-}
-
-
-static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- long long unsigned val;
- u64 req;
- if (sscanf(cmd, "%llx", &val) != 1)
- return -1;
- req = val;
- return wpas_p2p_sd_cancel_request(wpa_s, req);
-}
-
-
-static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
-{
- int freq;
- u8 dst[ETH_ALEN];
- u8 dialog_token;
- struct wpabuf *resp_tlvs;
- char *pos, *pos2;
- size_t len;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- freq = atoi(cmd);
- if (freq == 0)
- return -1;
-
- if (hwaddr_aton(pos, dst))
- return -1;
- pos += 17;
- if (*pos != ' ')
- return -1;
- pos++;
-
- pos2 = os_strchr(pos, ' ');
- if (pos2 == NULL)
- return -1;
- *pos2++ = '\0';
- dialog_token = atoi(pos);
-
- len = os_strlen(pos2);
- if (len & 1)
- return -1;
- len /= 2;
- resp_tlvs = wpabuf_alloc(len);
- if (resp_tlvs == NULL)
- return -1;
- if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
- wpabuf_free(resp_tlvs);
- return -1;
- }
-
- wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
- wpabuf_free(resp_tlvs);
- return 0;
-}
-
-
-static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1"))
- return -1;
- wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
- return 0;
-}
-
-
-static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *pos;
- size_t len;
- struct wpabuf *query, *resp;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- len = os_strlen(cmd);
- if (len & 1)
- return -1;
- len /= 2;
- query = wpabuf_alloc(len);
- if (query == NULL)
- return -1;
- if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
- wpabuf_free(query);
- return -1;
- }
-
- len = os_strlen(pos);
- if (len & 1) {
- wpabuf_free(query);
- return -1;
- }
- len /= 2;
- resp = wpabuf_alloc(len);
- if (resp == NULL) {
- wpabuf_free(query);
- return -1;
- }
- if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
- wpabuf_free(query);
- wpabuf_free(resp);
- return -1;
- }
-
- if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
- wpabuf_free(query);
- wpabuf_free(resp);
- return -1;
- }
- return 0;
-}
-
-
-static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- u8 version;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (hexstr2bin(cmd, &version, 1) < 0)
- return -1;
-
- return wpas_p2p_service_add_upnp(wpa_s, version, pos);
-}
-
-
-static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s,
- u8 replace, char *cmd)
-{
- char *pos;
- char *adv_str;
- u32 auto_accept, adv_id, svc_state, config_methods;
- char *svc_info = NULL;
- char *cpt_prio_str;
- u8 cpt_prio[P2PS_FEATURE_CAPAB_CPT_MAX + 1];
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- /* Auto-Accept value is mandatory, and must be one of the
- * single values (0, 1, 2, 4) */
- auto_accept = atoi(cmd);
- switch (auto_accept) {
- case P2PS_SETUP_NONE: /* No auto-accept */
- case P2PS_SETUP_NEW:
- case P2PS_SETUP_CLIENT:
- case P2PS_SETUP_GROUP_OWNER:
- break;
- default:
- return -1;
- }
-
- /* Advertisement ID is mandatory */
- cmd = pos;
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- /* Handle Adv_ID == 0 (wildcard "org.wi-fi.wfds") internally. */
- if (sscanf(cmd, "%x", &adv_id) != 1 || adv_id == 0)
- return -1;
-
- /* Only allow replacements if exist, and adds if not */
- if (wpas_p2p_service_p2ps_id_exists(wpa_s, adv_id)) {
- if (!replace)
- return -1;
- } else {
- if (replace)
- return -1;
- }
-
- /* svc_state between 0 - 0xff is mandatory */
- if (sscanf(pos, "%x", &svc_state) != 1 || svc_state > 0xff)
- return -1;
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
-
- /* config_methods is mandatory */
- pos++;
- if (sscanf(pos, "%x", &config_methods) != 1)
- return -1;
-
- if (!(config_methods &
- (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | WPS_CONFIG_P2PS)))
- return -1;
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
-
- pos++;
- adv_str = pos;
-
- /* Advertisement string is mandatory */
- if (!pos[0] || pos[0] == ' ')
- return -1;
-
- /* Terminate svc string */
- pos = os_strchr(pos, ' ');
- if (pos != NULL)
- *pos++ = '\0';
-
- cpt_prio_str = (pos && pos[0]) ? os_strstr(pos, "cpt=") : NULL;
- if (cpt_prio_str) {
- pos = os_strchr(pos, ' ');
- if (pos != NULL)
- *pos++ = '\0';
-
- if (p2ps_ctrl_parse_cpt_priority(cpt_prio_str + 4, cpt_prio))
- return -1;
- } else {
- cpt_prio[0] = P2PS_FEATURE_CAPAB_UDP_TRANSPORT;
- cpt_prio[1] = 0;
- }
-
- /* Service and Response Information are optional */
- if (pos && pos[0]) {
- size_t len;
-
- /* Note the bare ' included, which cannot exist legally
- * in unescaped string. */
- svc_info = os_strstr(pos, "svc_info='");
-
- if (svc_info) {
- svc_info += 9;
- len = os_strlen(svc_info);
- utf8_unescape(svc_info, len, svc_info, len);
- }
- }
-
- return wpas_p2p_service_add_asp(wpa_s, auto_accept, adv_id, adv_str,
- (u8) svc_state, (u16) config_methods,
- svc_info, cpt_prio);
-}
-
-
-static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "bonjour") == 0)
- return p2p_ctrl_service_add_bonjour(wpa_s, pos);
- if (os_strcmp(cmd, "upnp") == 0)
- return p2p_ctrl_service_add_upnp(wpa_s, pos);
- if (os_strcmp(cmd, "asp") == 0)
- return p2p_ctrl_service_add_asp(wpa_s, 0, pos);
- wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
- return -1;
-}
-
-
-static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- size_t len;
- struct wpabuf *query;
- int ret;
-
- len = os_strlen(cmd);
- if (len & 1)
- return -1;
- len /= 2;
- query = wpabuf_alloc(len);
- if (query == NULL)
- return -1;
- if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
- wpabuf_free(query);
- return -1;
- }
-
- ret = wpas_p2p_service_del_bonjour(wpa_s, query);
- wpabuf_free(query);
- return ret;
-}
-
-
-static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- u8 version;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (hexstr2bin(cmd, &version, 1) < 0)
- return -1;
-
- return wpas_p2p_service_del_upnp(wpa_s, version, pos);
-}
-
-
-static int p2p_ctrl_service_del_asp(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u32 adv_id;
-
- if (os_strcmp(cmd, "all") == 0) {
- wpas_p2p_service_flush_asp(wpa_s);
- return 0;
- }
-
- if (sscanf(cmd, "%x", &adv_id) != 1)
- return -1;
-
- return wpas_p2p_service_del_asp(wpa_s, adv_id);
-}
-
-
-static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "bonjour") == 0)
- return p2p_ctrl_service_del_bonjour(wpa_s, pos);
- if (os_strcmp(cmd, "upnp") == 0)
- return p2p_ctrl_service_del_upnp(wpa_s, pos);
- if (os_strcmp(cmd, "asp") == 0)
- return p2p_ctrl_service_del_asp(wpa_s, pos);
- wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
- return -1;
-}
-
-
-static int p2p_ctrl_service_replace(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- if (os_strcmp(cmd, "asp") == 0)
- return p2p_ctrl_service_add_asp(wpa_s, 1, pos);
-
- wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
- return -1;
-}
-
-
-static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 addr[ETH_ALEN];
-
- /* <addr> */
-
- if (hwaddr_aton(cmd, addr))
- return -1;
-
- return wpas_p2p_reject(wpa_s, addr);
-}
-
-
-static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- int id;
- struct wpa_ssid *ssid;
- u8 *_peer = NULL, peer[ETH_ALEN];
- int freq = 0, pref_freq = 0;
- int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0;
- int edmg;
- bool allow_6ghz;
-
- id = atoi(cmd);
- pos = os_strstr(cmd, " peer=");
- if (pos) {
- pos += 6;
- if (hwaddr_aton(pos, peer))
- return -1;
- _peer = peer;
- }
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL || ssid->disabled != 2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
- "for persistent P2P group",
- id);
- return -1;
- }
-
- pos = os_strstr(cmd, " freq=");
- if (pos) {
- pos += 6;
- freq = atoi(pos);
- if (freq <= 0)
- return -1;
- }
-
- pos = os_strstr(cmd, " pref=");
- if (pos) {
- pos += 6;
- pref_freq = atoi(pos);
- if (pref_freq <= 0)
- return -1;
- }
-
- vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
- ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
- vht;
- he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he;
- edmg = (os_strstr(cmd, " edmg") != NULL) || wpa_s->conf->p2p_go_edmg;
-
- pos = os_strstr(cmd, "freq2=");
- if (pos)
- freq2 = atoi(pos + 6);
-
- pos = os_strstr(cmd, " max_oper_chwidth=");
- if (pos)
- chwidth = atoi(pos + 18);
-
- max_oper_chwidth = parse_freq(chwidth, freq2);
- if (max_oper_chwidth < 0)
- return -1;
-
- allow_6ghz = os_strstr(cmd, " allow_6ghz") != NULL;
-
- if (allow_6ghz && chwidth == 40)
- max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
-
- return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
- max_oper_chwidth, pref_freq, he, edmg,
- allow_6ghz);
-}
-
-
-static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
- bool allow_6ghz;
-
- pos = os_strstr(cmd, " peer=");
- if (!pos)
- return -1;
-
- *pos = '\0';
- pos += 6;
- if (hwaddr_aton(pos, peer)) {
- wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
- return -1;
- }
-
- allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
-
- pos = os_strstr(pos, " go_dev_addr=");
- if (pos) {
- pos += 13;
- if (hwaddr_aton(pos, go_dev_addr)) {
- wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
- pos);
- return -1;
- }
- go_dev = go_dev_addr;
- }
-
- return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev, allow_6ghz);
-}
-
-
-static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
-{
- if (os_strncmp(cmd, "persistent=", 11) == 0)
- return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
- if (os_strncmp(cmd, "group=", 6) == 0)
- return p2p_ctrl_invite_group(wpa_s, cmd + 6);
-
- return -1;
-}
-
-
-static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
- int id, int freq, int vht_center_freq2,
- int ht40, int vht, int vht_chwidth,
- int he, int edmg, bool allow_6ghz)
-{
- struct wpa_ssid *ssid;
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL || ssid->disabled != 2) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
- "for persistent P2P group",
- id);
- return -1;
- }
-
- return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
- vht_center_freq2, 0, ht40, vht,
- vht_chwidth, he, edmg,
- NULL, 0, 0, allow_6ghz);
-}
-
-
-static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
-{
- int freq = 0, persistent = 0, group_id = -1;
- bool allow_6ghz = false;
- int vht = wpa_s->conf->p2p_go_vht;
- int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
- int he = wpa_s->conf->p2p_go_he;
- int edmg = wpa_s->conf->p2p_go_edmg;
- int max_oper_chwidth, chwidth = 0, freq2 = 0;
- char *token, *context = NULL;
-#ifdef CONFIG_ACS
- int acs = 0;
-#endif /* CONFIG_ACS */
-
- while ((token = str_token(cmd, " ", &context))) {
- if (sscanf(token, "freq2=%d", &freq2) == 1 ||
- sscanf(token, "persistent=%d", &group_id) == 1 ||
- sscanf(token, "max_oper_chwidth=%d", &chwidth) == 1) {
- continue;
-#ifdef CONFIG_ACS
- } else if (os_strcmp(token, "freq=acs") == 0) {
- acs = 1;
-#endif /* CONFIG_ACS */
- } else if (sscanf(token, "freq=%d", &freq) == 1) {
- continue;
- } else if (os_strcmp(token, "ht40") == 0) {
- ht40 = 1;
- } else if (os_strcmp(token, "vht") == 0) {
- vht = 1;
- ht40 = 1;
- } else if (os_strcmp(token, "he") == 0) {
- he = 1;
- } else if (os_strcmp(token, "edmg") == 0) {
- edmg = 1;
- } else if (os_strcmp(token, "persistent") == 0) {
- persistent = 1;
- } else if (os_strcmp(token, "allow_6ghz") == 0) {
- allow_6ghz = true;
- } else {
- wpa_printf(MSG_DEBUG,
- "CTRL: Invalid P2P_GROUP_ADD parameter: '%s'",
- token);
- return -1;
- }
- }
-
-#ifdef CONFIG_ACS
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) &&
- (acs || freq == 2 || freq == 5)) {
- if (freq == 2 && wpa_s->best_24_freq <= 0) {
- wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211G;
- wpa_s->p2p_go_do_acs = 1;
- freq = 0;
- } else if (freq == 5 && wpa_s->best_5_freq <= 0) {
- wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211A;
- wpa_s->p2p_go_do_acs = 1;
- freq = 0;
- } else {
- wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
- wpa_s->p2p_go_do_acs = 1;
- }
- } else {
- wpa_s->p2p_go_do_acs = 0;
- }
-#endif /* CONFIG_ACS */
-
- max_oper_chwidth = parse_freq(chwidth, freq2);
- if (max_oper_chwidth < 0)
- return -1;
-
- if (allow_6ghz && chwidth == 40)
- max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
-
- /* Allow DFS to be used for Autonomous GO */
- wpa_s->p2p_go_allow_dfs = !!(wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_DFS_OFFLOAD);
-
- if (group_id >= 0)
- return p2p_ctrl_group_add_persistent(wpa_s, group_id,
- freq, freq2, ht40, vht,
- max_oper_chwidth, he,
- edmg, allow_6ghz);
-
- return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
- max_oper_chwidth, he, edmg, allow_6ghz);
-}
-
-
-static int p2p_ctrl_group_member(struct wpa_supplicant *wpa_s, const char *cmd,
- char *buf, size_t buflen)
-{
- u8 dev_addr[ETH_ALEN];
- struct wpa_ssid *ssid;
- int res;
- const u8 *iaddr;
-
- ssid = wpa_s->current_ssid;
- if (!wpa_s->global->p2p || !ssid || ssid->mode != WPAS_MODE_P2P_GO ||
- hwaddr_aton(cmd, dev_addr))
- return -1;
-
- iaddr = p2p_group_get_client_interface_addr(wpa_s->p2p_group, dev_addr);
- if (!iaddr)
- return -1;
- res = os_snprintf(buf, buflen, MACSTR, MAC2STR(iaddr));
- if (os_snprintf_error(buflen, res))
- return -1;
- return res;
-}
-
-
-static int wpas_find_p2p_dev_addr_bss(struct wpa_global *global,
- const u8 *p2p_dev_addr)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_bss_get_p2p_dev_addr(wpa_s, p2p_dev_addr))
- return 1;
- }
-
- return 0;
-}
-
-
-static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- u8 addr[ETH_ALEN], *addr_ptr, group_capab;
- int next, res;
- const struct p2p_peer_info *info;
- char *pos, *end;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
- struct wpa_ssid *ssid;
- size_t i;
-
- if (!wpa_s->global->p2p)
- return -1;
-
- if (os_strcmp(cmd, "FIRST") == 0) {
- addr_ptr = NULL;
- next = 0;
- } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
- if (hwaddr_aton(cmd + 5, addr) < 0)
- return -1;
- addr_ptr = addr;
- next = 1;
- } else {
- if (hwaddr_aton(cmd, addr) < 0)
- return -1;
- addr_ptr = addr;
- next = 0;
- }
-
- info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
- if (info == NULL)
- return -1;
- group_capab = info->group_capab;
-
- if (group_capab &&
- !wpas_find_p2p_dev_addr_bss(wpa_s->global, info->p2p_device_addr)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Could not find any BSS with p2p_dev_addr "
- MACSTR ", hence override group_capab from 0x%x to 0",
- MAC2STR(info->p2p_device_addr), group_capab);
- group_capab = 0;
- }
-
- pos = buf;
- end = buf + buflen;
-
- res = os_snprintf(pos, end - pos, MACSTR "\n"
- "pri_dev_type=%s\n"
- "device_name=%s\n"
- "manufacturer=%s\n"
- "model_name=%s\n"
- "model_number=%s\n"
- "serial_number=%s\n"
- "config_methods=0x%x\n"
- "dev_capab=0x%x\n"
- "group_capab=0x%x\n"
- "level=%d\n",
- MAC2STR(info->p2p_device_addr),
- wps_dev_type_bin2str(info->pri_dev_type,
- devtype, sizeof(devtype)),
- info->device_name,
- info->manufacturer,
- info->model_name,
- info->model_number,
- info->serial_number,
- info->config_methods,
- info->dev_capab,
- group_capab,
- info->level);
- if (os_snprintf_error(end - pos, res))
- return pos - buf;
- pos += res;
-
- for (i = 0; i < info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN; i++)
- {
- const u8 *t;
- t = &info->wps_sec_dev_type_list[i * WPS_DEV_TYPE_LEN];
- res = os_snprintf(pos, end - pos, "sec_dev_type=%s\n",
- wps_dev_type_bin2str(t, devtype,
- sizeof(devtype)));
- if (os_snprintf_error(end - pos, res))
- return pos - buf;
- pos += res;
- }
-
- ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0);
- if (ssid) {
- res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
- if (os_snprintf_error(end - pos, res))
- return pos - buf;
- pos += res;
- }
-
- res = p2p_get_peer_info_txt(info, pos, end - pos);
- if (res < 0)
- return pos - buf;
- pos += res;
-
- if (info->vendor_elems) {
- res = os_snprintf(pos, end - pos, "vendor_elems=");
- if (os_snprintf_error(end - pos, res))
- return pos - buf;
- pos += res;
-
- pos += wpa_snprintf_hex(pos, end - pos,
- wpabuf_head(info->vendor_elems),
- wpabuf_len(info->vendor_elems));
-
- res = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, res))
- return pos - buf;
- pos += res;
- }
-
- return pos - buf;
-}
-
-
-static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
- const char *param)
-{
- unsigned int i;
-
- if (wpa_s->global->p2p == NULL)
- return -1;
-
- if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0)
- return -1;
-
- for (i = 0; i < wpa_s->global->p2p_disallow_freq.num; i++) {
- struct wpa_freq_range *freq;
- freq = &wpa_s->global->p2p_disallow_freq.range[i];
- wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
- freq->min, freq->max);
- }
-
- wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
- return 0;
-}
-
-
-static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *param;
-
- if (wpa_s->global->p2p == NULL)
- return -1;
-
- param = os_strchr(cmd, ' ');
- if (param == NULL)
- return -1;
- *param++ = '\0';
-
- if (os_strcmp(cmd, "discoverability") == 0) {
- p2p_set_client_discoverability(wpa_s->global->p2p,
- atoi(param));
- return 0;
- }
-
- if (os_strcmp(cmd, "managed") == 0) {
- p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
- return 0;
- }
-
- if (os_strcmp(cmd, "listen_channel") == 0) {
- char *pos;
- u8 channel, op_class;
-
- channel = atoi(param);
- pos = os_strchr(param, ' ');
- op_class = pos ? atoi(pos) : 81;
-
- return p2p_set_listen_channel(wpa_s->global->p2p, op_class,
- channel, 1);
- }
-
- if (os_strcmp(cmd, "ssid_postfix") == 0) {
- return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
- os_strlen(param));
- }
-
- if (os_strcmp(cmd, "noa") == 0) {
- char *pos;
- int count, start, duration;
- /* GO NoA parameters: count,start_offset(ms),duration(ms) */
- count = atoi(param);
- pos = os_strchr(param, ',');
- if (pos == NULL)
- return -1;
- pos++;
- start = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- duration = atoi(pos);
- if (count < 0 || count > 255 || start < 0 || duration < 0)
- return -1;
- if (count == 0 && duration > 0)
- return -1;
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
- "start=%d duration=%d", count, start, duration);
- return wpas_p2p_set_noa(wpa_s, count, start, duration);
- }
-
- if (os_strcmp(cmd, "ps") == 0)
- return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
-
- if (os_strcmp(cmd, "oppps") == 0)
- return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
-
- if (os_strcmp(cmd, "ctwindow") == 0)
- return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
-
- if (os_strcmp(cmd, "disabled") == 0) {
- wpa_s->global->p2p_disabled = atoi(param);
- wpa_printf(MSG_DEBUG, "P2P functionality %s",
- wpa_s->global->p2p_disabled ?
- "disabled" : "enabled");
- if (wpa_s->global->p2p_disabled) {
- wpas_p2p_stop_find(wpa_s);
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
- p2p_flush(wpa_s->global->p2p);
- }
- return 0;
- }
-
- if (os_strcmp(cmd, "conc_pref") == 0) {
- if (os_strcmp(param, "sta") == 0)
- wpa_s->global->conc_pref = WPA_CONC_PREF_STA;
- else if (os_strcmp(param, "p2p") == 0)
- wpa_s->global->conc_pref = WPA_CONC_PREF_P2P;
- else {
- wpa_printf(MSG_INFO, "Invalid conc_pref value");
- return -1;
- }
- wpa_printf(MSG_DEBUG, "Single channel concurrency preference: "
- "%s", param);
- return 0;
- }
-
- if (os_strcmp(cmd, "force_long_sd") == 0) {
- wpa_s->force_long_sd = atoi(param);
- return 0;
- }
-
- if (os_strcmp(cmd, "peer_filter") == 0) {
- u8 addr[ETH_ALEN];
- if (hwaddr_aton(param, addr))
- return -1;
- p2p_set_peer_filter(wpa_s->global->p2p, addr);
- return 0;
- }
-
- if (os_strcmp(cmd, "cross_connect") == 0)
- return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
-
- if (os_strcmp(cmd, "go_apsd") == 0) {
- if (os_strcmp(param, "disable") == 0)
- wpa_s->set_ap_uapsd = 0;
- else {
- wpa_s->set_ap_uapsd = 1;
- wpa_s->ap_uapsd = atoi(param);
- }
- return 0;
- }
-
- if (os_strcmp(cmd, "client_apsd") == 0) {
- if (os_strcmp(param, "disable") == 0)
- wpa_s->set_sta_uapsd = 0;
- else {
- int be, bk, vi, vo;
- char *pos;
- /* format: BE,BK,VI,VO;max SP Length */
- be = atoi(param);
- pos = os_strchr(param, ',');
- if (pos == NULL)
- return -1;
- pos++;
- bk = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- vi = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- vo = atoi(pos);
- /* ignore max SP Length for now */
-
- wpa_s->set_sta_uapsd = 1;
- wpa_s->sta_uapsd = 0;
- if (be)
- wpa_s->sta_uapsd |= BIT(0);
- if (bk)
- wpa_s->sta_uapsd |= BIT(1);
- if (vi)
- wpa_s->sta_uapsd |= BIT(2);
- if (vo)
- wpa_s->sta_uapsd |= BIT(3);
- }
- return 0;
- }
-
- if (os_strcmp(cmd, "disallow_freq") == 0)
- return p2p_ctrl_disallow_freq(wpa_s, param);
-
- if (os_strcmp(cmd, "disc_int") == 0) {
- int min_disc_int, max_disc_int, max_disc_tu;
- char *pos;
-
- pos = param;
-
- min_disc_int = atoi(pos);
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- max_disc_int = atoi(pos);
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- max_disc_tu = atoi(pos);
-
- return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int,
- max_disc_int, max_disc_tu);
- }
-
- if (os_strcmp(cmd, "per_sta_psk") == 0) {
- wpa_s->global->p2p_per_sta_psk = !!atoi(param);
- return 0;
- }
-
-#ifdef CONFIG_WPS_NFC
- if (os_strcmp(cmd, "nfc_tag") == 0)
- return wpas_p2p_nfc_tag_enabled(wpa_s, !!atoi(param));
-#endif /* CONFIG_WPS_NFC */
-
- if (os_strcmp(cmd, "disable_ip_addr_req") == 0) {
- wpa_s->p2p_disable_ip_addr_req = !!atoi(param);
- return 0;
- }
-
- if (os_strcmp(cmd, "override_pref_op_chan") == 0) {
- int op_class, chan;
-
- op_class = atoi(param);
- param = os_strchr(param, ':');
- if (!param)
- return -1;
- param++;
- chan = atoi(param);
- p2p_set_override_pref_op_chan(wpa_s->global->p2p, op_class,
- chan);
- return 0;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
- cmd);
-
- return -1;
-}
-
-
-static void p2p_ctrl_flush(struct wpa_supplicant *wpa_s)
-{
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
- wpa_s->force_long_sd = 0;
-
-#ifdef CONFIG_TESTING_OPTIONS
- os_free(wpa_s->get_pref_freq_list_override);
- wpa_s->get_pref_freq_list_override = NULL;
-#endif /* CONFIG_TESTING_OPTIONS */
-
- wpas_p2p_stop_find(wpa_s);
- wpa_s->parent->p2ps_method_config_any = 0;
- if (wpa_s->global->p2p)
- p2p_flush(wpa_s->global->p2p);
-}
-
-
-static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos, *pos2;
- unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
-
- if (cmd[0]) {
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- dur1 = atoi(cmd);
-
- pos2 = os_strchr(pos, ' ');
- if (pos2)
- *pos2++ = '\0';
- int1 = atoi(pos);
- } else
- pos2 = NULL;
-
- if (pos2) {
- pos = os_strchr(pos2, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- dur2 = atoi(pos2);
- int2 = atoi(pos);
- }
-
- return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
-}
-
-
-static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- unsigned int period = 0, interval = 0;
-
- if (cmd[0]) {
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
- period = atoi(cmd);
- interval = atoi(pos);
- }
-
- return wpas_p2p_ext_listen(wpa_s, period, interval);
-}
-
-
-static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos;
- u8 peer[ETH_ALEN];
- int iface_addr = 0;
-
- pos = cmd;
- if (os_strncmp(pos, "iface=", 6) == 0) {
- iface_addr = 1;
- pos += 6;
- }
- if (hwaddr_aton(pos, peer))
- return -1;
-
- wpas_p2p_remove_client(wpa_s, peer, iface_addr);
- return 0;
-}
-
-
-static int p2p_ctrl_iface_p2p_lo_start(struct wpa_supplicant *wpa_s, char *cmd)
-{
- int freq = 0, period = 0, interval = 0, count = 0;
-
- if (sscanf(cmd, "%d %d %d %d", &freq, &period, &interval, &count) != 4)
- {
- wpa_printf(MSG_DEBUG,
- "CTRL: Invalid P2P LO Start parameter: '%s'", cmd);
- return -1;
- }
-
- return wpas_p2p_lo_start(wpa_s, freq, period, interval, count);
-}
-
-#endif /* CONFIG_P2P */
-
-
-static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s, char *val)
-{
- struct wpa_freq_range_list ranges;
- int *freqs = NULL;
- struct hostapd_hw_modes *mode;
- u16 i;
-
- if (wpa_s->hw.modes == NULL)
- return NULL;
-
- os_memset(&ranges, 0, sizeof(ranges));
- if (freq_range_list_parse(&ranges, val) < 0)
- return NULL;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- int j;
-
- mode = &wpa_s->hw.modes[i];
- for (j = 0; j < mode->num_channels; j++) {
- unsigned int freq;
-
- if (mode->channels[j].flag & HOSTAPD_CHAN_DISABLED)
- continue;
-
- freq = mode->channels[j].freq;
- if (!freq_range_list_includes(&ranges, freq))
- continue;
-
- int_array_add_unique(&freqs, freq);
- }
- }
-
- os_free(ranges.range);
- return freqs;
-}
-
-
-#ifdef CONFIG_INTERWORKING
-
-static int ctrl_interworking_select(struct wpa_supplicant *wpa_s, char *param)
-{
- int auto_sel = 0;
- int *freqs = NULL;
-
- if (param) {
- char *pos;
-
- auto_sel = os_strstr(param, "auto") != NULL;
-
- pos = os_strstr(param, "freq=");
- if (pos) {
- freqs = freq_range_to_channel_list(wpa_s, pos + 5);
- if (freqs == NULL)
- return -1;
- }
-
- }
-
- return interworking_select(wpa_s, auto_sel, freqs);
-}
-
-
-static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst,
- int only_add)
-{
- u8 bssid[ETH_ALEN];
- struct wpa_bss *bss;
-
- if (hwaddr_aton(dst, bssid)) {
- wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst);
- return -1;
- }
-
- bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- if (bss == NULL) {
- wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR,
- MAC2STR(bssid));
- return -1;
- }
-
- if (bss->ssid_len == 0) {
- int found = 0;
-
- wpa_printf(MSG_DEBUG, "Selected BSS entry for " MACSTR
- " does not have SSID information", MAC2STR(bssid));
-
- dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss,
- list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
- bss->ssid_len > 0) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- return -1;
- wpa_printf(MSG_DEBUG,
- "Found another matching BSS entry with SSID");
- }
-
- return interworking_connect(wpa_s, bss, only_add);
-}
-
-
-static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
-{
- u8 dst_addr[ETH_ALEN];
- int used, freq = 0;
- char *pos;
-#define MAX_ANQP_INFO_ID 100
- u16 id[MAX_ANQP_INFO_ID];
- size_t num_id = 0;
- u32 subtypes = 0;
- u32 mbo_subtypes = 0;
-
- used = hwaddr_aton2(dst, dst_addr);
- if (used < 0)
- return -1;
- pos = dst + used;
- if (*pos == ' ')
- pos++;
-
- if (os_strncmp(pos, "freq=", 5) == 0) {
- freq = atoi(pos + 5);
- pos = os_strchr(pos, ' ');
- if (!pos)
- return -1;
- pos++;
- }
-
- while (num_id < MAX_ANQP_INFO_ID) {
- if (os_strncmp(pos, "hs20:", 5) == 0) {
-#ifdef CONFIG_HS20
- int num = atoi(pos + 5);
- if (num <= 0 || num > 31)
- return -1;
- subtypes |= BIT(num);
-#else /* CONFIG_HS20 */
- return -1;
-#endif /* CONFIG_HS20 */
- } else if (os_strncmp(pos, "mbo:", 4) == 0) {
-#ifdef CONFIG_MBO
- int num = atoi(pos + 4);
-
- if (num <= 0 || num > MAX_MBO_ANQP_SUBTYPE)
- return -1;
- mbo_subtypes |= BIT(num);
-#else /* CONFIG_MBO */
- return -1;
-#endif /* CONFIG_MBO */
- } else {
- id[num_id] = atoi(pos);
- if (id[num_id])
- num_id++;
- }
- pos = os_strchr(pos + 1, ',');
- if (pos == NULL)
- break;
- pos++;
- }
-
- if (num_id == 0 && !subtypes && !mbo_subtypes)
- return -1;
-
- return anqp_send_req(wpa_s, dst_addr, freq, id, num_id, subtypes,
- mbo_subtypes);
-}
-
-
-static int gas_request(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 dst_addr[ETH_ALEN];
- struct wpabuf *advproto, *query = NULL;
- int used, ret = -1;
- char *pos, *end;
- size_t len;
-
- used = hwaddr_aton2(cmd, dst_addr);
- if (used < 0)
- return -1;
-
- pos = cmd + used;
- while (*pos == ' ')
- pos++;
-
- /* Advertisement Protocol ID */
- end = os_strchr(pos, ' ');
- if (end)
- len = end - pos;
- else
- len = os_strlen(pos);
- if (len & 0x01)
- return -1;
- len /= 2;
- if (len == 0)
- return -1;
- advproto = wpabuf_alloc(len);
- if (advproto == NULL)
- return -1;
- if (hexstr2bin(pos, wpabuf_put(advproto, len), len) < 0)
- goto fail;
-
- if (end) {
- /* Optional Query Request */
- pos = end + 1;
- while (*pos == ' ')
- pos++;
-
- len = os_strlen(pos);
- if (len) {
- if (len & 0x01)
- goto fail;
- len /= 2;
- if (len == 0)
- goto fail;
- query = wpabuf_alloc(len);
- if (query == NULL)
- goto fail;
- if (hexstr2bin(pos, wpabuf_put(query, len), len) < 0)
- goto fail;
- }
- }
-
- ret = gas_send_request(wpa_s, dst_addr, advproto, query);
-
-fail:
- wpabuf_free(advproto);
- wpabuf_free(query);
-
- return ret;
-}
-
-
-static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
- size_t buflen)
-{
- u8 addr[ETH_ALEN];
- int dialog_token;
- int used;
- char *pos;
- size_t resp_len, start, requested_len;
- struct wpabuf *resp;
- int ret;
-
- used = hwaddr_aton2(cmd, addr);
- if (used < 0)
- return -1;
-
- pos = cmd + used;
- while (*pos == ' ')
- pos++;
- dialog_token = atoi(pos);
-
- if (wpa_s->last_gas_resp &&
- os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) == 0 &&
- dialog_token == wpa_s->last_gas_dialog_token)
- resp = wpa_s->last_gas_resp;
- else if (wpa_s->prev_gas_resp &&
- os_memcmp(addr, wpa_s->prev_gas_addr, ETH_ALEN) == 0 &&
- dialog_token == wpa_s->prev_gas_dialog_token)
- resp = wpa_s->prev_gas_resp;
- else
- return -1;
-
- resp_len = wpabuf_len(resp);
- start = 0;
- requested_len = resp_len;
-
- pos = os_strchr(pos, ' ');
- if (pos) {
- start = atoi(pos);
- if (start > resp_len)
- return os_snprintf(buf, buflen, "FAIL-Invalid range");
- pos = os_strchr(pos, ',');
- if (pos == NULL)
- return -1;
- pos++;
- requested_len = atoi(pos);
- if (start + requested_len > resp_len)
- return os_snprintf(buf, buflen, "FAIL-Invalid range");
- }
-
- if (requested_len * 2 + 1 > buflen)
- return os_snprintf(buf, buflen, "FAIL-Too long response");
-
- ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(resp) + start,
- requested_len);
-
- if (start + requested_len == resp_len) {
- /*
- * Free memory by dropping the response after it has been
- * fetched.
- */
- if (resp == wpa_s->prev_gas_resp) {
- wpabuf_free(wpa_s->prev_gas_resp);
- wpa_s->prev_gas_resp = NULL;
- } else {
- wpabuf_free(wpa_s->last_gas_resp);
- wpa_s->last_gas_resp = NULL;
- }
- }
-
- return ret;
-}
-#endif /* CONFIG_INTERWORKING */
-
-
-#ifdef CONFIG_HS20
-
-static int get_hs20_anqp(struct wpa_supplicant *wpa_s, char *dst)
-{
- u8 dst_addr[ETH_ALEN];
- int used;
- char *pos;
- u32 subtypes = 0;
-
- used = hwaddr_aton2(dst, dst_addr);
- if (used < 0)
- return -1;
- pos = dst + used;
- if (*pos == ' ')
- pos++;
- for (;;) {
- int num = atoi(pos);
- if (num <= 0 || num > 31)
- return -1;
- subtypes |= BIT(num);
- pos = os_strchr(pos + 1, ',');
- if (pos == NULL)
- break;
- pos++;
- }
-
- if (subtypes == 0)
- return -1;
-
- return hs20_anqp_send_req(wpa_s, dst_addr, subtypes, NULL, 0, 0);
-}
-
-
-static int hs20_nai_home_realm_list(struct wpa_supplicant *wpa_s,
- const u8 *addr, const char *realm)
-{
- u8 *buf;
- size_t rlen, len;
- int ret;
-
- rlen = os_strlen(realm);
- len = 3 + rlen;
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
- buf[0] = 1; /* NAI Home Realm Count */
- buf[1] = 0; /* Formatted in accordance with RFC 4282 */
- buf[2] = rlen;
- os_memcpy(buf + 3, realm, rlen);
-
- ret = hs20_anqp_send_req(wpa_s, addr,
- BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
- buf, len, 0);
-
- os_free(buf);
-
- return ret;
-}
-
-
-static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s,
- char *dst)
-{
- struct wpa_cred *cred = wpa_s->conf->cred;
- u8 dst_addr[ETH_ALEN];
- int used;
- u8 *buf;
- size_t len;
- int ret;
-
- used = hwaddr_aton2(dst, dst_addr);
- if (used < 0)
- return -1;
-
- while (dst[used] == ' ')
- used++;
- if (os_strncmp(dst + used, "realm=", 6) == 0)
- return hs20_nai_home_realm_list(wpa_s, dst_addr,
- dst + used + 6);
-
- len = os_strlen(dst + used);
-
- if (len == 0 && cred && cred->realm)
- return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm);
-
- if (len & 1)
- return -1;
- len /= 2;
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
- if (hexstr2bin(dst + used, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- ret = hs20_anqp_send_req(wpa_s, dst_addr,
- BIT(HS20_STYPE_NAI_HOME_REALM_QUERY),
- buf, len, 0);
- os_free(buf);
-
- return ret;
-}
-
-
-static int get_hs20_icon(struct wpa_supplicant *wpa_s, char *cmd, char *reply,
- int buflen)
-{
- u8 dst_addr[ETH_ALEN];
- int used;
- char *ctx = NULL, *icon, *poffset, *psize;
-
- used = hwaddr_aton2(cmd, dst_addr);
- if (used < 0)
- return -1;
- cmd += used;
-
- icon = str_token(cmd, " ", &ctx);
- poffset = str_token(cmd, " ", &ctx);
- psize = str_token(cmd, " ", &ctx);
- if (!icon || !poffset || !psize)
- return -1;
-
- wpa_s->fetch_osu_icon_in_progress = 0;
- return hs20_get_icon(wpa_s, dst_addr, icon, atoi(poffset), atoi(psize),
- reply, buflen);
-}
-
-
-static int del_hs20_icon(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 dst_addr[ETH_ALEN];
- int used;
- char *icon;
-
- if (!cmd[0])
- return hs20_del_icon(wpa_s, NULL, NULL);
-
- used = hwaddr_aton2(cmd, dst_addr);
- if (used < 0)
- return -1;
-
- while (cmd[used] == ' ')
- used++;
- icon = cmd[used] ? &cmd[used] : NULL;
-
- return hs20_del_icon(wpa_s, dst_addr, icon);
-}
-
-
-static int hs20_icon_request(struct wpa_supplicant *wpa_s, char *cmd, int inmem)
-{
- u8 dst_addr[ETH_ALEN];
- int used;
- char *icon;
-
- used = hwaddr_aton2(cmd, dst_addr);
- if (used < 0)
- return -1;
-
- while (cmd[used] == ' ')
- used++;
- icon = &cmd[used];
-
- wpa_s->fetch_osu_icon_in_progress = 0;
- return hs20_anqp_send_req(wpa_s, dst_addr, BIT(HS20_STYPE_ICON_REQUEST),
- (u8 *) icon, os_strlen(icon), inmem);
-}
-
-#endif /* CONFIG_HS20 */
-
-
-#ifdef CONFIG_AUTOSCAN
-
-static int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- enum wpa_states state = wpa_s->wpa_state;
- char *new_params = NULL;
-
- if (os_strlen(cmd) > 0) {
- new_params = os_strdup(cmd);
- if (new_params == NULL)
- return -1;
- }
-
- os_free(wpa_s->conf->autoscan);
- wpa_s->conf->autoscan = new_params;
-
- if (wpa_s->conf->autoscan == NULL)
- autoscan_deinit(wpa_s);
- else if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
- autoscan_init(wpa_s, 1);
- else if (state == WPA_SCANNING)
- wpa_supplicant_reinit_autoscan(wpa_s);
- else
- wpa_printf(MSG_DEBUG, "No autoscan update in state %s",
- wpa_supplicant_state_txt(state));
-
- return 0;
-}
-
-#endif /* CONFIG_AUTOSCAN */
-
-
-#ifdef CONFIG_WNM
-
-static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
-{
- int enter;
- int intval = 0;
- char *pos;
- int ret;
- struct wpabuf *tfs_req = NULL;
-
- if (os_strncmp(cmd, "enter", 5) == 0)
- enter = 1;
- else if (os_strncmp(cmd, "exit", 4) == 0)
- enter = 0;
- else
- return -1;
-
- pos = os_strstr(cmd, " interval=");
- if (pos)
- intval = atoi(pos + 10);
-
- pos = os_strstr(cmd, " tfs_req=");
- if (pos) {
- char *end;
- size_t len;
- pos += 9;
- end = os_strchr(pos, ' ');
- if (end)
- len = end - pos;
- else
- len = os_strlen(pos);
- if (len & 1)
- return -1;
- len /= 2;
- tfs_req = wpabuf_alloc(len);
- if (tfs_req == NULL)
- return -1;
- if (hexstr2bin(pos, wpabuf_put(tfs_req, len), len) < 0) {
- wpabuf_free(tfs_req);
- return -1;
- }
- }
-
- ret = ieee802_11_send_wnmsleep_req(wpa_s, enter ? WNM_SLEEP_MODE_ENTER :
- WNM_SLEEP_MODE_EXIT, intval,
- tfs_req);
- wpabuf_free(tfs_req);
-
- return ret;
-}
-
-
-static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd)
-{
- int query_reason, list = 0;
- char *btm_candidates = NULL;
-
- query_reason = atoi(cmd);
-
- cmd = os_strchr(cmd, ' ');
- if (cmd) {
- if (os_strncmp(cmd, " list", 5) == 0)
- list = 1;
- else
- btm_candidates = cmd;
- }
-
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: WNM_BSS_QUERY query_reason=%d%s",
- query_reason, list ? " candidate list" : "");
-
- return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason,
- btm_candidates,
- list);
-}
-
-
-static int wpas_ctrl_iface_coloc_intf_report(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- struct wpabuf *elems;
- int ret;
-
- elems = wpabuf_parse_bin(cmd);
- if (!elems)
- return -1;
-
- ret = wnm_send_coloc_intf_report(wpa_s, 0, elems);
- wpabuf_free(elems);
- return ret;
-}
-
-#endif /* CONFIG_WNM */
-
-
-static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
- size_t buflen)
-{
- struct wpa_signal_info si;
- int ret;
- char *pos, *end;
-
- ret = wpa_drv_signal_poll(wpa_s, &si);
- if (ret)
- return -1;
-
- pos = buf;
- end = buf + buflen;
-
- ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n"
- "NOISE=%d\nFREQUENCY=%u\n",
- si.current_signal, si.current_txrate / 1000,
- si.current_noise, si.frequency);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
-
- if (si.chanwidth != CHAN_WIDTH_UNKNOWN) {
- ret = os_snprintf(pos, end - pos, "WIDTH=%s\n",
- channel_width_to_string(si.chanwidth));
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- if (si.center_frq1 > 0) {
- ret = os_snprintf(pos, end - pos, "CENTER_FRQ1=%d\n",
- si.center_frq1);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- if (si.center_frq2 > 0) {
- ret = os_snprintf(pos, end - pos, "CENTER_FRQ2=%d\n",
- si.center_frq2);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- if (si.avg_signal) {
- ret = os_snprintf(pos, end - pos,
- "AVG_RSSI=%d\n", si.avg_signal);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- if (si.avg_beacon_signal) {
- ret = os_snprintf(pos, end - pos,
- "AVG_BEACON_RSSI=%d\n", si.avg_beacon_signal);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int wpas_ctrl_iface_signal_monitor(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- const char *pos;
- int threshold = 0;
- int hysteresis = 0;
-
- if (wpa_s->bgscan && wpa_s->bgscan_priv) {
- wpa_printf(MSG_DEBUG,
- "Reject SIGNAL_MONITOR command - bgscan is active");
- return -1;
- }
- pos = os_strstr(cmd, "THRESHOLD=");
- if (pos)
- threshold = atoi(pos + 10);
- pos = os_strstr(cmd, "HYSTERESIS=");
- if (pos)
- hysteresis = atoi(pos + 11);
- return wpa_drv_signal_monitor(wpa_s, threshold, hysteresis);
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type if_type,
- unsigned int *num,
- unsigned int *freq_list)
-{
- char *pos = wpa_s->get_pref_freq_list_override;
- char *end;
- unsigned int count = 0;
-
- /* Override string format:
- * <if_type1>:<freq1>,<freq2>,... <if_type2>:... */
-
- while (pos) {
- if (atoi(pos) == (int) if_type)
- break;
- pos = os_strchr(pos, ' ');
- if (pos)
- pos++;
- }
- if (!pos)
- return -1;
- pos = os_strchr(pos, ':');
- if (!pos)
- return -1;
- pos++;
- end = os_strchr(pos, ' ');
- while (pos && (!end || pos < end) && count < *num) {
- freq_list[count++] = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos)
- pos++;
- }
-
- *num = count;
- return 0;
-}
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static int wpas_ctrl_iface_get_pref_freq_list(
- struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
-{
- unsigned int freq_list[100], num = 100, i;
- int ret;
- enum wpa_driver_if_type iface_type;
- char *pos, *end;
-
- pos = buf;
- end = buf + buflen;
-
- /* buf: "<interface_type>" */
- if (os_strcmp(cmd, "STATION") == 0)
- iface_type = WPA_IF_STATION;
- else if (os_strcmp(cmd, "AP") == 0)
- iface_type = WPA_IF_AP_BSS;
- else if (os_strcmp(cmd, "P2P_GO") == 0)
- iface_type = WPA_IF_P2P_GO;
- else if (os_strcmp(cmd, "P2P_CLIENT") == 0)
- iface_type = WPA_IF_P2P_CLIENT;
- else if (os_strcmp(cmd, "IBSS") == 0)
- iface_type = WPA_IF_IBSS;
- else if (os_strcmp(cmd, "TDLS") == 0)
- iface_type = WPA_IF_TDLS;
- else
- return -1;
-
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: GET_PREF_FREQ_LIST iface_type=%d (%s)",
- iface_type, cmd);
-
- ret = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &num, freq_list);
- if (ret)
- return -1;
-
- for (i = 0; i < num; i++) {
- ret = os_snprintf(pos, end - pos, "%s%u",
- i > 0 ? "," : "", freq_list[i]);
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static int wpas_ctrl_iface_driver_flags(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- int ret, i;
- char *pos, *end;
-
- ret = os_snprintf(buf, buflen, "%016llX:\n",
- (long long unsigned) wpa_s->drv_flags);
- if (os_snprintf_error(buflen, ret))
- return -1;
-
- pos = buf + ret;
- end = buf + buflen;
-
- for (i = 0; i < 64; i++) {
- if (wpa_s->drv_flags & (1LLU << i)) {
- ret = os_snprintf(pos, end - pos, "%s\n",
- driver_flag_to_string(1LLU << i));
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- }
-
- return pos - buf;
-}
-
-
-static int wpas_ctrl_iface_driver_flags2(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- int ret, i;
- char *pos, *end;
-
- ret = os_snprintf(buf, buflen, "%016llX:\n",
- (long long unsigned) wpa_s->drv_flags2);
- if (os_snprintf_error(buflen, ret))
- return -1;
-
- pos = buf + ret;
- end = buf + buflen;
-
- for (i = 0; i < 64; i++) {
- if (wpa_s->drv_flags2 & (1LLU << i)) {
- ret = os_snprintf(pos, end - pos, "%s\n",
- driver_flag2_to_string(1LLU << i));
- if (os_snprintf_error(end - pos, ret))
- return -1;
- pos += ret;
- }
- }
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
- size_t buflen)
-{
- struct hostap_sta_driver_data sta;
- int ret;
-
- ret = wpa_drv_pktcnt_poll(wpa_s, &sta);
- if (ret)
- return -1;
-
- ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n",
- sta.tx_packets, sta.tx_retry_failed, sta.rx_packets);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-#ifdef ANDROID
-static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- int ret;
-
- ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
- if (ret == 0) {
- if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
- struct p2p_data *p2p = wpa_s->global->p2p;
- if (p2p) {
- char country[3];
- country[0] = cmd[8];
- country[1] = cmd[9];
- country[2] = 0x04;
- p2p_set_country(p2p, country);
- }
- }
- ret = os_snprintf(buf, buflen, "%s\n", "OK");
- if (os_snprintf_error(buflen, ret))
- ret = -1;
- }
- return ret;
-}
-#endif /* ANDROID */
-
-
-static int wpa_supplicant_vendor_cmd(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- int ret;
- char *pos, *temp = NULL;
- u8 *data = NULL;
- unsigned int vendor_id, subcmd;
- enum nested_attr nested_attr_flag = NESTED_ATTR_UNSPECIFIED;
- struct wpabuf *reply;
- size_t data_len = 0;
-
- /**
- * cmd: <vendor id> <subcommand id> [<hex formatted data>]
- * [nested=<0|1>]
- */
- vendor_id = strtoul(cmd, &pos, 16);
- if (!isblank((unsigned char) *pos))
- return -EINVAL;
-
- subcmd = strtoul(pos, &pos, 10);
-
- if (*pos != '\0') {
- if (!isblank((unsigned char) *pos++))
- return -EINVAL;
-
- temp = os_strchr(pos, ' ');
- data_len = temp ? (size_t) (temp - pos) : os_strlen(pos);
- }
-
- if (data_len) {
- data_len /= 2;
- data = os_malloc(data_len);
- if (!data)
- return -1;
-
- if (hexstr2bin(pos, data, data_len)) {
- wpa_printf(MSG_DEBUG,
- "Vendor command: wrong parameter format");
- os_free(data);
- return -EINVAL;
- }
- }
-
- pos = os_strstr(cmd, "nested=");
- if (pos)
- nested_attr_flag = atoi(pos + 7) ? NESTED_ATTR_USED :
- NESTED_ATTR_NOT_USED;
-
- reply = wpabuf_alloc((buflen - 1) / 2);
- if (!reply) {
- os_free(data);
- return -1;
- }
-
- ret = wpa_drv_vendor_cmd(wpa_s, vendor_id, subcmd, data, data_len,
- nested_attr_flag, reply);
-
- if (ret == 0)
- ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(reply),
- wpabuf_len(reply));
-
- wpabuf_free(reply);
- os_free(data);
-
- return ret;
-}
-
-
-static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_P2P
- struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s ?
- wpa_s->global->p2p_init_wpa_s : wpa_s;
-#endif /* CONFIG_P2P */
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state");
-
- if (wpas_abort_ongoing_scan(wpa_s) == 0)
- wpa_s->ignore_post_flush_scan_res = 1;
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- /*
- * Avoid possible auto connect re-connection on getting
- * disconnected due to state flush.
- */
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- }
-
-#ifdef CONFIG_P2P
- wpas_p2p_group_remove(p2p_wpa_s, "*");
- wpas_p2p_cancel(p2p_wpa_s);
- p2p_ctrl_flush(p2p_wpa_s);
- wpas_p2p_service_flush(p2p_wpa_s);
- p2p_wpa_s->global->p2p_disabled = 0;
- p2p_wpa_s->global->p2p_per_sta_psk = 0;
- p2p_wpa_s->conf->num_sec_device_types = 0;
- p2p_wpa_s->p2p_disable_ip_addr_req = 0;
- os_free(p2p_wpa_s->global->p2p_go_avoid_freq.range);
- p2p_wpa_s->global->p2p_go_avoid_freq.range = NULL;
- p2p_wpa_s->global->p2p_go_avoid_freq.num = 0;
- p2p_wpa_s->global->pending_p2ps_group = 0;
- p2p_wpa_s->global->pending_p2ps_group_freq = 0;
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WPS_TESTING
- wps_version_number = 0x20;
- wps_testing_stub_cred = 0;
- wps_corrupt_pkhash = 0;
- wps_force_auth_types_in_use = 0;
- wps_force_encr_types_in_use = 0;
-#endif /* CONFIG_WPS_TESTING */
-#ifdef CONFIG_WPS
- wpa_s->wps_fragment_size = 0;
- wpas_wps_cancel(wpa_s);
- wps_registrar_flush(wpa_s->wps->registrar);
-#endif /* CONFIG_WPS */
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
-
-#ifdef CONFIG_DPP
- wpas_dpp_deinit(wpa_s);
- wpa_s->dpp_init_max_tries = 0;
- wpa_s->dpp_init_retry_time = 0;
- wpa_s->dpp_resp_wait_time = 0;
- wpa_s->dpp_resp_max_tries = 0;
- wpa_s->dpp_resp_retry_time = 0;
-#ifdef CONFIG_DPP2
- wpas_dpp_chirp_stop(wpa_s);
- wpa_s->dpp_pfs_fallback = 0;
-#endif /* CONFIG_DPP2 */
-#ifdef CONFIG_TESTING_OPTIONS
- os_memset(dpp_pkex_own_mac_override, 0, ETH_ALEN);
- os_memset(dpp_pkex_peer_mac_override, 0, ETH_ALEN);
- dpp_pkex_ephemeral_key_override_len = 0;
- dpp_protocol_key_override_len = 0;
- dpp_nonce_override_len = 0;
-#ifdef CONFIG_DPP3
- dpp_version_override = 3;
-#elif defined(CONFIG_DPP2)
- dpp_version_override = 2;
-#else /* CONFIG_DPP2 */
- dpp_version_override = 1;
-#endif /* CONFIG_DPP2 */
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_TDLS
-#ifdef CONFIG_TDLS_TESTING
- tdls_testing = 0;
-#endif /* CONFIG_TDLS_TESTING */
- wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL);
- wpa_tdls_enable(wpa_s->wpa, 1);
-#endif /* CONFIG_TDLS */
-
- eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
- wpa_supplicant_stop_countermeasures(wpa_s, NULL);
- wpa_s->last_michael_mic_error.sec = 0;
-
- wpa_s->no_keep_alive = 0;
- wpa_s->own_disconnect_req = 0;
- wpa_s->own_reconnect_req = 0;
- wpa_s->deny_ptk0_rekey = 0;
-
- os_free(wpa_s->disallow_aps_bssid);
- wpa_s->disallow_aps_bssid = NULL;
- wpa_s->disallow_aps_bssid_count = 0;
- os_free(wpa_s->disallow_aps_ssid);
- wpa_s->disallow_aps_ssid = NULL;
- wpa_s->disallow_aps_ssid_count = 0;
-
- wpa_s->set_sta_uapsd = 0;
- wpa_s->sta_uapsd = 0;
-
- wpa_s->consecutive_conn_failures = 0;
-
- wpa_drv_radio_disable(wpa_s, 0);
- wpa_bssid_ignore_clear(wpa_s);
- wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all");
- wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all");
- wpa_config_flush_blobs(wpa_s->conf);
- wpa_s->conf->auto_interworking = 0;
- wpa_s->conf->okc = 0;
-
- ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
- rsn_preauth_deinit(wpa_s->wpa);
-
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 43200);
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 70);
- wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, 60);
- eapol_sm_notify_logoff(wpa_s->eapol, false);
-
- radio_remove_works(wpa_s, NULL, 1);
- wpa_s->ext_work_in_progress = 0;
-
- wpa_s->next_ssid = NULL;
-
-#ifdef CONFIG_INTERWORKING
-#ifdef CONFIG_HS20
- hs20_cancel_fetch_osu(wpa_s);
- hs20_del_icon(wpa_s, NULL, NULL);
-#endif /* CONFIG_HS20 */
-#endif /* CONFIG_INTERWORKING */
-
- wpa_s->ext_mgmt_frame_handling = 0;
- wpa_s->ext_eapol_frame_io = 0;
-#ifdef CONFIG_TESTING_OPTIONS
- wpa_s->extra_roc_dur = 0;
- wpa_s->test_failure = WPAS_TEST_FAILURE_NONE;
- wpa_s->p2p_go_csa_on_inv = 0;
- wpa_s->ignore_auth_resp = 0;
- wpa_s->ignore_assoc_disallow = 0;
- wpa_s->disable_sa_query = 0;
- wpa_s->testing_resend_assoc = 0;
- wpa_s->ignore_sae_h2e_only = 0;
- wpa_s->ft_rsnxe_used = 0;
- wpa_s->reject_btm_req_reason = 0;
- wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL);
- os_free(wpa_s->get_pref_freq_list_override);
- wpa_s->get_pref_freq_list_override = NULL;
- wpabuf_free(wpa_s->sae_commit_override);
- wpa_s->sae_commit_override = NULL;
- os_free(wpa_s->extra_sae_rejected_groups);
- wpa_s->extra_sae_rejected_groups = NULL;
- wpabuf_free(wpa_s->rsne_override_eapol);
- wpa_s->rsne_override_eapol = NULL;
- wpabuf_free(wpa_s->rsnxe_override_assoc);
- wpa_s->rsnxe_override_assoc = NULL;
- wpabuf_free(wpa_s->rsnxe_override_eapol);
- wpa_s->rsnxe_override_eapol = NULL;
- wpas_clear_driver_signal_override(wpa_s);
- wpa_s->disable_scs_support = 0;
- wpa_s->disable_mscs_support = 0;
- wpa_s->enable_dscp_policy_capa = 0;
- wpa_s->oci_freq_override_eapol = 0;
- wpa_s->oci_freq_override_saquery_req = 0;
- wpa_s->oci_freq_override_saquery_resp = 0;
- wpa_s->oci_freq_override_eapol_g2 = 0;
- wpa_s->oci_freq_override_ft_assoc = 0;
- wpa_s->oci_freq_override_fils_assoc = 0;
- wpa_s->oci_freq_override_wnm_sleep = 0;
-#ifdef CONFIG_DPP
- os_free(wpa_s->dpp_config_obj_override);
- wpa_s->dpp_config_obj_override = NULL;
- os_free(wpa_s->dpp_discovery_override);
- wpa_s->dpp_discovery_override = NULL;
- os_free(wpa_s->dpp_groups_override);
- wpa_s->dpp_groups_override = NULL;
- dpp_test = DPP_TEST_DISABLED;
-#endif /* CONFIG_DPP */
-#endif /* CONFIG_TESTING_OPTIONS */
-
- wpa_s->disconnected = 0;
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = NULL;
- os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
- wpa_s->next_scan_bssid_wildcard_ssid = 0;
- os_free(wpa_s->select_network_scan_freqs);
- wpa_s->select_network_scan_freqs = NULL;
- os_memset(&wpa_s->robust_av, 0, sizeof(struct robust_av_data));
-
- wpa_bss_flush(wpa_s);
- if (!dl_list_empty(&wpa_s->bss)) {
- wpa_printf(MSG_DEBUG,
- "BSS table not empty after flush: %u entries, current_bss=%p bssid="
- MACSTR " pending_bssid=" MACSTR,
- dl_list_len(&wpa_s->bss), wpa_s->current_bss,
- MAC2STR(wpa_s->bssid),
- MAC2STR(wpa_s->pending_bssid));
- }
-
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
- wpa_s->wnmsleep_used = 0;
-
-#ifdef CONFIG_SME
- wpa_s->sme.last_unprot_disconnect.sec = 0;
- wpa_s->sme.auth_alg = 0;
-#endif /* CONFIG_SME */
-
- wpabuf_free(wpa_s->ric_ies);
- wpa_s->ric_ies = NULL;
-
- wpa_supplicant_update_channel_list(wpa_s, NULL);
-
- free_bss_tmp_disallowed(wpa_s);
-
- os_memset(&wpa_s->robust_av, 0, sizeof(struct robust_av_data));
-
-#ifdef CONFIG_PASN
- wpas_pasn_auth_stop(wpa_s);
-#endif /* CONFIG_PASN */
-
- if (wpa_s->mac_addr_changed && wpa_s->conf->mac_addr == 0)
- wpas_restore_permanent_mac_addr(wpa_s);
-}
-
-
-static int wpas_ctrl_radio_work_show(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- struct wpa_radio_work *work;
- char *pos, *end;
- struct os_reltime now, diff;
-
- pos = buf;
- end = buf + buflen;
-
- os_get_reltime(&now);
-
- dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
- {
- int ret;
-
- os_reltime_sub(&now, &work->time, &diff);
- ret = os_snprintf(pos, end - pos, "%s@%s:%u:%u:%ld.%06ld\n",
- work->type, work->wpa_s->ifname, work->freq,
- work->started, diff.sec, diff.usec);
- if (os_snprintf_error(end - pos, ret))
- break;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-static void wpas_ctrl_radio_work_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_radio_work *work = eloop_ctx;
- struct wpa_external_work *ework = work->ctx;
-
- wpa_dbg(work->wpa_s, MSG_DEBUG,
- "Timing out external radio work %u (%s)",
- ework->id, work->type);
- wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_TIMEOUT "%u", ework->id);
- work->wpa_s->ext_work_in_progress = 0;
- radio_work_done(work);
- os_free(ework);
-}
-
-
-static void wpas_ctrl_radio_work_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_external_work *ework = work->ctx;
-
- if (deinit) {
- if (work->started)
- eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
- work, NULL);
-
- /*
- * work->type points to a buffer in ework, so need to replace
- * that here with a fixed string to avoid use of freed memory
- * in debug prints.
- */
- work->type = "freed-ext-work";
- work->ctx = NULL;
- os_free(ework);
- return;
- }
-
- wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
- ework->id, ework->type);
- wpa_msg(work->wpa_s, MSG_INFO, EXT_RADIO_WORK_START "%u", ework->id);
- work->wpa_s->ext_work_in_progress = 1;
- if (!ework->timeout)
- ework->timeout = 10;
- eloop_register_timeout(ework->timeout, 0, wpas_ctrl_radio_work_timeout,
- work, NULL);
-}
-
-
-static int wpas_ctrl_radio_work_add(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- struct wpa_external_work *ework;
- char *pos, *pos2;
- size_t type_len;
- int ret;
- unsigned int freq = 0;
-
- /* format: <name> [freq=<MHz>] [timeout=<seconds>] */
-
- ework = os_zalloc(sizeof(*ework));
- if (ework == NULL)
- return -1;
-
- pos = os_strchr(cmd, ' ');
- if (pos) {
- type_len = pos - cmd;
- pos++;
-
- pos2 = os_strstr(pos, "freq=");
- if (pos2)
- freq = atoi(pos2 + 5);
-
- pos2 = os_strstr(pos, "timeout=");
- if (pos2)
- ework->timeout = atoi(pos2 + 8);
- } else {
- type_len = os_strlen(cmd);
- }
- if (4 + type_len >= sizeof(ework->type))
- type_len = sizeof(ework->type) - 4 - 1;
- os_strlcpy(ework->type, "ext:", sizeof(ework->type));
- os_memcpy(ework->type + 4, cmd, type_len);
- ework->type[4 + type_len] = '\0';
-
- wpa_s->ext_work_id++;
- if (wpa_s->ext_work_id == 0)
- wpa_s->ext_work_id++;
- ework->id = wpa_s->ext_work_id;
-
- if (radio_add_work(wpa_s, freq, ework->type, 0, wpas_ctrl_radio_work_cb,
- ework) < 0) {
- os_free(ework);
- return -1;
- }
-
- ret = os_snprintf(buf, buflen, "%u", ework->id);
- if (os_snprintf_error(buflen, ret))
- return -1;
- return ret;
-}
-
-
-static int wpas_ctrl_radio_work_done(struct wpa_supplicant *wpa_s, char *cmd)
-{
- struct wpa_radio_work *work;
- unsigned int id = atoi(cmd);
-
- dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
- {
- struct wpa_external_work *ework;
-
- if (os_strncmp(work->type, "ext:", 4) != 0)
- continue;
- ework = work->ctx;
- if (id && ework->id != id)
- continue;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Completed external radio work %u (%s)",
- ework->id, ework->type);
- eloop_cancel_timeout(wpas_ctrl_radio_work_timeout, work, NULL);
- wpa_s->ext_work_in_progress = 0;
- radio_work_done(work);
- os_free(ework);
- return 3; /* "OK\n" */
- }
-
- return -1;
-}
-
-
-static int wpas_ctrl_radio_work(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- if (os_strcmp(cmd, "show") == 0)
- return wpas_ctrl_radio_work_show(wpa_s, buf, buflen);
- if (os_strncmp(cmd, "add ", 4) == 0)
- return wpas_ctrl_radio_work_add(wpa_s, cmd + 4, buf, buflen);
- if (os_strncmp(cmd, "done ", 5) == 0)
- return wpas_ctrl_radio_work_done(wpa_s, cmd + 4);
- return -1;
-}
-
-
-void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s)
-{
- struct wpa_radio_work *work, *tmp;
-
- if (!wpa_s || !wpa_s->radio)
- return;
-
- dl_list_for_each_safe(work, tmp, &wpa_s->radio->work,
- struct wpa_radio_work, list) {
- struct wpa_external_work *ework;
-
- if (os_strncmp(work->type, "ext:", 4) != 0)
- continue;
- ework = work->ctx;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Flushing%s external radio work %u (%s)",
- work->started ? " started" : "", ework->id,
- ework->type);
- if (work->started)
- eloop_cancel_timeout(wpas_ctrl_radio_work_timeout,
- work, NULL);
- radio_work_done(work);
- os_free(ework);
- }
-}
-
-
-static void wpas_ctrl_eapol_response(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- eapol_sm_notify_ctrl_response(wpa_s->eapol);
-}
-
-
-static int scan_id_list_parse(struct wpa_supplicant *wpa_s, const char *value,
- unsigned int *scan_id_count, int scan_id[])
-{
- const char *pos = value;
-
- while (pos) {
- if (*pos == ' ' || *pos == '\0')
- break;
- if (*scan_id_count == MAX_SCAN_ID)
- return -1;
- scan_id[(*scan_id_count)++] = atoi(pos);
- pos = os_strchr(pos, ',');
- if (pos)
- pos++;
- }
-
- return 0;
-}
-
-
-static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
- char *reply, int reply_size, int *reply_len)
-{
- char *pos;
- unsigned int manual_scan_passive = 0;
- unsigned int manual_scan_use_id = 0;
- unsigned int manual_scan_only_new = 0;
- unsigned int scan_only = 0;
- unsigned int scan_id_count = 0;
- int scan_id[MAX_SCAN_ID];
- void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
- int *manual_scan_freqs = NULL;
- struct wpa_ssid_value *ssid = NULL, *ns;
- unsigned int ssid_count = 0;
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- *reply_len = -1;
- return;
- }
-
- if (radio_work_pending(wpa_s, "scan")) {
- wpa_printf(MSG_DEBUG,
- "Pending scan scheduled - reject new request");
- *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
- return;
- }
-
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select) {
- wpa_printf(MSG_DEBUG,
- "Interworking select in progress - reject new scan");
- *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
- return;
- }
-#endif /* CONFIG_INTERWORKING */
-
- if (params) {
- if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
- scan_only = 1;
-
- pos = os_strstr(params, "freq=");
- if (pos) {
- manual_scan_freqs = freq_range_to_channel_list(wpa_s,
- pos + 5);
- if (manual_scan_freqs == NULL) {
- *reply_len = -1;
- goto done;
- }
- }
-
- pos = os_strstr(params, "passive=");
- if (pos)
- manual_scan_passive = !!atoi(pos + 8);
-
- pos = os_strstr(params, "use_id=");
- if (pos)
- manual_scan_use_id = atoi(pos + 7);
-
- pos = os_strstr(params, "only_new=1");
- if (pos)
- manual_scan_only_new = 1;
-
- pos = os_strstr(params, "scan_id=");
- if (pos && scan_id_list_parse(wpa_s, pos + 8, &scan_id_count,
- scan_id) < 0) {
- *reply_len = -1;
- goto done;
- }
-
- pos = os_strstr(params, "bssid=");
- if (pos) {
- u8 bssid[ETH_ALEN];
-
- pos += 6;
- if (hwaddr_aton(pos, bssid)) {
- wpa_printf(MSG_ERROR, "Invalid BSSID %s", pos);
- *reply_len = -1;
- goto done;
- }
- os_memcpy(wpa_s->next_scan_bssid, bssid, ETH_ALEN);
-
- wpa_s->next_scan_bssid_wildcard_ssid =
- os_strstr(params, "wildcard_ssid=1") != NULL;
- }
-
- pos = params;
- while (pos && *pos != '\0') {
- if (os_strncmp(pos, "ssid ", 5) == 0) {
- char *end;
-
- pos += 5;
- end = pos;
- while (*end) {
- if (*end == '\0' || *end == ' ')
- break;
- end++;
- }
-
- ns = os_realloc_array(
- ssid, ssid_count + 1,
- sizeof(struct wpa_ssid_value));
- if (ns == NULL) {
- *reply_len = -1;
- goto done;
- }
- ssid = ns;
-
- if ((end - pos) & 0x01 ||
- end - pos > 2 * SSID_MAX_LEN ||
- hexstr2bin(pos, ssid[ssid_count].ssid,
- (end - pos) / 2) < 0) {
- wpa_printf(MSG_DEBUG,
- "Invalid SSID value '%s'",
- pos);
- *reply_len = -1;
- goto done;
- }
- ssid[ssid_count].ssid_len = (end - pos) / 2;
- wpa_hexdump_ascii(MSG_DEBUG, "scan SSID",
- ssid[ssid_count].ssid,
- ssid[ssid_count].ssid_len);
- ssid_count++;
- pos = end;
- }
-
- pos = os_strchr(pos, ' ');
- if (pos)
- pos++;
- }
- }
-
- wpa_s->num_ssids_from_scan_req = ssid_count;
- os_free(wpa_s->ssids_from_scan_req);
- if (ssid_count) {
- wpa_s->ssids_from_scan_req = ssid;
- ssid = NULL;
- } else {
- wpa_s->ssids_from_scan_req = NULL;
- }
-
- if (scan_only)
- scan_res_handler = scan_only_handler;
- else if (wpa_s->scan_res_handler == scan_only_handler)
- scan_res_handler = NULL;
- else
- scan_res_handler = wpa_s->scan_res_handler;
-
- if (!wpa_s->sched_scanning && !wpa_s->scanning &&
- ((wpa_s->wpa_state <= WPA_SCANNING) ||
- (wpa_s->wpa_state == WPA_COMPLETED))) {
- wpa_s->manual_scan_passive = manual_scan_passive;
- wpa_s->manual_scan_use_id = manual_scan_use_id;
- wpa_s->manual_scan_only_new = manual_scan_only_new;
- wpa_s->scan_id_count = scan_id_count;
- os_memcpy(wpa_s->scan_id, scan_id, scan_id_count * sizeof(int));
- wpa_s->scan_res_handler = scan_res_handler;
- os_free(wpa_s->manual_scan_freqs);
- wpa_s->manual_scan_freqs = manual_scan_freqs;
- manual_scan_freqs = NULL;
-
- wpa_s->normal_scans = 0;
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- if (wpa_s->manual_scan_use_id) {
- wpa_s->manual_scan_id++;
- wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u",
- wpa_s->manual_scan_id);
- *reply_len = os_snprintf(reply, reply_size, "%u\n",
- wpa_s->manual_scan_id);
- }
- } else if (wpa_s->sched_scanning) {
- wpa_s->manual_scan_passive = manual_scan_passive;
- wpa_s->manual_scan_use_id = manual_scan_use_id;
- wpa_s->manual_scan_only_new = manual_scan_only_new;
- wpa_s->scan_id_count = scan_id_count;
- os_memcpy(wpa_s->scan_id, scan_id, scan_id_count * sizeof(int));
- wpa_s->scan_res_handler = scan_res_handler;
- os_free(wpa_s->manual_scan_freqs);
- wpa_s->manual_scan_freqs = manual_scan_freqs;
- manual_scan_freqs = NULL;
-
- wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to allow requested full scan to proceed");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- if (wpa_s->manual_scan_use_id) {
- wpa_s->manual_scan_id++;
- *reply_len = os_snprintf(reply, reply_size, "%u\n",
- wpa_s->manual_scan_id);
- wpa_dbg(wpa_s, MSG_DEBUG, "Assigned scan id %u",
- wpa_s->manual_scan_id);
- }
- } else {
- wpa_printf(MSG_DEBUG, "Ongoing scan action - reject new request");
- *reply_len = os_snprintf(reply, reply_size, "FAIL-BUSY\n");
- }
-
-done:
- os_free(manual_scan_freqs);
- os_free(ssid);
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-
-static void wpas_ctrl_iface_mgmt_tx_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result
- result)
-{
- wpa_msg(wpa_s, MSG_INFO, "MGMT-TX-STATUS freq=%u dst=" MACSTR
- " src=" MACSTR " bssid=" MACSTR " result=%s",
- freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
- result == OFFCHANNEL_SEND_ACTION_SUCCESS ?
- "SUCCESS" : (result == OFFCHANNEL_SEND_ACTION_NO_ACK ?
- "NO_ACK" : "FAILED"));
-}
-
-
-static int wpas_ctrl_iface_mgmt_tx(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos, *param;
- size_t len;
- u8 *buf, da[ETH_ALEN], bssid[ETH_ALEN];
- int res, used;
- int freq = 0, no_cck = 0, wait_time = 0;
-
- /* <DA> <BSSID> [freq=<MHz>] [wait_time=<ms>] [no_cck=1]
- * <action=Action frame payload> */
-
- wpa_printf(MSG_DEBUG, "External MGMT TX: %s", cmd);
-
- pos = cmd;
- used = hwaddr_aton2(pos, da);
- if (used < 0)
- return -1;
- pos += used;
- while (*pos == ' ')
- pos++;
- used = hwaddr_aton2(pos, bssid);
- if (used < 0)
- return -1;
- pos += used;
-
- param = os_strstr(pos, " freq=");
- if (param) {
- param += 6;
- freq = atoi(param);
- }
-
- param = os_strstr(pos, " no_cck=");
- if (param) {
- param += 8;
- no_cck = atoi(param);
- }
-
- param = os_strstr(pos, " wait_time=");
- if (param) {
- param += 11;
- wait_time = atoi(param);
- }
-
- param = os_strstr(pos, " action=");
- if (param == NULL)
- return -1;
- param += 8;
-
- len = os_strlen(param);
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(param, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- res = offchannel_send_action(wpa_s, freq, da, wpa_s->own_addr, bssid,
- buf, len, wait_time,
- wpas_ctrl_iface_mgmt_tx_cb, no_cck);
- os_free(buf);
- return res;
-}
-
-
-static void wpas_ctrl_iface_mgmt_tx_done(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "External MGMT TX - done waiting");
- offchannel_send_action_done(wpa_s);
-}
-
-
-static int wpas_ctrl_iface_mgmt_rx_process(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *pos, *param;
- size_t len;
- u8 *buf;
- int freq = 0, datarate = 0, ssi_signal = 0;
- union wpa_event_data event;
-
- if (!wpa_s->ext_mgmt_frame_handling)
- return -1;
-
- /* freq=<MHz> datarate=<val> ssi_signal=<val> frame=<frame hexdump> */
-
- wpa_printf(MSG_DEBUG, "External MGMT RX process: %s", cmd);
-
- pos = cmd;
- param = os_strstr(pos, "freq=");
- if (param) {
- param += 5;
- freq = atoi(param);
- }
-
- param = os_strstr(pos, " datarate=");
- if (param) {
- param += 10;
- datarate = atoi(param);
- }
-
- param = os_strstr(pos, " ssi_signal=");
- if (param) {
- param += 12;
- ssi_signal = atoi(param);
- }
-
- param = os_strstr(pos, " frame=");
- if (param == NULL)
- return -1;
- param += 7;
-
- len = os_strlen(param);
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(param, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- os_memset(&event, 0, sizeof(event));
- event.rx_mgmt.freq = freq;
- event.rx_mgmt.frame = buf;
- event.rx_mgmt.frame_len = len;
- event.rx_mgmt.ssi_signal = ssi_signal;
- event.rx_mgmt.datarate = datarate;
- wpa_s->ext_mgmt_frame_handling = 0;
- wpa_supplicant_event(wpa_s, EVENT_RX_MGMT, &event);
- wpa_s->ext_mgmt_frame_handling = 1;
-
- os_free(buf);
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_driver_scan_res(struct wpa_supplicant *wpa_s,
- char *param)
-{
- struct wpa_scan_res *res;
- struct os_reltime now;
- char *pos, *end;
- int ret = -1;
-
- if (!param)
- return -1;
-
- if (os_strcmp(param, "START") == 0) {
- wpa_bss_update_start(wpa_s);
- return 0;
- }
-
- if (os_strcmp(param, "END") == 0) {
- wpa_bss_update_end(wpa_s, NULL, 1);
- return 0;
- }
-
- if (os_strncmp(param, "BSS ", 4) != 0)
- return -1;
- param += 3;
-
- res = os_zalloc(sizeof(*res) + os_strlen(param) / 2);
- if (!res)
- return -1;
-
- pos = os_strstr(param, " flags=");
- if (pos)
- res->flags = strtol(pos + 7, NULL, 16);
-
- pos = os_strstr(param, " bssid=");
- if (pos && hwaddr_aton(pos + 7, res->bssid))
- goto fail;
-
- pos = os_strstr(param, " freq=");
- if (pos)
- res->freq = atoi(pos + 6);
-
- pos = os_strstr(param, " beacon_int=");
- if (pos)
- res->beacon_int = atoi(pos + 12);
-
- pos = os_strstr(param, " caps=");
- if (pos)
- res->caps = strtol(pos + 6, NULL, 16);
-
- pos = os_strstr(param, " qual=");
- if (pos)
- res->qual = atoi(pos + 6);
-
- pos = os_strstr(param, " noise=");
- if (pos)
- res->noise = atoi(pos + 7);
-
- pos = os_strstr(param, " level=");
- if (pos)
- res->level = atoi(pos + 7);
-
- pos = os_strstr(param, " tsf=");
- if (pos)
- res->tsf = strtoll(pos + 5, NULL, 16);
-
- pos = os_strstr(param, " age=");
- if (pos)
- res->age = atoi(pos + 5);
-
- pos = os_strstr(param, " est_throughput=");
- if (pos)
- res->est_throughput = atoi(pos + 16);
-
- pos = os_strstr(param, " snr=");
- if (pos)
- res->snr = atoi(pos + 5);
-
- pos = os_strstr(param, " parent_tsf=");
- if (pos)
- res->parent_tsf = strtoll(pos + 7, NULL, 16);
-
- pos = os_strstr(param, " tsf_bssid=");
- if (pos && hwaddr_aton(pos + 11, res->tsf_bssid))
- goto fail;
-
- pos = os_strstr(param, " ie=");
- if (pos) {
- pos += 4;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
- res->ie_len = (end - pos) / 2;
- if (hexstr2bin(pos, (u8 *) (res + 1), res->ie_len))
- goto fail;
- }
-
- pos = os_strstr(param, " beacon_ie=");
- if (pos) {
- pos += 11;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
- res->beacon_ie_len = (end - pos) / 2;
- if (hexstr2bin(pos, ((u8 *) (res + 1)) + res->ie_len,
- res->beacon_ie_len))
- goto fail;
- }
-
- os_get_reltime(&now);
- wpa_bss_update_scan_res(wpa_s, res, &now);
- ret = 0;
-fail:
- os_free(res);
-
- return ret;
-}
-
-
-static int wpas_ctrl_iface_driver_event_assoc(struct wpa_supplicant *wpa_s,
- char *param)
-{
- union wpa_event_data event;
- struct assoc_info *ai;
- char *ctx = NULL;
- int ret = -1;
- struct wpabuf *req_ies = NULL;
- struct wpabuf *resp_ies = NULL;
- struct wpabuf *resp_frame = NULL;
- struct wpabuf *beacon_ies = NULL;
- struct wpabuf *key_replay_ctr = NULL;
- struct wpabuf *ptk_kck = NULL;
- struct wpabuf *ptk_kek = NULL;
- struct wpabuf *fils_pmk = NULL;
- char *str, *pos;
- u8 addr[ETH_ALEN];
- u8 fils_pmkid[PMKID_LEN];
-
- os_memset(&event, 0, sizeof(event));
- ai = &event.assoc_info;
-
- while ((str = str_token(param, " ", &ctx))) {
- pos = os_strchr(str, '=');
- if (!pos)
- goto fail;
- *pos++ = '\0';
-
- if (os_strcmp(str, "reassoc") == 0) {
- ai->reassoc = atoi(pos);
- } else if (os_strcmp(str, "req_ies") == 0) {
- wpabuf_free(req_ies);
- req_ies = wpabuf_parse_bin(pos);
- if (!req_ies)
- goto fail;
- ai->req_ies = wpabuf_head(req_ies);
- ai->req_ies_len = wpabuf_len(req_ies);
- } else if (os_strcmp(str, "resp_ies") == 0) {
- wpabuf_free(resp_ies);
- resp_ies = wpabuf_parse_bin(pos);
- if (!resp_ies)
- goto fail;
- ai->resp_ies = wpabuf_head(resp_ies);
- ai->resp_ies_len = wpabuf_len(resp_ies);
- } else if (os_strcmp(str, "resp_frame") == 0) {
- wpabuf_free(resp_frame);
- resp_frame = wpabuf_parse_bin(pos);
- if (!resp_frame)
- goto fail;
- ai->resp_frame = wpabuf_head(resp_frame);
- ai->resp_frame_len = wpabuf_len(resp_frame);
- } else if (os_strcmp(str, "beacon_ies") == 0) {
- wpabuf_free(beacon_ies);
- beacon_ies = wpabuf_parse_bin(pos);
- if (!beacon_ies)
- goto fail;
- ai->beacon_ies = wpabuf_head(beacon_ies);
- ai->beacon_ies_len = wpabuf_len(beacon_ies);
- } else if (os_strcmp(str, "freq") == 0) {
- ai->freq = atoi(pos);
- } else if (os_strcmp(str, "wmm::info_bitmap") == 0) {
- ai->wmm_params.info_bitmap = atoi(pos);
- } else if (os_strcmp(str, "wmm::uapsd_queues") == 0) {
- ai->wmm_params.uapsd_queues = atoi(pos);
- } else if (os_strcmp(str, "addr") == 0) {
- if (hwaddr_aton(pos, addr))
- goto fail;
- ai->addr = addr;
- } else if (os_strcmp(str, "authorized") == 0) {
- ai->authorized = atoi(pos);
- } else if (os_strcmp(str, "key_replay_ctr") == 0) {
- wpabuf_free(key_replay_ctr);
- key_replay_ctr = wpabuf_parse_bin(pos);
- if (!key_replay_ctr)
- goto fail;
- ai->key_replay_ctr = wpabuf_head(key_replay_ctr);
- ai->key_replay_ctr_len = wpabuf_len(key_replay_ctr);
- } else if (os_strcmp(str, "ptk_kck") == 0) {
- wpabuf_free(ptk_kck);
- ptk_kck = wpabuf_parse_bin(pos);
- if (!ptk_kck)
- goto fail;
- ai->ptk_kck = wpabuf_head(ptk_kck);
- ai->ptk_kck_len = wpabuf_len(ptk_kck);
- } else if (os_strcmp(str, "ptk_kek") == 0) {
- wpabuf_free(ptk_kek);
- ptk_kek = wpabuf_parse_bin(pos);
- if (!ptk_kek)
- goto fail;
- ai->ptk_kek = wpabuf_head(ptk_kek);
- ai->ptk_kek_len = wpabuf_len(ptk_kek);
- } else if (os_strcmp(str, "subnet_status") == 0) {
- ai->subnet_status = atoi(pos);
- } else if (os_strcmp(str, "fils_erp_next_seq_num") == 0) {
- ai->fils_erp_next_seq_num = atoi(pos);
- } else if (os_strcmp(str, "fils_pmk") == 0) {
- wpabuf_free(fils_pmk);
- fils_pmk = wpabuf_parse_bin(pos);
- if (!fils_pmk)
- goto fail;
- ai->fils_pmk = wpabuf_head(fils_pmk);
- ai->fils_pmk_len = wpabuf_len(fils_pmk);
- } else if (os_strcmp(str, "fils_pmkid") == 0) {
- if (hexstr2bin(pos, fils_pmkid, PMKID_LEN) < 0)
- goto fail;
- ai->fils_pmkid = fils_pmkid;
- } else {
- goto fail;
- }
- }
-
- wpa_supplicant_event(wpa_s, EVENT_ASSOC, &event);
- ret = 0;
-fail:
- wpabuf_free(req_ies);
- wpabuf_free(resp_ies);
- wpabuf_free(resp_frame);
- wpabuf_free(beacon_ies);
- wpabuf_free(key_replay_ctr);
- wpabuf_free(ptk_kck);
- wpabuf_free(ptk_kek);
- wpabuf_free(fils_pmk);
- return ret;
-}
-
-
-static int wpas_ctrl_iface_driver_event(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos, *param;
- union wpa_event_data event;
- enum wpa_event_type ev;
-
- /* <event name> [parameters..] */
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Testing - external driver event: %s", cmd);
-
- pos = cmd;
- param = os_strchr(pos, ' ');
- if (param)
- *param++ = '\0';
-
- os_memset(&event, 0, sizeof(event));
-
- if (os_strcmp(cmd, "INTERFACE_ENABLED") == 0) {
- ev = EVENT_INTERFACE_ENABLED;
- } else if (os_strcmp(cmd, "INTERFACE_DISABLED") == 0) {
- ev = EVENT_INTERFACE_DISABLED;
- } else if (os_strcmp(cmd, "AVOID_FREQUENCIES") == 0) {
- ev = EVENT_AVOID_FREQUENCIES;
- if (param == NULL)
- param = "";
- if (freq_range_list_parse(&event.freq_range, param) < 0)
- return -1;
- wpa_supplicant_event(wpa_s, ev, &event);
- os_free(event.freq_range.range);
- return 0;
- } else if (os_strcmp(cmd, "SCAN_RES") == 0) {
- return wpas_ctrl_iface_driver_scan_res(wpa_s, param);
- } else if (os_strcmp(cmd, "ASSOC") == 0) {
- return wpas_ctrl_iface_driver_event_assoc(wpa_s, param);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "Testing - unknown driver event: %s",
- cmd);
- return -1;
- }
-
- wpa_supplicant_event(wpa_s, ev, &event);
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_eapol_rx(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- u8 src[ETH_ALEN], *buf;
- int used;
- size_t len;
-
- wpa_printf(MSG_DEBUG, "External EAPOL RX: %s", cmd);
-
- pos = cmd;
- used = hwaddr_aton2(pos, src);
- if (used < 0)
- return -1;
- pos += used;
- while (*pos == ' ')
- pos++;
-
- len = os_strlen(pos);
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(pos, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- wpa_supplicant_rx_eapol(wpa_s, src, buf, len);
- os_free(buf);
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_eapol_tx(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos;
- u8 dst[ETH_ALEN], *buf;
- int used, ret;
- size_t len;
- unsigned int prev;
-
- wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
-
- pos = cmd;
- used = hwaddr_aton2(pos, dst);
- if (used < 0)
- return -1;
- pos += used;
- while (*pos == ' ')
- pos++;
-
- len = os_strlen(pos);
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (!buf || hexstr2bin(pos, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- prev = wpa_s->ext_eapol_frame_io;
- wpa_s->ext_eapol_frame_io = 0;
- ret = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, buf, len);
- wpa_s->ext_eapol_frame_io = prev;
- os_free(buf);
-
- return ret;
-}
-
-
-static u16 ipv4_hdr_checksum(const void *buf, size_t len)
-{
- size_t i;
- u32 sum = 0;
- const u16 *pos = buf;
-
- for (i = 0; i < len / 2; i++)
- sum += *pos++;
-
- while (sum >> 16)
- sum = (sum & 0xffff) + (sum >> 16);
-
- return sum ^ 0xffff;
-}
-
-
-#define HWSIM_PACKETLEN 1500
-#define HWSIM_IP_LEN (HWSIM_PACKETLEN - sizeof(struct ether_header))
-
-static void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
- size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const struct ether_header *eth;
- struct ip ip;
- const u8 *pos;
- unsigned int i;
- char extra[30];
-
- if (len < sizeof(*eth) + sizeof(ip) || len > HWSIM_PACKETLEN) {
- wpa_printf(MSG_DEBUG,
- "test data: RX - ignore unexpected length %d",
- (int) len);
- return;
- }
-
- eth = (const struct ether_header *) buf;
- os_memcpy(&ip, eth + 1, sizeof(ip));
- pos = &buf[sizeof(*eth) + sizeof(ip)];
-
- if (ip.ip_hl != 5 || ip.ip_v != 4 || ntohs(ip.ip_len) > HWSIM_IP_LEN) {
- wpa_printf(MSG_DEBUG,
- "test data: RX - ignore unexpected IP header");
- return;
- }
-
- for (i = 0; i < ntohs(ip.ip_len) - sizeof(ip); i++) {
- if (*pos != (u8) i) {
- wpa_printf(MSG_DEBUG,
- "test data: RX - ignore mismatching payload");
- return;
- }
- pos++;
- }
- extra[0] = '\0';
- if (ntohs(ip.ip_len) != HWSIM_IP_LEN)
- os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.ip_len));
- wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s",
- MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra);
-}
-
-
-static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- int enabled = atoi(cmd);
- char *pos;
- const char *ifname;
-
- if (!enabled) {
- if (wpa_s->l2_test) {
- l2_packet_deinit(wpa_s->l2_test);
- wpa_s->l2_test = NULL;
- wpa_dbg(wpa_s, MSG_DEBUG, "test data: Disabled");
- }
- return 0;
- }
-
- if (wpa_s->l2_test)
- return 0;
-
- pos = os_strstr(cmd, " ifname=");
- if (pos)
- ifname = pos + 8;
- else
- ifname = wpa_s->ifname;
-
- wpa_s->l2_test = l2_packet_init(ifname, wpa_s->own_addr,
- ETHERTYPE_IP, wpas_data_test_rx,
- wpa_s, 1);
- if (wpa_s->l2_test == NULL)
- return -1;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "test data: Enabled");
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
-{
- u8 dst[ETH_ALEN], src[ETH_ALEN];
- char *pos, *pos2;
- int used;
- long int val;
- u8 tos;
- u8 buf[2 + HWSIM_PACKETLEN];
- struct ether_header *eth;
- struct ip *ip;
- u8 *dpos;
- unsigned int i;
- size_t send_len = HWSIM_IP_LEN;
-
- if (wpa_s->l2_test == NULL)
- return -1;
-
- /* format: <dst> <src> <tos> [len=<length>] */
-
- pos = cmd;
- used = hwaddr_aton2(pos, dst);
- if (used < 0)
- return -1;
- pos += used;
- while (*pos == ' ')
- pos++;
- used = hwaddr_aton2(pos, src);
- if (used < 0)
- return -1;
- pos += used;
-
- val = strtol(pos, &pos2, 0);
- if (val < 0 || val > 0xff)
- return -1;
- tos = val;
-
- pos = os_strstr(pos2, " len=");
- if (pos) {
- i = atoi(pos + 5);
- if (i < sizeof(*ip) || i > HWSIM_IP_LEN)
- return -1;
- send_len = i;
- }
-
- eth = (struct ether_header *) &buf[2];
- os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
- os_memcpy(eth->ether_shost, src, ETH_ALEN);
- eth->ether_type = htons(ETHERTYPE_IP);
- ip = (struct ip *) (eth + 1);
- os_memset(ip, 0, sizeof(*ip));
- ip->ip_hl = 5;
- ip->ip_v = 4;
- ip->ip_ttl = 64;
- ip->ip_tos = tos;
- ip->ip_len = htons(send_len);
- ip->ip_p = 1;
- ip->ip_src.s_addr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
- ip->ip_dst.s_addr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
- ip->ip_sum = ipv4_hdr_checksum(ip, sizeof(*ip));
- dpos = (u8 *) (ip + 1);
- for (i = 0; i < send_len - sizeof(*ip); i++)
- *dpos++ = i;
-
- if (l2_packet_send(wpa_s->l2_test, dst, ETHERTYPE_IP, &buf[2],
- sizeof(struct ether_header) + send_len) < 0)
- return -1;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX dst=" MACSTR " src=" MACSTR
- " tos=0x%x", MAC2STR(dst), MAC2STR(src), tos);
-
- return 0;
-}
-
-
-static int wpas_ctrl_iface_data_test_frame(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- u8 *buf;
- struct ether_header *eth;
- struct l2_packet_data *l2 = NULL;
- size_t len;
- u16 ethertype;
- int res = -1;
-
- len = os_strlen(cmd);
- if (len & 1 || len < ETH_HLEN * 2)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(cmd, buf, len) < 0)
- goto done;
-
- eth = (struct ether_header *) buf;
- ethertype = ntohs(eth->ether_type);
-
- l2 = l2_packet_init(wpa_s->ifname, wpa_s->own_addr, ethertype,
- wpas_data_test_rx, wpa_s, 1);
- if (l2 == NULL)
- goto done;
-
- res = l2_packet_send(l2, eth->ether_dhost, ethertype, buf, len);
- wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX frame res=%d", res);
-done:
- if (l2)
- l2_packet_deinit(l2);
- os_free(buf);
-
- return res < 0 ? -1 : 0;
-}
-
-
-static int wpas_ctrl_test_alloc_fail(struct wpa_supplicant *wpa_s, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_fail_func, pos,
- sizeof(wpa_trace_fail_func));
- } else {
- wpa_trace_fail_after = 0;
- }
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
- wpa_trace_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_test_fail(struct wpa_supplicant *wpa_s, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_test_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_test_fail_func, pos,
- sizeof(wpa_trace_test_fail_func));
- } else {
- wpa_trace_test_fail_after = 0;
- }
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_get_fail(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
- wpa_trace_test_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static void wpas_ctrl_event_test_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- int i, count = (intptr_t) timeout_ctx;
-
- wpa_printf(MSG_DEBUG, "TEST: Send %d control interface event messages",
- count);
- for (i = 0; i < count; i++) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, "TEST-EVENT-MESSAGE %d/%d",
- i + 1, count);
- }
-}
-
-
-static int wpas_ctrl_event_test(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- int count;
-
- count = atoi(cmd);
- if (count <= 0)
- return -1;
-
- return eloop_register_timeout(0, 0, wpas_ctrl_event_test_cb, wpa_s,
- (void *) (intptr_t) count);
-}
-
-
-static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- struct wpabuf *buf;
- size_t len;
-
- len = os_strlen(cmd);
- if (len & 1)
- return -1;
- len /= 2;
-
- if (len == 0) {
- buf = NULL;
- } else {
- buf = wpabuf_alloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) {
- wpabuf_free(buf);
- return -1;
- }
- }
-
- wpa_sm_set_test_assoc_ie(wpa_s->wpa, buf);
- return 0;
-}
-
-
-static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s)
-{
- u8 zero[WPA_TK_MAX_LEN];
-
- if (wpa_s->last_tk_alg == WPA_ALG_NONE)
- return -1;
-
- wpa_printf(MSG_INFO, "TESTING: Reset PN");
- os_memset(zero, 0, sizeof(zero));
-
- /* First, use a zero key to avoid any possible duplicate key avoidance
- * in the driver. */
- if (wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
- wpa_s->last_tk_key_idx, 1, zero, 6,
- zero, wpa_s->last_tk_len,
- KEY_FLAG_PAIRWISE_RX_TX) < 0)
- return -1;
-
- /* Set the previously configured key to reset its TSC/RSC */
- return wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
- wpa_s->last_tk_key_idx, 1, zero, 6,
- wpa_s->last_tk, wpa_s->last_tk_len,
- KEY_FLAG_PAIRWISE_RX_TX);
-}
-
-
-static int wpas_ctrl_key_request(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos = cmd;
- int error, pairwise;
-
- error = atoi(pos);
- pos = os_strchr(pos, ' ');
- if (!pos)
- return -1;
- pairwise = atoi(pos);
- wpa_sm_key_request(wpa_s->wpa, error, pairwise);
- return 0;
-}
-
-
-static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_SME
- struct wpa_driver_associate_params params;
- int ret;
-
- os_memset(&params, 0, sizeof(params));
- params.bssid = wpa_s->bssid;
- params.ssid = wpa_s->sme.ssid;
- params.ssid_len = wpa_s->sme.ssid_len;
- params.freq.freq = wpa_s->sme.freq;
- if (wpa_s->last_assoc_req_wpa_ie) {
- params.wpa_ie = wpabuf_head(wpa_s->last_assoc_req_wpa_ie);
- params.wpa_ie_len = wpabuf_len(wpa_s->last_assoc_req_wpa_ie);
- }
- params.pairwise_suite = wpa_s->pairwise_cipher;
- params.group_suite = wpa_s->group_cipher;
- params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
- params.key_mgmt_suite = wpa_s->key_mgmt;
- params.wpa_proto = wpa_s->wpa_proto;
- params.mgmt_frame_protection = wpa_s->sme.mfp;
- params.rrm_used = wpa_s->rrm.rrm_used;
- if (wpa_s->sme.prev_bssid_set)
- params.prev_bssid = wpa_s->sme.prev_bssid;
- wpa_printf(MSG_INFO, "TESTING: Resend association request");
- ret = wpa_drv_associate(wpa_s, &params);
- wpa_s->testing_resend_assoc = 1;
- return ret;
-#else /* CONFIG_SME */
- return -1;
-#endif /* CONFIG_SME */
-}
-
-
-static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- u8 dtok = 1;
- int exponent = 10;
- int mantissa = 8192;
- u8 min_twt = 255;
- unsigned long long twt = 0;
- bool requestor = true;
- int setup_cmd = 0;
- bool trigger = true;
- bool implicit = true;
- bool flow_type = true;
- int flow_id = 0;
- bool protection = false;
- u8 twt_channel = 0;
- u8 control = BIT(4); /* Control field (IEEE P802.11ax/D8.0 Figure
- * 9-687): B4 = TWT Information Frame Disabled */
- const char *tok_s;
-
- tok_s = os_strstr(cmd, " dialog=");
- if (tok_s)
- dtok = atoi(tok_s + os_strlen(" dialog="));
-
- tok_s = os_strstr(cmd, " exponent=");
- if (tok_s)
- exponent = atoi(tok_s + os_strlen(" exponent="));
-
- tok_s = os_strstr(cmd, " mantissa=");
- if (tok_s)
- mantissa = atoi(tok_s + os_strlen(" mantissa="));
-
- tok_s = os_strstr(cmd, " min_twt=");
- if (tok_s)
- min_twt = atoi(tok_s + os_strlen(" min_twt="));
-
- tok_s = os_strstr(cmd, " setup_cmd=");
- if (tok_s)
- setup_cmd = atoi(tok_s + os_strlen(" setup_cmd="));
-
- tok_s = os_strstr(cmd, " twt=");
- if (tok_s)
- sscanf(tok_s + os_strlen(" twt="), "%llu", &twt);
-
- tok_s = os_strstr(cmd, " requestor=");
- if (tok_s)
- requestor = atoi(tok_s + os_strlen(" requestor="));
-
- tok_s = os_strstr(cmd, " trigger=");
- if (tok_s)
- trigger = atoi(tok_s + os_strlen(" trigger="));
-
- tok_s = os_strstr(cmd, " implicit=");
- if (tok_s)
- implicit = atoi(tok_s + os_strlen(" implicit="));
-
- tok_s = os_strstr(cmd, " flow_type=");
- if (tok_s)
- flow_type = atoi(tok_s + os_strlen(" flow_type="));
-
- tok_s = os_strstr(cmd, " flow_id=");
- if (tok_s)
- flow_id = atoi(tok_s + os_strlen(" flow_id="));
-
- tok_s = os_strstr(cmd, " protection=");
- if (tok_s)
- protection = atoi(tok_s + os_strlen(" protection="));
-
- tok_s = os_strstr(cmd, " twt_channel=");
- if (tok_s)
- twt_channel = atoi(tok_s + os_strlen(" twt_channel="));
-
- tok_s = os_strstr(cmd, " control=");
- if (tok_s)
- control = atoi(tok_s + os_strlen(" control="));
-
- return wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt,
- setup_cmd, twt, requestor, trigger, implicit,
- flow_type, flow_id, protection, twt_channel,
- control);
-}
-
-
-static int wpas_ctrl_iface_send_twt_teardown(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- u8 flags = 0x1;
- const char *tok_s;
-
- tok_s = os_strstr(cmd, " flags=");
- if (tok_s)
- flags = atoi(tok_s + os_strlen(" flags="));
-
- return wpas_twt_send_teardown(wpa_s, flags);
-}
-
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos = cmd;
- int frame;
- size_t len;
- struct wpabuf *buf;
- struct ieee802_11_elems elems;
-
- frame = atoi(pos);
- if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES)
- return -1;
- wpa_s = wpas_vendor_elem(wpa_s, frame);
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
- pos++;
-
- len = os_strlen(pos);
- if (len == 0)
- return 0;
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = wpabuf_alloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
- wpabuf_free(buf);
- return -1;
- }
-
- if (ieee802_11_parse_elems(wpabuf_head_u8(buf), len, &elems, 0) ==
- ParseFailed) {
- wpabuf_free(buf);
- return -1;
- }
-
- if (wpa_s->vendor_elem[frame] == NULL) {
- wpa_s->vendor_elem[frame] = buf;
- goto update_ies;
- }
-
- if (wpabuf_resize(&wpa_s->vendor_elem[frame], len) < 0) {
- wpabuf_free(buf);
- return -1;
- }
-
- wpabuf_put_buf(wpa_s->vendor_elem[frame], buf);
- wpabuf_free(buf);
-
-update_ies:
- wpas_vendor_elem_update(wpa_s);
-
- if (frame == VENDOR_ELEM_PROBE_REQ ||
- frame == VENDOR_ELEM_PROBE_REQ_P2P)
- wpa_supplicant_set_default_scan_ies(wpa_s);
-
- return 0;
-}
-
-
-static int wpas_ctrl_vendor_elem_get(struct wpa_supplicant *wpa_s, char *cmd,
- char *buf, size_t buflen)
-{
- int frame = atoi(cmd);
-
- if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES)
- return -1;
- wpa_s = wpas_vendor_elem(wpa_s, frame);
-
- if (wpa_s->vendor_elem[frame] == NULL)
- return 0;
-
- return wpa_snprintf_hex(buf, buflen,
- wpabuf_head_u8(wpa_s->vendor_elem[frame]),
- wpabuf_len(wpa_s->vendor_elem[frame]));
-}
-
-
-static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *pos = cmd;
- int frame;
- size_t len;
- u8 *buf;
- struct ieee802_11_elems elems;
- int res;
-
- frame = atoi(pos);
- if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES)
- return -1;
- wpa_s = wpas_vendor_elem(wpa_s, frame);
-
- pos = os_strchr(pos, ' ');
- if (pos == NULL)
- return -1;
- pos++;
-
- if (*pos == '*') {
- wpabuf_free(wpa_s->vendor_elem[frame]);
- wpa_s->vendor_elem[frame] = NULL;
- wpas_vendor_elem_update(wpa_s);
- return 0;
- }
-
- if (wpa_s->vendor_elem[frame] == NULL)
- return -1;
-
- len = os_strlen(pos);
- if (len == 0)
- return 0;
- if (len & 1)
- return -1;
- len /= 2;
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
-
- if (hexstr2bin(pos, buf, len) < 0) {
- os_free(buf);
- return -1;
- }
-
- if (ieee802_11_parse_elems(buf, len, &elems, 0) == ParseFailed) {
- os_free(buf);
- return -1;
- }
-
- res = wpas_vendor_elem_remove(wpa_s, frame, buf, len);
- os_free(buf);
- return res;
-}
-
-
-static void wpas_ctrl_neighbor_rep_cb(void *ctx, struct wpabuf *neighbor_rep)
-{
- struct wpa_supplicant *wpa_s = ctx;
- size_t len;
- const u8 *data;
-
- /*
- * Neighbor Report element (IEEE P802.11-REVmc/D5.0)
- * BSSID[6]
- * BSSID Information[4]
- * Operating Class[1]
- * Channel Number[1]
- * PHY Type[1]
- * Optional Subelements[variable]
- */
-#define NR_IE_MIN_LEN (ETH_ALEN + 4 + 1 + 1 + 1)
-
- if (!neighbor_rep || wpabuf_len(neighbor_rep) == 0) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_FAILED);
- goto out;
- }
-
- data = wpabuf_head_u8(neighbor_rep);
- len = wpabuf_len(neighbor_rep);
-
- while (len >= 2 + NR_IE_MIN_LEN) {
- const u8 *nr;
- char lci[256 * 2 + 1];
- char civic[256 * 2 + 1];
- u8 nr_len = data[1];
- const u8 *pos = data, *end;
-
- if (pos[0] != WLAN_EID_NEIGHBOR_REPORT ||
- nr_len < NR_IE_MIN_LEN) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "CTRL: Invalid Neighbor Report element: id=%u len=%u",
- data[0], nr_len);
- goto out;
- }
-
- if (2U + nr_len > len) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "CTRL: Invalid Neighbor Report element: id=%u len=%zu nr_len=%u",
- data[0], len, nr_len);
- goto out;
- }
- pos += 2;
- end = pos + nr_len;
-
- nr = pos;
- pos += NR_IE_MIN_LEN;
-
- lci[0] = '\0';
- civic[0] = '\0';
- while (end - pos > 2) {
- u8 s_id, s_len;
-
- s_id = *pos++;
- s_len = *pos++;
- if (s_len > end - pos)
- goto out;
- if (s_id == WLAN_EID_MEASURE_REPORT && s_len > 3) {
- /* Measurement Token[1] */
- /* Measurement Report Mode[1] */
- /* Measurement Type[1] */
- /* Measurement Report[variable] */
- switch (pos[2]) {
- case MEASURE_TYPE_LCI:
- if (lci[0])
- break;
- wpa_snprintf_hex(lci, sizeof(lci),
- pos, s_len);
- break;
- case MEASURE_TYPE_LOCATION_CIVIC:
- if (civic[0])
- break;
- wpa_snprintf_hex(civic, sizeof(civic),
- pos, s_len);
- break;
- }
- }
-
- pos += s_len;
- }
-
- wpa_msg(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED
- "bssid=" MACSTR
- " info=0x%x op_class=%u chan=%u phy_type=%u%s%s%s%s",
- MAC2STR(nr), WPA_GET_LE32(nr + ETH_ALEN),
- nr[ETH_ALEN + 4], nr[ETH_ALEN + 5],
- nr[ETH_ALEN + 6],
- lci[0] ? " lci=" : "", lci,
- civic[0] ? " civic=" : "", civic);
-
- data = end;
- len -= 2 + nr_len;
- }
-
-out:
- wpabuf_free(neighbor_rep);
-}
-
-
-static int wpas_ctrl_iface_send_neighbor_rep(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- struct wpa_ssid_value ssid, *ssid_p = NULL;
- int ret, lci = 0, civic = 0;
- char *ssid_s;
-
- ssid_s = os_strstr(cmd, "ssid=");
- if (ssid_s) {
- if (ssid_parse(ssid_s + 5, &ssid)) {
- wpa_msg(wpa_s, MSG_INFO,
- "CTRL: Send Neighbor Report: bad SSID");
- return -1;
- }
-
- ssid_p = &ssid;
-
- /*
- * Move cmd after the SSID text that may include "lci" or
- * "civic".
- */
- cmd = os_strchr(ssid_s + 6, ssid_s[5] == '"' ? '"' : ' ');
- if (cmd)
- cmd++;
-
- }
-
- if (cmd && os_strstr(cmd, "lci"))
- lci = 1;
-
- if (cmd && os_strstr(cmd, "civic"))
- civic = 1;
-
- ret = wpas_rrm_send_neighbor_rep_request(wpa_s, ssid_p, lci, civic,
- wpas_ctrl_neighbor_rep_cb,
- wpa_s);
-
- return ret;
-}
-
-
-static int wpas_ctrl_iface_erp_flush(struct wpa_supplicant *wpa_s)
-{
- eapol_sm_erp_flush(wpa_s->eapol);
- return 0;
-}
-
-
-static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *token, *context = NULL;
- unsigned int enable = ~0, type = 0;
- u8 _addr[ETH_ALEN], _mask[ETH_ALEN];
- u8 *addr = NULL, *mask = NULL;
-
- while ((token = str_token(cmd, " ", &context))) {
- if (os_strcasecmp(token, "scan") == 0) {
- type |= MAC_ADDR_RAND_SCAN;
- } else if (os_strcasecmp(token, "sched") == 0) {
- type |= MAC_ADDR_RAND_SCHED_SCAN;
- } else if (os_strcasecmp(token, "pno") == 0) {
- type |= MAC_ADDR_RAND_PNO;
- } else if (os_strcasecmp(token, "all") == 0) {
- type = wpa_s->mac_addr_rand_supported;
- } else if (os_strncasecmp(token, "enable=", 7) == 0) {
- enable = atoi(token + 7);
- } else if (os_strncasecmp(token, "addr=", 5) == 0) {
- addr = _addr;
- if (hwaddr_aton(token + 5, addr)) {
- wpa_printf(MSG_INFO,
- "CTRL: Invalid MAC address: %s",
- token);
- return -1;
- }
- } else if (os_strncasecmp(token, "mask=", 5) == 0) {
- mask = _mask;
- if (hwaddr_aton(token + 5, mask)) {
- wpa_printf(MSG_INFO,
- "CTRL: Invalid MAC address mask: %s",
- token);
- return -1;
- }
- } else {
- wpa_printf(MSG_INFO,
- "CTRL: Invalid MAC_RAND_SCAN parameter: %s",
- token);
- return -1;
- }
- }
-
- if (!type) {
- wpa_printf(MSG_INFO, "CTRL: MAC_RAND_SCAN no type specified");
- return -1;
- }
-
- if (enable > 1) {
- wpa_printf(MSG_INFO,
- "CTRL: MAC_RAND_SCAN enable=<0/1> not specified");
- return -1;
- }
-
- if (!enable)
- return wpas_disable_mac_addr_randomization(wpa_s, type);
-
- return wpas_enable_mac_addr_randomization(wpa_s, type, addr, mask);
-}
-
-
-static int wpas_ctrl_iface_pmksa(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- size_t reply_len;
-
- reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, buf, buflen);
-#ifdef CONFIG_AP
- reply_len += wpas_ap_pmksa_cache_list(wpa_s, &buf[reply_len],
- buflen - reply_len);
-#endif /* CONFIG_AP */
- return reply_len;
-}
-
-
-static void wpas_ctrl_iface_pmksa_flush(struct wpa_supplicant *wpa_s)
-{
- ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
-#ifdef CONFIG_AP
- wpas_ap_pmksa_cache_flush(wpa_s);
-#endif /* CONFIG_AP */
-}
-
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-
-static int wpas_ctrl_iface_pmksa_get(struct wpa_supplicant *wpa_s,
- const char *cmd, char *buf, size_t buflen)
-{
- struct rsn_pmksa_cache_entry *entry;
- struct wpa_ssid *ssid;
- char *pos, *pos2, *end;
- int ret;
- struct os_reltime now;
-
- ssid = wpa_config_get_network(wpa_s->conf, atoi(cmd));
- if (!ssid)
- return -1;
-
- pos = buf;
- end = buf + buflen;
-
- os_get_reltime(&now);
-
- /*
- * Entry format:
- * <BSSID> <PMKID> <PMK> <reauth_time in seconds>
- * <expiration in seconds> <akmp> <opportunistic>
- * [FILS Cache Identifier]
- */
-
- for (entry = wpa_sm_pmksa_cache_head(wpa_s->wpa); entry;
- entry = entry->next) {
- if (entry->network_ctx != ssid)
- continue;
-
- pos2 = pos;
- ret = os_snprintf(pos2, end - pos2, MACSTR " ",
- MAC2STR(entry->aa));
- if (os_snprintf_error(end - pos2, ret))
- break;
- pos2 += ret;
-
- pos2 += wpa_snprintf_hex(pos2, end - pos2, entry->pmkid,
- PMKID_LEN);
-
- ret = os_snprintf(pos2, end - pos2, " ");
- if (os_snprintf_error(end - pos2, ret))
- break;
- pos2 += ret;
-
- pos2 += wpa_snprintf_hex(pos2, end - pos2, entry->pmk,
- entry->pmk_len);
-
- ret = os_snprintf(pos2, end - pos2, " %d %d %d %d",
- (int) (entry->reauth_time - now.sec),
- (int) (entry->expiration - now.sec),
- entry->akmp,
- entry->opportunistic);
- if (os_snprintf_error(end - pos2, ret))
- break;
- pos2 += ret;
-
- if (entry->fils_cache_id_set) {
- ret = os_snprintf(pos2, end - pos2, " %02x%02x",
- entry->fils_cache_id[0],
- entry->fils_cache_id[1]);
- if (os_snprintf_error(end - pos2, ret))
- break;
- pos2 += ret;
- }
-
- ret = os_snprintf(pos2, end - pos2, "\n");
- if (os_snprintf_error(end - pos2, ret))
- break;
- pos2 += ret;
-
- pos = pos2;
- }
-
- return pos - buf;
-}
-
-
-static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- struct rsn_pmksa_cache_entry *entry;
- struct wpa_ssid *ssid;
- char *pos, *pos2;
- int ret = -1;
- struct os_reltime now;
- int reauth_time = 0, expiration = 0, i;
-
- /*
- * Entry format:
- * <network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds>
- * <expiration in seconds> <akmp> <opportunistic>
- * [FILS Cache Identifier]
- */
-
- ssid = wpa_config_get_network(wpa_s->conf, atoi(cmd));
- if (!ssid)
- return -1;
-
- pos = os_strchr(cmd, ' ');
- if (!pos)
- return -1;
- pos++;
-
- entry = os_zalloc(sizeof(*entry));
- if (!entry)
- return -1;
-
- if (hwaddr_aton(pos, entry->aa))
- goto fail;
-
- pos = os_strchr(pos, ' ');
- if (!pos)
- goto fail;
- pos++;
-
- if (hexstr2bin(pos, entry->pmkid, PMKID_LEN) < 0)
- goto fail;
-
- pos = os_strchr(pos, ' ');
- if (!pos)
- goto fail;
- pos++;
-
- pos2 = os_strchr(pos, ' ');
- if (!pos2)
- goto fail;
- entry->pmk_len = (pos2 - pos) / 2;
- if (entry->pmk_len < PMK_LEN || entry->pmk_len > PMK_LEN_MAX ||
- hexstr2bin(pos, entry->pmk, entry->pmk_len) < 0)
- goto fail;
-
- pos = os_strchr(pos, ' ');
- if (!pos)
- goto fail;
- pos++;
-
- if (sscanf(pos, "%d %d %d %d", &reauth_time, &expiration,
- &entry->akmp, &entry->opportunistic) != 4)
- goto fail;
- if (reauth_time > expiration)
- goto fail;
- for (i = 0; i < 4; i++) {
- pos = os_strchr(pos, ' ');
- if (!pos) {
- if (i < 3)
- goto fail;
- break;
- }
- pos++;
- }
- if (pos) {
- if (hexstr2bin(pos, entry->fils_cache_id,
- FILS_CACHE_ID_LEN) < 0)
- goto fail;
- entry->fils_cache_id_set = 1;
- }
- os_get_reltime(&now);
- entry->expiration = now.sec + expiration;
- entry->reauth_time = now.sec + reauth_time;
-
- entry->network_ctx = ssid;
-
- entry->external = true;
-
- wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
- entry = NULL;
- ret = 0;
-fail:
- os_free(entry);
- return ret;
-}
-
-
-#ifdef CONFIG_MESH
-
-static int wpas_ctrl_iface_mesh_pmksa_get(struct wpa_supplicant *wpa_s,
- const char *cmd, char *buf,
- size_t buflen)
-{
- u8 spa[ETH_ALEN];
-
- if (!wpa_s->ifmsh)
- return -1;
-
- if (os_strcasecmp(cmd, "any") == 0)
- return wpas_ap_pmksa_cache_list_mesh(wpa_s, NULL, buf, buflen);
-
- if (hwaddr_aton(cmd, spa))
- return -1;
-
- return wpas_ap_pmksa_cache_list_mesh(wpa_s, spa, buf, buflen);
-}
-
-
-static int wpas_ctrl_iface_mesh_pmksa_add(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- /*
- * We do not check mesh interface existence because PMKSA should be
- * stored before wpa_s->ifmsh creation to suppress commit message
- * creation.
- */
- return wpas_ap_pmksa_cache_add_external(wpa_s, cmd);
-}
-
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
-
-#ifdef CONFIG_FILS
-static int wpas_ctrl_iface_fils_hlp_req_add(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- struct fils_hlp_req *req;
- const char *pos;
-
- /* format: <dst> <packet starting from ethertype> */
-
- req = os_zalloc(sizeof(*req));
- if (!req)
- return -1;
-
- if (hwaddr_aton(cmd, req->dst))
- goto fail;
-
- pos = os_strchr(cmd, ' ');
- if (!pos)
- goto fail;
- pos++;
- req->pkt = wpabuf_parse_bin(pos);
- if (!req->pkt)
- goto fail;
-
- dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
- return 0;
-fail:
- wpabuf_free(req->pkt);
- os_free(req);
- return -1;
-}
-#endif /* CONFIG_FILS */
-
-
-static int wpas_ctrl_cmd_debug_level(const char *cmd)
-{
- if (os_strcmp(cmd, "PING") == 0 ||
- os_strncmp(cmd, "BSS ", 4) == 0 ||
- os_strncmp(cmd, "GET_NETWORK ", 12) == 0 ||
- os_strncmp(cmd, "STATUS", 6) == 0 ||
- os_strncmp(cmd, "STA ", 4) == 0 ||
- os_strncmp(cmd, "STA-", 4) == 0)
- return MSG_EXCESSIVE;
- return MSG_DEBUG;
-}
-
-
-static int wpas_ctrl_iface_configure_mscs(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- size_t frame_classifier_len;
- const char *pos, *end;
- struct robust_av_data *robust_av = &wpa_s->robust_av;
- int val;
-
- /*
- * format:
- * <add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>]
- * [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>]
- */
- os_memset(robust_av, 0, sizeof(struct robust_av_data));
- if (os_strncmp(cmd, "add ", 4) == 0) {
- robust_av->request_type = SCS_REQ_ADD;
- } else if (os_strcmp(cmd, "remove") == 0) {
- robust_av->request_type = SCS_REQ_REMOVE;
- robust_av->valid_config = false;
- return wpas_send_mscs_req(wpa_s);
- } else if (os_strncmp(cmd, "change ", 7) == 0) {
- robust_av->request_type = SCS_REQ_CHANGE;
- } else {
- return -1;
- }
-
- pos = os_strstr(cmd, "up_bitmap=");
- if (!pos)
- return -1;
-
- val = hex2byte(pos + 10);
- if (val < 0)
- return -1;
- robust_av->up_bitmap = val;
-
- pos = os_strstr(cmd, "up_limit=");
- if (!pos)
- return -1;
-
- robust_av->up_limit = atoi(pos + 9);
-
- pos = os_strstr(cmd, "stream_timeout=");
- if (!pos)
- return -1;
-
- robust_av->stream_timeout = atoi(pos + 15);
- if (robust_av->stream_timeout == 0)
- return -1;
-
- pos = os_strstr(cmd, "frame_classifier=");
- if (!pos)
- return -1;
-
- pos += 17;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- frame_classifier_len = (end - pos) / 2;
- if (frame_classifier_len > sizeof(robust_av->frame_classifier) ||
- hexstr2bin(pos, robust_av->frame_classifier, frame_classifier_len))
- return -1;
-
- robust_av->frame_classifier_len = frame_classifier_len;
- robust_av->valid_config = true;
-
- return wpas_send_mscs_req(wpa_s);
-}
-
-
-#ifdef CONFIG_PASN
-static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
-{
- char *token, *context = NULL;
- u8 bssid[ETH_ALEN];
- int akmp = -1, cipher = -1, got_bssid = 0;
- u16 group = 0xFFFF;
- u8 *comeback = NULL;
- size_t comeback_len = 0;
- int id = 0, ret = -1;
-
- /*
- * Entry format: bssid=<BSSID> akmp=<AKMP> cipher=<CIPHER> group=<group>
- * [comeback=<hexdump>]
- */
- while ((token = str_token(cmd, " ", &context))) {
- if (os_strncmp(token, "bssid=", 6) == 0) {
- if (hwaddr_aton(token + 6, bssid))
- goto out;
- got_bssid = 1;
- } else if (os_strcmp(token, "akmp=PASN") == 0) {
- akmp = WPA_KEY_MGMT_PASN;
-#ifdef CONFIG_IEEE80211R
- } else if (os_strcmp(token, "akmp=FT-PSK") == 0) {
- akmp = WPA_KEY_MGMT_FT_PSK;
- } else if (os_strcmp(token, "akmp=FT-EAP-SHA384") == 0) {
- akmp = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
- } else if (os_strcmp(token, "akmp=FT-EAP") == 0) {
- akmp = WPA_KEY_MGMT_FT_IEEE8021X;
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_SAE
- } else if (os_strcmp(token, "akmp=SAE") == 0) {
- akmp = WPA_KEY_MGMT_SAE;
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_FILS
- } else if (os_strcmp(token, "akmp=FILS-SHA256") == 0) {
- akmp = WPA_KEY_MGMT_FILS_SHA256;
- } else if (os_strcmp(token, "akmp=FILS-SHA384") == 0) {
- akmp = WPA_KEY_MGMT_FILS_SHA384;
-#endif /* CONFIG_FILS */
- } else if (os_strcmp(token, "cipher=CCMP-256") == 0) {
- cipher = WPA_CIPHER_CCMP_256;
- } else if (os_strcmp(token, "cipher=GCMP-256") == 0) {
- cipher = WPA_CIPHER_GCMP_256;
- } else if (os_strcmp(token, "cipher=CCMP") == 0) {
- cipher = WPA_CIPHER_CCMP;
- } else if (os_strcmp(token, "cipher=GCMP") == 0) {
- cipher = WPA_CIPHER_GCMP;
- } else if (os_strncmp(token, "group=", 6) == 0) {
- group = atoi(token + 6);
- } else if (os_strncmp(token, "nid=", 4) == 0) {
- id = atoi(token + 4);
- } else if (os_strncmp(token, "comeback=", 9) == 0) {
- comeback_len = os_strlen(token + 9);
- if (comeback || !comeback_len || comeback_len % 2)
- goto out;
-
- comeback_len /= 2;
- comeback = os_malloc(comeback_len);
- if (!comeback ||
- hexstr2bin(token + 9, comeback, comeback_len))
- goto out;
- } else {
- wpa_printf(MSG_DEBUG,
- "CTRL: PASN Invalid parameter: '%s'",
- token);
- goto out;
- }
- }
-
- if (!got_bssid || akmp == -1 || cipher == -1 || group == 0xFFFF) {
- wpa_printf(MSG_DEBUG,"CTRL: PASN missing parameter");
- goto out;
- }
-
- ret = wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id,
- comeback, comeback_len);
-out:
- os_free(comeback);
- return ret;
-}
-
-
-static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- u8 bssid[ETH_ALEN];
-
- if (os_strncmp(cmd, "bssid=", 6) != 0 || hwaddr_aton(cmd + 6, bssid)) {
- wpa_printf(MSG_DEBUG,
- "CTRL: PASN_DEAUTH without valid BSSID");
- return -1;
- }
-
- return wpas_pasn_deauthenticate(wpa_s, bssid);
-}
-
-#endif /* CONFIG_PASN */
-
-
-static int set_type4_frame_classifier(const char *cmd,
- struct type4_params *param)
-{
- const char *pos, *end;
- u8 classifier_mask = 0;
- int ret;
- char addr[INET6_ADDRSTRLEN];
- size_t alen;
-
- if (os_strstr(cmd, "ip_version=ipv4")) {
- param->ip_version = IPV4;
- } else if (os_strstr(cmd, "ip_version=ipv6")) {
- param->ip_version = IPV6;
- } else {
- wpa_printf(MSG_ERROR, "IP version missing/invalid");
- return -1;
- }
-
- classifier_mask |= BIT(0);
-
- pos = os_strstr(cmd, "src_ip=");
- if (pos) {
- pos += 7;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- alen = end - pos;
- if (alen >= INET6_ADDRSTRLEN)
- return -1;
- os_memcpy(addr, pos, alen);
- addr[alen] = '\0';
- if (param->ip_version == IPV4)
- ret = inet_pton(AF_INET, addr,
- &param->ip_params.v4.src_ip);
- else
- ret = inet_pton(AF_INET6, addr,
- &param->ip_params.v6.src_ip);
-
- if (ret != 1) {
- wpa_printf(MSG_ERROR,
- "Error converting src IP address to binary ret=%d",
- ret);
- return -1;
- }
-
- classifier_mask |= BIT(1);
- }
-
- pos = os_strstr(cmd, "dst_ip=");
- if (pos) {
- pos += 7;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- alen = end - pos;
- if (alen >= INET6_ADDRSTRLEN)
- return -1;
- os_memcpy(addr, pos, alen);
- addr[alen] = '\0';
- if (param->ip_version == IPV4)
- ret = inet_pton(AF_INET, addr,
- &param->ip_params.v4.dst_ip);
- else
- ret = inet_pton(AF_INET6, addr,
- &param->ip_params.v6.dst_ip);
-
- if (ret != 1) {
- wpa_printf(MSG_ERROR,
- "Error converting dst IP address to binary ret=%d",
- ret);
- return -1;
- }
-
- classifier_mask |= BIT(2);
- }
-
- pos = os_strstr(cmd, "src_port=");
- if (pos && atoi(pos + 9) > 0) {
- if (param->ip_version == IPV4)
- param->ip_params.v4.src_port = atoi(pos + 9);
- else
- param->ip_params.v6.src_port = atoi(pos + 9);
- classifier_mask |= BIT(3);
- }
-
- pos = os_strstr(cmd, "dst_port=");
- if (pos && atoi(pos + 9) > 0) {
- if (param->ip_version == IPV4)
- param->ip_params.v4.dst_port = atoi(pos + 9);
- else
- param->ip_params.v6.dst_port = atoi(pos + 9);
- classifier_mask |= BIT(4);
- }
-
- pos = os_strstr(cmd, "dscp=");
- if (pos && atoi(pos + 5) > 0) {
- if (param->ip_version == IPV4)
- param->ip_params.v4.dscp = atoi(pos + 5);
- else
- param->ip_params.v6.dscp = atoi(pos + 5);
- classifier_mask |= BIT(5);
- }
-
- if (param->ip_version == IPV4) {
- pos = os_strstr(cmd, "protocol=");
- if (pos) {
- if (os_strstr(pos, "udp")) {
- param->ip_params.v4.protocol = 17;
- } else if (os_strstr(pos, "tcp")) {
- param->ip_params.v4.protocol = 6;
- } else if (os_strstr(pos, "esp")) {
- param->ip_params.v4.protocol = 50;
- } else {
- wpa_printf(MSG_ERROR, "Invalid protocol");
- return -1;
- }
- classifier_mask |= BIT(6);
- }
- } else {
- pos = os_strstr(cmd, "next_header=");
- if (pos) {
- if (os_strstr(pos, "udp")) {
- param->ip_params.v6.next_header = 17;
- } else if (os_strstr(pos, "tcp")) {
- param->ip_params.v6.next_header = 6;
- } else if (os_strstr(pos, "esp")) {
- param->ip_params.v6.next_header = 50;
- } else {
- wpa_printf(MSG_ERROR, "Invalid next header");
- return -1;
- }
-
- classifier_mask |= BIT(6);
- }
-
- pos = os_strstr(cmd, "flow_label=");
- if (pos) {
- pos += 11;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- if (end - pos != 6 ||
- hexstr2bin(pos, param->ip_params.v6.flow_label,
- 3) ||
- param->ip_params.v6.flow_label[0] > 0x0F) {
- wpa_printf(MSG_ERROR, "Invalid flow label");
- return -1;
- }
-
- classifier_mask |= BIT(7);
- }
- }
-
- param->classifier_mask = classifier_mask;
- return 0;
-}
-
-
-static int set_type10_frame_classifier(const char *cmd,
- struct type10_params *param)
-{
- const char *pos, *end;
- size_t filter_len;
-
- pos = os_strstr(cmd, "prot_instance=");
- if (!pos) {
- wpa_printf(MSG_ERROR, "Protocol instance missing");
- return -1;
- }
- param->prot_instance = atoi(pos + 14);
-
- pos = os_strstr(cmd, "prot_number=");
- if (!pos) {
- wpa_printf(MSG_ERROR, "Protocol number missing");
- return -1;
- }
- if (os_strstr(pos, "udp")) {
- param->prot_number = 17;
- } else if (os_strstr(pos, "tcp")) {
- param->prot_number = 6;
- } else if (os_strstr(pos, "esp")) {
- param->prot_number = 50;
- } else {
- wpa_printf(MSG_ERROR, "Invalid protocol number");
- return -1;
- }
-
- pos = os_strstr(cmd, "filter_value=");
- if (!pos) {
- wpa_printf(MSG_ERROR,
- "Classifier parameter filter_value missing");
- return -1;
- }
-
- pos += 13;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- filter_len = (end - pos) / 2;
- param->filter_value = os_malloc(filter_len);
- if (!param->filter_value)
- return -1;
-
- if (hexstr2bin(pos, param->filter_value, filter_len)) {
- wpa_printf(MSG_ERROR, "Invalid filter_value %s", pos);
- goto free;
- }
-
- pos = os_strstr(cmd, "filter_mask=");
- if (!pos) {
- wpa_printf(MSG_ERROR,
- "Classifier parameter filter_mask missing");
- goto free;
- }
-
- pos += 12;
- end = os_strchr(pos, ' ');
- if (!end)
- end = pos + os_strlen(pos);
-
- if (filter_len != (size_t) (end - pos) / 2) {
- wpa_printf(MSG_ERROR,
- "Filter mask length mismatch expected=%zu received=%zu",
- filter_len, (size_t) (end - pos) / 2);
- goto free;
- }
-
- param->filter_mask = os_malloc(filter_len);
- if (!param->filter_mask)
- goto free;
-
- if (hexstr2bin(pos, param->filter_mask, filter_len)) {
- wpa_printf(MSG_ERROR, "Invalid filter mask %s", pos);
- os_free(param->filter_mask);
- param->filter_mask = NULL;
- goto free;
- }
-
- param->filter_len = filter_len;
- return 0;
-free:
- os_free(param->filter_value);
- param->filter_value = NULL;
- return -1;
-}
-
-
-static int scs_parse_type4(struct tclas_element *elem, const char *pos)
-{
- struct type4_params type4_param = { 0 };
-
- if (set_type4_frame_classifier(pos, &type4_param) == -1) {
- wpa_printf(MSG_ERROR, "Failed to set frame_classifier 4");
- return -1;
- }
-
- os_memcpy(&elem->frame_classifier.type4_param,
- &type4_param, sizeof(struct type4_params));
- return 0;
-}
-
-
-static int scs_parse_type10(struct tclas_element *elem, const char *pos)
-{
- struct type10_params type10_param = { 0 };
-
- if (set_type10_frame_classifier(pos, &type10_param) == -1) {
- wpa_printf(MSG_ERROR, "Failed to set frame_classifier 10");
- return -1;
- }
-
- os_memcpy(&elem->frame_classifier.type10_param,
- &type10_param, sizeof(struct type10_params));
- return 0;
-}
-
-
-static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
- char *cmd)
-{
- char *pos1, *pos;
- struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
- struct scs_desc_elem desc_elem = { 0 };
- int val;
- unsigned int num_scs_desc = 0;
-
- if (wpa_s->ongoing_scs_req) {
- wpa_printf(MSG_ERROR, "%s: SCS Request already in queue",
- __func__);
- return -1;
- }
-
- /**
- * format:
- * [scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>]
- * [classifier_type=<4|10>]
- * [classifier params based on classifier type]
- * [tclas_processing=<0|1>] [scs_id=<decimal number>] ...
- */
- pos1 = os_strstr(cmd, "scs_id=");
- if (!pos1) {
- wpa_printf(MSG_ERROR, "SCSID not present");
- return -1;
- }
-
- free_up_scs_desc(scs_data);
-
- while (pos1) {
- struct scs_desc_elem *n1;
- struct active_scs_elem *active_scs_desc;
- char *next_scs_desc;
- unsigned int num_tclas_elem = 0;
- bool scsid_active = false;
-
- desc_elem.scs_id = atoi(pos1 + 7);
- pos1 += 7;
-
- next_scs_desc = os_strstr(pos1, "scs_id=");
- if (next_scs_desc) {
- char temp[20];
-
- os_snprintf(temp, sizeof(temp), "scs_id=%d ",
- desc_elem.scs_id);
- if (os_strstr(next_scs_desc, temp)) {
- wpa_printf(MSG_ERROR,
- "Multiple SCS descriptors configured with same SCSID(=%d)",
- desc_elem.scs_id);
- goto free_scs_desc;
- }
- pos1[next_scs_desc - pos1 - 1] = '\0';
- }
-
- dl_list_for_each(active_scs_desc, &wpa_s->active_scs_ids,
- struct active_scs_elem, list) {
- if (desc_elem.scs_id == active_scs_desc->scs_id) {
- scsid_active = true;
- break;
- }
- }
-
- if (os_strstr(pos1, "add ")) {
- desc_elem.request_type = SCS_REQ_ADD;
- if (scsid_active) {
- wpa_printf(MSG_ERROR, "SCSID %d already active",
- desc_elem.scs_id);
- return -1;
- }
- } else if (os_strstr(pos1, "remove")) {
- desc_elem.request_type = SCS_REQ_REMOVE;
- if (!scsid_active) {
- wpa_printf(MSG_ERROR, "SCSID %d not active",
- desc_elem.scs_id);
- return -1;
- }
- goto scs_desc_end;
- } else if (os_strstr(pos1, "change ")) {
- desc_elem.request_type = SCS_REQ_CHANGE;
- if (!scsid_active) {
- wpa_printf(MSG_ERROR, "SCSID %d not active",
- desc_elem.scs_id);
- return -1;
- }
- } else {
- wpa_printf(MSG_ERROR, "SCS Request type invalid");
- goto free_scs_desc;
- }
-
- pos1 = os_strstr(pos1, "scs_up=");
- if (!pos1) {
- wpa_printf(MSG_ERROR,
- "Intra-Access user priority not present");
- goto free_scs_desc;
- }
-
- val = atoi(pos1 + 7);
- if (val < 0 || val > 7) {
- wpa_printf(MSG_ERROR,
- "Intra-Access user priority invalid %d",
- val);
- goto free_scs_desc;
- }
-
- desc_elem.intra_access_priority = val;
- desc_elem.scs_up_avail = true;
-
- pos = os_strstr(pos1, "classifier_type=");
- if (!pos) {
- wpa_printf(MSG_ERROR, "classifier type empty");
- goto free_scs_desc;
- }
-
- while (pos) {
- struct tclas_element elem = { 0 }, *n;
- char *next_tclas_elem;
-
- val = atoi(pos + 16);
- if (val != 4 && val != 10) {
- wpa_printf(MSG_ERROR,
- "classifier type invalid %d", val);
- goto free_scs_desc;
- }
-
- elem.classifier_type = val;
- pos += 16;
-
- next_tclas_elem = os_strstr(pos, "classifier_type=");
- if (next_tclas_elem) {
- pos1 = next_tclas_elem;
- pos[next_tclas_elem - pos - 1] = '\0';
- }
-
- switch (val) {
- case 4:
- if (scs_parse_type4(&elem, pos) < 0)
- goto free_scs_desc;
- break;
- case 10:
- if (scs_parse_type10(&elem, pos) < 0)
- goto free_scs_desc;
- break;
- }
-
- n = os_realloc(desc_elem.tclas_elems,
- (num_tclas_elem + 1) * sizeof(elem));
- if (!n)
- goto free_scs_desc;
-
- desc_elem.tclas_elems = n;
- os_memcpy((u8 *) desc_elem.tclas_elems +
- num_tclas_elem * sizeof(elem),
- &elem, sizeof(elem));
- num_tclas_elem++;
- desc_elem.num_tclas_elem = num_tclas_elem;
- pos = next_tclas_elem;
- }
-
- if (desc_elem.num_tclas_elem > 1) {
- pos1 = os_strstr(pos1, "tclas_processing=");
- if (!pos1) {
- wpa_printf(MSG_ERROR, "tclas_processing empty");
- goto free_scs_desc;
- }
-
- val = atoi(pos1 + 17);
- if (val != 0 && val != 1) {
- wpa_printf(MSG_ERROR,
- "tclas_processing invalid");
- goto free_scs_desc;
- }
-
- desc_elem.tclas_processing = val;
- }
-
-scs_desc_end:
- n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
- sizeof(struct scs_desc_elem));
- if (!n1)
- goto free_scs_desc;
-
- scs_data->scs_desc_elems = n1;
- os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_desc *
- sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
- num_scs_desc++;
- scs_data->num_scs_desc = num_scs_desc;
- pos1 = next_scs_desc;
- os_memset(&desc_elem, 0, sizeof(desc_elem));
- }
-
- return wpas_send_scs_req(wpa_s);
-
-free_scs_desc:
- free_up_tclas_elem(&desc_elem);
- free_up_scs_desc(scs_data);
- return -1;
-}
-
-
-static int wpas_ctrl_iface_send_dscp_resp(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- char *pos;
- struct dscp_policy_status *policy = NULL, *n;
- int num_policies = 0, ret = -1;
- struct dscp_resp_data resp_data;
-
- /*
- * format:
- * <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
- */
-
- os_memset(&resp_data, 0, sizeof(resp_data));
-
- resp_data.more = os_strstr(cmd, "more") != NULL;
-
- if (os_strstr(cmd, "reset")) {
- resp_data.reset = true;
- resp_data.solicited = false;
- goto send_resp;
- }
-
- resp_data.solicited = os_strstr(cmd, "solicited") != NULL;
-
- pos = os_strstr(cmd, "policy_id=");
- while (pos) {
- n = os_realloc(policy, (num_policies + 1) * sizeof(*policy));
- if (!n)
- goto fail;
-
- policy = n;
- pos += 10;
- policy[num_policies].id = atoi(pos);
- if (policy[num_policies].id == 0) {
- wpa_printf(MSG_ERROR, "DSCP: Invalid policy id");
- goto fail;
- }
-
- pos = os_strstr(pos, "status=");
- if (!pos) {
- wpa_printf(MSG_ERROR,
- "DSCP: Status is not found for a policy");
- goto fail;
- }
-
- pos += 7;
- policy[num_policies].status = atoi(pos);
- num_policies++;
-
- pos = os_strstr(pos, "policy_id");
- }
-
- resp_data.policy = policy;
- resp_data.num_policies = num_policies;
-send_resp:
- ret = wpas_send_dscp_response(wpa_s, &resp_data);
- if (ret)
- wpa_printf(MSG_ERROR, "DSCP: Failed to send DSCP response");
-fail:
- os_free(policy);
- return ret;
-}
-
-
-static int wpas_ctrl_iface_send_dscp_query(struct wpa_supplicant *wpa_s,
- const char *cmd)
-{
- char *pos;
-
- /*
- * format:
- * Wildcard DSCP query
- * <wildcard>
- *
- * DSCP query with a domain name attribute:
- * [domain_name=<string>]
- */
-
- if (os_strstr(cmd, "wildcard")) {
- wpa_printf(MSG_DEBUG, "QM: Send wildcard DSCP policy query");
- return wpas_send_dscp_query(wpa_s, NULL, 0);
- }
-
- pos = os_strstr(cmd, "domain_name=");
- if (!pos || !os_strlen(pos + 12)) {
- wpa_printf(MSG_ERROR, "QM: Domain name not preset");
- return -1;
- }
-
- return wpas_send_dscp_query(wpa_s, pos + 12, os_strlen(pos + 12));
-}
-
-
-char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
- char *buf, size_t *resp_len)
-{
- char *reply;
- const int reply_size = 4096;
- int reply_len;
-
- if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
- os_strncmp(buf, "SET_NETWORK ", 12) == 0 ||
- os_strncmp(buf, "PMKSA_ADD ", 10) == 0 ||
- os_strncmp(buf, "MESH_PMKSA_ADD ", 15) == 0) {
- if (wpa_debug_show_keys)
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Control interface command '%s'", buf);
- else
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Control interface command '%s [REMOVED]'",
- os_strncmp(buf, WPA_CTRL_RSP,
- os_strlen(WPA_CTRL_RSP)) == 0 ?
- WPA_CTRL_RSP :
- (os_strncmp(buf, "SET_NETWORK ", 12) == 0 ?
- "SET_NETWORK" : "key-add"));
- } else if (os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 ||
- os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0) {
- wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
- (const u8 *) buf, os_strlen(buf));
- } else {
- int level = wpas_ctrl_cmd_debug_level(buf);
- wpa_dbg(wpa_s, level, "Control interface command '%s'", buf);
- }
-
- reply = os_malloc(reply_size);
- if (reply == NULL) {
- *resp_len = 1;
- return NULL;
- }
-
- os_memcpy(reply, "OK\n", 3);
- reply_len = 3;
-
- if (os_strcmp(buf, "PING") == 0) {
- os_memcpy(reply, "PONG\n", 5);
- reply_len = 5;
- } else if (os_strcmp(buf, "IFNAME") == 0) {
- reply_len = os_strlen(wpa_s->ifname);
- os_memcpy(reply, wpa_s->ifname, reply_len);
- } else if (os_strncmp(buf, "RELOG", 5) == 0) {
- if (wpa_debug_reopen_file() < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
- wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
- } else if (os_strcmp(buf, "MIB") == 0) {
- reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
- if (reply_len >= 0) {
- reply_len += eapol_sm_get_mib(wpa_s->eapol,
- reply + reply_len,
- reply_size - reply_len);
-#ifdef CONFIG_MACSEC
- reply_len += ieee802_1x_kay_get_mib(
- wpa_s->kay, reply + reply_len,
- reply_size - reply_len);
-#endif /* CONFIG_MACSEC */
- }
- } else if (os_strncmp(buf, "STATUS", 6) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_status(
- wpa_s, buf + 6, reply, reply_size);
- } else if (os_strcmp(buf, "PMKSA") == 0) {
- reply_len = wpas_ctrl_iface_pmksa(wpa_s, reply, reply_size);
- } else if (os_strcmp(buf, "PMKSA_FLUSH") == 0) {
- wpas_ctrl_iface_pmksa_flush(wpa_s);
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- } else if (os_strncmp(buf, "PMKSA_GET ", 10) == 0) {
- reply_len = wpas_ctrl_iface_pmksa_get(wpa_s, buf + 10,
- reply, reply_size);
- } else if (os_strncmp(buf, "PMKSA_ADD ", 10) == 0) {
- if (wpas_ctrl_iface_pmksa_add(wpa_s, buf + 10) < 0)
- reply_len = -1;
-#ifdef CONFIG_MESH
- } else if (os_strncmp(buf, "MESH_PMKSA_GET ", 15) == 0) {
- reply_len = wpas_ctrl_iface_mesh_pmksa_get(wpa_s, buf + 15,
- reply, reply_size);
- } else if (os_strncmp(buf, "MESH_PMKSA_ADD ", 15) == 0) {
- if (wpas_ctrl_iface_mesh_pmksa_add(wpa_s, buf + 15) < 0)
- reply_len = -1;
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
- } else if (os_strncmp(buf, "SET ", 4) == 0) {
- if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
- reply_len = -1;
- } else if (os_strncmp(buf, "DUMP", 4) == 0) {
- reply_len = wpa_config_dump_values(wpa_s->conf,
- reply, reply_size);
- } else if (os_strncmp(buf, "GET ", 4) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
- reply, reply_size);
- } else if (os_strcmp(buf, "LOGON") == 0) {
- eapol_sm_notify_logoff(wpa_s->eapol, false);
- } else if (os_strcmp(buf, "LOGOFF") == 0) {
- eapol_sm_notify_logoff(wpa_s->eapol, true);
- } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- reply_len = -1;
- else
- wpas_request_connection(wpa_s);
- } else if (os_strcmp(buf, "REATTACH") == 0) {
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED ||
- !wpa_s->current_ssid)
- reply_len = -1;
- else {
- wpa_s->reattach = 1;
- wpas_request_connection(wpa_s);
- }
- } else if (os_strcmp(buf, "RECONNECT") == 0) {
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- reply_len = -1;
- else if (wpa_s->disconnected)
- wpas_request_connection(wpa_s);
-#ifdef IEEE8021X_EAPOL
- } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
- if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
- reply_len = -1;
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_IEEE80211R
- } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
- if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
- reply_len = -1;
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_WPS
- } else if (os_strcmp(buf, "WPS_PBC") == 0) {
- int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL);
- if (res == -2) {
- os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
- reply_len = 17;
- } else if (res)
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
- int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8);
- if (res == -2) {
- os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
- reply_len = 17;
- } else if (res)
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
- reply,
- reply_size);
- } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
- wpa_s, buf + 14, reply, reply_size);
- } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
- if (wpas_wps_cancel(wpa_s))
- reply_len = -1;
-#ifdef CONFIG_WPS_NFC
- } else if (os_strcmp(buf, "WPS_NFC") == 0) {
- if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, NULL))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token(
- wpa_s, buf + 21, reply, reply_size);
- } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
- wpa_s, buf + 14, reply, reply_size);
- } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s,
- buf + 17))
- reply_len = -1;
- } else if (os_strncmp(buf, "NFC_GET_HANDOVER_REQ ", 21) == 0) {
- reply_len = wpas_ctrl_nfc_get_handover_req(
- wpa_s, buf + 21, reply, reply_size);
- } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) {
- reply_len = wpas_ctrl_nfc_get_handover_sel(
- wpa_s, buf + 21, reply, reply_size);
- } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) {
- if (wpas_ctrl_nfc_report_handover(wpa_s, buf + 20))
- reply_len = -1;
-#endif /* CONFIG_WPS_NFC */
- } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
- reply_len = -1;
-#ifdef CONFIG_AP
- } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
- wpa_s, buf + 11, reply, reply_size);
-#endif /* CONFIG_AP */
-#ifdef CONFIG_WPS_ER
- } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
- if (wpas_wps_er_start(wpa_s, NULL))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
- if (wpas_wps_er_start(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
- wpas_wps_er_stop(wpa_s);
- } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
- int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
- if (ret == -2) {
- os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
- reply_len = 17;
- } else if (ret == -3) {
- os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
- reply_len = 18;
- } else if (ret == -4) {
- os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
- reply_len = 20;
- } else if (ret)
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
- buf + 18))
- reply_len = -1;
- } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
- if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
- reply_len = -1;
-#ifdef CONFIG_WPS_NFC
- } else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
- wpa_s, buf + 24, reply, reply_size);
-#endif /* CONFIG_WPS_NFC */
-#endif /* CONFIG_WPS_ER */
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_IBSS_RSN
- } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
- if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
- reply_len = -1;
-#endif /* CONFIG_IBSS_RSN */
-#ifdef CONFIG_MESH
- } else if (os_strncmp(buf, "MESH_INTERFACE_ADD ", 19) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_mesh_interface_add(
- wpa_s, buf + 19, reply, reply_size);
- } else if (os_strcmp(buf, "MESH_INTERFACE_ADD") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_mesh_interface_add(
- wpa_s, "", reply, reply_size);
- } else if (os_strncmp(buf, "MESH_GROUP_ADD ", 15) == 0) {
- if (wpa_supplicant_ctrl_iface_mesh_group_add(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "MESH_GROUP_REMOVE ", 18) == 0) {
- if (wpa_supplicant_ctrl_iface_mesh_group_remove(wpa_s,
- buf + 18))
- reply_len = -1;
- } else if (os_strncmp(buf, "MESH_PEER_REMOVE ", 17) == 0) {
- if (wpa_supplicant_ctrl_iface_mesh_peer_remove(wpa_s, buf + 17))
- reply_len = -1;
- } else if (os_strncmp(buf, "MESH_PEER_ADD ", 14) == 0) {
- if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "MESH_LINK_PROBE ", 16) == 0) {
- if (wpa_supplicant_ctrl_iface_mesh_link_probe(wpa_s, buf + 16))
- reply_len = -1;
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_P2P
- } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
- if (p2p_ctrl_find(wpa_s, buf + 8))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_FIND") == 0) {
- if (p2p_ctrl_find(wpa_s, ""))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
- wpas_p2p_stop_find(wpa_s);
- } else if (os_strncmp(buf, "P2P_ASP_PROVISION ", 18) == 0) {
- if (p2p_ctrl_asp_provision(wpa_s, buf + 18))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_ASP_PROVISION_RESP ", 23) == 0) {
- if (p2p_ctrl_asp_provision_resp(wpa_s, buf + 23))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
- reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
- reply_size);
- } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
- if (p2p_ctrl_listen(wpa_s, buf + 11))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
- if (p2p_ctrl_listen(wpa_s, ""))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
- if (wpas_p2p_group_remove(wpa_s, buf + 17))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
- if (p2p_ctrl_group_add(wpa_s, ""))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
- if (p2p_ctrl_group_add(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_GROUP_MEMBER ", 17) == 0) {
- reply_len = p2p_ctrl_group_member(wpa_s, buf + 17, reply,
- reply_size);
- } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
- if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
- reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
- reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
- reply_size);
- } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
- if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
- if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
- wpas_p2p_sd_service_update(wpa_s);
- } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
- if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
- wpas_p2p_service_flush(wpa_s);
- } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
- if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
- if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_SERVICE_REP ", 16) == 0) {
- if (p2p_ctrl_service_replace(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
- if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
- if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
- reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
- reply_size);
- } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
- if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
- p2p_ctrl_flush(wpa_s);
- } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
- if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
- if (wpas_p2p_cancel(wpa_s))
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
- if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
- if (p2p_ctrl_presence_req(wpa_s, "") < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
- if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
- if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_REMOVE_CLIENT ", 18) == 0) {
- if (p2p_ctrl_remove_client(wpa_s, buf + 18) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "P2P_LO_START ", 13) == 0) {
- if (p2p_ctrl_iface_p2p_lo_start(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strcmp(buf, "P2P_LO_STOP") == 0) {
- if (wpas_p2p_lo_stop(wpa_s))
- reply_len = -1;
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_WIFI_DISPLAY
- } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) {
- if (wifi_display_subelem_set(wpa_s->global, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) {
- reply_len = wifi_display_subelem_get(wpa_s->global, buf + 16,
- reply, reply_size);
-#endif /* CONFIG_WIFI_DISPLAY */
-#ifdef CONFIG_INTERWORKING
- } else if (os_strcmp(buf, "FETCH_ANQP") == 0) {
- if (interworking_fetch_anqp(wpa_s) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
- interworking_stop_fetch_anqp(wpa_s);
- } else if (os_strcmp(buf, "INTERWORKING_SELECT") == 0) {
- if (ctrl_interworking_select(wpa_s, NULL) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "INTERWORKING_SELECT ", 20) == 0) {
- if (ctrl_interworking_select(wpa_s, buf + 20) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
- if (ctrl_interworking_connect(wpa_s, buf + 21, 0) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "INTERWORKING_ADD_NETWORK ", 25) == 0) {
- int id;
-
- id = ctrl_interworking_connect(wpa_s, buf + 25, 1);
- if (id < 0)
- reply_len = -1;
- else {
- reply_len = os_snprintf(reply, reply_size, "%d\n", id);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) {
- if (get_anqp(wpa_s, buf + 9) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "GAS_REQUEST ", 12) == 0) {
- if (gas_request(wpa_s, buf + 12) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "GAS_RESPONSE_GET ", 17) == 0) {
- reply_len = gas_response_get(wpa_s, buf + 17, reply,
- reply_size);
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_HS20
- } else if (os_strncmp(buf, "HS20_ANQP_GET ", 14) == 0) {
- if (get_hs20_anqp(wpa_s, buf + 14) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) {
- if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "HS20_ICON_REQUEST ", 18) == 0) {
- if (hs20_icon_request(wpa_s, buf + 18, 0) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "REQ_HS20_ICON ", 14) == 0) {
- if (hs20_icon_request(wpa_s, buf + 14, 1) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "GET_HS20_ICON ", 14) == 0) {
- reply_len = get_hs20_icon(wpa_s, buf + 14, reply, reply_size);
- } else if (os_strncmp(buf, "DEL_HS20_ICON ", 14) == 0) {
- if (del_hs20_icon(wpa_s, buf + 14) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "FETCH_OSU") == 0) {
- if (hs20_fetch_osu(wpa_s, 0) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "FETCH_OSU no-scan") == 0) {
- if (hs20_fetch_osu(wpa_s, 1) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "CANCEL_FETCH_OSU") == 0) {
- hs20_cancel_fetch_osu(wpa_s);
-#endif /* CONFIG_HS20 */
- } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
- {
- if (wpa_supplicant_ctrl_iface_ctrl_rsp(
- wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
- reply_len = -1;
- else {
- /*
- * Notify response from timeout to allow the control
- * interface response to be sent first.
- */
- eloop_register_timeout(0, 0, wpas_ctrl_eapol_response,
- wpa_s, NULL);
- }
- } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
- if (wpa_supplicant_reload_configuration(wpa_s))
- reply_len = -1;
- } else if (os_strcmp(buf, "TERMINATE") == 0) {
- wpa_supplicant_terminate_proc(wpa_s->global);
- } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
- if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
- reply_len = -1;
- } else if (os_strncmp(buf, "BSSID_IGNORE", 12) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_bssid_ignore(
- wpa_s, buf + 12, reply, reply_size);
- } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
- /* deprecated backwards compatibility alias for BSSID_IGNORE */
- reply_len = wpa_supplicant_ctrl_iface_bssid_ignore(
- wpa_s, buf + 9, reply, reply_size);
- } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_log_level(
- wpa_s, buf + 9, reply, reply_size);
- } else if (os_strncmp(buf, "LIST_NETWORKS ", 14) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_list_networks(
- wpa_s, buf + 14, reply, reply_size);
- } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_list_networks(
- wpa_s, NULL, reply, reply_size);
- } else if (os_strcmp(buf, "DISCONNECT") == 0) {
- wpas_request_disconnection(wpa_s);
- } else if (os_strcmp(buf, "SCAN") == 0) {
- wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
- } else if (os_strncmp(buf, "SCAN ", 5) == 0) {
- wpas_ctrl_scan(wpa_s, buf + 5, reply, reply_size, &reply_len);
- } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_scan_results(
- wpa_s, reply, reply_size);
- } else if (os_strcmp(buf, "ABORT_SCAN") == 0) {
- if (wpas_abort_ongoing_scan(wpa_s) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
- if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
- if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
- if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
- reply_len = -1;
- } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_add_network(
- wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
- if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
- if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
- reply_len = -1;
- } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_get_network(
- wpa_s, buf + 12, reply, reply_size);
- } else if (os_strncmp(buf, "DUP_NETWORK ", 12) == 0) {
- if (wpa_supplicant_ctrl_iface_dup_network(wpa_s, buf + 12,
- wpa_s))
- reply_len = -1;
- } else if (os_strcmp(buf, "LIST_CREDS") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_list_creds(
- wpa_s, reply, reply_size);
- } else if (os_strcmp(buf, "ADD_CRED") == 0) {
- reply_len = wpa_supplicant_ctrl_iface_add_cred(
- wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) {
- if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12))
- reply_len = -1;
- } else if (os_strncmp(buf, "SET_CRED ", 9) == 0) {
- if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9))
- reply_len = -1;
- } else if (os_strncmp(buf, "GET_CRED ", 9) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_get_cred(wpa_s, buf + 9,
- reply,
- reply_size);
-#ifndef CONFIG_NO_CONFIG_WRITE
- } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
- if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
- reply_len = -1;
-#endif /* CONFIG_NO_CONFIG_WRITE */
- } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_get_capability(
- wpa_s, buf + 15, reply, reply_size);
- } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
- if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
- reply_len = -1;
- } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) {
- if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
- reply_len = wpa_supplicant_global_iface_list(
- wpa_s->global, reply, reply_size);
- } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
- reply_len = wpa_supplicant_global_iface_interfaces(
- wpa_s->global, buf + 10, reply, reply_size);
- } else if (os_strncmp(buf, "BSS ", 4) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_bss(
- wpa_s, buf + 4, reply, reply_size);
-#ifdef CONFIG_AP
- } else if (os_strcmp(buf, "STA-FIRST") == 0) {
- reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "STA ", 4) == 0) {
- reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
- reply_size);
- } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
- reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
- reply_size);
- } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
- if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
- if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
- if (ap_ctrl_iface_chanswitch(wpa_s, buf + 12))
- reply_len = -1;
- } else if (os_strcmp(buf, "STOP_AP") == 0) {
- if (wpas_ap_stop_ap(wpa_s))
- reply_len = -1;
- } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
- if (wpas_ap_update_beacon(wpa_s))
- reply_len = -1;
-#endif /* CONFIG_AP */
- } else if (os_strcmp(buf, "SUSPEND") == 0) {
- wpas_notify_suspend(wpa_s->global);
- } else if (os_strcmp(buf, "RESUME") == 0) {
- wpas_notify_resume(wpa_s->global);
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strcmp(buf, "DROP_SA") == 0) {
- wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
-#endif /* CONFIG_TESTING_OPTIONS */
- } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
- if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
- reply_len = -1;
- } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
- wpa_s->auto_reconnect_disabled = atoi(buf + 16) == 0;
- } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
- if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
- reply_len = -1;
- } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
- if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s,
- buf + 17))
- reply_len = -1;
- } else if (os_strncmp(buf, "BSS_FLUSH ", 10) == 0) {
- wpa_supplicant_ctrl_iface_bss_flush(wpa_s, buf + 10);
-#ifdef CONFIG_TDLS
- } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
- if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
- if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
- reply_len = -1;
- } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
- if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "TDLS_CHAN_SWITCH ", 17) == 0) {
- if (wpa_supplicant_ctrl_iface_tdls_chan_switch(wpa_s,
- buf + 17))
- reply_len = -1;
- } else if (os_strncmp(buf, "TDLS_CANCEL_CHAN_SWITCH ", 24) == 0) {
- if (wpa_supplicant_ctrl_iface_tdls_cancel_chan_switch(wpa_s,
- buf + 24))
- reply_len = -1;
- } else if (os_strncmp(buf, "TDLS_LINK_STATUS ", 17) == 0) {
- reply_len = wpa_supplicant_ctrl_iface_tdls_link_status(
- wpa_s, buf + 17, reply, reply_size);
-#endif /* CONFIG_TDLS */
- } else if (os_strcmp(buf, "WMM_AC_STATUS") == 0) {
- reply_len = wpas_wmm_ac_status(wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "WMM_AC_ADDTS ", 13) == 0) {
- if (wmm_ac_ctrl_addts(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strncmp(buf, "WMM_AC_DELTS ", 13) == 0) {
- if (wmm_ac_ctrl_delts(wpa_s, buf + 13))
- reply_len = -1;
- } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
- reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
- reply_size);
- } else if (os_strncmp(buf, "SIGNAL_MONITOR", 14) == 0) {
- if (wpas_ctrl_iface_signal_monitor(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) {
- reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply,
- reply_size);
-#ifdef CONFIG_AUTOSCAN
- } else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) {
- if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
- reply_len = -1;
-#endif /* CONFIG_AUTOSCAN */
- } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {
- reply_len = wpas_ctrl_iface_driver_flags(wpa_s, reply,
- reply_size);
- } else if (os_strcmp(buf, "DRIVER_FLAGS2") == 0) {
- reply_len = wpas_ctrl_iface_driver_flags2(wpa_s, reply,
- reply_size);
-#ifdef ANDROID
- } else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
- reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
- reply_size);
-#endif /* ANDROID */
- } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
- reply_len = wpa_supplicant_vendor_cmd(wpa_s, buf + 7, reply,
- reply_size);
- } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
- pmksa_cache_clear_current(wpa_s->wpa);
- eapol_sm_request_reauth(wpa_s->eapol);
-#ifdef CONFIG_WNM
- } else if (os_strncmp(buf, "WNM_SLEEP ", 10) == 0) {
- if (wpas_ctrl_iface_wnm_sleep(wpa_s, buf + 10))
- reply_len = -1;
- } else if (os_strncmp(buf, "WNM_BSS_QUERY ", 14) == 0) {
- if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "COLOC_INTF_REPORT ", 18) == 0) {
- if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
- reply_len = -1;
-#endif /* CONFIG_WNM */
- } else if (os_strcmp(buf, "FLUSH") == 0) {
- wpa_supplicant_ctrl_iface_flush(wpa_s);
- } else if (os_strncmp(buf, "RADIO_WORK ", 11) == 0) {
- reply_len = wpas_ctrl_radio_work(wpa_s, buf + 11, reply,
- reply_size);
-#ifdef CONFIG_TESTING_OPTIONS
- } else if (os_strncmp(buf, "MGMT_TX ", 8) == 0) {
- if (wpas_ctrl_iface_mgmt_tx(wpa_s, buf + 8) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "MGMT_TX_DONE") == 0) {
- wpas_ctrl_iface_mgmt_tx_done(wpa_s);
- } else if (os_strncmp(buf, "MGMT_RX_PROCESS ", 16) == 0) {
- if (wpas_ctrl_iface_mgmt_rx_process(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DRIVER_EVENT ", 13) == 0) {
- if (wpas_ctrl_iface_driver_event(wpa_s, buf + 13) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
- if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
- if (wpas_ctrl_iface_eapol_tx(wpa_s, buf + 9) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
- if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DATA_TEST_TX ", 13) == 0) {
- if (wpas_ctrl_iface_data_test_tx(wpa_s, buf + 13) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DATA_TEST_FRAME ", 16) == 0) {
- if (wpas_ctrl_iface_data_test_frame(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
- if (wpas_ctrl_test_alloc_fail(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
- reply_len = wpas_ctrl_get_alloc_fail(wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
- if (wpas_ctrl_test_fail(wpa_s, buf + 10) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "GET_FAIL") == 0) {
- reply_len = wpas_ctrl_get_fail(wpa_s, reply, reply_size);
- } else if (os_strncmp(buf, "EVENT_TEST ", 11) == 0) {
- if (wpas_ctrl_event_test(wpa_s, buf + 11) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "TEST_ASSOC_IE ", 14) == 0) {
- if (wpas_ctrl_test_assoc_ie(wpa_s, buf + 14) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "RESET_PN") == 0) {
- if (wpas_ctrl_reset_pn(wpa_s) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "KEY_REQUEST ", 12) == 0) {
- if (wpas_ctrl_key_request(wpa_s, buf + 12) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "RESEND_ASSOC") == 0) {
- if (wpas_ctrl_resend_assoc(wpa_s) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) {
- sme_event_unprot_disconnect(
- wpa_s, wpa_s->bssid, NULL,
- WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
- } else if (os_strncmp(buf, "TWT_SETUP ", 10) == 0) {
- if (wpas_ctrl_iface_send_twt_setup(wpa_s, buf + 9))
- reply_len = -1;
- } else if (os_strcmp(buf, "TWT_SETUP") == 0) {
- if (wpas_ctrl_iface_send_twt_setup(wpa_s, ""))
- reply_len = -1;
- } else if (os_strncmp(buf, "TWT_TEARDOWN ", 13) == 0) {
- if (wpas_ctrl_iface_send_twt_teardown(wpa_s, buf + 12))
- reply_len = -1;
- } else if (os_strcmp(buf, "TWT_TEARDOWN") == 0) {
- if (wpas_ctrl_iface_send_twt_teardown(wpa_s, ""))
- reply_len = -1;
-#endif /* CONFIG_TESTING_OPTIONS */
- } else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
- if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "VENDOR_ELEM_GET ", 16) == 0) {
- reply_len = wpas_ctrl_vendor_elem_get(wpa_s, buf + 16, reply,
- reply_size);
- } else if (os_strncmp(buf, "VENDOR_ELEM_REMOVE ", 19) == 0) {
- if (wpas_ctrl_vendor_elem_remove(wpa_s, buf + 19) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "NEIGHBOR_REP_REQUEST", 20) == 0) {
- if (wpas_ctrl_iface_send_neighbor_rep(wpa_s, buf + 20))
- reply_len = -1;
- } else if (os_strcmp(buf, "ERP_FLUSH") == 0) {
- wpas_ctrl_iface_erp_flush(wpa_s);
- } else if (os_strncmp(buf, "MAC_RAND_SCAN ", 14) == 0) {
- if (wpas_ctrl_iface_mac_rand_scan(wpa_s, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "GET_PREF_FREQ_LIST ", 19) == 0) {
- reply_len = wpas_ctrl_iface_get_pref_freq_list(
- wpa_s, buf + 19, reply, reply_size);
-#ifdef CONFIG_FILS
- } else if (os_strncmp(buf, "FILS_HLP_REQ_ADD ", 17) == 0) {
- if (wpas_ctrl_iface_fils_hlp_req_add(wpa_s, buf + 17))
- reply_len = -1;
- } else if (os_strcmp(buf, "FILS_HLP_REQ_FLUSH") == 0) {
- wpas_flush_fils_hlp_req(wpa_s);
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_DPP
- } else if (os_strncmp(buf, "DPP_QR_CODE ", 12) == 0) {
- int res;
-
- res = wpas_dpp_qr_code(wpa_s, buf + 12);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_NFC_URI ", 12) == 0) {
- int res;
-
- res = wpas_dpp_nfc_uri(wpa_s, buf + 12);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_NFC_HANDOVER_REQ ", 21) == 0) {
- int res;
-
- res = wpas_dpp_nfc_handover_req(wpa_s, buf + 20);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_NFC_HANDOVER_SEL ", 21) == 0) {
- int res;
-
- res = wpas_dpp_nfc_handover_sel(wpa_s, buf + 20);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
- int res;
-
- res = dpp_bootstrap_gen(wpa_s->dpp, buf + 18);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
- if (dpp_bootstrap_remove(wpa_s->dpp, buf + 21) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
- const char *uri;
-
- uri = dpp_bootstrap_get_uri(wpa_s->dpp, atoi(buf + 22));
- if (!uri) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%s", uri);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
- reply_len = dpp_bootstrap_info(wpa_s->dpp, atoi(buf + 19),
- reply, reply_size);
- } else if (os_strncmp(buf, "DPP_BOOTSTRAP_SET ", 18) == 0) {
- if (dpp_bootstrap_set(wpa_s->dpp, atoi(buf + 18),
- os_strchr(buf + 18, ' ')) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
- if (wpas_dpp_auth_init(wpa_s, buf + 13) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_LISTEN ", 11) == 0) {
- if (wpas_dpp_listen(wpa_s, buf + 11) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "DPP_STOP_LISTEN") == 0) {
- wpas_dpp_stop(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- } else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
- int res;
-
- res = dpp_configurator_add(wpa_s->dpp, buf + 20);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
- if (dpp_configurator_remove(wpa_s->dpp, buf + 24) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
- if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
- reply_len = dpp_configurator_get_key_id(wpa_s->dpp,
- atoi(buf + 25),
- reply, reply_size);
- } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
- int res;
-
- res = wpas_dpp_pkex_add(wpa_s, buf + 12);
- if (res < 0) {
- reply_len = -1;
- } else {
- reply_len = os_snprintf(reply, reply_size, "%d", res);
- if (os_snprintf_error(reply_size, reply_len))
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DPP_PKEX_REMOVE ", 16) == 0) {
- if (wpas_dpp_pkex_remove(wpa_s, buf + 16) < 0)
- reply_len = -1;
-#ifdef CONFIG_DPP2
- } else if (os_strncmp(buf, "DPP_CONTROLLER_START ", 21) == 0) {
- if (wpas_dpp_controller_start(wpa_s, buf + 20) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "DPP_CONTROLLER_START") == 0) {
- if (wpas_dpp_controller_start(wpa_s, NULL) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "DPP_CONTROLLER_STOP") == 0) {
- dpp_controller_stop(wpa_s->dpp);
- } else if (os_strncmp(buf, "DPP_CHIRP ", 10) == 0) {
- if (wpas_dpp_chirp(wpa_s, buf + 9) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "DPP_STOP_CHIRP") == 0) {
- wpas_dpp_chirp_stop(wpa_s);
- } else if (os_strncmp(buf, "DPP_RECONFIG ", 13) == 0) {
- if (wpas_dpp_reconfig(wpa_s, buf + 13) < 0)
- reply_len = -1;
- } else if (os_strncmp(buf, "DPP_CA_SET ", 11) == 0) {
- if (wpas_dpp_ca_set(wpa_s, buf + 10) < 0)
- reply_len = -1;
-#endif /* CONFIG_DPP2 */
-#endif /* CONFIG_DPP */
- } else if (os_strncmp(buf, "MSCS ", 5) == 0) {
- if (wpas_ctrl_iface_configure_mscs(wpa_s, buf + 5))
- reply_len = -1;
-#ifdef CONFIG_PASN
- } else if (os_strncmp(buf, "PASN_START ", 11) == 0) {
- if (wpas_ctrl_iface_pasn_start(wpa_s, buf + 11) < 0)
- reply_len = -1;
- } else if (os_strcmp(buf, "PASN_STOP") == 0) {
- wpas_pasn_auth_stop(wpa_s);
- } else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
- reply_len = ptksa_cache_list(wpa_s->ptksa, reply, reply_size);
- } else if (os_strncmp(buf, "PASN_DEAUTH ", 12) == 0) {
- if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
- reply_len = -1;
-#endif /* CONFIG_PASN */
- } else if (os_strncmp(buf, "SCS ", 4) == 0) {
- if (wpas_ctrl_iface_configure_scs(wpa_s, buf + 4))
- reply_len = -1;
- } else if (os_strncmp(buf, "DSCP_RESP ", 10) == 0) {
- if (wpas_ctrl_iface_send_dscp_resp(wpa_s, buf + 10))
- reply_len = -1;
- } else if (os_strncmp(buf, "DSCP_QUERY ", 11) == 0) {
- if (wpas_ctrl_iface_send_dscp_query(wpa_s, buf + 11))
- reply_len = -1;
- } else {
- os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- reply_len = 16;
- }
-
- if (reply_len < 0) {
- os_memcpy(reply, "FAIL\n", 5);
- reply_len = 5;
- }
-
- *resp_len = reply_len;
- return reply;
-}
-
-
-static int wpa_supplicant_global_iface_add(struct wpa_global *global,
- char *cmd)
-{
- struct wpa_interface iface;
- char *pos, *extra;
- struct wpa_supplicant *wpa_s;
- unsigned int create_iface = 0;
- u8 mac_addr[ETH_ALEN];
- enum wpa_driver_if_type type = WPA_IF_STATION;
-
- /*
- * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
- * TAB<bridge_ifname>[TAB<create>[TAB<interface_type>]]
- */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
-
- os_memset(&iface, 0, sizeof(iface));
-
- do {
- iface.ifname = pos = cmd;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.ifname[0] == '\0')
- return -1;
- if (pos == NULL)
- break;
-
- iface.confname = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.confname[0] == '\0')
- iface.confname = NULL;
- if (pos == NULL)
- break;
-
- iface.driver = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.driver[0] == '\0')
- iface.driver = NULL;
- if (pos == NULL)
- break;
-
- iface.ctrl_interface = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.ctrl_interface[0] == '\0')
- iface.ctrl_interface = NULL;
- if (pos == NULL)
- break;
-
- iface.driver_param = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.driver_param[0] == '\0')
- iface.driver_param = NULL;
- if (pos == NULL)
- break;
-
- iface.bridge_ifname = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (iface.bridge_ifname[0] == '\0')
- iface.bridge_ifname = NULL;
- if (pos == NULL)
- break;
-
- extra = pos;
- pos = os_strchr(pos, '\t');
- if (pos)
- *pos++ = '\0';
- if (!extra[0])
- break;
-
- if (os_strcmp(extra, "create") == 0) {
- create_iface = 1;
- if (!pos)
- break;
-
- if (os_strcmp(pos, "sta") == 0) {
- type = WPA_IF_STATION;
- } else if (os_strcmp(pos, "ap") == 0) {
- type = WPA_IF_AP_BSS;
- } else {
- wpa_printf(MSG_DEBUG,
- "INTERFACE_ADD unsupported interface type: '%s'",
- pos);
- return -1;
- }
- } else {
- wpa_printf(MSG_DEBUG,
- "INTERFACE_ADD unsupported extra parameter: '%s'",
- extra);
- return -1;
- }
- } while (0);
-
- if (create_iface) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE creating interface '%s'",
- iface.ifname);
- if (!global->ifaces)
- return -1;
- if (wpa_drv_if_add(global->ifaces, type, iface.ifname,
- NULL, NULL, NULL, mac_addr, NULL) < 0) {
- wpa_printf(MSG_ERROR,
- "CTRL_IFACE interface creation failed");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE interface '%s' created with MAC addr: "
- MACSTR, iface.ifname, MAC2STR(mac_addr));
- }
-
- if (wpa_supplicant_get_iface(global, iface.ifname))
- goto fail;
-
- wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
- if (!wpa_s)
- goto fail;
- wpa_s->added_vif = create_iface;
- return 0;
-
-fail:
- if (create_iface)
- wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, iface.ifname);
- return -1;
-}
-
-
-static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
- char *cmd)
-{
- struct wpa_supplicant *wpa_s;
- int ret;
- unsigned int delete_iface;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
-
- wpa_s = wpa_supplicant_get_iface(global, cmd);
- if (wpa_s == NULL)
- return -1;
- delete_iface = wpa_s->added_vif;
- ret = wpa_supplicant_remove_iface(global, wpa_s, 0);
- if (!ret && delete_iface) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE deleting the interface '%s'",
- cmd);
- ret = wpa_drv_if_remove(global->ifaces, WPA_IF_STATION, cmd);
- }
- return ret;
-}
-
-
-static void wpa_free_iface_info(struct wpa_interface_info *iface)
-{
- struct wpa_interface_info *prev;
-
- while (iface) {
- prev = iface;
- iface = iface->next;
-
- os_free(prev->ifname);
- os_free(prev->desc);
- os_free(prev);
- }
-}
-
-
-static int wpa_supplicant_global_iface_list(struct wpa_global *global,
- char *buf, int len)
-{
- int i, res;
- struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
- char *pos, *end;
-
- for (i = 0; wpa_drivers[i]; i++) {
- const struct wpa_driver_ops *drv = wpa_drivers[i];
- if (drv->get_interfaces == NULL)
- continue;
- tmp = drv->get_interfaces(global->drv_priv[i]);
- if (tmp == NULL)
- continue;
-
- if (last == NULL)
- iface = last = tmp;
- else
- last->next = tmp;
- while (last->next)
- last = last->next;
- }
-
- pos = buf;
- end = buf + len;
- for (tmp = iface; tmp; tmp = tmp->next) {
- res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
- tmp->drv_name, tmp->ifname,
- tmp->desc ? tmp->desc : "");
- if (os_snprintf_error(end - pos, res)) {
- *pos = '\0';
- break;
- }
- pos += res;
- }
-
- wpa_free_iface_info(iface);
-
- return pos - buf;
-}
-
-
-static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
- const char *input,
- char *buf, int len)
-{
- int res;
- char *pos, *end;
- struct wpa_supplicant *wpa_s;
- int show_ctrl = 0;
-
- if (input)
- show_ctrl = !!os_strstr(input, "ctrl");
-
- wpa_s = global->ifaces;
- pos = buf;
- end = buf + len;
-
- while (wpa_s) {
- if (show_ctrl)
- res = os_snprintf(pos, end - pos, "%s ctrl_iface=%s\n",
- wpa_s->ifname,
- wpa_s->conf->ctrl_interface ?
- wpa_s->conf->ctrl_interface : "N/A");
- else
- res = os_snprintf(pos, end - pos, "%s\n",
- wpa_s->ifname);
-
- if (os_snprintf_error(end - pos, res)) {
- *pos = '\0';
- break;
- }
- pos += res;
- wpa_s = wpa_s->next;
- }
- return pos - buf;
-}
-
-
-static char * wpas_global_ctrl_iface_ifname(struct wpa_global *global,
- const char *ifname,
- char *cmd, size_t *resp_len)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_strcmp(ifname, wpa_s->ifname) == 0)
- break;
- }
-
- if (wpa_s == NULL) {
- char *resp = os_strdup("FAIL-NO-IFNAME-MATCH\n");
- if (resp)
- *resp_len = os_strlen(resp);
- else
- *resp_len = 1;
- return resp;
- }
-
- return wpa_supplicant_ctrl_iface_process(wpa_s, cmd, resp_len);
-}
-
-
-static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global,
- char *buf, size_t *resp_len)
-{
-#ifdef CONFIG_P2P
- static const char * cmd[] = {
- "LIST_NETWORKS",
- "P2P_FIND",
- "P2P_STOP_FIND",
- "P2P_LISTEN",
- "P2P_GROUP_ADD",
- "P2P_GET_PASSPHRASE",
- "P2P_SERVICE_UPDATE",
- "P2P_SERVICE_FLUSH",
- "P2P_FLUSH",
- "P2P_CANCEL",
- "P2P_PRESENCE_REQ",
- "P2P_EXT_LISTEN",
-#ifdef CONFIG_AP
- "STA-FIRST",
-#endif /* CONFIG_AP */
- NULL
- };
- static const char * prefix[] = {
-#ifdef ANDROID
- "DRIVER ",
-#endif /* ANDROID */
- "GET_CAPABILITY ",
- "GET_NETWORK ",
- "REMOVE_NETWORK ",
- "P2P_FIND ",
- "P2P_CONNECT ",
- "P2P_LISTEN ",
- "P2P_GROUP_REMOVE ",
- "P2P_GROUP_ADD ",
- "P2P_GROUP_MEMBER ",
- "P2P_PROV_DISC ",
- "P2P_SERV_DISC_REQ ",
- "P2P_SERV_DISC_CANCEL_REQ ",
- "P2P_SERV_DISC_RESP ",
- "P2P_SERV_DISC_EXTERNAL ",
- "P2P_SERVICE_ADD ",
- "P2P_SERVICE_DEL ",
- "P2P_SERVICE_REP ",
- "P2P_REJECT ",
- "P2P_INVITE ",
- "P2P_PEER ",
- "P2P_SET ",
- "P2P_UNAUTHORIZE ",
- "P2P_PRESENCE_REQ ",
- "P2P_EXT_LISTEN ",
- "P2P_REMOVE_CLIENT ",
- "WPS_NFC_TOKEN ",
- "WPS_NFC_TAG_READ ",
- "NFC_GET_HANDOVER_SEL ",
- "NFC_GET_HANDOVER_REQ ",
- "NFC_REPORT_HANDOVER ",
- "P2P_ASP_PROVISION ",
- "P2P_ASP_PROVISION_RESP ",
-#ifdef CONFIG_AP
- "STA ",
- "STA-NEXT ",
-#endif /* CONFIG_AP */
- NULL
- };
- int found = 0;
- int i;
-
- if (global->p2p_init_wpa_s == NULL)
- return NULL;
-
- for (i = 0; !found && cmd[i]; i++) {
- if (os_strcmp(buf, cmd[i]) == 0)
- found = 1;
- }
-
- for (i = 0; !found && prefix[i]; i++) {
- if (os_strncmp(buf, prefix[i], os_strlen(prefix[i])) == 0)
- found = 1;
- }
-
- if (found)
- return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s,
- buf, resp_len);
-#endif /* CONFIG_P2P */
- return NULL;
-}
-
-
-static char * wpas_global_ctrl_iface_redir_wfd(struct wpa_global *global,
- char *buf, size_t *resp_len)
-{
-#ifdef CONFIG_WIFI_DISPLAY
- if (global->p2p_init_wpa_s == NULL)
- return NULL;
- if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0 ||
- os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0)
- return wpa_supplicant_ctrl_iface_process(global->p2p_init_wpa_s,
- buf, resp_len);
-#endif /* CONFIG_WIFI_DISPLAY */
- return NULL;
-}
-
-
-static char * wpas_global_ctrl_iface_redir(struct wpa_global *global,
- char *buf, size_t *resp_len)
-{
- char *ret;
-
- ret = wpas_global_ctrl_iface_redir_p2p(global, buf, resp_len);
- if (ret)
- return ret;
-
- ret = wpas_global_ctrl_iface_redir_wfd(global, buf, resp_len);
- if (ret)
- return ret;
-
- return NULL;
-}
-
-
-static int wpas_global_ctrl_iface_set(struct wpa_global *global, char *cmd)
-{
- char *value;
-
- value = os_strchr(cmd, ' ');
- if (value == NULL)
- return -1;
- *value++ = '\0';
-
- wpa_printf(MSG_DEBUG, "GLOBAL_CTRL_IFACE SET '%s'='%s'", cmd, value);
-
-#ifdef CONFIG_WIFI_DISPLAY
- if (os_strcasecmp(cmd, "wifi_display") == 0) {
- wifi_display_enable(global, !!atoi(value));
- return 0;
- }
-#endif /* CONFIG_WIFI_DISPLAY */
-
- /* Restore cmd to its original value to allow redirection */
- value[-1] = ' ';
-
- return -1;
-}
-
-
-static int wpas_global_ctrl_iface_dup_network(struct wpa_global *global,
- char *cmd)
-{
- struct wpa_supplicant *wpa_s[2]; /* src, dst */
- char *p;
- unsigned int i;
-
- /* cmd: "<src ifname> <dst ifname> <src network id> <dst network id>
- * <variable name> */
-
- for (i = 0; i < ARRAY_SIZE(wpa_s) ; i++) {
- p = os_strchr(cmd, ' ');
- if (p == NULL)
- return -1;
- *p = '\0';
-
- wpa_s[i] = global->ifaces;
- for (; wpa_s[i]; wpa_s[i] = wpa_s[i]->next) {
- if (os_strcmp(cmd, wpa_s[i]->ifname) == 0)
- break;
- }
-
- if (!wpa_s[i]) {
- wpa_printf(MSG_DEBUG,
- "CTRL_IFACE: Could not find iface=%s", cmd);
- return -1;
- }
-
- cmd = p + 1;
- }
-
- return wpa_supplicant_ctrl_iface_dup_network(wpa_s[0], cmd, wpa_s[1]);
-}
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-static int wpas_global_ctrl_iface_save_config(struct wpa_global *global)
-{
- int ret = 0, saved = 0;
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (!wpa_s->conf->update_config) {
- wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed to update configuration (update_config=0)");
- continue;
- }
-
- if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to update configuration");
- ret = 1;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration updated");
- saved++;
- }
- }
-
- if (!saved && !ret) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "CTRL_IFACE: SAVE_CONFIG - No configuration files could be updated");
- ret = 1;
- }
-
- return ret;
-}
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-static int wpas_global_ctrl_iface_status(struct wpa_global *global,
- char *buf, size_t buflen)
-{
- char *pos, *end;
- int ret;
- struct wpa_supplicant *wpa_s;
-
- pos = buf;
- end = buf + buflen;
-
-#ifdef CONFIG_P2P
- if (global->p2p && !global->p2p_disabled) {
- ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
- "\n"
- "p2p_state=%s\n",
- MAC2STR(global->p2p_dev_addr),
- p2p_get_state_txt(global->p2p));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- } else if (global->p2p) {
- ret = os_snprintf(pos, end - pos, "p2p_state=DISABLED\n");
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WIFI_DISPLAY
- ret = os_snprintf(pos, end - pos, "wifi_display=%d\n",
- !!global->wifi_display);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-#endif /* CONFIG_WIFI_DISPLAY */
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- ret = os_snprintf(pos, end - pos, "ifname=%s\n"
- "address=" MACSTR "\n",
- wpa_s->ifname, MAC2STR(wpa_s->own_addr));
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- return pos - buf;
-}
-
-
-#ifdef CONFIG_FST
-
-static int wpas_global_ctrl_iface_fst_attach(struct wpa_global *global,
- char *cmd, char *buf,
- size_t reply_size)
-{
- char ifname[IFNAMSIZ + 1];
- struct fst_iface_cfg cfg;
- struct wpa_supplicant *wpa_s;
- struct fst_wpa_obj iface_obj;
-
- if (!fst_parse_attach_command(cmd, ifname, sizeof(ifname), &cfg)) {
- wpa_s = wpa_supplicant_get_iface(global, ifname);
- if (wpa_s) {
- if (wpa_s->fst) {
- wpa_printf(MSG_INFO, "FST: Already attached");
- return -1;
- }
- fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
- wpa_s->fst = fst_attach(ifname, wpa_s->own_addr,
- &iface_obj, &cfg);
- if (wpa_s->fst)
- return os_snprintf(buf, reply_size, "OK\n");
- }
- }
-
- return -1;
-}
-
-
-static int wpas_global_ctrl_iface_fst_detach(struct wpa_global *global,
- char *cmd, char *buf,
- size_t reply_size)
-{
- char ifname[IFNAMSIZ + 1];
- struct wpa_supplicant *wpa_s;
-
- if (!fst_parse_detach_command(cmd, ifname, sizeof(ifname))) {
- wpa_s = wpa_supplicant_get_iface(global, ifname);
- if (wpa_s) {
- if (!fst_iface_detach(ifname)) {
- wpa_s->fst = NULL;
- return os_snprintf(buf, reply_size, "OK\n");
- }
- }
- }
-
- return -1;
-}
-
-#endif /* CONFIG_FST */
-
-
-char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
- char *buf, size_t *resp_len)
-{
- char *reply;
- const int reply_size = 2048;
- int reply_len;
- int level = MSG_DEBUG;
-
- if (os_strncmp(buf, "IFNAME=", 7) == 0) {
- char *pos = os_strchr(buf + 7, ' ');
- if (pos) {
- *pos++ = '\0';
- return wpas_global_ctrl_iface_ifname(global,
- buf + 7, pos,
- resp_len);
- }
- }
-
- reply = wpas_global_ctrl_iface_redir(global, buf, resp_len);
- if (reply)
- return reply;
-
- if (os_strcmp(buf, "PING") == 0)
- level = MSG_EXCESSIVE;
- wpa_hexdump_ascii(level, "RX global ctrl_iface",
- (const u8 *) buf, os_strlen(buf));
-
- reply = os_malloc(reply_size);
- if (reply == NULL) {
- *resp_len = 1;
- return NULL;
- }
-
- os_memcpy(reply, "OK\n", 3);
- reply_len = 3;
-
- if (os_strcmp(buf, "PING") == 0) {
- os_memcpy(reply, "PONG\n", 5);
- reply_len = 5;
- } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
- if (wpa_supplicant_global_iface_add(global, buf + 14))
- reply_len = -1;
- } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
- if (wpa_supplicant_global_iface_remove(global, buf + 17))
- reply_len = -1;
- } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
- reply_len = wpa_supplicant_global_iface_list(
- global, reply, reply_size);
- } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
- reply_len = wpa_supplicant_global_iface_interfaces(
- global, buf + 10, reply, reply_size);
-#ifdef CONFIG_FST
- } else if (os_strncmp(buf, "FST-ATTACH ", 11) == 0) {
- reply_len = wpas_global_ctrl_iface_fst_attach(global, buf + 11,
- reply,
- reply_size);
- } else if (os_strncmp(buf, "FST-DETACH ", 11) == 0) {
- reply_len = wpas_global_ctrl_iface_fst_detach(global, buf + 11,
- reply,
- reply_size);
- } else if (os_strncmp(buf, "FST-MANAGER ", 12) == 0) {
- reply_len = fst_ctrl_iface_receive(buf + 12, reply, reply_size);
-#endif /* CONFIG_FST */
- } else if (os_strcmp(buf, "TERMINATE") == 0) {
- wpa_supplicant_terminate_proc(global);
- } else if (os_strcmp(buf, "SUSPEND") == 0) {
- wpas_notify_suspend(global);
- } else if (os_strcmp(buf, "RESUME") == 0) {
- wpas_notify_resume(global);
- } else if (os_strncmp(buf, "SET ", 4) == 0) {
- if (wpas_global_ctrl_iface_set(global, buf + 4)) {
-#ifdef CONFIG_P2P
- if (global->p2p_init_wpa_s) {
- os_free(reply);
- /* Check if P2P redirection would work for this
- * command. */
- return wpa_supplicant_ctrl_iface_process(
- global->p2p_init_wpa_s,
- buf, resp_len);
- }
-#endif /* CONFIG_P2P */
- reply_len = -1;
- }
- } else if (os_strncmp(buf, "DUP_NETWORK ", 12) == 0) {
- if (wpas_global_ctrl_iface_dup_network(global, buf + 12))
- reply_len = -1;
-#ifndef CONFIG_NO_CONFIG_WRITE
- } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
- if (wpas_global_ctrl_iface_save_config(global))
- reply_len = -1;
-#endif /* CONFIG_NO_CONFIG_WRITE */
- } else if (os_strcmp(buf, "STATUS") == 0) {
- reply_len = wpas_global_ctrl_iface_status(global, reply,
- reply_size);
-#ifdef CONFIG_MODULE_TESTS
- } else if (os_strcmp(buf, "MODULE_TESTS") == 0) {
- if (wpas_module_tests() < 0)
- reply_len = -1;
-#endif /* CONFIG_MODULE_TESTS */
- } else if (os_strncmp(buf, "RELOG", 5) == 0) {
- if (wpa_debug_reopen_file() < 0)
- reply_len = -1;
- } else {
- os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
- reply_len = 16;
- }
-
- if (reply_len < 0) {
- os_memcpy(reply, "FAIL\n", 5);
- reply_len = 5;
- }
-
- *resp_len = reply_len;
- return reply;
-}
diff --git a/wpa_supplicant/ctrl_iface.h b/wpa_supplicant/ctrl_iface.h
deleted file mode 100644
index dfbd25a03b1b..000000000000
--- a/wpa_supplicant/ctrl_iface.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * WPA Supplicant / UNIX domain socket -based control interface
- * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_H
-#define CTRL_IFACE_H
-
-#ifdef CONFIG_CTRL_IFACE
-
-#ifndef CTRL_IFACE_MAX_LEN
-#define CTRL_IFACE_MAX_LEN 8192
-#endif /* CTRL_IFACE_MAX_LEN */
-
-/* Shared functions from ctrl_iface.c; to be called by ctrl_iface backends */
-
-/**
- * wpa_supplicant_ctrl_iface_process - Process ctrl_iface command
- * @wpa_s: Pointer to wpa_supplicant data
- * @buf: Received command buffer (nul terminated string)
- * @resp_len: Variable to be set to the response length
- * Returns: Response (*resp_len bytes) or %NULL on failure
- *
- * Control interface backends call this function when receiving a message that
- * they do not process internally, i.e., anything else than ATTACH, DETACH,
- * and LEVEL. The return response value is then sent to the external program
- * that sent the command. Caller is responsible for freeing the buffer after
- * this. If %NULL is returned, *resp_len can be set to two special values:
- * 1 = send "FAIL\n" response, 2 = send "OK\n" response. If *resp_len has any
- * other value, no response is sent.
- */
-char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
- char *buf, size_t *resp_len);
-
-/**
- * wpa_supplicant_global_ctrl_iface_process - Process global ctrl_iface command
- * @global: Pointer to global data from wpa_supplicant_init()
- * @buf: Received command buffer (nul terminated string)
- * @resp_len: Variable to be set to the response length
- * Returns: Response (*resp_len bytes) or %NULL on failure
- *
- * Control interface backends call this function when receiving a message from
- * the global ctrl_iface connection. The return response value is then sent to
- * the external program that sent the command. Caller is responsible for
- * freeing the buffer after this. If %NULL is returned, *resp_len can be set to
- * two special values: 1 = send "FAIL\n" response, 2 = send "OK\n" response. If
- * *resp_len has any other value, no response is sent.
- */
-char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
- char *buf, size_t *resp_len);
-
-
-/* Functions that each ctrl_iface backend must implement */
-
-/**
- * wpa_supplicant_ctrl_iface_init - Initialize control interface
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: Pointer to private data on success, %NULL on failure
- *
- * Initialize the control interface and start receiving commands from external
- * programs.
- *
- * Required to be implemented in each control interface backend.
- */
-struct ctrl_iface_priv *
-wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s);
-
-/**
- * wpa_supplicant_ctrl_iface_deinit - Deinitialize control interface
- * @wpa_s: Pointer to wpa_supplicant data
- * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
- *
- * Deinitialize the control interface that was initialized with
- * wpa_supplicant_ctrl_iface_init() and any data related to the wpa_s instance.
- * @priv may be %NULL if the control interface has not yet been initialized.
- *
- * Required to be implemented in each control interface backend.
- */
-void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv);
-
-/**
- * wpa_supplicant_ctrl_iface_wait - Wait for ctrl_iface monitor
- * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
- *
- * Wait until the first message from an external program using the control
- * interface is received. This function can be used to delay normal startup
- * processing to allow control interface programs to attach with
- * %wpa_supplicant before normal operations are started.
- *
- * Required to be implemented in each control interface backend.
- */
-void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv);
-
-/**
- * wpa_supplicant_global_ctrl_iface_init - Initialize global control interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: Pointer to private data on success, %NULL on failure
- *
- * Initialize the global control interface and start receiving commands from
- * external programs.
- *
- * Required to be implemented in each control interface backend.
- */
-struct ctrl_iface_global_priv *
-wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global);
-
-/**
- * wpa_supplicant_global_ctrl_iface_deinit - Deinitialize global ctrl interface
- * @priv: Pointer to private data from wpa_supplicant_global_ctrl_iface_init()
- *
- * Deinitialize the global control interface that was initialized with
- * wpa_supplicant_global_ctrl_iface_init().
- *
- * Required to be implemented in each control interface backend.
- */
-void wpa_supplicant_global_ctrl_iface_deinit(
- struct ctrl_iface_global_priv *priv);
-
-void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s);
-
-#else /* CONFIG_CTRL_IFACE */
-
-static inline struct ctrl_iface_priv *
-wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
-{
- return (void *) -1;
-}
-
-static inline void
-wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
-}
-
-static inline void
-wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, int level,
- char *buf, size_t len)
-{
-}
-
-static inline void
-wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
-{
-}
-
-static inline struct ctrl_iface_global_priv *
-wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
-{
- return (void *) 1;
-}
-
-static inline void
-wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
-{
-}
-
-static inline void wpas_ctrl_radio_work_flush(struct wpa_supplicant *wpa_s)
-{
-}
-
-#endif /* CONFIG_CTRL_IFACE */
-
-#endif /* CTRL_IFACE_H */
diff --git a/wpa_supplicant/ctrl_iface_named_pipe.c b/wpa_supplicant/ctrl_iface_named_pipe.c
deleted file mode 100644
index bddc0414245e..000000000000
--- a/wpa_supplicant/ctrl_iface_named_pipe.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * WPA Supplicant / Windows Named Pipe -based control interface
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "config.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "wpa_supplicant_i.h"
-#include "ctrl_iface.h"
-#include "common/wpa_ctrl.h"
-
-#ifdef __MINGW32_VERSION
-/* mingw-w32api v3.1 does not yet include sddl.h, so define needed parts here
- */
-#define SDDL_REVISION_1 1
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
- LPCSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG);
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
- LPCWSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG);
-#ifdef UNICODE
-#define ConvertStringSecurityDescriptorToSecurityDescriptor \
-ConvertStringSecurityDescriptorToSecurityDescriptorW
-#else
-#define ConvertStringSecurityDescriptorToSecurityDescriptor \
-ConvertStringSecurityDescriptorToSecurityDescriptorA
-#endif
-#else /* __MINGW32_VERSION */
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
-#endif
-#include <sddl.h>
-#endif /* __MINGW32_VERSION */
-
-#ifndef WPA_SUPPLICANT_NAMED_PIPE
-#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
-#endif
-#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)
-
-/* Per-interface ctrl_iface */
-
-#define REQUEST_BUFSIZE CTRL_IFACE_MAX_LEN
-#define REPLY_BUFSIZE 4096
-
-struct ctrl_iface_priv;
-
-/**
- * struct wpa_ctrl_dst - Internal data structure of control interface clients
- *
- * This structure is used to store information about registered control
- * interface monitors into struct wpa_supplicant. This data is private to
- * ctrl_iface_named_pipe.c and should not be touched directly from other files.
- */
-struct wpa_ctrl_dst {
- /* Note: OVERLAPPED must be the first member of struct wpa_ctrl_dst */
- OVERLAPPED overlap;
- struct wpa_ctrl_dst *next, *prev;
- struct ctrl_iface_priv *priv;
- HANDLE pipe;
- int attached;
- int debug_level;
- int errors;
- char req_buf[REQUEST_BUFSIZE];
- char *rsp_buf;
- int used;
-};
-
-
-struct ctrl_iface_priv {
- struct wpa_supplicant *wpa_s;
- struct wpa_ctrl_dst *ctrl_dst;
- SECURITY_ATTRIBUTES attr;
- int sec_attr_set;
-};
-
-
-static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
- int level, const char *buf,
- size_t len);
-
-static void ctrl_close_pipe(struct wpa_ctrl_dst *dst);
-static void wpa_supplicant_ctrl_iface_receive(void *, void *);
-static VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap);
-
-struct wpa_global_dst;
-static void global_close_pipe(struct wpa_global_dst *dst);
-static void wpa_supplicant_global_iface_receive(void *eloop_data,
- void *user_ctx);
-static VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap);
-
-
-static int ctrl_broken_pipe(HANDLE pipe, int used)
-{
- DWORD err;
-
- if (PeekNamedPipe(pipe, NULL, 0, NULL, NULL, NULL))
- return 0;
-
- err = GetLastError();
- if (err == ERROR_BROKEN_PIPE || (err == ERROR_BAD_PIPE && used))
- return 1;
- return 0;
-}
-
-
-static void ctrl_flush_broken_pipes(struct ctrl_iface_priv *priv)
-{
- struct wpa_ctrl_dst *dst, *next;
-
- dst = priv->ctrl_dst;
-
- while (dst) {
- next = dst->next;
- if (ctrl_broken_pipe(dst->pipe, dst->used)) {
- wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
- dst);
- ctrl_close_pipe(dst);
- }
- dst = next;
- }
-}
-
-
-static int ctrl_open_pipe(struct ctrl_iface_priv *priv)
-{
- struct wpa_ctrl_dst *dst;
- DWORD err;
- TCHAR name[256];
-
- dst = os_zalloc(sizeof(*dst));
- if (dst == NULL)
- return -1;
- wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);
-
- dst->priv = priv;
- dst->debug_level = MSG_INFO;
- dst->pipe = INVALID_HANDLE_VALUE;
-
- dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- if (dst->overlap.hEvent == NULL) {
- wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
- (int) GetLastError());
- goto fail;
- }
-
- eloop_register_event(dst->overlap.hEvent,
- sizeof(dst->overlap.hEvent),
- wpa_supplicant_ctrl_iface_receive, dst, NULL);
-
-#ifdef UNICODE
- _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
- priv->wpa_s->ifname);
-#else /* UNICODE */
- os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
- priv->wpa_s->ifname);
-#endif /* UNICODE */
-
- /* TODO: add support for configuring access list for the pipe */
- dst->pipe = CreateNamedPipe(name,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_MESSAGE |
- PIPE_READMODE_MESSAGE |
- PIPE_WAIT,
- 15, REPLY_BUFSIZE, REQUEST_BUFSIZE,
- 1000,
- priv->sec_attr_set ? &priv->attr : NULL);
- if (dst->pipe == INVALID_HANDLE_VALUE) {
- wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
- (int) GetLastError());
- goto fail;
- }
-
- if (ConnectNamedPipe(dst->pipe, &dst->overlap)) {
- wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
- (int) GetLastError());
- CloseHandle(dst->pipe);
- os_free(dst);
- return -1;
- }
-
- err = GetLastError();
- switch (err) {
- case ERROR_IO_PENDING:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in "
- "progress");
- break;
- case ERROR_PIPE_CONNECTED:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already "
- "connected");
- if (SetEvent(dst->overlap.hEvent))
- break;
- /* fall through */
- default:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
- (int) err);
- CloseHandle(dst->pipe);
- os_free(dst);
- return -1;
- }
-
- dst->next = priv->ctrl_dst;
- if (dst->next)
- dst->next->prev = dst;
- priv->ctrl_dst = dst;
-
- return 0;
-
-fail:
- ctrl_close_pipe(dst);
- return -1;
-}
-
-
-static void ctrl_close_pipe(struct wpa_ctrl_dst *dst)
-{
- wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst);
-
- if (dst->overlap.hEvent) {
- eloop_unregister_event(dst->overlap.hEvent,
- sizeof(dst->overlap.hEvent));
- CloseHandle(dst->overlap.hEvent);
- }
-
- if (dst->pipe != INVALID_HANDLE_VALUE) {
- /*
- * Could use FlushFileBuffers() here to guarantee that all data
- * gets delivered to the client, but that can block, so let's
- * not do this for now.
- * FlushFileBuffers(dst->pipe);
- */
- CloseHandle(dst->pipe);
- }
-
- if (dst->prev)
- dst->prev->next = dst->next;
- else
- dst->priv->ctrl_dst = dst->next;
- if (dst->next)
- dst->next->prev = dst->prev;
-
- os_free(dst->rsp_buf);
- os_free(dst);
-}
-
-
-static VOID WINAPI ctrl_iface_write_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap)
-{
- struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap;
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p "
- "err=%d bytes=%d", dst, (int) err, (int) bytes);
- if (err) {
- ctrl_close_pipe(dst);
- return;
- }
-
- os_free(dst->rsp_buf);
- dst->rsp_buf = NULL;
-
- if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
- &dst->overlap, ctrl_iface_read_completed)) {
- wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
- (int) GetLastError());
- ctrl_close_pipe(dst);
- return;
- }
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
-}
-
-
-static void wpa_supplicant_ctrl_iface_rx(struct wpa_ctrl_dst *dst, size_t len)
-{
- struct wpa_supplicant *wpa_s = dst->priv->wpa_s;
- char *reply = NULL, *send_buf;
- size_t reply_len = 0, send_len;
- int new_attached = 0;
- char *buf = dst->req_buf;
-
- dst->used = 1;
- if (len >= REQUEST_BUFSIZE)
- len = REQUEST_BUFSIZE - 1;
- buf[len] = '\0';
-
- if (os_strcmp(buf, "ATTACH") == 0) {
- dst->attached = 1;
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached");
- new_attached = 1;
- reply_len = 2;
- } else if (os_strcmp(buf, "DETACH") == 0) {
- dst->attached = 0;
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached");
- reply_len = 2;
- } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", buf + 6);
- dst->debug_level = atoi(buf + 6);
- reply_len = 2;
- } else {
- reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
- &reply_len);
- }
-
- if (reply) {
- send_buf = reply;
- send_len = reply_len;
- } else if (reply_len == 2) {
- send_buf = "OK\n";
- send_len = 3;
- } else {
- send_buf = "FAIL\n";
- send_len = 5;
- }
-
- os_free(dst->rsp_buf);
- dst->rsp_buf = os_memdup(send_buf, send_len);
- if (dst->rsp_buf == NULL) {
- ctrl_close_pipe(dst);
- os_free(reply);
- return;
- }
- os_free(reply);
-
- if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
- ctrl_iface_write_completed)) {
- wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
- (int) GetLastError());
- ctrl_close_pipe(dst);
- } else {
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
- dst);
- }
-
- if (new_attached)
- eapol_sm_notify_ctrl_attached(wpa_s->eapol);
-}
-
-
-static VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap)
-{
- struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap;
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d "
- "bytes=%d", dst, (int) err, (int) bytes);
- if (err == 0 && bytes > 0)
- wpa_supplicant_ctrl_iface_rx(dst, bytes);
-}
-
-
-static void wpa_supplicant_ctrl_iface_receive(void *eloop_data, void *user_ctx)
-{
- struct wpa_ctrl_dst *dst = eloop_data;
- struct ctrl_iface_priv *priv = dst->priv;
- DWORD bytes;
-
- wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_ctrl_iface_receive");
- ResetEvent(dst->overlap.hEvent);
-
- if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) {
- wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d",
- (int) GetLastError());
- return;
- }
- wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client "
- "connected");
-
- /* Open a new named pipe for the next client. */
- ctrl_open_pipe(priv);
-
- /* Use write completion function to start reading a command */
- ctrl_iface_write_completed(0, 0, &dst->overlap);
-
- ctrl_flush_broken_pipes(priv);
-}
-
-
-static int ctrl_iface_parse(struct ctrl_iface_priv *priv, const char *params)
-{
- const char *sddl = NULL;
- TCHAR *t_sddl;
-
- if (os_strncmp(params, "SDDL=", 5) == 0)
- sddl = params + 5;
- if (!sddl) {
- sddl = os_strstr(params, " SDDL=");
- if (sddl)
- sddl += 6;
- }
-
- if (!sddl)
- return 0;
-
- wpa_printf(MSG_DEBUG, "CTRL: SDDL='%s'", sddl);
- os_memset(&priv->attr, 0, sizeof(priv->attr));
- priv->attr.nLength = sizeof(priv->attr);
- priv->attr.bInheritHandle = FALSE;
- t_sddl = wpa_strdup_tchar(sddl);
- if (t_sddl == NULL)
- return -1;
- if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
- t_sddl, SDDL_REVISION_1,
- (PSECURITY_DESCRIPTOR *) (void *)
- &priv->attr.lpSecurityDescriptor,
- NULL)) {
- os_free(t_sddl);
- wpa_printf(MSG_ERROR, "CTRL: SDDL='%s' - could not convert to "
- "security descriptor: %d",
- sddl, (int) GetLastError());
- return -1;
- }
- os_free(t_sddl);
-
- priv->sec_attr_set = 1;
-
- return 0;
-}
-
-
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
- enum wpa_msg_type type,
- const char *txt, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s == NULL || wpa_s->ctrl_iface == NULL)
- return;
- wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len);
-}
-
-
-struct ctrl_iface_priv *
-wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
-{
- struct ctrl_iface_priv *priv;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- priv->wpa_s = wpa_s;
-
- if (wpa_s->conf->ctrl_interface == NULL)
- return priv;
-
- if (ctrl_iface_parse(priv, wpa_s->conf->ctrl_interface) < 0) {
- os_free(priv);
- return NULL;
- }
-
- if (ctrl_open_pipe(priv) < 0) {
- os_free(priv);
- return NULL;
- }
-
- wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
-
- return priv;
-}
-
-
-void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
- if (!priv)
- return;
- while (priv->ctrl_dst)
- ctrl_close_pipe(priv->ctrl_dst);
- if (priv->sec_attr_set)
- LocalFree(priv->attr.lpSecurityDescriptor);
- os_free(priv);
-}
-
-
-static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
- int level, const char *buf,
- size_t len)
-{
- struct wpa_ctrl_dst *dst, *next;
- char levelstr[10];
- int idx;
- char *sbuf;
- int llen;
- DWORD written;
-
- dst = priv->ctrl_dst;
- if (dst == NULL)
- return;
-
- os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
-
- llen = os_strlen(levelstr);
- sbuf = os_malloc(llen + len);
- if (sbuf == NULL)
- return;
-
- os_memcpy(sbuf, levelstr, llen);
- os_memcpy(sbuf + llen, buf, len);
-
- idx = 0;
- while (dst) {
- next = dst->next;
- if (dst->attached && level >= dst->debug_level) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %p",
- dst);
- if (!WriteFile(dst->pipe, sbuf, llen + len, &written,
- NULL)) {
- wpa_printf(MSG_DEBUG, "CTRL: WriteFile to dst "
- "%p failed: %d",
- dst, (int) GetLastError());
- dst->errors++;
- if (dst->errors > 10)
- ctrl_close_pipe(dst);
- } else
- dst->errors = 0;
- }
- idx++;
- dst = next;
- }
- os_free(sbuf);
-}
-
-
-void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
-{
- wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor",
- priv->wpa_s->ifname);
- if (priv->ctrl_dst == NULL)
- return;
- WaitForSingleObject(priv->ctrl_dst->pipe, INFINITE);
-}
-
-
-/* Global ctrl_iface */
-
-struct ctrl_iface_global_priv;
-
-struct wpa_global_dst {
- /* Note: OVERLAPPED must be the first member of struct wpa_global_dst
- */
- OVERLAPPED overlap;
- struct wpa_global_dst *next, *prev;
- struct ctrl_iface_global_priv *priv;
- HANDLE pipe;
- char req_buf[REQUEST_BUFSIZE];
- char *rsp_buf;
- int used;
-};
-
-struct ctrl_iface_global_priv {
- struct wpa_global *global;
- struct wpa_global_dst *ctrl_dst;
-};
-
-
-static void global_flush_broken_pipes(struct ctrl_iface_global_priv *priv)
-{
- struct wpa_global_dst *dst, *next;
-
- dst = priv->ctrl_dst;
-
- while (dst) {
- next = dst->next;
- if (ctrl_broken_pipe(dst->pipe, dst->used)) {
- wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
- dst);
- global_close_pipe(dst);
- }
- dst = next;
- }
-}
-
-
-static int global_open_pipe(struct ctrl_iface_global_priv *priv)
-{
- struct wpa_global_dst *dst;
- DWORD err;
-
- dst = os_zalloc(sizeof(*dst));
- if (dst == NULL)
- return -1;
- wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);
-
- dst->priv = priv;
- dst->pipe = INVALID_HANDLE_VALUE;
-
- dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- if (dst->overlap.hEvent == NULL) {
- wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
- (int) GetLastError());
- goto fail;
- }
-
- eloop_register_event(dst->overlap.hEvent,
- sizeof(dst->overlap.hEvent),
- wpa_supplicant_global_iface_receive, dst, NULL);
-
- /* TODO: add support for configuring access list for the pipe */
- dst->pipe = CreateNamedPipe(NAMED_PIPE_PREFIX,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_MESSAGE |
- PIPE_READMODE_MESSAGE |
- PIPE_WAIT,
- 10, REPLY_BUFSIZE, REQUEST_BUFSIZE,
- 1000, NULL);
- if (dst->pipe == INVALID_HANDLE_VALUE) {
- wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
- (int) GetLastError());
- goto fail;
- }
-
- if (ConnectNamedPipe(dst->pipe, &dst->overlap)) {
- wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
- (int) GetLastError());
- CloseHandle(dst->pipe);
- os_free(dst);
- return -1;
- }
-
- err = GetLastError();
- switch (err) {
- case ERROR_IO_PENDING:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in "
- "progress");
- break;
- case ERROR_PIPE_CONNECTED:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already "
- "connected");
- if (SetEvent(dst->overlap.hEvent))
- break;
- /* fall through */
- default:
- wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
- (int) err);
- CloseHandle(dst->pipe);
- os_free(dst);
- return -1;
- }
-
- dst->next = priv->ctrl_dst;
- if (dst->next)
- dst->next->prev = dst;
- priv->ctrl_dst = dst;
-
- return 0;
-
-fail:
- global_close_pipe(dst);
- return -1;
-}
-
-
-static void global_close_pipe(struct wpa_global_dst *dst)
-{
- wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst);
-
- if (dst->overlap.hEvent) {
- eloop_unregister_event(dst->overlap.hEvent,
- sizeof(dst->overlap.hEvent));
- CloseHandle(dst->overlap.hEvent);
- }
-
- if (dst->pipe != INVALID_HANDLE_VALUE) {
- /*
- * Could use FlushFileBuffers() here to guarantee that all data
- * gets delivered to the client, but that can block, so let's
- * not do this for now.
- * FlushFileBuffers(dst->pipe);
- */
- CloseHandle(dst->pipe);
- }
-
- if (dst->prev)
- dst->prev->next = dst->next;
- else
- dst->priv->ctrl_dst = dst->next;
- if (dst->next)
- dst->next->prev = dst->prev;
-
- os_free(dst->rsp_buf);
- os_free(dst);
-}
-
-
-static VOID WINAPI global_iface_write_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap)
-{
- struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap;
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p "
- "err=%d bytes=%d", dst, (int) err, (int) bytes);
- if (err) {
- global_close_pipe(dst);
- return;
- }
-
- os_free(dst->rsp_buf);
- dst->rsp_buf = NULL;
-
- if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
- &dst->overlap, global_iface_read_completed)) {
- wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
- (int) GetLastError());
- global_close_pipe(dst);
- /* FIX: if this was the pipe waiting for new global
- * connections, at this point there are no open global pipes..
- * Should try to open a new pipe.. */
- return;
- }
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
-}
-
-
-static void wpa_supplicant_global_iface_rx(struct wpa_global_dst *dst,
- size_t len)
-{
- struct wpa_global *global = dst->priv->global;
- char *reply = NULL, *send_buf;
- size_t reply_len = 0, send_len;
- char *buf = dst->req_buf;
-
- dst->used = 1;
- if (len >= REQUEST_BUFSIZE)
- len = REQUEST_BUFSIZE - 1;
- buf[len] = '\0';
-
- reply = wpa_supplicant_global_ctrl_iface_process(global, buf,
- &reply_len);
- if (reply) {
- send_buf = reply;
- send_len = reply_len;
- } else if (reply_len) {
- send_buf = "FAIL\n";
- send_len = 5;
- } else {
- os_free(dst->rsp_buf);
- dst->rsp_buf = NULL;
- return;
- }
-
- os_free(dst->rsp_buf);
- dst->rsp_buf = os_memdup(send_buf, send_len);
- if (dst->rsp_buf == NULL) {
- global_close_pipe(dst);
- os_free(reply);
- return;
- }
- os_free(reply);
-
- if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
- global_iface_write_completed)) {
- wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
- (int) GetLastError());
- global_close_pipe(dst);
- } else {
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
- dst);
- }
-}
-
-
-static VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes,
- LPOVERLAPPED overlap)
-{
- struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap;
- wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d "
- "bytes=%d", dst, (int) err, (int) bytes);
- if (err == 0 && bytes > 0)
- wpa_supplicant_global_iface_rx(dst, bytes);
-}
-
-
-static void wpa_supplicant_global_iface_receive(void *eloop_data,
- void *user_ctx)
-{
- struct wpa_global_dst *dst = eloop_data;
- struct ctrl_iface_global_priv *priv = dst->priv;
- DWORD bytes;
-
- wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_global_iface_receive");
- ResetEvent(dst->overlap.hEvent);
-
- if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) {
- wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d",
- (int) GetLastError());
- return;
- }
- wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client "
- "connected");
-
- /* Open a new named pipe for the next client. */
- if (global_open_pipe(priv) < 0) {
- wpa_printf(MSG_DEBUG, "CTRL: global_open_pipe failed");
- return;
- }
-
- /* Use write completion function to start reading a command */
- global_iface_write_completed(0, 0, &dst->overlap);
-
- global_flush_broken_pipes(priv);
-}
-
-
-struct ctrl_iface_global_priv *
-wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
-{
- struct ctrl_iface_global_priv *priv;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- priv->global = global;
-
- if (global_open_pipe(priv) < 0) {
- os_free(priv);
- return NULL;
- }
-
- return priv;
-}
-
-
-void
-wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
-{
- while (priv->ctrl_dst)
- global_close_pipe(priv->ctrl_dst);
- os_free(priv);
-}
diff --git a/wpa_supplicant/ctrl_iface_udp.c b/wpa_supplicant/ctrl_iface_udp.c
deleted file mode 100644
index 1cbf7fa28d3f..000000000000
--- a/wpa_supplicant/ctrl_iface_udp.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * WPA Supplicant / UDP socket -based control interface
- * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "config.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "wpa_supplicant_i.h"
-#include "ctrl_iface.h"
-#include "common/wpa_ctrl.h"
-
-
-#define COOKIE_LEN 8
-
-/* Per-interface ctrl_iface */
-
-/**
- * struct wpa_ctrl_dst - Internal data structure of control interface monitors
- *
- * This structure is used to store information about registered control
- * interface monitors into struct wpa_supplicant. This data is private to
- * ctrl_iface_udp.c and should not be touched directly from other files.
- */
-struct wpa_ctrl_dst {
- struct wpa_ctrl_dst *next;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 addr;
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in addr;
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t addrlen;
- int debug_level;
- int errors;
-};
-
-
-struct ctrl_iface_priv {
- struct wpa_supplicant *wpa_s;
- int sock;
- struct wpa_ctrl_dst *ctrl_dst;
- u8 cookie[COOKIE_LEN];
-};
-
-struct ctrl_iface_global_priv {
- int sock;
- struct wpa_ctrl_dst *ctrl_dst;
- u8 cookie[COOKIE_LEN];
-};
-
-
-static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
- const char *ifname, int sock,
- struct wpa_ctrl_dst **head,
- int level, const char *buf,
- size_t len);
-
-
-static void wpas_ctrl_iface_free_dst(struct wpa_ctrl_dst *dst)
-{
- struct wpa_ctrl_dst *prev;
-
- while (dst) {
- prev = dst;
- dst = dst->next;
- os_free(prev);
- }
-}
-
-
-static int wpa_supplicant_ctrl_iface_attach(struct wpa_ctrl_dst **head,
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 *from,
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in *from,
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t fromlen)
-{
- struct wpa_ctrl_dst *dst;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_UDP_IPV6 */
-
- dst = os_zalloc(sizeof(*dst));
- if (dst == NULL)
- return -1;
- os_memcpy(&dst->addr, from, sizeof(*from));
- dst->addrlen = fromlen;
- dst->debug_level = MSG_INFO;
- dst->next = *head;
- *head = dst;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",
- inet_ntop(AF_INET6, &from->sin6_addr, addr, sizeof(*from)),
- ntohs(from->sin6_port));
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",
- inet_ntoa(from->sin_addr), ntohs(from->sin_port));
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- return 0;
-}
-
-
-static int wpa_supplicant_ctrl_iface_detach(struct wpa_ctrl_dst **head,
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 *from,
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in *from,
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t fromlen)
-{
- struct wpa_ctrl_dst *dst, *prev = NULL;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-
- dst = *head;
- while (dst) {
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- if (from->sin6_port == dst->addr.sin6_port &&
- !os_memcmp(&from->sin6_addr, &dst->addr.sin6_addr,
- sizeof(from->sin6_addr))) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached %s:%d",
- inet_ntop(AF_INET6, &from->sin6_addr, addr,
- sizeof(*from)),
- ntohs(from->sin6_port));
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
- from->sin_port == dst->addr.sin_port) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached "
- "%s:%d", inet_ntoa(from->sin_addr),
- ntohs(from->sin_port));
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (prev == NULL)
- *head = dst->next;
- else
- prev->next = dst->next;
- os_free(dst);
- return 0;
- }
- prev = dst;
- dst = dst->next;
- }
- return -1;
-}
-
-
-static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 *from,
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in *from,
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t fromlen,
- char *level)
-{
- struct wpa_ctrl_dst *dst;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
-
- dst = priv->ctrl_dst;
- while (dst) {
-#if CONFIG_CTRL_IFACE_UDP_IPV6
- if (from->sin6_port == dst->addr.sin6_port &&
- !os_memcmp(&from->sin6_addr, &dst->addr.sin6_addr,
- sizeof(from->sin6_addr))) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor level %s:%d",
- inet_ntop(AF_INET6, &from->sin6_addr, addr,
- sizeof(*from)),
- ntohs(from->sin6_port));
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
- from->sin_port == dst->addr.sin_port) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor "
- "level %s:%d", inet_ntoa(from->sin_addr),
- ntohs(from->sin_port));
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- dst->debug_level = atoi(level);
- return 0;
- }
- dst = dst->next;
- }
-
- return -1;
-}
-
-
-static char *
-wpa_supplicant_ctrl_iface_get_cookie(struct ctrl_iface_priv *priv,
- size_t *reply_len)
-{
- char *reply;
- reply = os_malloc(7 + 2 * COOKIE_LEN + 1);
- if (reply == NULL) {
- *reply_len = 1;
- return NULL;
- }
-
- os_memcpy(reply, "COOKIE=", 7);
- wpa_snprintf_hex(reply + 7, 2 * COOKIE_LEN + 1,
- priv->cookie, COOKIE_LEN);
-
- *reply_len = 7 + 2 * COOKIE_LEN;
- return reply;
-}
-
-
-static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
- void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct ctrl_iface_priv *priv = sock_ctx;
- char *buf, *pos;
- int res;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 from;
-#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in from;
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t fromlen = sizeof(from);
- char *reply = NULL;
- size_t reply_len = 0;
- int new_attached = 0;
- u8 cookie[COOKIE_LEN];
-
- buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
- if (!buf)
- return;
- res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN, 0,
- (struct sockaddr *) &from, &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
- strerror(errno));
- os_free(buf);
- return;
- }
-
-#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- inet_ntop(AF_INET6, &from.sin6_addr, addr, sizeof(from));
- if (os_strcmp(addr, "::1")) {
- wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected source %s",
- addr);
- os_free(buf);
- return;
- }
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
- /*
- * The OS networking stack is expected to drop this kind of
- * frames since the socket is bound to only localhost address.
- * Just in case, drop the frame if it is coming from any other
- * address.
- */
- wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected "
- "source %s", inet_ntoa(from.sin_addr));
- os_free(buf);
- return;
- }
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-
- if ((size_t) res > CTRL_IFACE_MAX_LEN) {
- wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
- os_free(buf);
- return;
- }
- buf[res] = '\0';
-
- if (os_strcmp(buf, "GET_COOKIE") == 0) {
- reply = wpa_supplicant_ctrl_iface_get_cookie(priv, &reply_len);
- goto done;
- }
-
- /*
- * Require that the client includes a prefix with the 'cookie' value
- * fetched with GET_COOKIE command. This is used to verify that the
- * client has access to a bidirectional link over UDP in order to
- * avoid attacks using forged localhost IP address even if the OS does
- * not block such frames from remote destinations.
- */
- if (os_strncmp(buf, "COOKIE=", 7) != 0) {
- wpa_printf(MSG_DEBUG, "CTLR: No cookie in the request - "
- "drop request");
- os_free(buf);
- return;
- }
-
- if (hexstr2bin(buf + 7, cookie, COOKIE_LEN) < 0) {
- wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie format in the "
- "request - drop request");
- os_free(buf);
- return;
- }
-
- if (os_memcmp(cookie, priv->cookie, COOKIE_LEN) != 0) {
- wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie in the request - "
- "drop request");
- os_free(buf);
- return;
- }
-
- pos = buf + 7 + 2 * COOKIE_LEN;
- while (*pos == ' ')
- pos++;
-
- if (os_strcmp(pos, "ATTACH") == 0) {
- if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
- &from, fromlen))
- reply_len = 1;
- else {
- new_attached = 1;
- reply_len = 2;
- }
- } else if (os_strcmp(pos, "DETACH") == 0) {
- if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst,
- &from, fromlen))
- reply_len = 1;
- else
- reply_len = 2;
- } else if (os_strncmp(pos, "LEVEL ", 6) == 0) {
- if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
- pos + 6))
- reply_len = 1;
- else
- reply_len = 2;
- } else {
- reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos,
- &reply_len);
- }
-
- done:
- if (reply) {
- sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
- fromlen);
- os_free(reply);
- } else if (reply_len == 1) {
- sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
- fromlen);
- } else if (reply_len == 2) {
- sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
- fromlen);
- }
-
- os_free(buf);
-
- if (new_attached)
- eapol_sm_notify_ctrl_attached(wpa_s->eapol);
-}
-
-
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
- enum wpa_msg_type type,
- const char *txt, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (!wpa_s)
- return;
-
- if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) {
- struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;
-
- if (priv->ctrl_dst) {
- wpa_supplicant_ctrl_iface_send(
- wpa_s,
- type != WPA_MSG_PER_INTERFACE ?
- NULL : wpa_s->ifname,
- priv->sock, &priv->ctrl_dst, level, txt, len);
- }
- }
-
- if (type == WPA_MSG_ONLY_GLOBAL || !wpa_s->ctrl_iface)
- return;
-
- wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock,
- &wpa_s->ctrl_iface->ctrl_dst,
- level, txt, len);
-}
-
-
-struct ctrl_iface_priv *
-wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
-{
- struct ctrl_iface_priv *priv;
- char port_str[40];
- int port = WPA_CTRL_IFACE_PORT;
- char *pos;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 addr;
- int domain = PF_INET6;
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in addr;
- int domain = PF_INET;
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- priv->wpa_s = wpa_s;
- priv->sock = -1;
- os_get_random(priv->cookie, COOKIE_LEN);
-
- if (wpa_s->conf->ctrl_interface == NULL)
- return priv;
-
- pos = os_strstr(wpa_s->conf->ctrl_interface, "udp:");
- if (pos) {
- pos += 4;
- port = atoi(pos);
- if (port <= 0) {
- wpa_printf(MSG_ERROR, "Invalid ctrl_iface UDP port: %s",
- wpa_s->conf->ctrl_interface);
- goto fail;
- }
- }
-
- priv->sock = socket(domain, SOCK_DGRAM, 0);
- if (priv->sock < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_INET): %s", strerror(errno));
- goto fail;
- }
-
- os_memset(&addr, 0, sizeof(addr));
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- addr.sin6_family = AF_INET6;
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- addr.sin6_addr = in6addr_any;
-#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
- inet_pton(AF_INET6, "::1", &addr.sin6_addr);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- addr.sin_family = AF_INET;
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- addr.sin_addr.s_addr = INADDR_ANY;
-#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
- addr.sin_addr.s_addr = htonl((127 << 24) | 1);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-try_again:
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- addr.sin6_port = htons(port);
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- addr.sin_port = htons(port);
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- port--;
- if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT)
- goto try_again;
- wpa_printf(MSG_ERROR, "bind(AF_INET): %s", strerror(errno));
- goto fail;
- }
-
- /* Update the ctrl_interface value to match the selected port */
- os_snprintf(port_str, sizeof(port_str), "udp:%d", port);
- os_free(wpa_s->conf->ctrl_interface);
- wpa_s->conf->ctrl_interface = os_strdup(port_str);
- if (!wpa_s->conf->ctrl_interface) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to malloc ctrl_interface");
- goto fail;
- }
-
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- wpa_msg(wpa_s, MSG_DEBUG, "ctrl_iface_init UDP port: %d", port);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-
- eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
- wpa_s, priv);
- wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
-
- return priv;
-
-fail:
- if (priv->sock >= 0)
- close(priv->sock);
- os_free(priv);
- return NULL;
-}
-
-
-void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
- if (!priv)
- return;
-
- if (priv->sock > -1) {
- eloop_unregister_read_sock(priv->sock);
- if (priv->ctrl_dst) {
- /*
- * Wait before closing the control socket if
- * there are any attached monitors in order to allow
- * them to receive any pending messages.
- */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
- "monitors to receive messages");
- os_sleep(0, 100000);
- }
- close(priv->sock);
- priv->sock = -1;
- }
-
- wpas_ctrl_iface_free_dst(priv->ctrl_dst);
- os_free(priv);
-}
-
-
-static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
- const char *ifname, int sock,
- struct wpa_ctrl_dst **head,
- int level, const char *buf,
- size_t len)
-{
- struct wpa_ctrl_dst *dst, *next;
- char levelstr[64];
- int idx;
- char *sbuf;
- int llen;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-
- dst = *head;
- if (sock < 0 || dst == NULL)
- return;
-
- if (ifname)
- os_snprintf(levelstr, sizeof(levelstr), "IFNAME=%s <%d>",
- ifname, level);
- else
- os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
-
- llen = os_strlen(levelstr);
- sbuf = os_malloc(llen + len);
- if (sbuf == NULL)
- return;
-
- os_memcpy(sbuf, levelstr, llen);
- os_memcpy(sbuf + llen, buf, len);
-
- idx = 0;
- while (dst) {
- next = dst->next;
- if (level >= dst->debug_level) {
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %s:%d",
- inet_ntop(AF_INET6, &dst->addr.sin6_addr,
- addr, sizeof(dst->addr)),
- ntohs(dst->addr.sin6_port));
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %s:%d",
- inet_ntoa(dst->addr.sin_addr),
- ntohs(dst->addr.sin_port));
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (sendto(sock, sbuf, llen + len, 0,
- (struct sockaddr *) &dst->addr,
- sizeof(dst->addr)) < 0) {
- wpa_printf(MSG_ERROR,
- "sendto(CTRL_IFACE monitor): %s",
- strerror(errno));
- dst->errors++;
- if (dst->errors > 10) {
- wpa_supplicant_ctrl_iface_detach(
- head, &dst->addr,
- dst->addrlen);
- }
- } else
- dst->errors = 0;
- }
- idx++;
- dst = next;
- }
- os_free(sbuf);
-}
-
-
-void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
-{
- wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor",
- priv->wpa_s->ifname);
- eloop_wait_for_read_sock(priv->sock);
-}
-
-
-/* Global ctrl_iface */
-
-static char *
-wpa_supplicant_global_get_cookie(struct ctrl_iface_global_priv *priv,
- size_t *reply_len)
-{
- char *reply;
- reply = os_malloc(7 + 2 * COOKIE_LEN + 1);
- if (reply == NULL) {
- *reply_len = 1;
- return NULL;
- }
-
- os_memcpy(reply, "COOKIE=", 7);
- wpa_snprintf_hex(reply + 7, 2 * COOKIE_LEN + 1,
- priv->cookie, COOKIE_LEN);
-
- *reply_len = 7 + 2 * COOKIE_LEN;
- return reply;
-}
-
-
-static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
- void *sock_ctx)
-{
- struct wpa_global *global = eloop_ctx;
- struct ctrl_iface_global_priv *priv = sock_ctx;
- char *buf, *pos;
- int res;
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- struct sockaddr_in6 from;
-#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
- char addr[INET6_ADDRSTRLEN];
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- struct sockaddr_in from;
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- socklen_t fromlen = sizeof(from);
- char *reply = NULL;
- size_t reply_len;
- u8 cookie[COOKIE_LEN];
-
- buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
- if (!buf)
- return;
- res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN, 0,
- (struct sockaddr *) &from, &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
- strerror(errno));
- os_free(buf);
- return;
- }
-
-#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
-#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
- inet_ntop(AF_INET6, &from.sin6_addr, addr, sizeof(from));
- if (os_strcmp(addr, "::1")) {
- wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected source %s",
- addr);
- os_free(buf);
- return;
- }
-#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
- if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
- /*
- * The OS networking stack is expected to drop this kind of
- * frames since the socket is bound to only localhost address.
- * Just in case, drop the frame if it is coming from any other
- * address.
- */
- wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected "
- "source %s", inet_ntoa(from.sin_addr));
- os_free(buf);
- return;
- }
-#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-
- if ((size_t) res > CTRL_IFACE_MAX_LEN) {
- wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
- os_free(buf);
- return;
- }
- buf[res] = '\0';
-
- if (os_strcmp(buf, "GET_COOKIE") == 0) {
- reply = wpa_supplicant_global_get_cookie(priv, &reply_len);
- goto done;
- }
-
- if (os_strncmp(buf, "COOKIE=", 7) != 0) {
- wpa_printf(MSG_DEBUG, "CTLR: No cookie in the request - "
- "drop request");
- os_free(buf);
- return;
- }
-
- if (hexstr2bin(buf + 7, cookie, COOKIE_LEN) < 0) {
- wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie format in the "
- "request - drop request");
- os_free(buf);
- return;
- }
-
- if (os_memcmp(cookie, priv->cookie, COOKIE_LEN) != 0) {
- wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie in the request - "
- "drop request");
- os_free(buf);
- return;
- }
-
- pos = buf + 7 + 2 * COOKIE_LEN;
- while (*pos == ' ')
- pos++;
-
- if (os_strcmp(pos, "ATTACH") == 0) {
- if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
- &from, fromlen))
- reply_len = 1;
- else
- reply_len = 2;
- } else if (os_strcmp(pos, "DETACH") == 0) {
- if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst,
- &from, fromlen))
- reply_len = 1;
- else
- reply_len = 2;
- } else {
- reply = wpa_supplicant_global_ctrl_iface_process(global, pos,
- &reply_len);
- }
-
- done:
- if (reply) {
- sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
- fromlen);
- os_free(reply);
- } else if (reply_len == 1) {
- sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
- fromlen);
- } else if (reply_len == 2) {
- sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
- fromlen);
- }
-
- os_free(buf);
-}
-
-
-struct ctrl_iface_global_priv *
-wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
-{
- struct ctrl_iface_global_priv *priv;
- struct sockaddr_in addr;
- char *pos;
- int port = WPA_GLOBAL_CTRL_IFACE_PORT;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- priv->sock = -1;
- os_get_random(priv->cookie, COOKIE_LEN);
-
- if (global->params.ctrl_interface == NULL)
- return priv;
-
- wpa_printf(MSG_DEBUG, "Global control interface '%s'",
- global->params.ctrl_interface);
-
- pos = os_strstr(global->params.ctrl_interface, "udp:");
- if (pos) {
- pos += 4;
- port = atoi(pos);
- if (port <= 0) {
- wpa_printf(MSG_ERROR, "Invalid global ctrl UDP port %s",
- global->params.ctrl_interface);
- goto fail;
- }
- }
-
- priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (priv->sock < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_INET): %s", strerror(errno));
- goto fail;
- }
-
- os_memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- addr.sin_addr.s_addr = INADDR_ANY;
-#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
- addr.sin_addr.s_addr = htonl((127 << 24) | 1);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-try_again:
- addr.sin_port = htons(port);
- if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- port++;
- if ((port - WPA_GLOBAL_CTRL_IFACE_PORT) <
- WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT && !pos)
- goto try_again;
- wpa_printf(MSG_ERROR, "bind(AF_INET): %s", strerror(errno));
- goto fail;
- }
-
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- wpa_printf(MSG_DEBUG, "global_ctrl_iface_init UDP port: %d", port);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-
- eloop_register_read_sock(priv->sock,
- wpa_supplicant_global_ctrl_iface_receive,
- global, priv);
- wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
-
- return priv;
-
-fail:
- if (priv->sock >= 0)
- close(priv->sock);
- os_free(priv);
- return NULL;
-}
-
-
-void
-wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
-{
- if (priv->sock >= 0) {
- eloop_unregister_read_sock(priv->sock);
- close(priv->sock);
- }
-
- wpas_ctrl_iface_free_dst(priv->ctrl_dst);
- os_free(priv);
-}
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
deleted file mode 100644
index 639573dae75e..000000000000
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ /dev/null
@@ -1,1431 +0,0 @@
-/*
- * WPA Supplicant / UNIX domain socket -based control interface
- * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <grp.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef __linux__
-#include <sys/ioctl.h>
-#endif /* __linux__ */
-#ifdef ANDROID
-#include <cutils/sockets.h>
-#endif /* ANDROID */
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/list.h"
-#include "common/ctrl_iface_common.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "ctrl_iface.h"
-
-/* Per-interface ctrl_iface */
-
-struct ctrl_iface_priv {
- struct wpa_supplicant *wpa_s;
- int sock;
- struct dl_list ctrl_dst;
- int android_control_socket;
- struct dl_list msg_queue;
- unsigned int throttle_count;
-};
-
-
-struct ctrl_iface_global_priv {
- struct wpa_global *global;
- int sock;
- struct dl_list ctrl_dst;
- int android_control_socket;
- struct dl_list msg_queue;
- unsigned int throttle_count;
-};
-
-struct ctrl_iface_msg {
- struct dl_list list;
- struct wpa_supplicant *wpa_s;
- int level;
- enum wpa_msg_type type;
- const char *txt;
- size_t len;
-};
-
-
-static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
- const char *ifname, int sock,
- struct dl_list *ctrl_dst,
- int level, const char *buf,
- size_t len,
- struct ctrl_iface_priv *priv,
- struct ctrl_iface_global_priv *gp);
-static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv);
-static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
- struct ctrl_iface_global_priv *priv);
-
-
-static void wpas_ctrl_sock_debug(const char *title, int sock, const char *buf,
- size_t len)
-{
-#ifdef __linux__
- socklen_t optlen;
- int sndbuf, outq;
- int level = MSG_MSGDUMP;
-
- if (len >= 5 && os_strncmp(buf, "PONG\n", 5) == 0)
- level = MSG_EXCESSIVE;
-
- optlen = sizeof(sndbuf);
- sndbuf = 0;
- if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0)
- sndbuf = -1;
-
- if (ioctl(sock, TIOCOUTQ, &outq) < 0)
- outq = -1;
-
- wpa_printf(level,
- "CTRL-DEBUG: %s: sock=%d sndbuf=%d outq=%d send_len=%d",
- title, sock, sndbuf, outq, (int) len);
-#endif /* __linux__ */
-}
-
-
-static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst,
- struct sockaddr_storage *from,
- socklen_t fromlen, int global)
-{
- return ctrl_iface_attach(ctrl_dst, from, fromlen, NULL);
-}
-
-
-static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst,
- struct sockaddr_storage *from,
- socklen_t fromlen)
-{
- return ctrl_iface_detach(ctrl_dst, from, fromlen);
-}
-
-
-static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
- struct sockaddr_storage *from,
- socklen_t fromlen,
- char *level)
-{
- wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
-
- return ctrl_iface_level(&priv->ctrl_dst, from, fromlen, level);
-}
-
-
-static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
- void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct ctrl_iface_priv *priv = sock_ctx;
- char *buf;
- int res;
- struct sockaddr_storage from;
- socklen_t fromlen = sizeof(from);
- char *reply = NULL, *reply_buf = NULL;
- size_t reply_len = 0;
- int new_attached = 0;
-
- buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
- if (!buf)
- return;
- res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0,
- (struct sockaddr *) &from, &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
- strerror(errno));
- os_free(buf);
- return;
- }
- if ((size_t) res > CTRL_IFACE_MAX_LEN) {
- wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
- os_free(buf);
- return;
- }
- buf[res] = '\0';
-
- if (os_strcmp(buf, "ATTACH") == 0) {
- if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
- fromlen, 0))
- reply_len = 1;
- else {
- new_attached = 1;
- reply_len = 2;
- }
- } else if (os_strcmp(buf, "DETACH") == 0) {
- if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
- fromlen))
- reply_len = 1;
- else
- reply_len = 2;
- } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
- if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
- buf + 6))
- reply_len = 1;
- else
- reply_len = 2;
- } else {
- reply_buf = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
- &reply_len);
- reply = reply_buf;
-
- /*
- * There could be some password/key material in the command, so
- * clear the buffer explicitly now that it is not needed
- * anymore.
- */
- os_memset(buf, 0, res);
- }
-
- if (!reply && reply_len == 1) {
- reply = "FAIL\n";
- reply_len = 5;
- } else if (!reply && reply_len == 2) {
- reply = "OK\n";
- reply_len = 3;
- }
-
- if (reply) {
- wpas_ctrl_sock_debug("ctrl_sock-sendto", sock, reply,
- reply_len);
- if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
- fromlen) < 0) {
- int _errno = errno;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "ctrl_iface sendto failed: %d - %s",
- _errno, strerror(_errno));
- if (_errno == ENOBUFS || _errno == EAGAIN) {
- /*
- * The socket send buffer could be full. This
- * may happen if client programs are not
- * receiving their pending messages. Close and
- * reopen the socket as a workaround to avoid
- * getting stuck being unable to send any new
- * responses.
- */
- sock = wpas_ctrl_iface_reinit(wpa_s, priv);
- if (sock < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket");
- }
- }
- if (new_attached) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to send response to ATTACH - detaching");
- new_attached = 0;
- wpa_supplicant_ctrl_iface_detach(
- &priv->ctrl_dst, &from, fromlen);
- }
- }
- }
- os_free(reply_buf);
- os_free(buf);
-
- if (new_attached)
- eapol_sm_notify_ctrl_attached(wpa_s->eapol);
-}
-
-
-static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s)
-{
- char *buf;
- size_t len;
- char *pbuf, *dir = NULL;
- int res;
-
- if (wpa_s->conf->ctrl_interface == NULL)
- return NULL;
-
- pbuf = os_strdup(wpa_s->conf->ctrl_interface);
- if (pbuf == NULL)
- return NULL;
- if (os_strncmp(pbuf, "DIR=", 4) == 0) {
- char *gid_str;
- dir = pbuf + 4;
- gid_str = os_strstr(dir, " GROUP=");
- if (gid_str)
- *gid_str = '\0';
- } else
- dir = pbuf;
-
- len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2;
- buf = os_malloc(len);
- if (buf == NULL) {
- os_free(pbuf);
- return NULL;
- }
-
- res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname);
- if (os_snprintf_error(len, res)) {
- os_free(pbuf);
- os_free(buf);
- return NULL;
- }
-#ifdef __CYGWIN__
- {
- /* Windows/WinPcap uses interface names that are not suitable
- * as a file name - convert invalid chars to underscores */
- char *pos = buf;
- while (*pos) {
- if (*pos == '\\')
- *pos = '_';
- pos++;
- }
- }
-#endif /* __CYGWIN__ */
- os_free(pbuf);
- return buf;
-}
-
-
-static int wpas_ctrl_iface_throttle(int sock)
-{
-#ifdef __linux__
- socklen_t optlen;
- int sndbuf, outq;
-
- optlen = sizeof(sndbuf);
- sndbuf = 0;
- if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0 ||
- ioctl(sock, TIOCOUTQ, &outq) < 0 ||
- sndbuf <= 0 || outq < 0)
- return 0;
- return outq > sndbuf / 2;
-#else /* __linux__ */
- return 0;
-#endif /* __linux__ */
-}
-
-
-static void wpas_ctrl_msg_send_pending_global(struct wpa_global *global)
-{
- struct ctrl_iface_global_priv *gpriv;
- struct ctrl_iface_msg *msg;
-
- gpriv = global->ctrl_iface;
- while (gpriv && !dl_list_empty(&gpriv->msg_queue) &&
- !wpas_ctrl_iface_throttle(gpriv->sock)) {
- msg = dl_list_first(&gpriv->msg_queue, struct ctrl_iface_msg,
- list);
- if (!msg)
- break;
- dl_list_del(&msg->list);
- wpa_supplicant_ctrl_iface_send(
- msg->wpa_s,
- msg->type != WPA_MSG_PER_INTERFACE ?
- NULL : msg->wpa_s->ifname,
- gpriv->sock, &gpriv->ctrl_dst, msg->level,
- msg->txt, msg->len, NULL, gpriv);
- os_free(msg);
- }
-}
-
-
-static void wpas_ctrl_msg_send_pending_iface(struct wpa_supplicant *wpa_s)
-{
- struct ctrl_iface_priv *priv;
- struct ctrl_iface_msg *msg;
-
- priv = wpa_s->ctrl_iface;
- while (priv && !dl_list_empty(&priv->msg_queue) &&
- !wpas_ctrl_iface_throttle(priv->sock)) {
- msg = dl_list_first(&priv->msg_queue, struct ctrl_iface_msg,
- list);
- if (!msg)
- break;
- dl_list_del(&msg->list);
- wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock,
- &priv->ctrl_dst, msg->level,
- msg->txt, msg->len, priv, NULL);
- os_free(msg);
- }
-}
-
-
-static void wpas_ctrl_msg_queue_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct ctrl_iface_priv *priv;
- struct ctrl_iface_global_priv *gpriv;
- int sock = -1, gsock = -1;
-
- wpas_ctrl_msg_send_pending_global(wpa_s->global);
- wpas_ctrl_msg_send_pending_iface(wpa_s);
-
- priv = wpa_s->ctrl_iface;
- if (priv && !dl_list_empty(&priv->msg_queue))
- sock = priv->sock;
-
- gpriv = wpa_s->global->ctrl_iface;
- if (gpriv && !dl_list_empty(&gpriv->msg_queue))
- gsock = gpriv->sock;
-
- if (sock > -1 || gsock > -1) {
- /* Continue pending message transmission from a timeout */
- wpa_printf(MSG_MSGDUMP,
- "CTRL: Had to throttle pending event message transmission for (sock %d gsock %d)",
- sock, gsock);
- eloop_register_timeout(0, 20000, wpas_ctrl_msg_queue_timeout,
- wpa_s, NULL);
- }
-}
-
-
-static void wpas_ctrl_msg_queue(struct dl_list *queue,
- struct wpa_supplicant *wpa_s, int level,
- enum wpa_msg_type type,
- const char *txt, size_t len)
-{
- struct ctrl_iface_msg *msg;
-
- msg = os_zalloc(sizeof(*msg) + len);
- if (!msg)
- return;
-
- msg->wpa_s = wpa_s;
- msg->level = level;
- msg->type = type;
- os_memcpy(msg + 1, txt, len);
- msg->txt = (const char *) (msg + 1);
- msg->len = len;
- dl_list_add_tail(queue, &msg->list);
- eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
- eloop_register_timeout(0, 0, wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
-}
-
-
-static void wpas_ctrl_msg_queue_limit(unsigned int throttle_count,
- struct dl_list *queue)
-{
- struct ctrl_iface_msg *msg;
-
- if (throttle_count < 2000)
- return;
-
- msg = dl_list_first(queue, struct ctrl_iface_msg, list);
- if (msg) {
- wpa_printf(MSG_DEBUG, "CTRL: Dropped oldest pending message");
- dl_list_del(&msg->list);
- os_free(msg);
- }
-}
-
-
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
- enum wpa_msg_type type,
- const char *txt, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct ctrl_iface_priv *priv;
- struct ctrl_iface_global_priv *gpriv;
-
- if (wpa_s == NULL)
- return;
-
- gpriv = wpa_s->global->ctrl_iface;
-
- if (type != WPA_MSG_NO_GLOBAL && gpriv &&
- !dl_list_empty(&gpriv->ctrl_dst)) {
- if (!dl_list_empty(&gpriv->msg_queue) ||
- wpas_ctrl_iface_throttle(gpriv->sock)) {
- if (gpriv->throttle_count == 0) {
- wpa_printf(MSG_MSGDUMP,
- "CTRL: Had to throttle global event message for sock %d",
- gpriv->sock);
- }
- gpriv->throttle_count++;
- wpas_ctrl_msg_queue_limit(gpriv->throttle_count,
- &gpriv->msg_queue);
- wpas_ctrl_msg_queue(&gpriv->msg_queue, wpa_s, level,
- type, txt, len);
- } else {
- if (gpriv->throttle_count) {
- wpa_printf(MSG_MSGDUMP,
- "CTRL: Had to throttle %u global event message(s) for sock %d",
- gpriv->throttle_count, gpriv->sock);
- }
- gpriv->throttle_count = 0;
- wpa_supplicant_ctrl_iface_send(
- wpa_s,
- type != WPA_MSG_PER_INTERFACE ?
- NULL : wpa_s->ifname,
- gpriv->sock, &gpriv->ctrl_dst, level,
- txt, len, NULL, gpriv);
- }
- }
-
- priv = wpa_s->ctrl_iface;
-
- if (type != WPA_MSG_ONLY_GLOBAL && priv) {
- if (!dl_list_empty(&priv->msg_queue) ||
- wpas_ctrl_iface_throttle(priv->sock)) {
- if (priv->throttle_count == 0) {
- wpa_printf(MSG_MSGDUMP,
- "CTRL: Had to throttle event message for sock %d",
- priv->sock);
- }
- priv->throttle_count++;
- wpas_ctrl_msg_queue_limit(priv->throttle_count,
- &priv->msg_queue);
- wpas_ctrl_msg_queue(&priv->msg_queue, wpa_s, level,
- type, txt, len);
- } else {
- if (priv->throttle_count) {
- wpa_printf(MSG_MSGDUMP,
- "CTRL: Had to throttle %u event message(s) for sock %d",
- priv->throttle_count, priv->sock);
- }
- priv->throttle_count = 0;
- wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock,
- &priv->ctrl_dst, level,
- txt, len, priv, NULL);
- }
- }
-}
-
-
-static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
- struct sockaddr_un addr;
- char *fname = NULL;
- gid_t gid = 0;
- int gid_set = 0;
- char *buf, *dir = NULL, *gid_str = NULL;
- struct group *grp;
- char *endp;
- int flags;
-
- buf = os_strdup(wpa_s->conf->ctrl_interface);
- if (buf == NULL)
- goto fail;
-#ifdef ANDROID
- os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
- wpa_s->conf->ctrl_interface);
- priv->sock = android_get_control_socket(addr.sun_path);
- if (priv->sock >= 0) {
- priv->android_control_socket = 1;
- goto havesock;
- }
-#endif /* ANDROID */
- if (os_strncmp(buf, "DIR=", 4) == 0) {
- dir = buf + 4;
- gid_str = os_strstr(dir, " GROUP=");
- if (gid_str) {
- *gid_str = '\0';
- gid_str += 7;
- }
- } else {
- dir = buf;
- gid_str = wpa_s->conf->ctrl_interface_group;
- }
-
- if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
- if (errno == EEXIST) {
- wpa_printf(MSG_DEBUG, "Using existing control "
- "interface directory.");
- } else {
- wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s",
- dir, strerror(errno));
- goto fail;
- }
- }
-
-#ifdef ANDROID
- /*
- * wpa_supplicant is started from /init.*.rc on Android and that seems
- * to be using umask 0077 which would leave the control interface
- * directory without group access. This breaks things since Wi-Fi
- * framework assumes that this directory can be accessed by other
- * applications in the wifi group. Fix this by adding group access even
- * if umask value would prevent this.
- */
- if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
- wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
- strerror(errno));
- /* Try to continue anyway */
- }
-#endif /* ANDROID */
-
- if (gid_str) {
- grp = getgrnam(gid_str);
- if (grp) {
- gid = grp->gr_gid;
- gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
- " (from group name '%s')",
- (int) gid, gid_str);
- } else {
- /* Group name not found - try to parse this as gid */
- gid = strtol(gid_str, &endp, 10);
- if (*gid_str == '\0' || *endp != '\0') {
- wpa_printf(MSG_ERROR, "CTRL: Invalid group "
- "'%s'", gid_str);
- goto fail;
- }
- gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
- (int) gid);
- }
- }
-
- if (gid_set && lchown(dir, -1, gid) < 0) {
- wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s",
- dir, (int) gid, strerror(errno));
- goto fail;
- }
-
- /* Make sure the group can enter and read the directory */
- if (gid_set &&
- chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
- wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
- strerror(errno));
- goto fail;
- }
-
- if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
- sizeof(addr.sun_path)) {
- wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
- goto fail;
- }
-
- priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (priv->sock < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
- goto fail;
- }
-
- os_memset(&addr, 0, sizeof(addr));
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- addr.sun_len = sizeof(addr);
-#endif /* __FreeBSD__ */
- addr.sun_family = AF_UNIX;
- fname = wpa_supplicant_ctrl_iface_path(wpa_s);
- if (fname == NULL)
- goto fail;
- os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
- if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
- strerror(errno));
- if (connect(priv->sock, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
- " allow connections - assuming it was left"
- "over from forced program termination");
- if (unlink(fname) < 0) {
- wpa_printf(MSG_ERROR,
- "Could not unlink existing ctrl_iface socket '%s': %s",
- fname, strerror(errno));
- goto fail;
- }
- if (bind(priv->sock, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s",
- strerror(errno));
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
- "ctrl_iface socket '%s'", fname);
- } else {
- wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
- "be in use - cannot override it");
- wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
- "not used anymore", fname);
- os_free(fname);
- fname = NULL;
- goto fail;
- }
- }
-
- if (gid_set && lchown(fname, -1, gid) < 0) {
- wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s",
- fname, (int) gid, strerror(errno));
- goto fail;
- }
-
- if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
- wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s",
- fname, strerror(errno));
- goto fail;
- }
- os_free(fname);
-
-#ifdef ANDROID
-havesock:
-#endif /* ANDROID */
-
- /*
- * Make socket non-blocking so that we don't hang forever if
- * target dies unexpectedly.
- */
- flags = fcntl(priv->sock, F_GETFL);
- if (flags >= 0) {
- flags |= O_NONBLOCK;
- if (fcntl(priv->sock, F_SETFL, flags) < 0) {
- wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
- strerror(errno));
- /* Not fatal, continue on.*/
- }
- }
-
- eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
- wpa_s, priv);
- wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
-
- os_free(buf);
- return 0;
-
-fail:
- if (priv->sock >= 0) {
- close(priv->sock);
- priv->sock = -1;
- }
- if (fname) {
- unlink(fname);
- os_free(fname);
- }
- os_free(buf);
- return -1;
-}
-
-
-struct ctrl_iface_priv *
-wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
-{
- struct ctrl_iface_priv *priv;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- dl_list_init(&priv->ctrl_dst);
- dl_list_init(&priv->msg_queue);
- priv->wpa_s = wpa_s;
- priv->sock = -1;
-
- if (wpa_s->conf->ctrl_interface == NULL)
- return priv;
-
-#ifdef ANDROID
- if (wpa_s->global->params.ctrl_interface) {
- int same = 0;
-
- if (wpa_s->global->params.ctrl_interface[0] == '/') {
- if (os_strcmp(wpa_s->global->params.ctrl_interface,
- wpa_s->conf->ctrl_interface) == 0)
- same = 1;
- } else if (os_strncmp(wpa_s->global->params.ctrl_interface,
- "@android:", 9) == 0 ||
- os_strncmp(wpa_s->global->params.ctrl_interface,
- "@abstract:", 10) == 0) {
- char *pos;
-
- /*
- * Currently, Android uses @android:wpa_* as the naming
- * convention for the global ctrl interface. This logic
- * needs to be revisited if the above naming convention
- * is modified.
- */
- pos = os_strchr(wpa_s->global->params.ctrl_interface,
- '_');
- if (pos &&
- os_strcmp(pos + 1,
- wpa_s->conf->ctrl_interface) == 0)
- same = 1;
- }
-
- if (same) {
- /*
- * The invalid configuration combination might be
- * possible to hit in an Android OTA upgrade case, so
- * instead of refusing to start the wpa_supplicant
- * process, do not open the per-interface ctrl_iface
- * and continue with the global control interface that
- * was set from the command line since the Wi-Fi
- * framework will use it for operations.
- */
- wpa_printf(MSG_ERROR,
- "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface",
- wpa_s->global->params.ctrl_interface,
- wpa_s->conf->ctrl_interface);
- return priv;
- }
- }
-#endif /* ANDROID */
-
- if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) {
- os_free(priv);
- return NULL;
- }
-
- return priv;
-}
-
-
-static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
- int res;
-
- if (priv->sock <= 0)
- return -1;
-
- /*
- * On Android, the control socket being used may be the socket
- * that is created when wpa_supplicant is started as a /init.*.rc
- * service. Such a socket is maintained as a key-value pair in
- * Android's environment. Closing this control socket would leave us
- * in a bad state with an invalid socket descriptor.
- */
- if (priv->android_control_socket)
- return priv->sock;
-
- eloop_unregister_read_sock(priv->sock);
- close(priv->sock);
- priv->sock = -1;
- res = wpas_ctrl_iface_open_sock(wpa_s, priv);
- if (res < 0)
- return -1;
- return priv->sock;
-}
-
-
-static void
-wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global,
- struct wpa_supplicant *wpa_s)
-{
- struct ctrl_iface_global_priv *gpriv;
- struct ctrl_iface_msg *msg, *prev_msg;
- unsigned int count = 0;
-
- if (!global || !global->ctrl_iface)
- return;
-
- gpriv = global->ctrl_iface;
- dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
- struct ctrl_iface_msg, list) {
- if (msg->wpa_s == wpa_s) {
- count++;
- dl_list_del(&msg->list);
- os_free(msg);
- }
- }
-
- if (count) {
- wpa_printf(MSG_DEBUG,
- "CTRL: Dropped %u pending message(s) for interface that is being removed",
- count);
- }
-}
-
-
-void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
- struct ctrl_iface_priv *priv)
-{
- struct wpa_ctrl_dst *dst, *prev;
- struct ctrl_iface_msg *msg, *prev_msg;
- struct ctrl_iface_global_priv *gpriv;
-
- if (!priv) {
- /* Control interface has not yet been initialized, so there is
- * nothing to deinitialize here. However, there might be a
- * pending message for this interface, so get rid of any such
- * entry before completing interface removal. */
- wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
- eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
- return;
- }
-
- if (priv->sock > -1) {
- char *fname;
- char *buf, *dir = NULL;
- eloop_unregister_read_sock(priv->sock);
- if (!dl_list_empty(&priv->ctrl_dst)) {
- /*
- * Wait before closing the control socket if
- * there are any attached monitors in order to allow
- * them to receive any pending messages.
- */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
- "monitors to receive messages");
- os_sleep(0, 100000);
- }
- close(priv->sock);
- priv->sock = -1;
- fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
- if (fname) {
- unlink(fname);
- os_free(fname);
- }
-
- if (priv->wpa_s->conf->ctrl_interface == NULL)
- goto free_dst;
- buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
- if (buf == NULL)
- goto free_dst;
- if (os_strncmp(buf, "DIR=", 4) == 0) {
- char *gid_str;
- dir = buf + 4;
- gid_str = os_strstr(dir, " GROUP=");
- if (gid_str)
- *gid_str = '\0';
- } else
- dir = buf;
-
- if (rmdir(dir) < 0) {
- if (errno == ENOTEMPTY) {
- wpa_printf(MSG_DEBUG, "Control interface "
- "directory not empty - leaving it "
- "behind");
- } else {
- wpa_printf(MSG_ERROR,
- "rmdir[ctrl_interface=%s]: %s",
- dir, strerror(errno));
- }
- }
- os_free(buf);
- }
-
-free_dst:
- dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
- list) {
- dl_list_del(&dst->list);
- os_free(dst);
- }
- dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue,
- struct ctrl_iface_msg, list) {
- dl_list_del(&msg->list);
- os_free(msg);
- }
- gpriv = priv->wpa_s->global->ctrl_iface;
- if (gpriv) {
- dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
- struct ctrl_iface_msg, list) {
- if (msg->wpa_s == priv->wpa_s) {
- dl_list_del(&msg->list);
- os_free(msg);
- }
- }
- }
- wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
- eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL);
- os_free(priv);
-}
-
-
-/**
- * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
- * @ifname: Interface name for global control socket or %NULL
- * @sock: Local socket fd
- * @ctrl_dst: List of attached listeners
- * @level: Priority level of the message
- * @buf: Message data
- * @len: Message length
- *
- * Send a packet to all monitor programs attached to the control interface.
- */
-static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
- const char *ifname, int sock,
- struct dl_list *ctrl_dst,
- int level, const char *buf,
- size_t len,
- struct ctrl_iface_priv *priv,
- struct ctrl_iface_global_priv *gp)
-{
- struct wpa_ctrl_dst *dst, *next;
- char levelstr[10];
- int idx, res;
- struct msghdr msg;
- struct iovec io[5];
-
- if (sock < 0 || dl_list_empty(ctrl_dst))
- return;
-
- res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
- if (os_snprintf_error(sizeof(levelstr), res))
- return;
- idx = 0;
- if (ifname) {
- io[idx].iov_base = "IFNAME=";
- io[idx].iov_len = 7;
- idx++;
- io[idx].iov_base = (char *) ifname;
- io[idx].iov_len = os_strlen(ifname);
- idx++;
- io[idx].iov_base = " ";
- io[idx].iov_len = 1;
- idx++;
- }
- io[idx].iov_base = levelstr;
- io[idx].iov_len = os_strlen(levelstr);
- idx++;
- io[idx].iov_base = (char *) buf;
- io[idx].iov_len = len;
- idx++;
- os_memset(&msg, 0, sizeof(msg));
- msg.msg_iov = io;
- msg.msg_iovlen = idx;
-
- dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
- int _errno;
- char txt[200];
-
- if (level < dst->debug_level)
- continue;
-
- msg.msg_name = (void *) &dst->addr;
- msg.msg_namelen = dst->addrlen;
- wpas_ctrl_sock_debug("ctrl_sock-sendmsg", sock, buf, len);
- if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) {
- sockaddr_print(MSG_MSGDUMP,
- "CTRL_IFACE monitor sent successfully to",
- &dst->addr, dst->addrlen);
- dst->errors = 0;
- continue;
- }
-
- _errno = errno;
- os_snprintf(txt, sizeof(txt), "CTRL_IFACE monitor: %d (%s) for",
- _errno, strerror(_errno));
- sockaddr_print(MSG_DEBUG, txt, &dst->addr, dst->addrlen);
- dst->errors++;
-
- if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) {
- sockaddr_print(MSG_INFO, "CTRL_IFACE: Detach monitor that cannot receive messages:",
- &dst->addr, dst->addrlen);
- wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr,
- dst->addrlen);
- }
-
- if (_errno == ENOBUFS || _errno == EAGAIN) {
- /*
- * The socket send buffer could be full. This may happen
- * if client programs are not receiving their pending
- * messages. Close and reopen the socket as a workaround
- * to avoid getting stuck being unable to send any new
- * responses.
- */
- if (priv)
- sock = wpas_ctrl_iface_reinit(wpa_s, priv);
- else if (gp)
- sock = wpas_ctrl_iface_global_reinit(
- wpa_s->global, gp);
- else
- break;
- if (sock < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Failed to reinitialize ctrl_iface socket");
- break;
- }
- }
- }
-}
-
-
-void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
-{
- char buf[256];
- int res;
- struct sockaddr_storage from;
- socklen_t fromlen = sizeof(from);
-
- if (priv->sock == -1)
- return;
-
- for (;;) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
- "attach", priv->wpa_s->ifname);
- eloop_wait_for_read_sock(priv->sock);
-
- res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
- (struct sockaddr *) &from, &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
- strerror(errno));
- continue;
- }
- buf[res] = '\0';
-
- if (os_strcmp(buf, "ATTACH") == 0) {
- /* handle ATTACH signal of first monitor interface */
- if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
- &from, fromlen,
- 0)) {
- if (sendto(priv->sock, "OK\n", 3, 0,
- (struct sockaddr *) &from, fromlen) <
- 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
- strerror(errno));
- }
- /* OK to continue */
- return;
- } else {
- if (sendto(priv->sock, "FAIL\n", 5, 0,
- (struct sockaddr *) &from, fromlen) <
- 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
- strerror(errno));
- }
- }
- } else {
- /* return FAIL for all other signals */
- if (sendto(priv->sock, "FAIL\n", 5, 0,
- (struct sockaddr *) &from, fromlen) < 0) {
- wpa_printf(MSG_DEBUG,
- "ctrl_iface sendto failed: %s",
- strerror(errno));
- }
- }
- }
-}
-
-
-/* Global ctrl_iface */
-
-static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
- void *sock_ctx)
-{
- struct wpa_global *global = eloop_ctx;
- struct ctrl_iface_global_priv *priv = sock_ctx;
- char *buf;
- int res;
- struct sockaddr_storage from;
- socklen_t fromlen = sizeof(from);
- char *reply = NULL, *reply_buf = NULL;
- size_t reply_len;
-
- buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
- if (!buf)
- return;
- res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0,
- (struct sockaddr *) &from, &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
- strerror(errno));
- os_free(buf);
- return;
- }
- if ((size_t) res > CTRL_IFACE_MAX_LEN) {
- wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
- os_free(buf);
- return;
- }
- buf[res] = '\0';
-
- if (os_strcmp(buf, "ATTACH") == 0) {
- if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
- fromlen, 1))
- reply_len = 1;
- else
- reply_len = 2;
- } else if (os_strcmp(buf, "DETACH") == 0) {
- if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
- fromlen))
- reply_len = 1;
- else
- reply_len = 2;
- } else {
- reply_buf = wpa_supplicant_global_ctrl_iface_process(
- global, buf, &reply_len);
- reply = reply_buf;
-
- /*
- * There could be some password/key material in the command, so
- * clear the buffer explicitly now that it is not needed
- * anymore.
- */
- os_memset(buf, 0, res);
- }
-
- if (!reply && reply_len == 1) {
- reply = "FAIL\n";
- reply_len = 5;
- } else if (!reply && reply_len == 2) {
- reply = "OK\n";
- reply_len = 3;
- }
-
- if (reply) {
- wpas_ctrl_sock_debug("global_ctrl_sock-sendto",
- sock, reply, reply_len);
- if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
- fromlen) < 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
- strerror(errno));
- }
- }
- os_free(reply_buf);
- os_free(buf);
-}
-
-
-static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global,
- struct ctrl_iface_global_priv *priv)
-{
- struct sockaddr_un addr;
- const char *ctrl = global->params.ctrl_interface;
- int flags;
-
- wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl);
-
-#ifdef ANDROID
- if (os_strncmp(ctrl, "@android:", 9) == 0) {
- priv->sock = android_get_control_socket(ctrl + 9);
- if (priv->sock < 0) {
- wpa_printf(MSG_ERROR, "Failed to open Android control "
- "socket '%s'", ctrl + 9);
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "Using Android control socket '%s'",
- ctrl + 9);
- priv->android_control_socket = 1;
- goto havesock;
- }
-
- if (os_strncmp(ctrl, "@abstract:", 10) != 0) {
- /*
- * Backwards compatibility - try to open an Android control
- * socket and if that fails, assume this was a UNIX domain
- * socket instead.
- */
- priv->sock = android_get_control_socket(ctrl);
- if (priv->sock >= 0) {
- wpa_printf(MSG_DEBUG,
- "Using Android control socket '%s'",
- ctrl);
- priv->android_control_socket = 1;
- goto havesock;
- }
- }
-#endif /* ANDROID */
-
- priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (priv->sock < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
- goto fail;
- }
-
- os_memset(&addr, 0, sizeof(addr));
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- addr.sun_len = sizeof(addr);
-#endif /* __FreeBSD__ */
- addr.sun_family = AF_UNIX;
-
- if (os_strncmp(ctrl, "@abstract:", 10) == 0) {
- addr.sun_path[0] = '\0';
- os_strlcpy(addr.sun_path + 1, ctrl + 10,
- sizeof(addr.sun_path) - 1);
- if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) <
- 0) {
- wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: "
- "bind(PF_UNIX;%s) failed: %s",
- ctrl, strerror(errno));
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'",
- ctrl + 10);
- goto havesock;
- }
-
- os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
- if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s",
- ctrl, strerror(errno));
- if (connect(priv->sock, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
- " allow connections - assuming it was left"
- "over from forced program termination");
- if (unlink(ctrl) < 0) {
- wpa_printf(MSG_ERROR,
- "Could not unlink existing ctrl_iface socket '%s': %s",
- ctrl, strerror(errno));
- goto fail;
- }
- if (bind(priv->sock, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s",
- ctrl, strerror(errno));
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
- "ctrl_iface socket '%s'",
- ctrl);
- } else {
- wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
- "be in use - cannot override it");
- wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
- "not used anymore",
- ctrl);
- goto fail;
- }
- }
-
- wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl);
-
- if (global->params.ctrl_interface_group) {
- char *gid_str = global->params.ctrl_interface_group;
- gid_t gid = 0;
- struct group *grp;
- char *endp;
-
- grp = getgrnam(gid_str);
- if (grp) {
- gid = grp->gr_gid;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
- " (from group name '%s')",
- (int) gid, gid_str);
- } else {
- /* Group name not found - try to parse this as gid */
- gid = strtol(gid_str, &endp, 10);
- if (*gid_str == '\0' || *endp != '\0') {
- wpa_printf(MSG_ERROR, "CTRL: Invalid group "
- "'%s'", gid_str);
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
- (int) gid);
- }
- if (lchown(ctrl, -1, gid) < 0) {
- wpa_printf(MSG_ERROR,
- "lchown[global_ctrl_interface=%s,gid=%d]: %s",
- ctrl, (int) gid, strerror(errno));
- goto fail;
- }
-
- if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) {
- wpa_printf(MSG_ERROR,
- "chmod[global_ctrl_interface=%s]: %s",
- ctrl, strerror(errno));
- goto fail;
- }
- } else {
- if (chmod(ctrl, S_IRWXU) < 0) {
- wpa_printf(MSG_DEBUG,
- "chmod[global_ctrl_interface=%s](S_IRWXU): %s",
- ctrl, strerror(errno));
- /* continue anyway since group change was not required
- */
- }
- }
-
-havesock:
-
- /*
- * Make socket non-blocking so that we don't hang forever if
- * target dies unexpectedly.
- */
- flags = fcntl(priv->sock, F_GETFL);
- if (flags >= 0) {
- flags |= O_NONBLOCK;
- if (fcntl(priv->sock, F_SETFL, flags) < 0) {
- wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
- strerror(errno));
- /* Not fatal, continue on.*/
- }
- }
-
- eloop_register_read_sock(priv->sock,
- wpa_supplicant_global_ctrl_iface_receive,
- global, priv);
-
- return 0;
-
-fail:
- if (priv->sock >= 0) {
- close(priv->sock);
- priv->sock = -1;
- }
- return -1;
-}
-
-
-struct ctrl_iface_global_priv *
-wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
-{
- struct ctrl_iface_global_priv *priv;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- dl_list_init(&priv->ctrl_dst);
- dl_list_init(&priv->msg_queue);
- priv->global = global;
- priv->sock = -1;
-
- if (global->params.ctrl_interface == NULL)
- return priv;
-
- if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) {
- os_free(priv);
- return NULL;
- }
-
- wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
-
- return priv;
-}
-
-
-static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
- struct ctrl_iface_global_priv *priv)
-{
- int res;
-
- if (priv->sock <= 0)
- return -1;
-
- /*
- * On Android, the control socket being used may be the socket
- * that is created when wpa_supplicant is started as a /init.*.rc
- * service. Such a socket is maintained as a key-value pair in
- * Android's environment. Closing this control socket would leave us
- * in a bad state with an invalid socket descriptor.
- */
- if (priv->android_control_socket)
- return priv->sock;
-
- eloop_unregister_read_sock(priv->sock);
- close(priv->sock);
- priv->sock = -1;
- res = wpas_global_ctrl_iface_open_sock(global, priv);
- if (res < 0)
- return -1;
- return priv->sock;
-}
-
-
-void
-wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
-{
- struct wpa_ctrl_dst *dst, *prev;
- struct ctrl_iface_msg *msg, *prev_msg;
-
- if (priv->sock >= 0) {
- eloop_unregister_read_sock(priv->sock);
- close(priv->sock);
- }
- if (priv->global->params.ctrl_interface)
- unlink(priv->global->params.ctrl_interface);
- dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
- list) {
- dl_list_del(&dst->list);
- os_free(dst);
- }
- dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue,
- struct ctrl_iface_msg, list) {
- dl_list_del(&msg->list);
- os_free(msg);
- }
- os_free(priv);
-}
diff --git a/wpa_supplicant/dbus/.gitignore b/wpa_supplicant/dbus/.gitignore
deleted file mode 100644
index 6db2468ff2d3..000000000000
--- a/wpa_supplicant/dbus/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-libwpadbus.a
diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile
deleted file mode 100644
index 4d8700428dcb..000000000000
--- a/wpa_supplicant/dbus/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-all: libwpadbus.a
-
-clean:
- rm -f *~ *.o *.d *.gcno *.gcda *.gcov
- rm -f libwpadbus.a
-
-install:
- @echo Nothing to be made.
-
-ifndef CC
-CC=gcc
-endif
-
-ifndef CFLAGS
-CFLAGS = -MMD -O2 -Wall -g
-endif
-
-PKG_CONFIG ?= pkg-config
-CFLAGS += -I../../src -I../../src/utils
-
-
-Q=@
-E=echo
-ifeq ($(V), 1)
-Q=
-E=true
-endif
-
-%.o: %.c
- $(Q)$(CC) -c -o $@ $(CFLAGS) $<
- @$(E) " CC " $<
-
-
-ifdef CONFIG_WPS
-CFLAGS += -DCONFIG_WPS
-endif
-
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
-
-ifndef DBUS_LIBS
-DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
-endif
-ifndef DBUS_INCLUDE
-DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
-endif
-ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
-DBUS_INCLUDE += $(shell xml2-config --cflags)
-DBUS_LIBS += $(shell xml2-config --libs)
-endif
-
-CFLAGS += $(DBUS_INCLUDE)
-
-LIB_OBJS= \
- dbus_common.o \
- dbus_new.o \
- dbus_new_handlers.o \
- dbus_new_helpers.o \
- dbus_new_introspect.o \
- dbus_dict_helpers.o
-
-ifdef CONFIG_WPS
-LIB_OBJS += dbus_new_handlers_wps.o
-endif
-
-libwpadbus.a: $(LIB_OBJS)
- $(AR) crT $@ $?
-
--include $(OBJS:%.o=%.d)
diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
deleted file mode 100644
index e81b495f4b99..000000000000
--- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
- <policy user="root">
- <allow own="fi.w1.wpa_supplicant1"/>
-
- <allow send_destination="fi.w1.wpa_supplicant1"/>
- <allow send_interface="fi.w1.wpa_supplicant1"/>
- <allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
- </policy>
- <policy context="default">
- <deny own="fi.w1.wpa_supplicant1"/>
- <deny send_destination="fi.w1.wpa_supplicant1"/>
- <deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
- </policy>
-</busconfig>
diff --git a/wpa_supplicant/dbus/dbus_common.c b/wpa_supplicant/dbus/dbus_common.c
deleted file mode 100644
index a727217fd6f9..000000000000
--- a/wpa_supplicant/dbus/dbus_common.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * wpa_supplicant D-Bus control interface - common functionality
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <dbus/dbus.h>
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "dbus_common.h"
-#include "dbus_common_i.h"
-#include "dbus_new.h"
-#include "../wpa_supplicant_i.h"
-
-
-#ifndef SIGPOLL
-#ifdef SIGIO
-/*
- * If we do not have SIGPOLL, try to use SIGIO instead. This is needed for
- * FreeBSD.
- */
-#define SIGPOLL SIGIO
-#endif
-#endif
-
-
-static void dispatch_data(DBusConnection *con)
-{
- while (dbus_connection_get_dispatch_status(con) ==
- DBUS_DISPATCH_DATA_REMAINS)
- dbus_connection_dispatch(con);
-}
-
-
-/**
- * dispatch_initial_dbus_messages - Dispatch initial dbus messages after
- * claiming bus name
- * @eloop_ctx: the DBusConnection to dispatch on
- * @timeout_ctx: unused
- *
- * If clients are quick to notice that service claimed its bus name,
- * there may have been messages that came in before initialization was
- * all finished. Dispatch those here.
- */
-static void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx)
-{
- DBusConnection *con = eloop_ctx;
- dispatch_data(con);
-}
-
-
-static void process_watch(struct wpas_dbus_priv *priv,
- DBusWatch *watch, eloop_event_type type)
-{
- dbus_connection_ref(priv->con);
-
- priv->should_dispatch = 0;
-
- if (type == EVENT_TYPE_READ)
- dbus_watch_handle(watch, DBUS_WATCH_READABLE);
- else if (type == EVENT_TYPE_WRITE)
- dbus_watch_handle(watch, DBUS_WATCH_WRITABLE);
- else if (type == EVENT_TYPE_EXCEPTION)
- dbus_watch_handle(watch, DBUS_WATCH_ERROR);
-
- if (priv->should_dispatch) {
- dispatch_data(priv->con);
- priv->should_dispatch = 0;
- }
-
- dbus_connection_unref(priv->con);
-}
-
-
-static void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx)
-{
- process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION);
-}
-
-
-static void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx)
-{
- process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ);
-}
-
-
-static void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx)
-{
- process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE);
-}
-
-
-static dbus_bool_t add_watch(DBusWatch *watch, void *data)
-{
- struct wpas_dbus_priv *priv = data;
- unsigned int flags;
- int fd;
-
- if (!dbus_watch_get_enabled(watch))
- return TRUE;
-
- flags = dbus_watch_get_flags(watch);
- fd = dbus_watch_get_unix_fd(watch);
-
- if (eloop_register_sock(fd, EVENT_TYPE_EXCEPTION,
- process_watch_exception, priv, watch) < 0)
- return FALSE;
-
- if ((flags & DBUS_WATCH_READABLE) &&
- eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read,
- priv, watch) < 0)
- return FALSE;
- if ((flags & DBUS_WATCH_WRITABLE) &&
- eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write,
- priv, watch) < 0)
- return FALSE;
-
- dbus_watch_set_data(watch, priv, NULL);
-
- return TRUE;
-}
-
-
-static void remove_watch(DBusWatch *watch, void *data)
-{
- unsigned int flags;
- int fd;
-
- flags = dbus_watch_get_flags(watch);
- fd = dbus_watch_get_unix_fd(watch);
-
- eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION);
-
- if (flags & DBUS_WATCH_READABLE)
- eloop_unregister_sock(fd, EVENT_TYPE_READ);
- if (flags & DBUS_WATCH_WRITABLE)
- eloop_unregister_sock(fd, EVENT_TYPE_WRITE);
-
- dbus_watch_set_data(watch, NULL, NULL);
-}
-
-
-static void watch_toggled(DBusWatch *watch, void *data)
-{
- if (dbus_watch_get_enabled(watch))
- add_watch(watch, data);
- else
- remove_watch(watch, data);
-}
-
-
-static void process_timeout(void *eloop_ctx, void *sock_ctx)
-{
- DBusTimeout *timeout = sock_ctx;
- dbus_timeout_handle(timeout);
-}
-
-
-static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
-{
- struct wpas_dbus_priv *priv = data;
-
- if (!dbus_timeout_get_enabled(timeout))
- return TRUE;
-
- eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000,
- process_timeout, priv, timeout);
-
- dbus_timeout_set_data(timeout, priv, NULL);
-
- return TRUE;
-}
-
-
-static void remove_timeout(DBusTimeout *timeout, void *data)
-{
- struct wpas_dbus_priv *priv = data;
-
- eloop_cancel_timeout(process_timeout, priv, timeout);
- dbus_timeout_set_data(timeout, NULL, NULL);
-}
-
-
-static void timeout_toggled(DBusTimeout *timeout, void *data)
-{
- if (dbus_timeout_get_enabled(timeout))
- add_timeout(timeout, data);
- else
- remove_timeout(timeout, data);
-}
-
-
-static void process_wakeup_main(int sig, void *signal_ctx)
-{
- struct wpas_dbus_priv *priv = signal_ctx;
-
- if (sig != SIGPOLL || !priv->con)
- return;
-
- if (dbus_connection_get_dispatch_status(priv->con) !=
- DBUS_DISPATCH_DATA_REMAINS)
- return;
-
- /* Only dispatch once - we do not want to starve other events */
- dbus_connection_ref(priv->con);
- dbus_connection_dispatch(priv->con);
- dbus_connection_unref(priv->con);
-}
-
-
-/**
- * wakeup_main - Attempt to wake our mainloop up
- * @data: dbus control interface private data
- *
- * Try to wake up the main eloop so it will process
- * dbus events that may have happened.
- */
-static void wakeup_main(void *data)
-{
- struct wpas_dbus_priv *priv = data;
-
- /* Use SIGPOLL to break out of the eloop select() */
- raise(SIGPOLL);
- priv->should_dispatch = 1;
-}
-
-
-/**
- * integrate_with_eloop - Register our mainloop integration with dbus
- * @connection: connection to the system message bus
- * @priv: a dbus control interface data structure
- * Returns: 0 on success, -1 on failure
- */
-static int integrate_with_eloop(struct wpas_dbus_priv *priv)
-{
- if (!dbus_connection_set_watch_functions(priv->con, add_watch,
- remove_watch, watch_toggled,
- priv, NULL) ||
- !dbus_connection_set_timeout_functions(priv->con, add_timeout,
- remove_timeout,
- timeout_toggled, priv,
- NULL)) {
- wpa_printf(MSG_ERROR, "dbus: Failed to set callback functions");
- return -1;
- }
-
- if (eloop_register_signal(SIGPOLL, process_wakeup_main, priv))
- return -1;
- dbus_connection_set_wakeup_main_function(priv->con, wakeup_main,
- priv, NULL);
-
- return 0;
-}
-
-
-static DBusHandlerResult disconnect_filter(DBusConnection *conn,
- DBusMessage *message, void *data)
-{
- struct wpas_dbus_priv *priv = data;
-
- if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
- "Disconnected")) {
- wpa_printf(MSG_DEBUG, "dbus: bus disconnected, terminating");
- dbus_connection_set_exit_on_disconnect(conn, FALSE);
- wpa_supplicant_terminate_proc(priv->global);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-static int wpas_dbus_init_common(struct wpas_dbus_priv *priv)
-{
- DBusError error;
- int ret = 0;
-
- /* Get a reference to the system bus */
- dbus_error_init(&error);
- priv->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
- if (priv->con) {
- dbus_connection_add_filter(priv->con, disconnect_filter, priv,
- NULL);
- } else {
- wpa_printf(MSG_ERROR,
- "dbus: Could not acquire the system bus: %s - %s",
- error.name, error.message);
- ret = -1;
- }
- dbus_error_free(&error);
-
- return ret;
-}
-
-
-static int wpas_dbus_init_common_finish(struct wpas_dbus_priv *priv)
-{
- /* Tell dbus about our mainloop integration functions */
- integrate_with_eloop(priv);
-
- /*
- * Dispatch initial DBus messages that may have come in since the bus
- * name was claimed above. Happens when clients are quick to notice the
- * service.
- *
- * FIXME: is there a better solution to this problem?
- */
- eloop_register_timeout(0, 50, dispatch_initial_dbus_messages,
- priv->con, NULL);
-
- return 0;
-}
-
-
-static void wpas_dbus_deinit_common(struct wpas_dbus_priv *priv)
-{
- if (priv->con) {
- eloop_cancel_timeout(dispatch_initial_dbus_messages,
- priv->con, NULL);
- eloop_cancel_timeout(process_timeout, priv, ELOOP_ALL_CTX);
-
- dbus_connection_set_watch_functions(priv->con, NULL, NULL,
- NULL, NULL, NULL);
- dbus_connection_set_timeout_functions(priv->con, NULL, NULL,
- NULL, NULL, NULL);
- dbus_connection_remove_filter(priv->con, disconnect_filter,
- priv);
-
- dbus_connection_unref(priv->con);
- }
-
- os_free(priv);
-}
-
-
-struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global)
-{
- struct wpas_dbus_priv *priv;
-
- priv = os_zalloc(sizeof(*priv));
- if (priv == NULL)
- return NULL;
- priv->global = global;
-
- if (wpas_dbus_init_common(priv) < 0 ||
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- wpas_dbus_ctrl_iface_init(priv) < 0 ||
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
- wpas_dbus_init_common_finish(priv) < 0) {
- wpas_dbus_deinit(priv);
- return NULL;
- }
-
- return priv;
-}
-
-
-void wpas_dbus_deinit(struct wpas_dbus_priv *priv)
-{
- if (priv == NULL)
- return;
-
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- wpas_dbus_ctrl_iface_deinit(priv);
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-
- wpas_dbus_deinit_common(priv);
-}
diff --git a/wpa_supplicant/dbus/dbus_common.h b/wpa_supplicant/dbus/dbus_common.h
deleted file mode 100644
index aea7db742b41..000000000000
--- a/wpa_supplicant/dbus/dbus_common.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * wpa_supplicant D-Bus control interface - common definitions
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DBUS_COMMON_H
-#define DBUS_COMMON_H
-
-struct wpas_dbus_priv;
-struct wpa_global;
-
-struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global);
-void wpas_dbus_deinit(struct wpas_dbus_priv *priv);
-
-#endif /* DBUS_COMMON_H */
diff --git a/wpa_supplicant/dbus/dbus_common_i.h b/wpa_supplicant/dbus/dbus_common_i.h
deleted file mode 100644
index 95eb4bcb50ca..000000000000
--- a/wpa_supplicant/dbus/dbus_common_i.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * wpa_supplicant D-Bus control interface - internal definitions
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DBUS_COMMON_I_H
-#define DBUS_COMMON_I_H
-
-#include <dbus/dbus.h>
-
-struct wpa_dbus_property_desc;
-
-struct wpas_dbus_priv {
- DBusConnection *con;
- int should_dispatch;
- struct wpa_global *global;
- u32 next_objid;
- int dbus_new_initialized;
-
-#if defined(CONFIG_CTRL_IFACE_DBUS_NEW)
- struct wpa_dbus_property_desc *all_interface_properties;
- int globals_start;
-#if defined(CONFIG_AP)
- int dbus_noc_refcnt;
-#endif /* CONFIG_AP */
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-};
-
-#endif /* DBUS_COMMON_I_H */
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
deleted file mode 100644
index e4e9b8da96b7..000000000000
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <dbus/dbus.h>
-
-#include "common.h"
-#include "wpabuf.h"
-#include "dbus_dict_helpers.h"
-
-
-/**
- * Start a dict in a dbus message. Should be paired with a call to
- * wpa_dbus_dict_close_write().
- *
- * @param iter A valid dbus message iterator
- * @param iter_dict (out) A dict iterator to pass to further dict functions
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
- DBusMessageIter *iter_dict)
-{
- dbus_bool_t result;
-
- if (!iter || !iter_dict)
- return FALSE;
-
- result = dbus_message_iter_open_container(
- iter,
- DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- iter_dict);
- return result;
-}
-
-
-/**
- * End a dict element in a dbus message. Should be paired with
- * a call to wpa_dbus_dict_open_write().
- *
- * @param iter valid dbus message iterator, same as passed to
- * wpa_dbus_dict_open_write()
- * @param iter_dict a dbus dict iterator returned from
- * wpa_dbus_dict_open_write()
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
- DBusMessageIter *iter_dict)
-{
- if (!iter || !iter_dict)
- return FALSE;
-
- return dbus_message_iter_close_container(iter, iter_dict);
-}
-
-
-const char * wpa_dbus_type_as_string(const int type)
-{
- switch (type) {
- case DBUS_TYPE_BYTE:
- return DBUS_TYPE_BYTE_AS_STRING;
- case DBUS_TYPE_BOOLEAN:
- return DBUS_TYPE_BOOLEAN_AS_STRING;
- case DBUS_TYPE_INT16:
- return DBUS_TYPE_INT16_AS_STRING;
- case DBUS_TYPE_UINT16:
- return DBUS_TYPE_UINT16_AS_STRING;
- case DBUS_TYPE_INT32:
- return DBUS_TYPE_INT32_AS_STRING;
- case DBUS_TYPE_UINT32:
- return DBUS_TYPE_UINT32_AS_STRING;
- case DBUS_TYPE_INT64:
- return DBUS_TYPE_INT64_AS_STRING;
- case DBUS_TYPE_UINT64:
- return DBUS_TYPE_UINT64_AS_STRING;
- case DBUS_TYPE_DOUBLE:
- return DBUS_TYPE_DOUBLE_AS_STRING;
- case DBUS_TYPE_STRING:
- return DBUS_TYPE_STRING_AS_STRING;
- case DBUS_TYPE_OBJECT_PATH:
- return DBUS_TYPE_OBJECT_PATH_AS_STRING;
- case DBUS_TYPE_ARRAY:
- return DBUS_TYPE_ARRAY_AS_STRING;
- default:
- return NULL;
- }
-}
-
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_start(
- DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
- const char *key, const int value_type)
-{
- if (!dbus_message_iter_open_container(iter_dict,
- DBUS_TYPE_DICT_ENTRY, NULL,
- iter_dict_entry))
- return FALSE;
-
- return dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
- &key);
-}
-
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_end(
- DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val)
-{
- if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
- return FALSE;
-
- return dbus_message_iter_close_container(iter_dict, iter_dict_entry);
-}
-
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
- const char *key,
- const int value_type,
- const void *value)
-{
- DBusMessageIter iter_dict_entry, iter_dict_val;
- const char *type_as_string = NULL;
-
- if (key == NULL)
- return FALSE;
-
- type_as_string = wpa_dbus_type_as_string(value_type);
- if (!type_as_string)
- return FALSE;
-
- if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
- key, value_type) ||
- !dbus_message_iter_open_container(&iter_dict_entry,
- DBUS_TYPE_VARIANT,
- type_as_string, &iter_dict_val) ||
- !dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
- return FALSE;
-
- return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
- &iter_dict_val);
-}
-
-
-static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
- DBusMessageIter *iter_dict, const char *key,
- const char *value, const dbus_uint32_t value_len)
-{
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
- dbus_uint32_t i;
-
- if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
- key, DBUS_TYPE_ARRAY) ||
- !dbus_message_iter_open_container(&iter_dict_entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &iter_dict_val) ||
- !dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &iter_array))
- return FALSE;
-
- for (i = 0; i < value_len; i++) {
- if (!dbus_message_iter_append_basic(&iter_array,
- DBUS_TYPE_BYTE,
- &(value[i])))
- return FALSE;
- }
-
- if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
- return FALSE;
-
- return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
- &iter_dict_val);
-}
-
-
-/**
- * Add a string entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The string value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
- const char *key, const char *value)
-{
- if (!value)
- return FALSE;
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
- &value);
-}
-
-
-/**
- * Add a boolean entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The boolean value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
- const char *key, const dbus_bool_t value)
-{
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
- DBUS_TYPE_BOOLEAN, &value);
-}
-
-
-/**
- * Add a 16-bit signed integer entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The 16-bit signed integer value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_int16_t value)
-{
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
- &value);
-}
-
-
-/**
- * Add a 16-bit unsigned integer entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The 16-bit unsigned integer value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_uint16_t value)
-{
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
- &value);
-}
-
-
-/**
- * Add a 32-bit signed integer to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The 32-bit signed integer value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_int32_t value)
-{
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
- &value);
-}
-
-
-/**
- * Add a 32-bit unsigned integer entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The 32-bit unsigned integer value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_uint32_t value)
-{
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
- &value);
-}
-
-
-/**
- * Add a DBus object path entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The DBus object path value
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
- const char *key,
- const char *value)
-{
- if (!value)
- return FALSE;
- return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
- DBUS_TYPE_OBJECT_PATH, &value);
-}
-
-
-/**
- * Add a byte array entry to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param value The byte array
- * @param value_len The length of the byte array, in bytes
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
- const char *key,
- const char *value,
- const dbus_uint32_t value_len)
-{
- if (!key || (!value && value_len != 0))
- return FALSE;
- return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
- value_len);
-}
-
-
-/**
- * Begin an array entry in the dict
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param type The type of the contained data
- * @param iter_dict_entry A private DBusMessageIter provided by the caller to
- * be passed to wpa_dbus_dict_end_string_array()
- * @param iter_dict_val A private DBusMessageIter provided by the caller to
- * be passed to wpa_dbus_dict_end_string_array()
- * @param iter_array On return, the DBusMessageIter to be passed to
- * wpa_dbus_dict_string_array_add_element()
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict,
- const char *key, const char *type,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array)
-{
- char array_type[10];
- int err;
-
- err = os_snprintf(array_type, sizeof(array_type),
- DBUS_TYPE_ARRAY_AS_STRING "%s",
- type);
- if (os_snprintf_error(sizeof(array_type), err))
- return FALSE;
-
- if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array ||
- !_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
- key, DBUS_TYPE_ARRAY) ||
- !dbus_message_iter_open_container(iter_dict_entry,
- DBUS_TYPE_VARIANT,
- array_type,
- iter_dict_val))
- return FALSE;
-
- return dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
- type, iter_array);
-}
-
-
-dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
- const char *key,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array)
-{
- return wpa_dbus_dict_begin_array(
- iter_dict, key,
- DBUS_TYPE_STRING_AS_STRING,
- iter_dict_entry, iter_dict_val, iter_array);
-}
-
-
-/**
- * Add a single string element to a string array dict entry
- *
- * @param iter_array A valid DBusMessageIter returned from
- * wpa_dbus_dict_begin_string_array()'s
- * iter_array parameter
- * @param elem The string element to be added to the dict entry's string array
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
- const char *elem)
-{
- if (!iter_array || !elem)
- return FALSE;
-
- return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
- &elem);
-}
-
-
-/**
- * Add a single byte array element to a string array dict entry
- *
- * @param iter_array A valid DBusMessageIter returned from
- * wpa_dbus_dict_begin_array()'s iter_array
- * parameter -- note that wpa_dbus_dict_begin_array()
- * must have been called with "ay" as the type
- * @param value The data to be added to the dict entry's array
- * @param value_len The length of the data
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
- const u8 *value,
- size_t value_len)
-{
- DBusMessageIter iter_bytes;
- size_t i;
-
- if (!iter_array || !value ||
- !dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &iter_bytes))
- return FALSE;
-
- for (i = 0; i < value_len; i++) {
- if (!dbus_message_iter_append_basic(&iter_bytes,
- DBUS_TYPE_BYTE,
- &(value[i])))
- return FALSE;
- }
-
- return dbus_message_iter_close_container(iter_array, &iter_bytes);
-}
-
-
-/**
- * End an array dict entry
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param iter_dict_entry A private DBusMessageIter returned from
- * wpa_dbus_dict_begin_string_array() or
- * wpa_dbus_dict_begin_array()
- * @param iter_dict_val A private DBusMessageIter returned from
- * wpa_dbus_dict_begin_string_array() or
- * wpa_dbus_dict_begin_array()
- * @param iter_array A DBusMessageIter returned from
- * wpa_dbus_dict_begin_string_array() or
- * wpa_dbus_dict_begin_array()
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array)
-{
- if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array ||
- !dbus_message_iter_close_container(iter_dict_val, iter_array))
- return FALSE;
-
- return _wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
- iter_dict_val);
-}
-
-
-/**
- * Convenience function to add an entire string array to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param items The array of strings
- * @param num_items The number of strings in the array
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
- const char *key,
- const char **items,
- const dbus_uint32_t num_items)
-{
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
- dbus_uint32_t i;
-
- if (!key || (!items && num_items != 0) ||
- !wpa_dbus_dict_begin_string_array(iter_dict, key,
- &iter_dict_entry, &iter_dict_val,
- &iter_array))
- return FALSE;
-
- for (i = 0; i < num_items; i++) {
- if (!wpa_dbus_dict_string_array_add_element(&iter_array,
- items[i]))
- return FALSE;
- }
-
- return wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
- &iter_dict_val, &iter_array);
-}
-
-
-/**
- * Convenience function to add an wpabuf binary array to the dict.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_write()
- * @param key The key of the dict item
- * @param items The array of wpabuf structures
- * @param num_items The number of strings in the array
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
- const char *key,
- const struct wpabuf **items,
- const dbus_uint32_t num_items)
-{
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
- dbus_uint32_t i;
-
- if (!key ||
- (!items && num_items != 0) ||
- !wpa_dbus_dict_begin_array(iter_dict, key,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &iter_dict_entry, &iter_dict_val,
- &iter_array))
- return FALSE;
-
- for (i = 0; i < num_items; i++) {
- if (!wpa_dbus_dict_bin_array_add_element(&iter_array,
- wpabuf_head(items[i]),
- wpabuf_len(items[i])))
- return FALSE;
- }
-
- return wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry,
- &iter_dict_val, &iter_array);
-}
-
-
-/*****************************************************/
-/* Stuff for reading dicts */
-/*****************************************************/
-
-/**
- * Start reading from a dbus dict.
- *
- * @param iter A valid DBusMessageIter pointing to the start of the dict
- * @param iter_dict (out) A DBusMessageIter to be passed to
- * wpa_dbus_dict_read_next_entry()
- * @error on failure a descriptive error
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
- DBusMessageIter *iter_dict,
- DBusError *error)
-{
- int type;
-
- wpa_printf(MSG_MSGDUMP, "%s: start reading a dict entry", __func__);
- if (!iter || !iter_dict) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "[internal] missing message iterators");
- return FALSE;
- }
-
- type = dbus_message_iter_get_arg_type(iter);
- if (type != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
- wpa_printf(MSG_DEBUG,
- "%s: unexpected message argument types (arg=%c element=%c)",
- __func__, type,
- type != DBUS_TYPE_ARRAY ? '?' :
- dbus_message_iter_get_element_type(iter));
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "unexpected message argument types");
- return FALSE;
- }
-
- dbus_message_iter_recurse(iter, iter_dict);
- return TRUE;
-}
-
-
-#define BYTE_ARRAY_CHUNK_SIZE 34
-#define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
-
-static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
- DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
-{
- dbus_uint32_t count = 0;
- dbus_bool_t success = FALSE;
- char *buffer, *nbuffer;
-
- entry->bytearray_value = NULL;
- entry->array_type = DBUS_TYPE_BYTE;
-
- buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE);
- if (!buffer)
- return FALSE;
-
- entry->array_len = 0;
- while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
- char byte;
-
- if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
- nbuffer = os_realloc_array(
- buffer, count + BYTE_ARRAY_CHUNK_SIZE,
- BYTE_ARRAY_ITEM_SIZE);
- if (nbuffer == NULL) {
- os_free(buffer);
- wpa_printf(MSG_ERROR,
- "dbus: %s out of memory trying to retrieve the string array",
- __func__);
- goto done;
- }
- buffer = nbuffer;
- }
-
- dbus_message_iter_get_basic(iter, &byte);
- buffer[count] = byte;
- entry->array_len = ++count;
- dbus_message_iter_next(iter);
- }
- entry->bytearray_value = buffer;
- wpa_hexdump_key(MSG_MSGDUMP, "dbus: byte array contents",
- entry->bytearray_value, entry->array_len);
-
- /* Zero-length arrays are valid. */
- if (entry->array_len == 0) {
- os_free(entry->bytearray_value);
- entry->bytearray_value = NULL;
- }
-
- success = TRUE;
-
-done:
- return success;
-}
-
-
-#define STR_ARRAY_CHUNK_SIZE 8
-#define STR_ARRAY_ITEM_SIZE (sizeof(char *))
-
-static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
- DBusMessageIter *iter, int array_type,
- struct wpa_dbus_dict_entry *entry)
-{
- dbus_uint32_t count = 0;
- char **buffer, **nbuffer;
-
- entry->strarray_value = NULL;
- entry->array_len = 0;
- entry->array_type = DBUS_TYPE_STRING;
-
- buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
- if (buffer == NULL)
- return FALSE;
-
- while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
- const char *value;
- char *str;
-
- if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
- nbuffer = os_realloc_array(
- buffer, count + STR_ARRAY_CHUNK_SIZE,
- STR_ARRAY_ITEM_SIZE);
- if (nbuffer == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s out of memory trying to retrieve the string array",
- __func__);
- goto fail;
- }
- buffer = nbuffer;
- }
-
- dbus_message_iter_get_basic(iter, &value);
- wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s",
- __func__, wpa_debug_show_keys ? value : "[omitted]");
- str = os_strdup(value);
- if (str == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s out of memory trying to duplicate the string array",
- __func__);
- goto fail;
- }
- buffer[count++] = str;
- dbus_message_iter_next(iter);
- }
- entry->strarray_value = buffer;
- entry->array_len = count;
- wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
- __func__, entry->array_len);
-
- /* Zero-length arrays are valid. */
- if (entry->array_len == 0) {
- os_free(entry->strarray_value);
- entry->strarray_value = NULL;
- }
-
- return TRUE;
-
-fail:
- while (count > 0) {
- count--;
- os_free(buffer[count]);
- }
- os_free(buffer);
- return FALSE;
-}
-
-
-#define BIN_ARRAY_CHUNK_SIZE 10
-#define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *))
-
-static dbus_bool_t _wpa_dbus_dict_entry_get_binarray(
- DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
-{
- struct wpa_dbus_dict_entry tmpentry;
- size_t buflen = 0;
- int i, type;
-
- entry->array_type = WPAS_DBUS_TYPE_BINARRAY;
- entry->array_len = 0;
- entry->binarray_value = NULL;
-
- type = dbus_message_iter_get_arg_type(iter);
- wpa_printf(MSG_MSGDUMP, "%s: parsing binarray type %c", __func__, type);
- if (type == DBUS_TYPE_INVALID) {
- /* Likely an empty array of arrays */
- return TRUE;
- }
- if (type != DBUS_TYPE_ARRAY) {
- wpa_printf(MSG_DEBUG, "%s: not an array type: %c",
- __func__, type);
- return FALSE;
- }
-
- type = dbus_message_iter_get_element_type(iter);
- if (type != DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG, "%s: unexpected element type %c",
- __func__, type);
- return FALSE;
- }
-
- while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
- DBusMessageIter iter_array;
-
- if (entry->array_len == buflen) {
- struct wpabuf **newbuf;
-
- buflen += BIN_ARRAY_CHUNK_SIZE;
-
- newbuf = os_realloc_array(entry->binarray_value,
- buflen, BIN_ARRAY_ITEM_SIZE);
- if (!newbuf)
- goto cleanup;
- entry->binarray_value = newbuf;
- }
-
- dbus_message_iter_recurse(iter, &iter_array);
- os_memset(&tmpentry, 0, sizeof(tmpentry));
- tmpentry.type = DBUS_TYPE_ARRAY;
- if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
- == FALSE)
- goto cleanup;
-
- entry->binarray_value[entry->array_len] =
- wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value,
- tmpentry.array_len);
- if (entry->binarray_value[entry->array_len] == NULL) {
- wpa_dbus_dict_entry_clear(&tmpentry);
- goto cleanup;
- }
- entry->array_len++;
- dbus_message_iter_next(iter);
- }
- wpa_printf(MSG_MSGDUMP, "%s: binarray length %u",
- __func__, entry->array_len);
-
- return TRUE;
-
- cleanup:
- for (i = 0; i < (int) entry->array_len; i++)
- wpabuf_free(entry->binarray_value[i]);
- os_free(entry->binarray_value);
- entry->array_len = 0;
- entry->binarray_value = NULL;
- return FALSE;
-}
-
-
-static dbus_bool_t _wpa_dbus_dict_entry_get_array(
- DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
-{
- int array_type = dbus_message_iter_get_element_type(iter_dict_val);
- dbus_bool_t success = FALSE;
- DBusMessageIter iter_array;
-
- wpa_printf(MSG_MSGDUMP, "%s: array_type %c", __func__, array_type);
-
- dbus_message_iter_recurse(iter_dict_val, &iter_array);
-
- switch (array_type) {
- case DBUS_TYPE_BYTE:
- success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
- entry);
- break;
- case DBUS_TYPE_STRING:
- success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
- array_type,
- entry);
- break;
- case DBUS_TYPE_ARRAY:
- success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
- break;
- default:
- wpa_printf(MSG_MSGDUMP, "%s: unsupported array type %c",
- __func__, array_type);
- break;
- }
-
- return success;
-}
-
-
-static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
- struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter)
-{
- const char *v;
-
- switch (entry->type) {
- case DBUS_TYPE_OBJECT_PATH:
- dbus_message_iter_get_basic(iter, &v);
- wpa_printf(MSG_MSGDUMP, "%s: object path value: %s",
- __func__, v);
- entry->str_value = os_strdup(v);
- if (entry->str_value == NULL)
- return FALSE;
- break;
- case DBUS_TYPE_STRING:
- dbus_message_iter_get_basic(iter, &v);
- wpa_printf(MSG_MSGDUMP, "%s: string value: %s",
- __func__, wpa_debug_show_keys ? v : "[omitted]");
- entry->str_value = os_strdup(v);
- if (entry->str_value == NULL)
- return FALSE;
- break;
- case DBUS_TYPE_BOOLEAN:
- dbus_message_iter_get_basic(iter, &entry->bool_value);
- wpa_printf(MSG_MSGDUMP, "%s: boolean value: %d",
- __func__, entry->bool_value);
- break;
- case DBUS_TYPE_BYTE:
- dbus_message_iter_get_basic(iter, &entry->byte_value);
- wpa_printf(MSG_MSGDUMP, "%s: byte value: %d",
- __func__, entry->byte_value);
- break;
- case DBUS_TYPE_INT16:
- dbus_message_iter_get_basic(iter, &entry->int16_value);
- wpa_printf(MSG_MSGDUMP, "%s: int16 value: %d",
- __func__, entry->int16_value);
- break;
- case DBUS_TYPE_UINT16:
- dbus_message_iter_get_basic(iter, &entry->uint16_value);
- wpa_printf(MSG_MSGDUMP, "%s: uint16 value: %d",
- __func__, entry->uint16_value);
- break;
- case DBUS_TYPE_INT32:
- dbus_message_iter_get_basic(iter, &entry->int32_value);
- wpa_printf(MSG_MSGDUMP, "%s: int32 value: %d",
- __func__, entry->int32_value);
- break;
- case DBUS_TYPE_UINT32:
- dbus_message_iter_get_basic(iter, &entry->uint32_value);
- wpa_printf(MSG_MSGDUMP, "%s: uint32 value: %d",
- __func__, entry->uint32_value);
- break;
- case DBUS_TYPE_INT64:
- dbus_message_iter_get_basic(iter, &entry->int64_value);
- wpa_printf(MSG_MSGDUMP, "%s: int64 value: %lld",
- __func__, (long long int) entry->int64_value);
- break;
- case DBUS_TYPE_UINT64:
- dbus_message_iter_get_basic(iter, &entry->uint64_value);
- wpa_printf(MSG_MSGDUMP, "%s: uint64 value: %llu",
- __func__,
- (unsigned long long int) entry->uint64_value);
- break;
- case DBUS_TYPE_DOUBLE:
- dbus_message_iter_get_basic(iter, &entry->double_value);
- wpa_printf(MSG_MSGDUMP, "%s: double value: %f",
- __func__, entry->double_value);
- break;
- case DBUS_TYPE_ARRAY:
- return _wpa_dbus_dict_entry_get_array(iter, entry);
- default:
- wpa_printf(MSG_MSGDUMP, "%s: unsupported type %c",
- __func__, entry->type);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * Read the current key/value entry from the dict. Entries are dynamically
- * allocated when needed and must be freed after use with the
- * wpa_dbus_dict_entry_clear() function.
- *
- * The returned entry object will be filled with the type and value of the next
- * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
- * occurred.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_read()
- * @param entry A valid dict entry object into which the dict key and value
- * will be placed
- * @return TRUE on success, FALSE on failure
- *
- */
-dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
- struct wpa_dbus_dict_entry * entry)
-{
- DBusMessageIter iter_dict_entry, iter_dict_val;
- int type;
- const char *key;
-
- if (!iter_dict || !entry ||
- dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY) {
- wpa_printf(MSG_DEBUG, "%s: not a dict entry", __func__);
- goto error;
- }
-
- dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
- dbus_message_iter_get_basic(&iter_dict_entry, &key);
- wpa_printf(MSG_MSGDUMP, "%s: dict entry key: %s", __func__, key);
- entry->key = key;
-
- if (!dbus_message_iter_next(&iter_dict_entry)) {
- wpa_printf(MSG_DEBUG, "%s: no variant in dict entry", __func__);
- goto error;
- }
- type = dbus_message_iter_get_arg_type(&iter_dict_entry);
- if (type != DBUS_TYPE_VARIANT) {
- wpa_printf(MSG_DEBUG,
- "%s: unexpected dict entry variant type: %c",
- __func__, type);
- goto error;
- }
-
- dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
- entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
- wpa_printf(MSG_MSGDUMP, "%s: dict entry variant content type: %c",
- __func__, entry->type);
- entry->array_type = DBUS_TYPE_INVALID;
- if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val)) {
- wpa_printf(MSG_DEBUG,
- "%s: failed to fetch dict values from variant",
- __func__);
- goto error;
- }
-
- dbus_message_iter_next(iter_dict);
- return TRUE;
-
-error:
- if (entry) {
- wpa_dbus_dict_entry_clear(entry);
- entry->type = DBUS_TYPE_INVALID;
- entry->array_type = DBUS_TYPE_INVALID;
- }
-
- return FALSE;
-}
-
-
-/**
- * Return whether or not there are additional dictionary entries.
- *
- * @param iter_dict A valid DBusMessageIter returned from
- * wpa_dbus_dict_open_read()
- * @return TRUE if more dict entries exists, FALSE if no more dict entries
- * exist
- */
-dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
-{
- if (!iter_dict)
- return FALSE;
- return dbus_message_iter_get_arg_type(iter_dict) ==
- DBUS_TYPE_DICT_ENTRY;
-}
-
-
-/**
- * Free any memory used by the entry object.
- *
- * @param entry The entry object
- */
-void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
-{
- unsigned int i;
-
- if (!entry)
- return;
- switch (entry->type) {
- case DBUS_TYPE_OBJECT_PATH:
- case DBUS_TYPE_STRING:
- os_free(entry->str_value);
- break;
- case DBUS_TYPE_ARRAY:
- switch (entry->array_type) {
- case DBUS_TYPE_BYTE:
- os_free(entry->bytearray_value);
- break;
- case DBUS_TYPE_STRING:
- if (!entry->strarray_value)
- break;
- for (i = 0; i < entry->array_len; i++)
- os_free(entry->strarray_value[i]);
- os_free(entry->strarray_value);
- break;
- case WPAS_DBUS_TYPE_BINARRAY:
- for (i = 0; i < entry->array_len; i++)
- wpabuf_free(entry->binarray_value[i]);
- os_free(entry->binarray_value);
- break;
- }
- break;
- }
-
- os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
-}
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.h b/wpa_supplicant/dbus/dbus_dict_helpers.h
deleted file mode 100644
index 94a0efdbeb1f..000000000000
--- a/wpa_supplicant/dbus/dbus_dict_helpers.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DBUS_DICT_HELPERS_H
-#define DBUS_DICT_HELPERS_H
-
-#include "wpabuf.h"
-
-/*
- * Adding a dict to a DBusMessage
- */
-
-dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
- DBusMessageIter *iter_dict);
-
-dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
- DBusMessageIter *iter_dict);
-
-const char * wpa_dbus_type_as_string(const int type);
-
-dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
- const char *key, const char *value);
-
-dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_bool_t value);
-
-dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_int16_t value);
-
-dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_uint16_t value);
-
-dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_int32_t value);
-
-dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
- const char *key,
- const dbus_uint32_t value);
-
-dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
- const char *key,
- const char *value);
-
-dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
- const char *key,
- const char *value,
- const dbus_uint32_t value_len);
-
-/* Manual construction and addition of array elements */
-dbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict,
- const char *key, const char *type,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array);
-
-dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
- const char *key,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array);
-
-dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
- const char *elem);
-
-dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
- const u8 *value,
- size_t value_len);
-
-dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array);
-
-static inline dbus_bool_t
-wpa_dbus_dict_end_string_array(DBusMessageIter *iter_dict,
- DBusMessageIter *iter_dict_entry,
- DBusMessageIter *iter_dict_val,
- DBusMessageIter *iter_array)
-{
- return wpa_dbus_dict_end_array(iter_dict, iter_dict_entry,
- iter_dict_val, iter_array);
-}
-
-/* Convenience function to add a whole string list */
-dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
- const char *key,
- const char **items,
- const dbus_uint32_t num_items);
-
-dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
- const char *key,
- const struct wpabuf **items,
- const dbus_uint32_t num_items);
-
-/*
- * Reading a dict from a DBusMessage
- */
-
-/*
- * Used only in struct wpa_dbus_dict_entry::array_type internally to identify
- * special binary array case.
- */
-#define WPAS_DBUS_TYPE_BINARRAY ((int) '@')
-
-struct wpa_dbus_dict_entry {
- int type; /** the dbus type of the dict entry's value */
- int array_type; /** the dbus type of the array elements if the dict
- entry value contains an array, or the special
- WPAS_DBUS_TYPE_BINARRAY */
- const char *key; /** key of the dict entry */
-
- /** Possible values of the property */
- union {
- char *str_value;
- char byte_value;
- dbus_bool_t bool_value;
- dbus_int16_t int16_value;
- dbus_uint16_t uint16_value;
- dbus_int32_t int32_value;
- dbus_uint32_t uint32_value;
- dbus_int64_t int64_value;
- dbus_uint64_t uint64_value;
- double double_value;
- char *bytearray_value;
- char **strarray_value;
- struct wpabuf **binarray_value;
- };
- dbus_uint32_t array_len; /** length of the array if the dict entry's
- value contains an array */
-};
-
-dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
- DBusMessageIter *iter_dict,
- DBusError *error);
-
-dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
- struct wpa_dbus_dict_entry *entry);
-
-dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict);
-
-void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry);
-
-#endif /* DBUS_DICT_HELPERS_H */
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
deleted file mode 100644
index 9279ae4d5847..000000000000
--- a/wpa_supplicant/dbus/dbus_new.c
+++ /dev/null
@@ -1,5105 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "common/ieee802_11_defs.h"
-#include "wps/wps.h"
-#include "ap/sta_info.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../bss.h"
-#include "../wpas_glue.h"
-#include "dbus_new_helpers.h"
-#include "dbus_dict_helpers.h"
-#include "dbus_new.h"
-#include "dbus_new_handlers.h"
-#include "dbus_common_i.h"
-#include "dbus_new_handlers_p2p.h"
-#include "p2p/p2p.h"
-#include "../p2p_supplicant.h"
-
-#ifdef CONFIG_AP /* until needed by something else */
-
-/*
- * NameOwnerChanged handling
- *
- * Some services we provide allow an application to register for
- * a signal that it needs. While it can also unregister, we must
- * be prepared for the case where the application simply crashes
- * and thus doesn't clean up properly. The way to handle this in
- * DBus is to register for the NameOwnerChanged signal which will
- * signal an owner change to NULL if the peer closes the socket
- * for whatever reason.
- *
- * Handle this signal via a filter function whenever necessary.
- * The code below also handles refcounting in case in the future
- * there will be multiple instances of this subscription scheme.
- */
-static const char wpas_dbus_noc_filter_str[] =
- "interface=org.freedesktop.DBus,member=NameOwnerChanged";
-
-
-static DBusHandlerResult noc_filter(DBusConnection *conn,
- DBusMessage *message, void *data)
-{
- struct wpas_dbus_priv *priv = data;
-
- if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
- "NameOwnerChanged")) {
- const char *name;
- const char *prev_owner;
- const char *new_owner;
- DBusError derr;
- struct wpa_supplicant *wpa_s;
-
- dbus_error_init(&derr);
-
- if (!dbus_message_get_args(message, &derr,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &prev_owner,
- DBUS_TYPE_STRING, &new_owner,
- DBUS_TYPE_INVALID)) {
- /* Ignore this error */
- dbus_error_free(&derr);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->preq_notify_peer != NULL &&
- os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
- (new_owner == NULL || os_strlen(new_owner) == 0)) {
- /* probe request owner disconnected */
- os_free(wpa_s->preq_notify_peer);
- wpa_s->preq_notify_peer = NULL;
- wpas_dbus_unsubscribe_noc(priv);
- }
- }
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-
-void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
-{
- priv->dbus_noc_refcnt++;
- if (priv->dbus_noc_refcnt > 1)
- return;
-
- if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
- wpa_printf(MSG_ERROR, "dbus: failed to add filter");
- return;
- }
-
- dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
-}
-
-
-void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
-{
- priv->dbus_noc_refcnt--;
- if (priv->dbus_noc_refcnt > 0)
- return;
-
- dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
- dbus_connection_remove_filter(priv->con, noc_filter, priv);
-}
-
-#endif /* CONFIG_AP */
-
-
-/**
- * wpas_dbus_signal_interface - Send a interface related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
- * @properties: Whether to add second argument with object properties
- *
- * Notify listeners about event related with interface
- */
-static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
- const char *sig_name,
- dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE, sig_name);
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &wpa_s->dbus_new_path) ||
- (properties &&
- !wpa_dbus_get_object_properties(
- iface, wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_interface_added - Send a interface created signal
- * @wpa_s: %wpa_supplicant network interface data
- *
- * Notify listeners about creating new interface
- */
-static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
-{
- wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
-}
-
-
-/**
- * wpas_dbus_signal_interface_removed - Send a interface removed signal
- * @wpa_s: %wpa_supplicant network interface data
- *
- * Notify listeners about removing interface
- */
-static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
-{
- wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
-
-}
-
-
-/**
- * wpas_dbus_signal_scan_done - send scan done signal
- * @wpa_s: %wpa_supplicant network interface data
- * @success: indicates if scanning succeed or failed
- *
- * Notify listeners about finishing a scan
- */
-void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- dbus_bool_t succ;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "ScanDone");
- if (msg == NULL)
- return;
-
- succ = success ? TRUE : FALSE;
- if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
- DBUS_TYPE_INVALID))
- dbus_connection_send(iface->con, msg, NULL);
- else
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_bss - Send a BSS related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @bss_obj_path: BSS object path
- * @sig_name: signal name - BSSAdded or BSSRemoved
- * @properties: Whether to add second argument with object properties
- *
- * Notify listeners about event related with BSS
- */
-static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
- const char *bss_obj_path,
- const char *sig_name, dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- sig_name);
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &bss_obj_path) ||
- (properties &&
- !wpa_dbus_get_object_properties(iface, bss_obj_path,
- WPAS_DBUS_NEW_IFACE_BSS,
- &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_bss_added - Send a BSS added signal
- * @wpa_s: %wpa_supplicant network interface data
- * @bss_obj_path: new BSS object path
- *
- * Notify listeners about adding new BSS
- */
-static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
- const char *bss_obj_path)
-{
- wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
-}
-
-
-/**
- * wpas_dbus_signal_bss_removed - Send a BSS removed signal
- * @wpa_s: %wpa_supplicant network interface data
- * @bss_obj_path: BSS object path
- *
- * Notify listeners about removing BSS
- */
-static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
- const char *bss_obj_path)
-{
- wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
-}
-
-
-/**
- * wpas_dbus_signal_blob - Send a blob related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @name: blob name
- * @sig_name: signal name - BlobAdded or BlobRemoved
- *
- * Notify listeners about event related with blob
- */
-static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
- const char *name, const char *sig_name)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- sig_name);
- if (msg == NULL)
- return;
-
- if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
- DBUS_TYPE_INVALID))
- dbus_connection_send(iface->con, msg, NULL);
- else
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_blob_added - Send a blob added signal
- * @wpa_s: %wpa_supplicant network interface data
- * @name: blob name
- *
- * Notify listeners about adding a new blob
- */
-void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
- const char *name)
-{
- wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
-}
-
-
-/**
- * wpas_dbus_signal_blob_removed - Send a blob removed signal
- * @wpa_s: %wpa_supplicant network interface data
- * @name: blob name
- *
- * Notify listeners about removing blob
- */
-void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
- const char *name)
-{
- wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
-}
-
-
-/**
- * wpas_dbus_signal_network - Send a network related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: new network id
- * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
- * @properties: determines if add second argument with object properties
- *
- * Notify listeners about event related with configured network
- */
-static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
- int id, const char *sig_name,
- dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
- wpa_s->dbus_new_path, id);
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- sig_name);
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- path = net_obj_path;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path) ||
- (properties &&
- !wpa_dbus_get_object_properties(
- iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
- &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_network_added - Send a network added signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: new network id
- *
- * Notify listeners about adding new network
- */
-static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
- int id)
-{
- wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
-}
-
-
-/**
- * wpas_dbus_signal_network_removed - Send a network removed signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: network id
- *
- * Notify listeners about removing a network
- */
-static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
- int id)
-{
- wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
-}
-
-
-/**
- * wpas_dbus_signal_network_selected - Send a network selected signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: network id
- *
- * Notify listeners about selecting a network
- */
-void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
-{
- wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
-}
-
-
-/**
- * wpas_dbus_signal_network_request - Indicate that additional information
- * (EAP password, etc.) is required to complete the association to this SSID
- * @wpa_s: %wpa_supplicant network interface data
- * @rtype: The specific additional information required
- * @default_text: Optional description of required information
- *
- * Request additional information or passwords to complete an association
- * request.
- */
-void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- enum wpa_ctrl_req_type rtype,
- const char *default_txt)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- const char *field, *txt = NULL, *net_ptr;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
- if (field == NULL)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "NetworkRequest");
- if (msg == NULL)
- return;
-
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
- wpa_s->dbus_new_path, ssid->id);
- net_ptr = &net_obj_path[0];
-
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &net_ptr) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
- * @wpa_s: %wpa_supplicant network interface data
- * @ssid: configured network which Enabled property has changed
- *
- * Sends PropertyChanged signals containing new value of Enabled property
- * for specified network
- */
-void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-
- char path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- if (!wpa_s->dbus_new_path)
- return;
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
- wpa_s->dbus_new_path, ssid->id);
-
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
- WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
-}
-
-
-#ifdef CONFIG_WPS
-
-/**
- * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
- * @wpa_s: %wpa_supplicant network interface data
- *
- * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
- */
-void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
-
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *key = "pbc-overlap";
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS, "Event");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_wps_event_success - Signals Success WPS event
- * @wpa_s: %wpa_supplicant network interface data
- *
- * Sends Event dbus signal with name "success" and empty dict as arguments
- */
-void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
-{
-
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *key = "success";
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS, "Event");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
- * @wpa_s: %wpa_supplicant network interface data
- * @fail: WPS failure information
- *
- * Sends Event dbus signal with name "fail" and dictionary containing
- * "msg field with fail message number (int32) as arguments
- */
-void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
-
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *key = "fail";
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS, "Event");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
- fail->config_error) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
- fail->error_indication) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
- * @wpa_s: %wpa_supplicant network interface data
- * @m2d: M2D event data information
- *
- * Sends Event dbus signal with name "m2d" and dictionary containing
- * fields of wps_event_m2d structure.
- */
-void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d)
-{
-
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *key = "m2d";
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS, "Event");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
- m2d->config_methods) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
- (const char *) m2d->manufacturer,
- m2d->manufacturer_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
- (const char *) m2d->model_name,
- m2d->model_name_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
- (const char *) m2d->model_number,
- m2d->model_number_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
- (const char *)
- m2d->serial_number,
- m2d->serial_number_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
- (const char *) m2d->dev_name,
- m2d->dev_name_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
- (const char *)
- m2d->primary_dev_type, 8) ||
- !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
- m2d->config_error) ||
- !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
- m2d->dev_password_id) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_wps_cred - Signals new credentials
- * @wpa_s: %wpa_supplicant network interface data
- * @cred: WPS Credential information
- *
- * Sends signal with credentials in directory argument
- */
-void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *auth_type[5]; /* we have five possible authentication types */
- int at_num = 0;
- char *encr_type[3]; /* we have three possible encryption types */
- int et_num = 0;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS,
- "Credentials");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
- goto nomem;
-
- if (cred->auth_type & WPS_AUTH_OPEN)
- auth_type[at_num++] = "open";
-#ifndef CONFIG_NO_TKIP
- if (cred->auth_type & WPS_AUTH_WPAPSK)
- auth_type[at_num++] = "wpa-psk";
- if (cred->auth_type & WPS_AUTH_WPA)
- auth_type[at_num++] = "wpa-eap";
-#endif /* CONFIG_NO_TKIP */
- if (cred->auth_type & WPS_AUTH_WPA2)
- auth_type[at_num++] = "wpa2-eap";
- if (cred->auth_type & WPS_AUTH_WPA2PSK)
- auth_type[at_num++] = "wpa2-psk";
-
- if (cred->encr_type & WPS_ENCR_NONE)
- encr_type[et_num++] = "none";
-#ifndef CONFIG_NO_TKIP
- if (cred->encr_type & WPS_ENCR_TKIP)
- encr_type[et_num++] = "tkip";
-#endif /* CONFIG_NO_TKIP */
- if (cred->encr_type & WPS_ENCR_AES)
- encr_type[et_num++] = "aes";
-
- if ((wpa_s->current_ssid &&
- !wpa_dbus_dict_append_byte_array(
- &dict_iter, "BSSID",
- (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
- (const char *) cred->ssid,
- cred->ssid_len) ||
- !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
- (const char **) auth_type,
- at_num) ||
- !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
- (const char **) encr_type,
- et_num) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
- (const char *) cred->key,
- cred->key_len) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
- cred->key_idx) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- goto nomem;
-
- dbus_connection_send(iface->con, msg, NULL);
-
-nomem:
- dbus_message_unref(msg);
-}
-
-#endif /* CONFIG_WPS */
-
-
-#ifdef CONFIG_MESH
-
-void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_MESH,
- "MeshGroupStarted");
- if (!msg)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
- (const char *) ssid->ssid,
- ssid->ssid_len) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
- const u8 *meshid, u8 meshid_len,
- int reason)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_MESH,
- "MeshGroupRemoved");
- if (!msg)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
- (const char *) meshid,
- meshid_len) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
- reason) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_MESH,
- "MeshPeerConnected");
- if (!msg)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
- (const char *) peer_addr,
- ETH_ALEN) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, int reason)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_MESH,
- "MeshPeerDisconnected");
- if (!msg)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
- (const char *) peer_addr,
- ETH_ALEN) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
- reason) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-#endif /* CONFIG_MESH */
-
-
-#ifdef CONFIG_INTERWORKING
-
-void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_cred *cred,
- const char *type,
- int excluded,
- int bh,
- int bss_load,
- int conn_capab)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
- char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "InterworkingAPAdded");
- if (!msg)
- return;
-
- os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, bss->id);
- bss_obj_path = bss_path;
-
- os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
- wpa_s->dbus_new_path, cred->id);
- cred_obj_path = cred_path;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &bss_obj_path) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &cred_obj_path) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "priority",
- cred->priority) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
- cred->sp_priority) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
- bss_load) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
- conn_capab) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "InterworkingSelectDone");
- if (!msg)
- return;
-
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-#endif /* CONFIG_INTERWORKING */
-
-
-void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
- int depth, const char *subject,
- const char *altsubject[],
- int num_altsubject,
- const char *cert_hash,
- const struct wpabuf *cert)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "Certification");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
- !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
- (altsubject && num_altsubject &&
- !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
- altsubject, num_altsubject)) ||
- (cert_hash &&
- !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
- cert_hash)) ||
- (cert &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
- wpabuf_head(cert),
- wpabuf_len(cert))) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
- const char *status, const char *parameter)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "EAP");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &parameter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_sta - Send a station related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @sta: station mac address
- * @sig_name: signal name - StaAuthorized or StaDeauthorized
- *
- * Notify listeners about event related with station
- */
-static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
- const u8 *sta, const char *sig_name)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
- char *dev_mac;
-
- os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
- dev_mac = sta_mac;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
- if (msg == NULL)
- return;
-
- if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
- DBUS_TYPE_INVALID))
- dbus_connection_send(iface->con, msg, NULL);
- else
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- dbus_message_unref(msg);
-
- wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
- sta_mac, sig_name);
-}
-
-
-/**
- * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
- * @wpa_s: %wpa_supplicant network interface data
- * @sta: station mac address
- *
- * Notify listeners a new station has been authorized
- */
-void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
- wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
-}
-
-
-/**
- * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
- * @wpa_s: %wpa_supplicant network interface data
- * @sta: station mac address
- *
- * Notify listeners a station has been deauthorized
- */
-void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
- wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
-}
-
-
-/**
- * wpas_dbus_signal_station - Send an event signal related to a station object
- * @wpa_s: %wpa_supplicant network interface data
- * @station_obj_path: Station object path
- * @sig_name: signal name - StationAdded or StationRemoved
- * @properties: Whether to add second argument with object properties
- *
- * Notify listeners about event related with station.
- */
-static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s,
- const char *station_obj_path,
- const char *sig_name,
- dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (!iface || !wpa_s->dbus_new_path)
- return;
-
- wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name);
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
- if (!msg)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &station_obj_path) ||
- (properties &&
- !wpa_dbus_get_object_properties(iface, station_obj_path,
- WPAS_DBUS_NEW_IFACE_STA,
- &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_station_added - Send a Station added signal
- * @wpa_s: %wpa_supplicant network interface data
- * @station_obj_path: new Station object path
- *
- * Notify listeners about adding new Station
- */
-static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s,
- const char *station_obj_path)
-{
- wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE);
-}
-
-
-/**
- * wpas_dbus_signal_station_removed - Send a Station removed signal
- * @wpa_s: %wpa_supplicant network interface data
- * @station_obj_path: Station object path
- *
- * Notify listeners about removing Station
- */
-static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s,
- const char *station_obj_path)
-{
- wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved",
- FALSE);
-}
-
-
-#ifdef CONFIG_P2P
-
-/**
- * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
- * @wpa_s: %wpa_supplicant network interface data
- * @role: role of this device (client or GO)
- * Sends signal with i/f name and role as string arguments
- */
-void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
- const char *role)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface = wpa_s->global->dbus;
- struct wpa_supplicant *parent;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- parent = wpa_s->parent;
- if (parent->p2p_mgmt)
- parent = parent->parent;
-
- if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
- !parent->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(parent->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "GroupFinished");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_object_path(&dict_iter,
- "interface_object",
- wpa_s->dbus_new_path) ||
- !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
- !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
- wpa_s->dbus_groupobj_path) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
- *
- * @dev_addr - who sent the request or responded to our request.
- * @request - Will be 1 if request, 0 for response.
- * @status - valid only in case of response
- * @config_methods - wps config methods
- * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
- *
- * Sends following provision discovery related events:
- * ProvisionDiscoveryRequestDisplayPin
- * ProvisionDiscoveryResponseDisplayPin
- * ProvisionDiscoveryRequestEnterPin
- * ProvisionDiscoveryResponseEnterPin
- * ProvisionDiscoveryPBCRequest
- * ProvisionDiscoveryPBCResponse
- *
- * TODO::
- * ProvisionDiscoveryFailure (timeout case)
- */
-void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int request,
- enum p2p_prov_disc_status status,
- u16 config_methods,
- unsigned int generated_pin)
-{
- DBusMessage *msg;
- DBusMessageIter iter;
- struct wpas_dbus_priv *iface;
- char *_signal;
- int add_pin = 0;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
- int error_ret = 1;
- char pin[9], *p_pin = NULL;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- if (request || !status) {
- if (config_methods & WPS_CONFIG_DISPLAY)
- _signal = request ?
- "ProvisionDiscoveryRequestDisplayPin" :
- "ProvisionDiscoveryResponseEnterPin";
- else if (config_methods & WPS_CONFIG_KEYPAD)
- _signal = request ?
- "ProvisionDiscoveryRequestEnterPin" :
- "ProvisionDiscoveryResponseDisplayPin";
- else if (config_methods & WPS_CONFIG_PUSHBUTTON)
- _signal = request ? "ProvisionDiscoveryPBCRequest" :
- "ProvisionDiscoveryPBCResponse";
- else
- return; /* Unknown or un-supported method */
- } else {
- /* Explicit check for failure response */
- _signal = "ProvisionDiscoveryFailure";
- }
-
- add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
- (!request && !status &&
- (config_methods & WPS_CONFIG_KEYPAD)));
-
- if (add_pin) {
- os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
- p_pin = pin;
- }
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
- if (msg == NULL)
- return;
-
- /* Check if this is a known peer */
- if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
- goto error;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(dev_addr));
-
- path = peer_obj_path;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter,
- DBUS_TYPE_OBJECT_PATH,
- &path))
- goto error;
-
- if (!request && status)
- /* Attach status to ProvisionDiscoveryFailure */
- error_ret = !dbus_message_iter_append_basic(&iter,
- DBUS_TYPE_INT32,
- &status);
- else
- error_ret = (add_pin &&
- !dbus_message_iter_append_basic(&iter,
- DBUS_TYPE_STRING,
- &p_pin));
-
-error:
- if (!error_ret)
- dbus_connection_send(iface->con, msg, NULL);
- else
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
- * @wpa_s: %wpa_supplicant network interface data
- * @src: Source address of the message triggering this notification
- * @dev_passwd_id: WPS Device Password Id
- * @go_intent: Peer's GO Intent value
- *
- * Sends signal to notify that a peer P2P Device is requesting group owner
- * negotiation with us.
- */
-void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
- const u8 *src, u16 dev_passwd_id,
- u8 go_intent)
-{
- DBusMessage *msg;
- DBusMessageIter iter;
- struct wpas_dbus_priv *iface;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(src));
- path = peer_obj_path;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "GONegotiationRequest");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
- &dev_passwd_id) ||
- !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
- &go_intent))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- char *group_obj_path)
-{
- char group_name[3];
-
- if (!wpa_s->dbus_new_path ||
- os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
- return -1;
-
- os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
- group_name[2] = '\0';
-
- os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
- wpa_s->dbus_new_path, group_name);
-
- return 0;
-}
-
-
-struct group_changed_data {
- struct wpa_supplicant *wpa_s;
- struct p2p_peer_info *info;
-};
-
-
-static int match_group_where_peer_is_client(struct p2p_group *group,
- void *user_data)
-{
- struct group_changed_data *data = user_data;
- const struct p2p_group_config *cfg;
- struct wpa_supplicant *wpa_s_go;
-
- if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
- return 1;
-
- cfg = p2p_group_get_config(group);
-
- wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
- cfg->ssid_len);
- if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
- wpas_dbus_signal_peer_groups_changed(
- data->wpa_s->p2pdev, data->info->p2p_device_addr);
- return 0;
- }
-
- return 1;
-}
-
-
-static void signal_peer_groups_changed(struct p2p_peer_info *info,
- void *user_data)
-{
- struct group_changed_data *data = user_data;
- struct wpa_supplicant *wpa_s_go;
-
- wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
- info->p2p_device_addr);
- if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
- wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
- info->p2p_device_addr);
- return;
- }
-
- data->info = info;
- p2p_loop_on_all_groups(data->wpa_s->global->p2p,
- match_group_where_peer_is_client, data);
- data->info = NULL;
-}
-
-
-static void peer_groups_changed(struct wpa_supplicant *wpa_s)
-{
- struct group_changed_data data;
-
- os_memset(&data, 0, sizeof(data));
- data.wpa_s = wpa_s;
-
- p2p_loop_on_known_peers(wpa_s->global->p2p,
- signal_peer_groups_changed, &data);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_group_started - Signals P2P group has
- * started. Emitted when a group is successfully started
- * irrespective of the role (client/GO) of the current device
- *
- * @wpa_s: %wpa_supplicant network interface data
- * @client: this device is P2P client
- * @persistent: 0 - non persistent group, 1 - persistent group
- * @ip: When group role is client, it contains local IP address, netmask, and
- * GO's IP address, if assigned; otherwise, NULL
- */
-void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
- int client, int persistent,
- const u8 *ip)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- struct wpa_supplicant *parent;
-
- parent = wpa_s->parent;
- if (parent->p2p_mgmt)
- parent = parent->parent;
-
- iface = parent->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
- return;
-
- if (wpa_s->dbus_groupobj_path == NULL)
- return;
-
- /* New interface has been created for this group */
- msg = dbus_message_new_signal(parent->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "GroupStarted");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- /*
- * In case the device supports creating a separate interface the
- * DBus client will need to know the object path for the interface
- * object this group was created on, so include it here.
- */
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_object_path(&dict_iter,
- "interface_object",
- wpa_s->dbus_new_path) ||
- !wpa_dbus_dict_append_string(&dict_iter, "role",
- client ? "client" : "GO") ||
- !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
- !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
- wpa_s->dbus_groupobj_path) ||
- (ip &&
- (!wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddr",
- (char *) ip, 4) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
- (char *) ip + 4, 4) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
- (char *) ip + 8, 4))) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- } else {
- dbus_connection_send(iface->con, msg, NULL);
- if (client)
- peer_groups_changed(wpa_s);
- }
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
- * @wpa_s: %wpa_supplicant network interface data
- * @res: Result of the GO Neg Request
- */
-void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
- struct wpas_dbus_priv *iface;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
- dbus_int32_t freqs[P2P_MAX_CHANNELS];
- dbus_int32_t *f_array = freqs;
-
-
- iface = wpa_s->global->dbus;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- os_memset(freqs, 0, sizeof(freqs));
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
- path = peer_obj_path;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- res->status ? "GONegotiationFailure" :
- "GONegotiationSuccess");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
- path) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
- goto err;
-
- if (!res->status) {
- int i = 0;
- int freq_list_num = 0;
-
- if ((res->role_go &&
- !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
- res->passphrase)) ||
- !wpa_dbus_dict_append_string(&dict_iter, "role_go",
- res->role_go ? "GO" :
- "client") ||
- !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
- res->freq) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
- (const char *) res->ssid,
- res->ssid_len) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter,
- "peer_device_addr",
- (const char *)
- res->peer_device_addr,
- ETH_ALEN) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter,
- "peer_interface_addr",
- (const char *)
- res->peer_interface_addr,
- ETH_ALEN) ||
- !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
- p2p_wps_method_text(
- res->wps_method)))
- goto err;
-
- for (i = 0; i < P2P_MAX_CHANNELS; i++) {
- if (res->freq_list[i]) {
- freqs[i] = res->freq_list[i];
- freq_list_num++;
- }
- }
-
- if (!wpa_dbus_dict_begin_array(&dict_iter,
- "frequency_list",
- DBUS_TYPE_INT32_AS_STRING,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_dict_array) ||
- !dbus_message_iter_append_fixed_array(&iter_dict_array,
- DBUS_TYPE_INT32,
- &f_array,
- freq_list_num) ||
- !wpa_dbus_dict_end_array(&dict_iter,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_dict_array) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
- res->persistent_group) ||
- !wpa_dbus_dict_append_uint32(&dict_iter,
- "peer_config_timeout",
- res->peer_config_timeout))
- goto err;
- }
-
- if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
- goto err;
-
- dbus_connection_send(iface->con, msg, NULL);
-err:
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
- * @wpa_s: %wpa_supplicant network interface data
- * @status: Status of invitation process
- * @bssid: Basic Service Set Identifier
- */
-void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
- int status, const u8 *bssid)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
-
- wpa_printf(MSG_DEBUG, "%s", __func__);
-
- iface = wpa_s->global->dbus;
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "InvitationResult");
-
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
- (bssid &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
- (const char *) bssid,
- ETH_ALEN)) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- *
- * Method to emit a signal for a peer joining the group.
- * The signal will carry path to the group member object
- * constructed using p2p i/f addr used for connecting.
- *
- * @wpa_s: %wpa_supplicant network interface data
- * @peer_addr: P2P Device Address of the peer joining the group
- */
-void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
- struct wpa_supplicant *parent;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (!wpa_s->dbus_groupobj_path)
- return;
-
- parent = wpa_s->parent;
- if (parent->p2p_mgmt)
- parent = parent->parent;
- if (!parent->dbus_new_path)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR,
- parent->dbus_new_path, MAC2STR(peer_addr));
-
- msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
- WPAS_DBUS_NEW_IFACE_P2P_GROUP,
- "PeerJoined");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- path = peer_obj_path;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path)) {
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- } else {
- dbus_connection_send(iface->con, msg, NULL);
- wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
- }
- dbus_message_unref(msg);
-}
-
-
-/**
- *
- * Method to emit a signal for a peer disconnecting the group.
- * The signal will carry path to the group member object
- * constructed using the P2P Device Address of the peer.
- *
- * @wpa_s: %wpa_supplicant network interface data
- * @peer_addr: P2P Device Address of the peer joining the group
- */
-void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
- struct wpa_supplicant *parent;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (!wpa_s->dbus_groupobj_path)
- return;
-
- parent = wpa_s->parent;
- if (parent->p2p_mgmt)
- parent = parent->parent;
- if (!parent->dbus_new_path)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR,
- parent->dbus_new_path, MAC2STR(peer_addr));
-
- msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
- WPAS_DBUS_NEW_IFACE_P2P_GROUP,
- "PeerDisconnected");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- path = peer_obj_path;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path)) {
- wpa_printf(MSG_ERROR,
- "dbus: Failed to construct PeerDisconnected signal");
- } else {
- dbus_connection_send(iface->con, msg, NULL);
- wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
- }
- dbus_message_unref(msg);
-}
-
-
-/**
- *
- * Method to emit a signal for a service discovery request.
- * The signal will carry station address, frequency, dialog token,
- * update indicator and it tlvs
- *
- * @wpa_s: %wpa_supplicant network interface data
- * @sa: station addr (p2p i/f) of the peer
- * @dialog_token: service discovery request dialog token
- * @update_indic: service discovery request update indicator
- * @tlvs: service discovery request generated byte array of tlvs
- * @tlvs_len: service discovery request tlvs length
- */
-void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
- int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs,
- size_t tlvs_len)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- /* Check if this is a known peer */
- if (!p2p_peer_known(wpa_s->global->p2p, sa))
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "ServiceDiscoveryRequest");
- if (msg == NULL)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
-
- path = peer_obj_path;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
- path) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
- dialog_token) ||
- !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
- update_indic) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
- (const char *) tlvs,
- tlvs_len) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- *
- * Method to emit a signal for a service discovery response.
- * The signal will carry station address, update indicator and it
- * tlvs
- *
- * @wpa_s: %wpa_supplicant network interface data
- * @sa: station addr (p2p i/f) of the peer
- * @update_indic: service discovery request update indicator
- * @tlvs: service discovery request generated byte array of tlvs
- * @tlvs_len: service discovery request tlvs length
- */
-void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- /* Check if this is a known peer */
- if (!p2p_peer_known(wpa_s->global->p2p, sa))
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "ServiceDiscoveryResponse");
- if (msg == NULL)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
-
- path = peer_obj_path;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
- path) ||
- !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
- update_indic) ||
- !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
- (const char *) tlvs,
- tlvs_len) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_persistent_group - Send a persistent group related
- * event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: new persistent group id
- * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
- * @properties: determines if add second argument with object properties
- *
- * Notify listeners about an event related to persistent groups.
- */
-static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
- int id, const char *sig_name,
- dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
- if (!wpa_s->dbus_new_path)
- return;
-
- os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
- wpa_s->dbus_new_path, id);
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- sig_name);
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- path = pgrp_obj_path;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path) ||
- (properties &&
- !wpa_dbus_get_object_properties(
- iface, pgrp_obj_path,
- WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_persistent_group_added - Send a persistent_group
- * added signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: new persistent group id
- *
- * Notify listeners about addition of a new persistent group.
- */
-static void wpas_dbus_signal_persistent_group_added(
- struct wpa_supplicant *wpa_s, int id)
-{
- wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
- TRUE);
-}
-
-
-/**
- * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
- * removed signal
- * @wpa_s: %wpa_supplicant network interface data
- * @id: persistent group id
- *
- * Notify listeners about removal of a persistent group.
- */
-static void wpas_dbus_signal_persistent_group_removed(
- struct wpa_supplicant *wpa_s, int id)
-{
- wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
- FALSE);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
- * @wpa_s: %wpa_supplicant network interface data
- * @fail: WPS failure information
- *
- * Sends Event dbus signal with name "fail" and dictionary containing
- * "msg" field with fail message number (int32) as arguments
- */
-void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
-
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
- char *key = "fail";
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- if (!wpa_s->dbus_new_path)
- return;
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "WpsFailed");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
- !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
- !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
- fail->config_error) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
- * @wpa_s: %wpa_supplicant network interface data
- * @reason: indicates the reason code for group formation failure
- *
- * Sends Event dbus signal and string reason code when available.
- */
-void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
- const char *reason)
-{
- DBusMessage *msg;
- struct wpas_dbus_priv *iface;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "GroupFormationFailure");
- if (msg == NULL)
- return;
-
- if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
- DBUS_TYPE_INVALID))
- dbus_connection_send(iface->con, msg, NULL);
- else
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
- * @wpa_s: %wpa_supplicant network interface data
- * @sa: Source address of the Invitation Request
- * @dev_add: GO Device Address
- * @bssid: P2P Group BSSID or %NULL if not received
- * @id: Persistent group id or %0 if not persistent group
- * @op_freq: Operating frequency for the group
- */
-
-void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *dev_addr,
- const u8 *bssid, int id,
- int op_freq)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *iface;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "InvitationReceived");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- (sa &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
- (const char *) sa, ETH_ALEN)) ||
- (dev_addr &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
- (const char *) dev_addr,
- ETH_ALEN)) ||
- (bssid &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
- (const char *) bssid,
- ETH_ALEN)) ||
- (id &&
- !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
- !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
- dbus_message_unref(msg);
- return;
- }
-
- dbus_connection_send(iface->con, msg, NULL);
- dbus_message_unref(msg);
-}
-
-
-#endif /* CONFIG_P2P */
-
-
-/**
- * wpas_dbus_signal_prop_changed - Signals change of property
- * @wpa_s: %wpa_supplicant network interface data
- * @property: indicates which property has changed
- *
- * Sends PropertyChanged signals with path, interface and arguments
- * depending on which property has changed.
- */
-void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_prop property)
-{
- char *prop;
- dbus_bool_t flush;
-
- if (wpa_s->dbus_new_path == NULL)
- return; /* Skip signal since D-Bus setup is not yet ready */
-
- flush = FALSE;
- switch (property) {
- case WPAS_DBUS_PROP_AP_SCAN:
- prop = "ApScan";
- break;
- case WPAS_DBUS_PROP_SCANNING:
- prop = "Scanning";
- break;
- case WPAS_DBUS_PROP_STATE:
- prop = "State";
- break;
- case WPAS_DBUS_PROP_CURRENT_BSS:
- prop = "CurrentBSS";
- break;
- case WPAS_DBUS_PROP_CURRENT_NETWORK:
- prop = "CurrentNetwork";
- break;
- case WPAS_DBUS_PROP_BSSS:
- prop = "BSSs";
- break;
- case WPAS_DBUS_PROP_STATIONS:
- prop = "Stations";
- break;
- case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
- prop = "CurrentAuthMode";
- break;
- case WPAS_DBUS_PROP_DISCONNECT_REASON:
- prop = "DisconnectReason";
- flush = TRUE;
- break;
- case WPAS_DBUS_PROP_AUTH_STATUS_CODE:
- prop = "AuthStatusCode";
- flush = TRUE;
- break;
- case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
- prop = "AssocStatusCode";
- flush = TRUE;
- break;
- case WPAS_DBUS_PROP_ROAM_TIME:
- prop = "RoamTime";
- break;
- case WPAS_DBUS_PROP_ROAM_COMPLETE:
- prop = "RoamComplete";
- break;
- case WPAS_DBUS_PROP_SESSION_LENGTH:
- prop = "SessionLength";
- break;
- case WPAS_DBUS_PROP_BSS_TM_STATUS:
- prop = "BSSTMStatus";
- break;
- default:
- wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
- __func__, property);
- return;
- }
-
- wpa_dbus_mark_property_changed(wpa_s->global->dbus,
- wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
- if (flush) {
- wpa_dbus_flush_object_changed_properties(
- wpa_s->global->dbus->con, wpa_s->dbus_new_path);
- }
-}
-
-
-/**
- * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
- * @wpa_s: %wpa_supplicant network interface data
- * @property: indicates which property has changed
- * @id: unique BSS identifier
- *
- * Sends PropertyChanged signals with path, interface, and arguments depending
- * on which property has changed.
- */
-void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_bss_prop property,
- unsigned int id)
-{
- char path[WPAS_DBUS_OBJECT_PATH_MAX];
- char *prop;
-
- if (!wpa_s->dbus_new_path)
- return;
-
- switch (property) {
- case WPAS_DBUS_BSS_PROP_SIGNAL:
- prop = "Signal";
- break;
- case WPAS_DBUS_BSS_PROP_FREQ:
- prop = "Frequency";
- break;
- case WPAS_DBUS_BSS_PROP_MODE:
- prop = "Mode";
- break;
- case WPAS_DBUS_BSS_PROP_PRIVACY:
- prop = "Privacy";
- break;
- case WPAS_DBUS_BSS_PROP_RATES:
- prop = "Rates";
- break;
- case WPAS_DBUS_BSS_PROP_WPA:
- prop = "WPA";
- break;
- case WPAS_DBUS_BSS_PROP_RSN:
- prop = "RSN";
- break;
- case WPAS_DBUS_BSS_PROP_WPS:
- prop = "WPS";
- break;
- case WPAS_DBUS_BSS_PROP_IES:
- prop = "IEs";
- break;
- case WPAS_DBUS_BSS_PROP_AGE:
- prop = "Age";
- break;
- default:
- wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
- __func__, property);
- return;
- }
-
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, id);
-
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
- WPAS_DBUS_NEW_IFACE_BSS, prop);
-}
-
-
-/**
- * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
- * @wpa_s: %wpa_supplicant network interface data
- * @property: indicates which property has changed
- * @address: unique BSS identifier
- *
- * Sends PropertyChanged signals with path, interface, and arguments depending
- * on which property has changed.
- */
-void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_bss_prop property,
- u8 address[ETH_ALEN])
-{
- char path[WPAS_DBUS_OBJECT_PATH_MAX];
- char *prop;
-
- switch (property) {
- case WPAS_DBUS_STA_PROP_ADDRESS:
- prop = "Address";
- break;
- default:
- wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
- __func__, property);
- return;
- }
-
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(address));
-
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
- WPAS_DBUS_NEW_IFACE_STA, prop);
-}
-
-
-/**
- * wpas_dbus_signal_debug_level_changed - Signals change of debug param
- * @global: wpa_global structure
- *
- * Sends PropertyChanged signals informing that debug level has changed.
- */
-void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
-{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugLevel");
-}
-
-
-/**
- * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
- * @global: wpa_global structure
- *
- * Sends PropertyChanged signals informing that debug timestamp has changed.
- */
-void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
-{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugTimestamp");
-}
-
-
-/**
- * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
- * @global: wpa_global structure
- *
- * Sends PropertyChanged signals informing that debug show_keys has changed.
- */
-void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
-{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugShowKeys");
-}
-
-
-static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
- void *priv,
- WPADBusArgumentFreeFunction priv_free,
- const struct wpa_dbus_method_desc *methods,
- const struct wpa_dbus_property_desc *properties,
- const struct wpa_dbus_signal_desc *signals)
-{
- int n;
-
- obj_desc->user_data = priv;
- obj_desc->user_data_free_func = priv_free;
- obj_desc->methods = methods;
- obj_desc->properties = properties;
- obj_desc->signals = signals;
-
- for (n = 0; properties && properties->dbus_property; properties++)
- n++;
-
- obj_desc->prop_changed_flags = os_zalloc(n);
- if (!obj_desc->prop_changed_flags)
- wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
- __func__);
-}
-
-
-static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
- { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
- {
- { "args", "a{sv}", ARG_IN },
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
- {
- { "path", "o", ARG_IN },
- END_ARGS
- }
- },
- { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
- {
- { "ifname", "s", ARG_IN },
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
- {
- END_ARGS
- }
- },
- { NULL, NULL, NULL, { END_ARGS } }
-};
-
-static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
- { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
- wpas_dbus_getter_debug_level,
- wpas_dbus_setter_debug_level,
- NULL
- },
- { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
- wpas_dbus_getter_debug_timestamp,
- wpas_dbus_setter_debug_timestamp,
- NULL
- },
- { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
- wpas_dbus_getter_debug_show_keys,
- wpas_dbus_setter_debug_show_keys,
- NULL
- },
- { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
- wpas_dbus_getter_interfaces,
- NULL,
- NULL
- },
- { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
- wpas_dbus_getter_eap_methods,
- NULL,
- NULL
- },
- { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
- wpas_dbus_getter_global_capabilities,
- NULL,
- NULL
- },
-#ifdef CONFIG_WIFI_DISPLAY
- { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
- wpas_dbus_getter_global_wfd_ies,
- wpas_dbus_setter_global_wfd_ies,
- NULL
- },
-#endif /* CONFIG_WIFI_DISPLAY */
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
- { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-
-static char * uscore_to_dbus(const char *uscore)
-{
- const char *p = uscore;
- char *str, *s;
- dbus_bool_t last_was_uscore = TRUE;
-
- s = str = os_zalloc(os_strlen(uscore) + 1);
- if (!str)
- return NULL;
- while (p && *p) {
- if (*p == '_') {
- last_was_uscore = TRUE;
- } else {
- *s++ = last_was_uscore ? toupper(*p) : *p;
- last_was_uscore = FALSE;
- }
- p++;
- }
-
- return str;
-}
-
-
-static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
-
-
-static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
-{
- int idx = priv->globals_start;
-
- /* Free all allocated property values */
- while (priv->all_interface_properties[idx].dbus_property)
- os_free((char *)
- priv->all_interface_properties[idx++].dbus_property);
- os_free((char *) priv->all_interface_properties);
-}
-
-
-/**
- * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: 0 on success or -1 on failure
- *
- * Initialize the dbus control interface for wpa_supplicant and start
- * receiving commands from external programs over the bus.
- */
-int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
-{
- struct wpa_dbus_object_desc *obj_desc;
- int ret;
-
- ret = wpa_dbus_ctrl_iface_props_init(priv);
- if (ret < 0) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to init interface properties");
- return -1;
- }
-
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto error;
- }
-
- wpas_dbus_register(obj_desc, priv->global, NULL,
- wpas_dbus_global_methods,
- wpas_dbus_global_properties,
- wpas_dbus_global_signals);
-
- wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
- WPAS_DBUS_NEW_PATH);
- ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_SERVICE,
- obj_desc);
- if (ret < 0) {
- free_dbus_object_desc(obj_desc);
- goto error;
- }
-
- priv->dbus_new_initialized = 1;
- return 0;
-
-error:
- wpa_dbus_ctrl_iface_props_deinit(priv);
- return -1;
-}
-
-
-/**
- * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
- * wpa_supplicant
- * @priv: Pointer to dbus private data from wpas_dbus_init()
- *
- * Deinitialize the dbus control interface that was initialized with
- * wpas_dbus_ctrl_iface_init().
- */
-void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
-{
- if (!priv->dbus_new_initialized)
- return;
- wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
- WPAS_DBUS_NEW_PATH);
- dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
- wpa_dbus_ctrl_iface_props_deinit(priv);
-}
-
-
-static void wpa_dbus_free(void *ptr)
-{
- os_free(ptr);
-}
-
-
-static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
- { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
- wpas_dbus_getter_network_properties,
- wpas_dbus_setter_network_properties,
- NULL
- },
- { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
- wpas_dbus_getter_enabled,
- wpas_dbus_setter_enabled,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-
-/**
- * wpas_dbus_register_network - Register a configured network with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @ssid: network configuration data
- * Returns: 0 on success, -1 on failure
- *
- * Registers network representing object with dbus
- */
-int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- struct network_handler_args *arg;
- char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
-#ifdef CONFIG_P2P
- /*
- * If it is a persistent group register it as such.
- * This is to handle cases where an interface is being initialized
- * with a list of networks read from config.
- */
- if (network_is_persistent_group(ssid))
- return wpas_dbus_register_persistent_group(wpa_s, ssid);
-#endif /* CONFIG_P2P */
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
- wpa_s->dbus_new_path, ssid->id);
-
- wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
- net_obj_path);
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- /* allocate memory for handlers arguments */
- arg = os_zalloc(sizeof(struct network_handler_args));
- if (!arg) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create arguments for method");
- goto err;
- }
-
- arg->wpa_s = wpa_s;
- arg->ssid = ssid;
-
- wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
- wpas_dbus_network_properties,
- wpas_dbus_network_signals);
-
- if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
- wpa_s->ifname, obj_desc))
- goto err;
-
- wpas_dbus_signal_network_added(wpa_s, ssid->id);
-
- return 0;
-
-err:
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-
-/**
- * wpas_dbus_unregister_network - Unregister a configured network from dbus
- * @wpa_s: wpa_supplicant interface structure
- * @nid: network id
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters network representing object from dbus
- */
-int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
-{
- struct wpas_dbus_priv *ctrl_iface;
- char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- int ret;
-#ifdef CONFIG_P2P
- struct wpa_ssid *ssid;
-
- ssid = wpa_config_get_network(wpa_s->conf, nid);
-
- /* If it is a persistent group unregister it as such */
- if (ssid && network_is_persistent_group(ssid))
- return wpas_dbus_unregister_persistent_group(wpa_s, nid);
-#endif /* CONFIG_P2P */
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
- wpa_s->dbus_new_path, nid);
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
- net_obj_path);
- ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
-
- if (!ret)
- wpas_dbus_signal_network_removed(wpa_s, nid);
-
- return ret;
-}
-
-
-static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
- { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- wpas_dbus_getter_bss_ssid,
- NULL,
- NULL
- },
- { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- wpas_dbus_getter_bss_bssid,
- NULL,
- NULL
- },
- { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
- wpas_dbus_getter_bss_privacy,
- NULL,
- NULL
- },
- { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
- wpas_dbus_getter_bss_mode,
- NULL,
- NULL
- },
- { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
- wpas_dbus_getter_bss_signal,
- NULL,
- NULL
- },
- { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
- wpas_dbus_getter_bss_frequency,
- NULL,
- NULL
- },
- { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
- wpas_dbus_getter_bss_rates,
- NULL,
- NULL
- },
- { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
- wpas_dbus_getter_bss_wpa,
- NULL,
- NULL
- },
- { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
- wpas_dbus_getter_bss_rsn,
- NULL,
- NULL
- },
- { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
- wpas_dbus_getter_bss_wps,
- NULL,
- NULL
- },
- { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
- wpas_dbus_getter_bss_ies,
- NULL,
- NULL
- },
- { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
- wpas_dbus_getter_bss_age,
- NULL,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-
-/**
- * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
- * @wpa_s: wpa_supplicant interface structure
- * @bssid: scanned network bssid
- * @id: unique BSS identifier
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters BSS representing object from dbus
- */
-int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id)
-{
- struct wpas_dbus_priv *ctrl_iface;
- char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, id);
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
- bss_obj_path);
- if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
- wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
- bss_obj_path);
- return -1;
- }
-
- wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
-
- return 0;
-}
-
-
-/**
- * wpas_dbus_register_bss - Register a scanned BSS with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @bssid: scanned network bssid
- * @id: unique BSS identifier
- * Returns: 0 on success, -1 on failure
- *
- * Registers BSS representing object with dbus
- */
-int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- struct bss_handler_args *arg;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, id);
-
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- arg = os_zalloc(sizeof(struct bss_handler_args));
- if (!arg) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create arguments for handler");
- goto err;
- }
- arg->wpa_s = wpa_s;
- arg->id = id;
-
- wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
- wpas_dbus_bss_properties,
- wpas_dbus_bss_signals);
-
- wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
- bss_obj_path);
- if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
- wpa_s->ifname, obj_desc)) {
- wpa_printf(MSG_ERROR,
- "Cannot register BSSID dbus object %s.",
- bss_obj_path);
- goto err;
- }
-
- wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
-
- return 0;
-
-err:
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-
-static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
- { "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
- wpas_dbus_getter_sta_address,
- NULL, NULL
- },
- { "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
- wpas_dbus_getter_sta_aid,
- NULL, NULL
- },
- { "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
- wpas_dbus_getter_sta_caps,
- NULL, NULL
- },
- { "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
- wpas_dbus_getter_sta_rx_packets,
- NULL, NULL
- },
- { "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
- wpas_dbus_getter_sta_tx_packets,
- NULL, NULL
- },
- { "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
- wpas_dbus_getter_sta_rx_bytes,
- NULL, NULL
- },
- { "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
- wpas_dbus_getter_sta_tx_bytes,
- NULL, NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-
-/**
- * wpas_dbus_unregister_sta - Unregister a connected station from dbus
- * @wpa_s: wpa_supplicant interface structure
- * @sta: station MAC address
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters STA representing object from dbus.
- */
-int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
-{
- struct wpas_dbus_priv *ctrl_iface;
- char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- /* Do nothing if the control interface is not turned on */
- if (!wpa_s || !wpa_s->global)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (!ctrl_iface)
- return 0;
-
- os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(sta));
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
- station_obj_path);
- if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
- station_obj_path)) {
- wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
- station_obj_path);
- return -1;
- }
-
- wpas_dbus_signal_station_removed(wpa_s, station_obj_path);
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
-
- return 0;
-}
-
-
-/**
- * wpas_dbus_register_sta - Register a connected station with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @sta: station MAC address
- * Returns: 0 on success, -1 on failure
- *
- * Registers STA representing object with dbus.
- */
-int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- struct sta_handler_args *arg;
-
- /* Do nothing if the control interface is not turned on */
- if (!wpa_s || !wpa_s->global)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (!ctrl_iface)
- return 0;
-
- os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(sta));
-
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- arg = os_zalloc(sizeof(struct sta_handler_args));
- if (!arg) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create arguments for handler");
- goto err;
- }
- arg->wpa_s = wpa_s;
- arg->sta = sta;
-
- wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
- wpas_dbus_sta_properties, wpas_dbus_sta_signals);
-
- wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
- station_obj_path);
- if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path,
- wpa_s->ifname, obj_desc)) {
- wpa_printf(MSG_ERROR,
- "Cannot register STA dbus object %s",
- station_obj_path);
- goto err;
- }
-
- wpas_dbus_signal_station_added(wpa_s, station_obj_path);
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
-
- return 0;
-
-err:
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-
-static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
- { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_scan,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
- {
- END_ARGS
- }
- },
- { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_add_network,
- {
- { "args", "a{sv}", ARG_IN },
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
- {
- END_ARGS
- }
- },
- { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_reattach,
- {
- END_ARGS
- }
- },
- { "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
- {
- END_ARGS
- }
- },
- { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
- {
- { "path", "o", ARG_IN },
- END_ARGS
- }
- },
- { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
- {
- END_ARGS
- }
- },
- { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_select_network,
- {
- { "path", "o", ARG_IN },
- END_ARGS
- }
- },
- { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
- {
- { "path", "o", ARG_IN },
- { "field", "s", ARG_IN },
- { "value", "s", ARG_IN },
- END_ARGS
- }
- },
- { "Roam", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_roam,
- {
- { "addr", "s", ARG_IN },
- END_ARGS
- }
- },
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
- { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
- {
- { "name", "s", ARG_IN },
- { "data", "ay", ARG_IN },
- END_ARGS
- }
- },
- { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
- {
- { "name", "s", ARG_IN },
- { "data", "ay", ARG_OUT },
- END_ARGS
- }
- },
- { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
- {
- { "name", "s", ARG_IN },
- END_ARGS
- }
- },
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler)
- wpas_dbus_handler_set_pkcs11_engine_and_module_path,
- {
- { "pkcs11_engine_path", "s", ARG_IN },
- { "pkcs11_module_path", "s", ARG_IN },
- END_ARGS
- }
- },
-#ifdef CONFIG_WPS
- { "Start", WPAS_DBUS_NEW_IFACE_WPS,
- (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
- {
- { "args", "a{sv}", ARG_IN },
- { "output", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
- (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
- {
- END_ARGS
- }
- },
- { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
- {
- { "timeout", "i", ARG_IN },
- END_ARGS
- }
- },
- { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
- {
- { "peer", "o", ARG_IN },
- { "config_method", "s", ARG_IN },
- END_ARGS
- }
- },
- { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
- {
- { "args", "a{sv}", ARG_IN },
- { "generated_pin", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
- {
- END_ARGS
- }
- },
- { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
- {
- END_ARGS
- }
- },
- { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
- {
- { "peer", "o", ARG_IN },
- END_ARGS
- }
- },
- { "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
- {
- END_ARGS
- }
- },
- { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
- {
- END_ARGS
- }
- },
- { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
- {
- { "args", "a{sv}", ARG_IN },
- { "ref", "t", ARG_OUT },
- END_ARGS
- }
- },
- { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
- {
- { "args", "t", ARG_IN },
- END_ARGS
- }
- },
- { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
- {
- END_ARGS
- }
- },
- { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
- {
- { "arg", "i", ARG_IN },
- END_ARGS
- }
- },
- { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
- {
- { "args", "a{sv}", ARG_IN },
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
- {
- { "path", "o", ARG_IN },
- END_ARGS
- }
- },
- { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- (WPADBusMethodHandler)
- wpas_dbus_handler_remove_all_persistent_groups,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_P2P */
- { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
- {
- { "age", "u", ARG_IN },
- END_ARGS
- }
- },
-#ifdef CONFIG_AP
- { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
- {
- END_ARGS
- }
- },
- { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_AP */
- { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
- {
- END_ARGS
- }
- },
- { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
- {
- END_ARGS
- }
- },
-#ifdef CONFIG_AUTOSCAN
- { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
- {
- { "arg", "s", ARG_IN },
- END_ARGS
- }
- },
-#endif /* CONFIG_AUTOSCAN */
-#ifdef CONFIG_TDLS
- { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
- {
- { "peer_address", "s", ARG_IN },
- END_ARGS
- }
- },
- { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
- {
- { "peer_address", "s", ARG_IN },
- END_ARGS
- }
- },
- { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
- {
- { "peer_address", "s", ARG_IN },
- { "status", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
- {
- { "peer_address", "s", ARG_IN },
- END_ARGS
- }
- },
- { "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
- {
- { "args", "a{sv}", ARG_IN },
- END_ARGS
- }
- },
- { "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_tdls_cancel_channel_switch,
- {
- { "peer_address", "s", ARG_IN },
- END_ARGS
- }
- },
-#endif /* CONFIG_TDLS */
- { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
- {
- { "frame_id", "i", ARG_IN },
- { "ielems", "ay", ARG_IN },
- END_ARGS
- }
- },
- { "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
- {
- { "frame_id", "i", ARG_IN },
- { "ielems", "ay", ARG_OUT },
- END_ARGS
- }
- },
- { "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
- {
- { "frame_id", "i", ARG_IN },
- { "ielems", "ay", ARG_IN },
- END_ARGS
- }
- },
-#ifndef CONFIG_NO_CONFIG_WRITE
- { "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_save_config,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_NO_CONFIG_WRITE */
- { "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_abort_scan,
- {
- END_ARGS
- }
- },
-#ifdef CONFIG_INTERWORKING
- { "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
- {
- { "args", "a{sv}", ARG_IN },
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
- {
- { "path", "o", ARG_IN },
- END_ARGS
- }
- },
- { "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
- {
- END_ARGS
- }
- },
- { "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_INTERWORKING */
- { NULL, NULL, NULL, { END_ARGS } }
-};
-
-static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
- { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
- wpas_dbus_getter_capabilities,
- NULL,
- NULL
- },
- { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_state,
- NULL,
- NULL
- },
- { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
- wpas_dbus_getter_scanning,
- NULL,
- NULL
- },
- { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_ap_scan,
- wpas_dbus_setter_ap_scan,
- NULL
- },
- { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_bss_expire_age,
- wpas_dbus_setter_bss_expire_age,
- NULL
- },
- { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_bss_expire_count,
- wpas_dbus_setter_bss_expire_count,
- NULL
- },
- { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_country,
- wpas_dbus_setter_country,
- NULL
- },
- { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_ifname,
- NULL,
- NULL
- },
- { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_driver,
- NULL,
- NULL
- },
- { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_bridge_ifname,
- wpas_dbus_setter_bridge_ifname,
- NULL
- },
- { "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_config_file,
- NULL,
- NULL
- },
- { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
- wpas_dbus_getter_current_bss,
- NULL,
- NULL
- },
- { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
- wpas_dbus_getter_current_network,
- NULL,
- NULL
- },
- { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_current_auth_mode,
- NULL,
- NULL
- },
- { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
- wpas_dbus_getter_blobs,
- NULL,
- NULL
- },
- { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
- wpas_dbus_getter_bsss,
- NULL,
- NULL
- },
- { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
- wpas_dbus_getter_networks,
- NULL,
- NULL
- },
- { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
- wpas_dbus_getter_fast_reauth,
- wpas_dbus_setter_fast_reauth,
- NULL
- },
- { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
- wpas_dbus_getter_scan_interval,
- wpas_dbus_setter_scan_interval,
- NULL
- },
- { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_pkcs11_engine_path,
- NULL,
- NULL
- },
- { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
- wpas_dbus_getter_pkcs11_module_path,
- NULL,
- NULL
- },
-#ifdef CONFIG_WPS
- { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
- wpas_dbus_getter_process_credentials,
- wpas_dbus_setter_process_credentials,
- NULL
- },
- { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_config_methods,
- wpas_dbus_setter_config_methods,
- NULL
- },
- {
- "DeviceName", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_wps_device_name,
- wpas_dbus_setter_wps_device_name,
- NULL
- },
- {
- "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_wps_manufacturer,
- wpas_dbus_setter_wps_manufacturer,
- NULL
- },
- {
- "ModelName", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_wps_device_model_name,
- wpas_dbus_setter_wps_device_model_name,
- NULL
- },
- {
- "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_wps_device_model_number,
- wpas_dbus_setter_wps_device_model_number,
- NULL
- },
- {
- "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
- wpas_dbus_getter_wps_device_serial_number,
- wpas_dbus_setter_wps_device_serial_number,
- NULL
- },
- {
- "DeviceType", WPAS_DBUS_NEW_IFACE_WPS, "ay",
- wpas_dbus_getter_wps_device_device_type,
- wpas_dbus_setter_wps_device_device_type,
- NULL
- },
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
- wpas_dbus_getter_p2p_device_config,
- wpas_dbus_setter_p2p_device_config,
- NULL
- },
- { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
- wpas_dbus_getter_p2p_peers,
- NULL,
- NULL
- },
- { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
- wpas_dbus_getter_p2p_role,
- NULL,
- NULL
- },
- { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
- wpas_dbus_getter_p2p_group,
- NULL,
- NULL
- },
- { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
- wpas_dbus_getter_p2p_peergo,
- NULL,
- NULL
- },
- { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
- wpas_dbus_getter_persistent_groups,
- NULL,
- NULL
- },
-#endif /* CONFIG_P2P */
- { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
- wpas_dbus_getter_disconnect_reason,
- NULL,
- NULL
- },
- { "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
- wpas_dbus_getter_auth_status_code,
- NULL,
- NULL
- },
- { "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
- wpas_dbus_getter_assoc_status_code,
- NULL,
- NULL
- },
- {
- "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_roam_time,
- NULL,
- NULL
- },
- {
- "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
- wpas_dbus_getter_roam_complete,
- NULL,
- NULL
- },
- {
- "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_session_length,
- NULL,
- NULL
- },
- {
- "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
- wpas_dbus_getter_bss_tm_status,
- NULL,
- NULL
- },
-#ifdef CONFIG_MESH
- { "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH, "aay",
- wpas_dbus_getter_mesh_peers,
- NULL,
- NULL
- },
- { "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH, "ay",
- wpas_dbus_getter_mesh_group,
- NULL,
- NULL
- },
-#endif /* CONFIG_MESH */
- { "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
- wpas_dbus_getter_stas,
- NULL,
- NULL
- },
- { "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
- "a{say}",
- wpas_dbus_getter_mac_address_randomization_mask,
- wpas_dbus_setter_mac_address_randomization_mask,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
- { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "success", "b", ARG_OUT },
- END_ARGS
- }
- },
- { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "name", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "name", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
-#ifdef CONFIG_WPS
- { "Event", WPAS_DBUS_NEW_IFACE_WPS,
- {
- { "name", "s", ARG_OUT },
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
- {
- { "credentials", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- END_ARGS
- }
- },
- { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- { "pin", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- { "pin", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "peer_object", "o", ARG_OUT },
- { "status", "i", ARG_OUT },
- END_ARGS
- }
- },
- { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "reason", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- { "dev_passwd_id", "q", ARG_OUT },
- { "device_go_intent", "y", ARG_OUT },
- END_ARGS
- }
- },
- { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "invite_result", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "sd_request", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "sd_response", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "name", "s", ARG_OUT },
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_AP
- { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
-#endif /* CONFIG_AP */
- { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "certification", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "status", "s", ARG_OUT },
- { "parameter", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "name", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "name", "s", ARG_OUT },
- END_ARGS
- }
- },
- { "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "path", "o", ARG_OUT },
- { "field", "s", ARG_OUT },
- { "text", "s", ARG_OUT },
- END_ARGS
- }
- },
-#ifdef CONFIG_MESH
- { "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH,
- {
- { "args", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_INTERWORKING
- { "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- { "bss", "o", ARG_OUT },
- { "cred", "o", ARG_OUT },
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
- {
- END_ARGS
- }
- },
-#endif /* CONFIG_INTERWORKING */
- { NULL, NULL, { END_ARGS } }
-};
-
-
-static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
-{
- size_t all_size;
- unsigned int i, j, count, num_const, num_globals;
- const char *global_name;
- static const char * const ignored_globals[] = {
- "bss_expiration_age", "bss_expiration_scan_count",
- "ap_scan", "country", "fast_reauth",
- "pkcs11_engine_path", "pkcs11_module_path"
- };
-
- /* wpas_dbus_interface_properties terminates with a NULL element */
- num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
-
- num_globals = wpa_config_get_num_global_field_names();
- priv->globals_start = num_const;
-
- /* allocate enough for all properties + terminating NULL element */
- all_size = (num_globals + num_const + 1) *
- sizeof(wpas_dbus_interface_properties[0]);
- priv->all_interface_properties = os_zalloc(all_size);
- if (!priv->all_interface_properties) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory for interface properties");
- return -1;
- }
-
- /* Copy constant interface properties to the start of the array */
- os_memcpy(priv->all_interface_properties,
- wpas_dbus_interface_properties,
- sizeof(wpas_dbus_interface_properties));
-
- /* Dynamically construct interface global properties */
- for (i = 0, count = num_const; i < num_globals; i++) {
- struct wpa_dbus_property_desc *desc;
- int no_var = 0;
-
- /* ignore globals that are actually just methods */
- global_name = wpa_config_get_global_field_name(i, &no_var);
- if (no_var)
- continue;
- /* Ignore fields already explicitly exposed */
- for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
- if (os_strcmp(global_name, ignored_globals[j]) == 0)
- break;
- }
- if (j < ARRAY_SIZE(ignored_globals))
- continue;
-
- desc = &priv->all_interface_properties[count++];
- desc->dbus_property = uscore_to_dbus(global_name);
- if (!desc->dbus_property) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory for D-Bus property name");
- goto error;
- }
- desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
- desc->type = "s";
- desc->getter = wpas_dbus_getter_iface_global;
- desc->setter = wpas_dbus_setter_iface_global;
- desc->data = global_name;
- }
-
- return 0;
-
-error:
- wpa_dbus_ctrl_iface_props_deinit(priv);
- return -1;
-}
-
-
-/**
- * wpas_dbus_register_interface - Register an interface with D-Bus
- * @wpa_s: wpa_supplicant interface structure
- * Returns: 0 on success, -1 on failure
- */
-int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
-{
- struct wpa_dbus_object_desc *obj_desc = NULL;
- struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
- int next;
-
- /* Do nothing if the control interface is not turned on */
- if (ctrl_iface == NULL)
- return 0;
-
- /* Create and set the interface's object path */
- wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (wpa_s->dbus_new_path == NULL)
- return -1;
- next = ctrl_iface->next_objid++;
- os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
- WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
- next);
-
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
- ctrl_iface->all_interface_properties,
- wpas_dbus_interface_signals);
-
- wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
- wpa_s->dbus_new_path);
- if (wpa_dbus_register_object_per_iface(ctrl_iface,
- wpa_s->dbus_new_path,
- wpa_s->ifname, obj_desc))
- goto err;
-
- wpas_dbus_signal_interface_added(wpa_s);
-
- return 0;
-
-err:
- os_free(wpa_s->dbus_new_path);
- wpa_s->dbus_new_path = NULL;
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-
-/**
- * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
- * @wpa_s: wpa_supplicant interface structure
- * Returns: 0 on success, -1 on failure
- */
-int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *ctrl_iface;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
- return 0;
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
- wpa_s->dbus_new_path);
-
-#ifdef CONFIG_AP
- if (wpa_s->preq_notify_peer) {
- wpas_dbus_unsubscribe_noc(ctrl_iface);
- os_free(wpa_s->preq_notify_peer);
- wpa_s->preq_notify_peer = NULL;
- }
-#endif /* CONFIG_AP */
-
- if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
- wpa_s->dbus_new_path))
- return -1;
-
- wpas_dbus_signal_interface_removed(wpa_s);
-
- os_free(wpa_s->dbus_new_path);
- wpa_s->dbus_new_path = NULL;
-
- return 0;
-}
-
-#ifdef CONFIG_P2P
-
-static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
- { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
- wpas_dbus_getter_p2p_peer_device_name,
- NULL,
- NULL
- },
- { "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
- wpas_dbus_getter_p2p_peer_manufacturer,
- NULL,
- NULL
- },
- { "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
- wpas_dbus_getter_p2p_peer_modelname,
- NULL,
- NULL
- },
- { "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
- wpas_dbus_getter_p2p_peer_modelnumber,
- NULL,
- NULL
- },
- { "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
- wpas_dbus_getter_p2p_peer_serialnumber,
- NULL,
- NULL
- },
- { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
- wpas_dbus_getter_p2p_peer_primary_device_type,
- NULL,
- NULL
- },
- { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
- wpas_dbus_getter_p2p_peer_config_method,
- NULL,
- NULL
- },
- { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
- wpas_dbus_getter_p2p_peer_level,
- NULL,
- NULL
- },
- { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
- wpas_dbus_getter_p2p_peer_device_capability,
- NULL,
- NULL
- },
- { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
- wpas_dbus_getter_p2p_peer_group_capability,
- NULL,
- NULL
- },
- { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
- wpas_dbus_getter_p2p_peer_secondary_device_types,
- NULL,
- NULL
- },
- { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
- wpas_dbus_getter_p2p_peer_vendor_extension,
- NULL,
- NULL
- },
- { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
- wpas_dbus_getter_p2p_peer_ies,
- NULL,
- NULL
- },
- { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
- wpas_dbus_getter_p2p_peer_device_address,
- NULL,
- NULL
- },
- { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
- wpas_dbus_getter_p2p_peer_groups,
- NULL,
- NULL
- },
- { "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
- wpas_dbus_getter_p2p_peer_vsie,
- NULL,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
- /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
- { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
- {
- { "properties", "a{sv}", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-/**
- * wpas_dbus_signal_peer - Send a peer related event signal
- * @wpa_s: %wpa_supplicant network interface data
- * @dev: peer device object
- * @interface: name of the interface emitting this signal.
- * In case of peer objects, it would be emitted by either
- * the "interface object" or by "peer objects"
- * @sig_name: signal name - DeviceFound
- * @properties: Whether to add a second argument with object properties
- *
- * Notify listeners about event related with p2p peer device
- */
-static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, const char *interface,
- const char *sig_name, dbus_bool_t properties)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
- DBusMessageIter iter;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL || !wpa_s->dbus_new_path)
- return;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(dev_addr));
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
- sig_name);
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &iter);
- path = peer_obj_path;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path) ||
- (properties && !wpa_dbus_get_object_properties(
- iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
- &iter)))
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
- else
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_peer_found - Send a peer found signal
- * @wpa_s: %wpa_supplicant network interface data
- * @dev_addr: Peer P2P Device Address
- *
- * Notify listeners about find a p2p peer device found
- */
-void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- wpas_dbus_signal_peer(wpa_s, dev_addr,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "DeviceFound", FALSE);
-
- wpas_dbus_signal_peer(wpa_s, dev_addr,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "DeviceFoundProperties", TRUE);
-}
-
-/**
- * wpas_dbus_signal_peer_lost - Send a peer lost signal
- * @wpa_s: %wpa_supplicant network interface data
- * @dev_addr: Peer P2P Device Address
- *
- * Notify listeners about lost a p2p peer device
- */
-void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- wpas_dbus_signal_peer(wpa_s, dev_addr,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "DeviceLost", FALSE);
-}
-
-/**
- * wpas_dbus_register_peer - Register a discovered peer object with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @dev_addr: P2P Device Address of the peer
- * Returns: 0 on success, -1 on failure
- *
- * Registers network representing object with dbus
- */
-int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- struct peer_handler_args *arg;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- wpa_s = wpa_s->parent->parent;
- if (!wpa_s->dbus_new_path)
- return 0;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(dev_addr));
-
- wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
- peer_obj_path);
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- /* allocate memory for handlers arguments */
- arg = os_zalloc(sizeof(struct peer_handler_args));
- if (!arg) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create arguments for method");
- goto err;
- }
-
- arg->wpa_s = wpa_s;
- os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
-
- wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
- NULL,
- wpas_dbus_p2p_peer_properties,
- wpas_dbus_p2p_peer_signals);
-
- if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
- wpa_s->ifname, obj_desc))
- goto err;
-
- return 0;
-
-err:
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-/**
- * wpas_dbus_unregister_peer - Unregister a peer object with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @dev_addr: p2p device addr
- * Returns: 0 on success, -1 on failure
- *
- * Registers network representing object with dbus
- */
-int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- struct wpas_dbus_priv *ctrl_iface;
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- int ret;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
-
- wpa_s = wpa_s->parent->parent;
- if (!wpa_s->dbus_new_path)
- return 0;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(dev_addr));
-
- wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
- peer_obj_path);
- ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
-
- return ret;
-}
-
-
-/**
- * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
- * @wpa_s: %wpa_supplicant network interface data
- *
- * Notify listeners about P2P Find stopped
- */
-void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *iface;
- DBusMessage *msg;
-
- iface = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (iface == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- if (!wpa_s->dbus_new_path)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_P2PDEVICE,
- "FindStopped");
- if (msg == NULL)
- return;
-
- dbus_connection_send(iface->con, msg, NULL);
-
- dbus_message_unref(msg);
-}
-
-
-/**
- * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
- * @wpa_s: %wpa_supplicant network interface data
- * @dev_addr: P2P Device Address
- *
- * Notify listeners about peer Groups property changes.
- */
-void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- if (!wpa_s->dbus_new_path)
- return;
- os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(dev_addr));
-
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
- WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
-}
-
-
-static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
- { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
- wpas_dbus_getter_p2p_group_members,
- NULL,
- NULL
- },
- { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
- wpas_dbus_getter_p2p_group,
- NULL,
- NULL
- },
- { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
- wpas_dbus_getter_p2p_role,
- NULL,
- NULL
- },
- { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
- wpas_dbus_getter_p2p_group_ssid,
- NULL,
- NULL
- },
- { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
- wpas_dbus_getter_p2p_group_bssid,
- NULL,
- NULL
- },
- { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
- wpas_dbus_getter_p2p_group_frequency,
- NULL,
- NULL
- },
- { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
- wpas_dbus_getter_p2p_group_passphrase,
- NULL,
- NULL
- },
- { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
- wpas_dbus_getter_p2p_group_psk,
- NULL,
- NULL
- },
- { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
- wpas_dbus_getter_p2p_group_vendor_ext,
- wpas_dbus_setter_p2p_group_vendor_ext,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
- { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
- {
- { "peer", "o", ARG_OUT },
- END_ARGS
- }
- },
- { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
- {
- { "peer", "o", ARG_OUT },
- END_ARGS
- }
- },
- { NULL, NULL, { END_ARGS } }
-};
-
-/**
- * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @ssid: SSID struct
- * Returns: 0 on success, -1 on failure
- *
- * Registers p2p group representing object with dbus
- */
-void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return;
-
- if (wpa_s->dbus_groupobj_path) {
- wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
- __func__, wpa_s->dbus_groupobj_path);
- return;
- }
-
- if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
- return;
-
- wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
- if (wpa_s->dbus_groupobj_path == NULL)
- return;
-
- wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
- group_obj_path);
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "Not enough memory to create object description");
- goto err;
- }
-
- wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
- wpas_dbus_p2p_group_properties,
- wpas_dbus_p2p_group_signals);
-
- if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
- wpa_s->ifname, obj_desc))
- goto err;
-
- return;
-
-err:
- if (wpa_s->dbus_groupobj_path) {
- os_free(wpa_s->dbus_groupobj_path);
- wpa_s->dbus_groupobj_path = NULL;
- }
-
- free_dbus_object_desc(obj_desc);
-}
-
-/**
- * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
- * @wpa_s: wpa_supplicant interface structure
- * @ssid: network name of the p2p group started
- */
-void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid)
-{
- struct wpas_dbus_priv *ctrl_iface;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return;
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return;
-
- if (!wpa_s->dbus_groupobj_path) {
- wpa_printf(MSG_DEBUG,
- "%s: Group object has already unregistered",
- __func__);
- return;
- }
-
- peer_groups_changed(wpa_s);
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
- wpa_s->dbus_groupobj_path);
-
- wpa_dbus_unregister_object_per_iface(ctrl_iface,
- wpa_s->dbus_groupobj_path);
-
- os_free(wpa_s->dbus_groupobj_path);
- wpa_s->dbus_groupobj_path = NULL;
-}
-
-static const struct wpa_dbus_property_desc
- wpas_dbus_persistent_group_properties[] = {
- { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
- wpas_dbus_getter_persistent_group_properties,
- wpas_dbus_setter_persistent_group_properties,
- NULL
- },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/* No signals intended for persistent group objects */
-
-/**
- * wpas_dbus_register_persistent_group - Register a configured(saved)
- * persistent group with dbus
- * @wpa_s: wpa_supplicant interface structure
- * @ssid: persistent group (still represented as a network within wpa)
- * configuration data
- * Returns: 0 on success, -1 on failure
- *
- * Registers a persistent group representing object with dbus.
- */
-int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpas_dbus_priv *ctrl_iface;
- struct wpa_dbus_object_desc *obj_desc;
- struct network_handler_args *arg;
- char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
- wpa_s = wpa_s->parent->parent;
- if (!wpa_s->dbus_new_path)
- return 0;
-
- /* Make sure ssid is a persistent group */
- if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
- return -1; /* should we return w/o complaining? */
-
- if (wpa_s->p2p_mgmt)
- wpa_s = wpa_s->parent;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL)
- return 0;
-
- /*
- * Intentionally not coming up with different numbering scheme
- * for persistent groups.
- */
- os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
- wpa_s->dbus_new_path, ssid->id);
-
- wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
- pgrp_obj_path);
- obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to create object description");
- goto err;
- }
-
- /*
- * Reusing the same context structure as that for networks
- * since these are represented using same data structure.
- */
- /* allocate memory for handlers arguments */
- arg = os_zalloc(sizeof(struct network_handler_args));
- if (!arg) {
- wpa_printf(MSG_ERROR,
- "dbus: Not enough memory to create arguments for method");
- goto err;
- }
-
- arg->wpa_s = wpa_s;
- arg->ssid = ssid;
-
- wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
- wpas_dbus_persistent_group_properties,
- NULL);
-
- if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
- wpa_s->ifname, obj_desc))
- goto err;
-
- wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
-
- return 0;
-
-err:
- free_dbus_object_desc(obj_desc);
- return -1;
-}
-
-
-/**
- * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
- * from dbus
- * @wpa_s: wpa_supplicant interface structure
- * @nid: network id
- * Returns: 0 on success, -1 on failure
- *
- * Unregisters persistent group representing object from dbus
- *
- * NOTE: There is a slight issue with the semantics here. While the
- * implementation simply means the persistent group is unloaded from memory,
- * it should not get interpreted as the group is actually being erased/removed
- * from persistent storage as well.
- */
-int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
- int nid)
-{
- struct wpas_dbus_priv *ctrl_iface;
- char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- int ret;
-
- /* Do nothing if the control interface is not turned on */
- if (wpa_s == NULL || wpa_s->global == NULL)
- return 0;
-
- wpa_s = wpa_s->parent->parent;
-
- ctrl_iface = wpa_s->global->dbus;
- if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
- return 0;
-
- os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
- wpa_s->dbus_new_path, nid);
-
- wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
- pgrp_obj_path);
- ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
-
- if (!ret)
- wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
-
- return ret;
-}
-
-#endif /* CONFIG_P2P */
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
deleted file mode 100644
index 26bdcb548de8..000000000000
--- a/wpa_supplicant/dbus/dbus_new.h
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_NEW_H
-#define CTRL_IFACE_DBUS_NEW_H
-
-#include "common/defs.h"
-#include "p2p/p2p.h"
-
-struct wpa_global;
-struct wpa_supplicant;
-struct wpa_ssid;
-struct wpa_cred;
-struct wpa_bss;
-struct wps_event_m2d;
-struct wps_event_fail;
-struct wps_credential;
-
-enum wpas_dbus_prop {
- WPAS_DBUS_PROP_AP_SCAN,
- WPAS_DBUS_PROP_SCANNING,
- WPAS_DBUS_PROP_STATE,
- WPAS_DBUS_PROP_CURRENT_BSS,
- WPAS_DBUS_PROP_CURRENT_NETWORK,
- WPAS_DBUS_PROP_CURRENT_AUTH_MODE,
- WPAS_DBUS_PROP_BSSS,
- WPAS_DBUS_PROP_STATIONS,
- WPAS_DBUS_PROP_DISCONNECT_REASON,
- WPAS_DBUS_PROP_AUTH_STATUS_CODE,
- WPAS_DBUS_PROP_ASSOC_STATUS_CODE,
- WPAS_DBUS_PROP_ROAM_TIME,
- WPAS_DBUS_PROP_ROAM_COMPLETE,
- WPAS_DBUS_PROP_SESSION_LENGTH,
- WPAS_DBUS_PROP_BSS_TM_STATUS,
-};
-
-enum wpas_dbus_bss_prop {
- WPAS_DBUS_BSS_PROP_SIGNAL,
- WPAS_DBUS_BSS_PROP_FREQ,
- WPAS_DBUS_BSS_PROP_MODE,
- WPAS_DBUS_BSS_PROP_PRIVACY,
- WPAS_DBUS_BSS_PROP_RATES,
- WPAS_DBUS_BSS_PROP_WPA,
- WPAS_DBUS_BSS_PROP_RSN,
- WPAS_DBUS_BSS_PROP_WPS,
- WPAS_DBUS_BSS_PROP_IES,
- WPAS_DBUS_BSS_PROP_AGE,
-};
-
-enum wpas_dbus_sta_prop {
- WPAS_DBUS_STA_PROP_ADDRESS,
-};
-
-#define WPAS_DBUS_OBJECT_PATH_MAX 150
-
-#define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1"
-#define WPAS_DBUS_NEW_PATH "/fi/w1/wpa_supplicant1"
-#define WPAS_DBUS_NEW_INTERFACE "fi.w1.wpa_supplicant1"
-
-#define WPAS_DBUS_NEW_PATH_INTERFACES WPAS_DBUS_NEW_PATH "/Interfaces"
-#define WPAS_DBUS_NEW_IFACE_INTERFACE WPAS_DBUS_NEW_INTERFACE ".Interface"
-#define WPAS_DBUS_NEW_IFACE_WPS WPAS_DBUS_NEW_IFACE_INTERFACE ".WPS"
-
-#define WPAS_DBUS_NEW_NETWORKS_PART "Networks"
-#define WPAS_DBUS_NEW_IFACE_NETWORK WPAS_DBUS_NEW_INTERFACE ".Network"
-
-#define WPAS_DBUS_NEW_BSSIDS_PART "BSSs"
-#define WPAS_DBUS_NEW_IFACE_BSS WPAS_DBUS_NEW_INTERFACE ".BSS"
-
-#define WPAS_DBUS_NEW_STAS_PART "Stations"
-#define WPAS_DBUS_NEW_IFACE_STA WPAS_DBUS_NEW_INTERFACE ".Station"
-
-#define WPAS_DBUS_NEW_IFACE_P2PDEVICE \
- WPAS_DBUS_NEW_IFACE_INTERFACE ".P2PDevice"
-
-#define WPAS_DBUS_NEW_IFACE_MESH WPAS_DBUS_NEW_IFACE_INTERFACE ".Mesh"
-
-/*
- * Groups correspond to P2P groups where this device is a GO (owner)
- */
-#define WPAS_DBUS_NEW_P2P_GROUPS_PART "Groups"
-#define WPAS_DBUS_NEW_IFACE_P2P_GROUP WPAS_DBUS_NEW_INTERFACE ".Group"
-
-/*
- * Different dbus object for persistent groups so they do not get confused
- * with regular (configured) network objects.
- */
-#define WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "PersistentGroups"
-#define WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP \
- WPAS_DBUS_NEW_INTERFACE ".PersistentGroup"
-
-#define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers"
-#define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
-
-#define WPAS_DBUS_NEW_CREDENTIALS_PART "Credentials"
-#define WPAS_DBUS_NEW_IFACE_CREDENTIAL WPAS_DBUS_NEW_INTERFACE ".Credential"
-
-/* Top-level Errors */
-#define WPAS_DBUS_ERROR_UNKNOWN_ERROR \
- WPAS_DBUS_NEW_INTERFACE ".UnknownError"
-#define WPAS_DBUS_ERROR_INVALID_ARGS \
- WPAS_DBUS_NEW_INTERFACE ".InvalidArgs"
-
-#define WPAS_DBUS_ERROR_IFACE_EXISTS \
- WPAS_DBUS_NEW_INTERFACE ".InterfaceExists"
-#define WPAS_DBUS_ERROR_IFACE_DISABLED \
- WPAS_DBUS_NEW_INTERFACE ".InterfaceDisabled"
-#define WPAS_DBUS_ERROR_IFACE_UNKNOWN \
- WPAS_DBUS_NEW_INTERFACE ".InterfaceUnknown"
-
-#define WPAS_DBUS_ERROR_NOT_CONNECTED \
- WPAS_DBUS_NEW_INTERFACE ".NotConnected"
-#define WPAS_DBUS_ERROR_NETWORK_UNKNOWN \
- WPAS_DBUS_NEW_INTERFACE ".NetworkUnknown"
-
-#define WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE \
- WPAS_DBUS_NEW_INTERFACE ".ConnectChannelUnavailable"
-#define WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED \
- WPAS_DBUS_NEW_INTERFACE ".ConnectChannelUnsupported"
-#define WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR \
- WPAS_DBUS_NEW_INTERFACE ".ConnectUnspecifiedError"
-
-#define WPAS_DBUS_ERROR_BLOB_EXISTS \
- WPAS_DBUS_NEW_INTERFACE ".BlobExists"
-#define WPAS_DBUS_ERROR_BLOB_UNKNOWN \
- WPAS_DBUS_NEW_INTERFACE ".BlobUnknown"
-
-#define WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE \
- WPAS_DBUS_NEW_INTERFACE ".SubscriptionInUse"
-#define WPAS_DBUS_ERROR_NO_SUBSCRIPTION \
- WPAS_DBUS_NEW_INTERFACE ".NoSubscription"
-#define WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM \
- WPAS_DBUS_NEW_INTERFACE ".SubscriptionNotYou"
-
-/* Interface-level errors */
-#define WPAS_DBUS_ERROR_IFACE_SCAN_ERROR \
- WPAS_DBUS_NEW_IFACE_INTERFACE ".ScanError"
-
-void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv);
-void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv);
-
-
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
-
-int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv);
-void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface);
-
-int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s);
-int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s);
-void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_prop property);
-void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_bss_prop property,
- unsigned int id);
-void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id);
-void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- enum wpa_ctrl_req_type rtype,
- const char *default_text);
-void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success);
-void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred);
-void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d);
-void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail);
-void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s);
-void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s);
-int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid);
-int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id);
-int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id);
-int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta);
-int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta);
-void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
- const char *name);
-void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
- const char *name);
-void wpas_dbus_signal_debug_level_changed(struct wpa_global *global);
-void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global);
-void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global);
-
-int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr);
-void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s);
-void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
- const char *role);
-void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int request,
- enum p2p_prov_disc_status status,
- u16 config_methods,
- unsigned int generated_pin);
-void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
- const u8 *src, u16 dev_passwd_id,
- u8 go_intent);
-void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
- int client, int persistent,
- const u8 *ip);
-void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
- const char *reason);
-void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res);
-void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid);
-int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
- int nid);
-void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
- int status, const u8 *bssid);
-void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *member);
-void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
- int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs,
- size_t tlvs_len);
-void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len);
-void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
- const u8 *member);
-void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail);
-void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
- int depth, const char *subject,
- const char *altsubject[],
- int num_altsubject,
- const char *cert_hash,
- const struct wpabuf *cert);
-void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len, u32 ssi_signal);
-void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
- const char *status, const char *parameter);
-void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta);
-void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
- const u8 *sta);
-void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *dev_addr,
- const u8 *bssid, int id,
- int op_freq);
-void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
- const u8 *meshid, u8 meshid_len,
- int reason);
-void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr);
-void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, int reason);
-void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_cred *cred,
- const char *type, int excluded,
- int bh, int bss_load,
- int conn_capab);
-void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s);
-
-#else /* CONFIG_CTRL_IFACE_DBUS_NEW */
-
-static inline int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-#define wpas_dbus_signal_state_changed(w, n, o) do { } while (0)
-
-static inline void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
- enum wpas_dbus_prop property)
-{
-}
-
-static inline void wpas_dbus_bss_signal_prop_changed(
- struct wpa_supplicant *wpa_s, enum wpas_dbus_bss_prop property,
- unsigned int id)
-{
-}
-
-static inline void wpas_dbus_signal_network_enabled_changed(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-}
-
-static inline void wpas_dbus_signal_network_selected(
- struct wpa_supplicant *wpa_s, int id)
-{
-}
-
-static inline void wpas_dbus_signal_network_request(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- enum wpa_ctrl_req_type rtype, const char *default_txt)
-{
-}
-
-static inline void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
- int success)
-{
-}
-
-static inline void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
-}
-
-static inline void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d)
-{
-}
-
-static inline void wpas_dbus_signal_wps_event_fail(
- struct wpa_supplicant *wpa_s, struct wps_event_fail *fail)
-{
-}
-
-static inline void wpas_dbus_signal_wps_event_success(
- struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_dbus_signal_wps_event_pbc_overlap(
- struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s,
- int nid)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id)
-{
- return 0;
-}
-
-static inline int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
- u8 bssid[ETH_ALEN], unsigned int id)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
- return 0;
-}
-
-static inline int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
- return 0;
-}
-
-static inline void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
- const char *name)
-{
-}
-
-static inline void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
- const char *name)
-{
-}
-
-static inline void wpas_dbus_signal_debug_level_changed(
- struct wpa_global *global)
-{
-}
-
-static inline void wpas_dbus_signal_debug_timestamp_changed(
- struct wpa_global *global)
-{
-}
-
-static inline void wpas_dbus_signal_debug_show_keys_changed(
- struct wpa_global *global)
-{
-}
-
-static inline int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- return 0;
-}
-
-static inline void
-wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
- const char *role)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int request,
- enum p2p_prov_disc_status status,
- u16 config_methods,
- unsigned int generated_pin)
-{
-}
-
-static inline void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
- const u8 *src,
- u16 dev_passwd_id,
- u8 go_intent)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
- int client, int persistent,
- const u8 *ip)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
- const char *reason)
-{
-}
-
-static inline void
-wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-}
-
-static inline int wpas_dbus_register_persistent_group(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-static inline int wpas_dbus_unregister_persistent_group(
- struct wpa_supplicant *wpa_s, int nid)
-{
- return 0;
-}
-
-static inline void
-wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res)
-{
-}
-
-static inline void
-wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid)
-{
-}
-
-static inline void wpas_dbus_signal_p2p_invitation_result(
- struct wpa_supplicant *wpa_s, int status,
- const u8 *bssid)
-{
-}
-
-static inline void
-wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
- const u8 *p2p_if_addr)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s, int freq,
- const u8 *sa, u8 dialog_token, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
-}
-
-static inline void
-wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
- const u8 *p2p_if_addr)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
- const u8 *member)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
-}
-
-static inline void
-wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *member)
-{
-}
-
-static inline void
-wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
-}
-
-static inline void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
- int depth,
- const char *subject,
- const char *altsubject[],
- int num_altsubject,
- const char *cert_hash,
- const struct wpabuf *cert)
-{
-}
-
-static inline void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *dst,
- const u8 *bssid,
- const u8 *ie, size_t ie_len,
- u32 ssi_signal)
-{
-}
-
-static inline void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
- const char *status,
- const char *parameter)
-{
-}
-
-static inline
-void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
-}
-
-static inline
-void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
- const u8 *sta)
-{
-}
-
-static inline
-void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *dev_addr,
- const u8 *bssid, int id,
- int op_freq)
-{
-}
-
-static inline
-void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-}
-
-static inline
-void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
- const u8 *meshid, u8 meshid_len,
- int reason)
-{
-}
-
-static inline
-void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
-}
-
-static inline
-void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, int reason)
-{
-}
-
-static inline
-void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_cred *cred,
- const char *type, int excluded,
- int bh, int bss_load,
- int conn_capab)
-{
-}
-
-static inline
-void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
-{
-}
-
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-
-#endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
deleted file mode 100644
index 545e9f64295a..000000000000
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ /dev/null
@@ -1,5926 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "common/ieee802_11_defs.h"
-#include "eap_peer/eap_methods.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "ap/hostapd.h"
-#include "ap/sta_info.h"
-#include "ap/ap_drv_ops.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../driver_i.h"
-#include "../notify.h"
-#include "../bss.h"
-#include "../scan.h"
-#include "../autoscan.h"
-#include "../ap.h"
-#include "../interworking.h"
-#include "dbus_new_helpers.h"
-#include "dbus_new.h"
-#include "dbus_new_handlers.h"
-#include "dbus_dict_helpers.h"
-#include "dbus_common_i.h"
-#include "drivers/driver.h"
-#ifdef CONFIG_MESH
-#include "ap/hostapd.h"
-#include "ap/sta_info.h"
-#endif /* CONFIG_MESH */
-
-static const char * const debug_strings[] = {
- "excessive", "msgdump", "debug", "info", "warning", "error", NULL
-};
-
-
-/**
- * wpas_dbus_error_unknown_error - Return a new UnknownError error message
- * @message: Pointer to incoming dbus message this error refers to
- * @arg: Optional string appended to error message
- * Returns: a dbus error message
- *
- * Convenience function to create and return an UnknownError
- */
-DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
- const char *arg)
-{
- return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
- arg);
-}
-
-
-/**
- * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: A dbus error message
- *
- * Convenience function to create and return an invalid interface error
- */
-static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
-{
- return dbus_message_new_error(
- message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
- "wpa_supplicant knows nothing about this interface.");
-}
-
-
-/**
- * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid network error
- */
-static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
-{
- return dbus_message_new_error(
- message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
- "There is no such a network in this interface.");
-}
-
-
-/**
- * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid options error
- */
-DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
- const char *arg)
-{
- DBusMessage *reply;
-
- reply = dbus_message_new_error(
- message, WPAS_DBUS_ERROR_INVALID_ARGS,
- "Did not receive correct message arguments.");
- if (arg != NULL)
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
- DBUS_TYPE_INVALID);
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_error_scan_error - Return a new ScanError error message
- * @message: Pointer to incoming dbus message this error refers to
- * @error: Optional string to be used as the error message
- * Returns: a dbus error message
- *
- * Convenience function to create and return a scan error
- */
-static DBusMessage * wpas_dbus_error_scan_error(DBusMessage *message,
- const char *error)
-{
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_IFACE_SCAN_ERROR,
- error);
-}
-
-
-DBusMessage * wpas_dbus_error_no_memory(DBusMessage *message)
-{
- wpa_printf(MSG_DEBUG, "dbus: Failed to allocate memory");
- return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
-}
-
-
-static const char * const dont_quote[] = {
- "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
- "bssid", "scan_freq", "freq_list", "scan_ssid", "bssid_hint",
- "bssid_ignore", "bssid_accept", /* deprecated aliases */
- "bssid_blacklist", "bssid_whitelist",
- "group_mgmt",
- "ignore_broadcast_ssid",
-#ifdef CONFIG_MESH
- "mesh_basic_rates",
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_P2P
- "go_p2p_dev_addr", "p2p_client_list", "psk_list",
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_INTERWORKING
- "roaming_consortium", "required_roaming_consortium",
-#endif /* CONFIG_INTERWORKING */
- NULL
-};
-
-static dbus_bool_t should_quote_opt(const char *key)
-{
- int i = 0;
-
- while (dont_quote[i] != NULL) {
- if (os_strcmp(key, dont_quote[i]) == 0)
- return FALSE;
- i++;
- }
- return TRUE;
-}
-
-/**
- * get_iface_by_dbus_path - Get a new network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @path: Pointer to a dbus object path representing an interface
- * Returns: Pointer to the interface or %NULL if not found
- */
-static struct wpa_supplicant * get_iface_by_dbus_path(
- struct wpa_global *global, const char *path)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->dbus_new_path &&
- os_strcmp(wpa_s->dbus_new_path, path) == 0)
- return wpa_s;
- }
- return NULL;
-}
-
-
-/**
- * set_network_properties - Set properties of a configured network
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network
- * @iter: DBus message iterator containing dictionary of network
- * properties to set.
- * @error: On failure, an error describing the failure
- * Returns: TRUE if the request succeeds, FALSE if it failed
- *
- * Sets network configuration with parameters given id DBus dictionary
- */
-dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- DBusMessageIter *iter,
- DBusError *error)
-{
- struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- DBusMessageIter iter_dict;
- char *value = NULL;
-
- if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
- return FALSE;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- size_t size = 50;
- int ret;
-
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- value = NULL;
- if (entry.type == DBUS_TYPE_ARRAY &&
- entry.array_type == DBUS_TYPE_BYTE) {
- if (entry.array_len <= 0)
- goto error;
-
- size = entry.array_len * 2 + 1;
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
-
- ret = wpa_snprintf_hex(value, size,
- (u8 *) entry.bytearray_value,
- entry.array_len);
- if (ret <= 0)
- goto error;
- } else if (entry.type == DBUS_TYPE_STRING) {
- if (should_quote_opt(entry.key)) {
- size = os_strlen(entry.str_value);
-
- size += 3;
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
-
- ret = os_snprintf(value, size, "\"%s\"",
- entry.str_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else {
- value = os_strdup(entry.str_value);
- if (value == NULL)
- goto error;
- }
- } else if (entry.type == DBUS_TYPE_UINT32) {
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
-
- ret = os_snprintf(value, size, "%u",
- entry.uint32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else if (entry.type == DBUS_TYPE_INT32) {
- value = os_zalloc(size);
- if (value == NULL)
- goto error;
-
- ret = os_snprintf(value, size, "%d",
- entry.int32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else
- goto error;
-
- ret = wpa_config_set(ssid, entry.key, value, 0);
- if (ret < 0)
- goto error;
- if (ret == 1)
- goto skip_update;
-
-#ifdef CONFIG_BGSCAN
- if (os_strcmp(entry.key, "bgscan") == 0) {
- /*
- * Reset the bgscan parameters for the current network
- * and continue. There's no need to flush caches for
- * bgscan parameter changes.
- */
- if (wpa_s->current_ssid == ssid &&
- wpa_s->wpa_state == WPA_COMPLETED)
- wpa_supplicant_reset_bgscan(wpa_s);
- os_free(value);
- value = NULL;
- wpa_dbus_dict_entry_clear(&entry);
- continue;
- }
-#endif /* CONFIG_BGSCAN */
-
- if (os_strcmp(entry.key, "bssid") != 0 &&
- os_strcmp(entry.key, "priority") != 0)
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
-
- if (wpa_s->current_ssid == ssid ||
- wpa_s->current_ssid == NULL) {
- /*
- * Invalidate the EAP session cache if anything in the
- * current or previously used configuration changes.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
-
- if ((os_strcmp(entry.key, "psk") == 0 &&
- value[0] == '"' && ssid->ssid_len) ||
- (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
- wpa_config_update_psk(ssid);
- else if (os_strcmp(entry.key, "priority") == 0)
- wpa_config_update_prio_list(wpa_s->conf);
-
- skip_update:
- os_free(value);
- value = NULL;
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- return TRUE;
-
-error:
- os_free(value);
- wpa_dbus_dict_entry_clear(&entry);
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
-}
-
-
-/**
- * set_cred_properties - Set the properties of a configured credential
- * @wpa_s: wpa_supplicant structure for a network interface
- * @cred: wpa_cred structure for a configured credential
- * @iter: DBus message iterator containing dictionary of network
- * properties to set.
- * @error: On failure, an error describing the failure
- * Returns: TRUE if the request succeeds, FALSE if it failed
- */
-static dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- DBusMessageIter *iter,
- DBusError *error)
-{
- struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- DBusMessageIter iter_dict;
- char *value = NULL;
-
- if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
- return FALSE;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- size_t size = 50;
- int ret;
-
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- value = NULL;
- if (entry.type == DBUS_TYPE_ARRAY &&
- entry.array_type == DBUS_TYPE_BYTE) {
- if (entry.array_len <= 0)
- goto error;
-
- size = entry.array_len * 2 + 1;
- value = os_zalloc(size);
- if (!value)
- goto error;
-
- ret = wpa_snprintf_hex(value, size,
- (u8 *) entry.bytearray_value,
- entry.array_len);
- if (ret <= 0)
- goto error;
- } else if (entry.type == DBUS_TYPE_STRING) {
- if (should_quote_opt(entry.key)) {
- size = os_strlen(entry.str_value);
-
- size += 3;
- value = os_zalloc(size);
- if (!value)
- goto error;
-
- ret = os_snprintf(value, size, "\"%s\"",
- entry.str_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else {
- value = os_strdup(entry.str_value);
- if (!value)
- goto error;
- }
- } else if (entry.type == DBUS_TYPE_UINT32) {
- value = os_zalloc(size);
- if (!value)
- goto error;
-
- ret = os_snprintf(value, size, "%u",
- entry.uint32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else if (entry.type == DBUS_TYPE_INT32) {
- value = os_zalloc(size);
- if (!value)
- goto error;
-
- ret = os_snprintf(value, size, "%d",
- entry.int32_value);
- if (os_snprintf_error(size, ret))
- goto error;
- } else {
- goto error;
- }
-
- ret = wpa_config_set_cred(cred, entry.key, value, 0);
- if (ret < 0)
- goto error;
-
- os_free(value);
- value = NULL;
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- return TRUE;
-
-error:
- os_free(value);
- wpa_dbus_dict_entry_clear(&entry);
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
-}
-
-
-/**
- * wpas_dbus_simple_property_getter - Get basic type property
- * @iter: Message iter to use when appending arguments
- * @type: DBus type of property (must be basic type)
- * @val: pointer to place holding property value
- * @error: On failure an error describing the failure
- * Returns: TRUE if the request was successful, FALSE if it failed
- *
- * Generic getter for basic type properties. Type is required to be basic.
- */
-dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
- const int type,
- const void *val,
- DBusError *error)
-{
- DBusMessageIter variant_iter;
-
- if (!dbus_type_is_basic(type)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: given type is not basic", __func__);
- return FALSE;
- }
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- wpa_dbus_type_as_string(type),
- &variant_iter) ||
- !dbus_message_iter_append_basic(&variant_iter, type, val) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: error constructing reply", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_simple_property_setter - Set basic type property
- * @message: Pointer to incoming dbus message
- * @type: DBus type of property (must be basic type)
- * @val: pointer to place where value being set will be stored
- * Returns: TRUE if the request was successful, FALSE if it failed
- *
- * Generic setter for basic type properties. Type is required to be basic.
- */
-dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
- DBusError *error,
- const int type, void *val)
-{
- DBusMessageIter variant_iter;
-
- if (!dbus_type_is_basic(type)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: given type is not basic", __func__);
- return FALSE;
- }
-
- /* Look at the new value */
- dbus_message_iter_recurse(iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "wrong property type");
- return FALSE;
- }
- dbus_message_iter_get_basic(&variant_iter, val);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_simple_array_property_getter - Get array type property
- * @iter: Pointer to incoming dbus message iterator
- * @type: DBus type of property array elements (must be basic type)
- * @array: pointer to array of elements to put into response message
- * @array_len: length of above array
- * @error: a pointer to an error to fill on failure
- * Returns: TRUE if the request succeeded, FALSE if it failed
- *
- * Generic getter for array type properties. Array elements type is
- * required to be basic.
- */
-dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
- const int type,
- const void *array,
- size_t array_len,
- DBusError *error)
-{
- DBusMessageIter variant_iter, array_iter;
- char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
- const char *sub_type_str;
- size_t element_size, i;
-
- if (!dbus_type_is_basic(type)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: given type is not basic", __func__);
- return FALSE;
- }
-
- sub_type_str = wpa_dbus_type_as_string(type);
- type_str[1] = sub_type_str[0];
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- type_str, &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- sub_type_str, &array_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message", __func__);
- return FALSE;
- }
-
- switch (type) {
- case DBUS_TYPE_BYTE:
- case DBUS_TYPE_BOOLEAN:
- element_size = 1;
- break;
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_UINT16:
- element_size = sizeof(uint16_t);
- break;
- case DBUS_TYPE_INT32:
- case DBUS_TYPE_UINT32:
- element_size = sizeof(uint32_t);
- break;
- case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- element_size = sizeof(uint64_t);
- break;
- case DBUS_TYPE_DOUBLE:
- element_size = sizeof(double);
- break;
- case DBUS_TYPE_STRING:
- case DBUS_TYPE_OBJECT_PATH:
- element_size = sizeof(char *);
- break;
- default:
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: unknown element type %d", __func__, type);
- return FALSE;
- }
-
- for (i = 0; i < array_len; i++) {
- if (!dbus_message_iter_append_basic(&array_iter, type,
- (const char *) array +
- i * element_size)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message 2.5",
- __func__);
- return FALSE;
- }
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message 3", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_simple_array_array_property_getter - Get array array type property
- * @iter: Pointer to incoming dbus message iterator
- * @type: DBus type of property array elements (must be basic type)
- * @array: pointer to array of elements to put into response message
- * @array_len: length of above array
- * @error: a pointer to an error to fill on failure
- * Returns: TRUE if the request succeeded, FALSE if it failed
- *
- * Generic getter for array type properties. Array elements type is
- * required to be basic.
- */
-dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
- const int type,
- struct wpabuf **array,
- size_t array_len,
- DBusError *error)
-{
- DBusMessageIter variant_iter, array_iter;
- char type_str[] = "aa?";
- char inner_type_str[] = "a?";
- const char *sub_type_str;
- size_t i;
-
- if (!dbus_type_is_basic(type)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: given type is not basic", __func__);
- return FALSE;
- }
-
- sub_type_str = wpa_dbus_type_as_string(type);
- type_str[2] = sub_type_str[0];
- inner_type_str[1] = sub_type_str[0];
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- type_str, &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- inner_type_str, &array_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message", __func__);
- return FALSE;
- }
-
- for (i = 0; i < array_len && array[i]; i++) {
- wpa_dbus_dict_bin_array_add_element(&array_iter,
- wpabuf_head(array[i]),
- wpabuf_len(array[i]));
-
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to close message", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_string_property_getter - Get string type property
- * @iter: Message iter to use when appending arguments
- * @val: Pointer to place holding property value, can be %NULL
- * @error: On failure an error describing the failure
- * Returns: TRUE if the request was successful, FALSE if it failed
- *
- * Generic getter for string type properties. %NULL is converted to an empty
- * string.
- */
-dbus_bool_t wpas_dbus_string_property_getter(DBusMessageIter *iter,
- const void *val,
- DBusError *error)
-{
- if (!val)
- val = "";
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &val, error);
-}
-
-
-/**
- * wpas_dbus_handler_create_interface - Request registration of a network iface
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the new interface object,
- * or a dbus error message with more information
- *
- * Handler function for "CreateInterface" method call. Handles requests
- * by dbus clients to register a network interface that wpa_supplicant
- * will manage.
- */
-DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *driver = NULL;
- char *ifname = NULL;
- char *confname = NULL;
- char *bridge_ifname = NULL;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
- if (os_strcmp(entry.key, "Driver") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(driver);
- driver = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (driver == NULL)
- goto oom;
- } else if (os_strcmp(entry.key, "Ifname") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(ifname);
- ifname = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (ifname == NULL)
- goto oom;
- } else if (os_strcmp(entry.key, "ConfigFile") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(confname);
- confname = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (confname == NULL)
- goto oom;
- } else if (os_strcmp(entry.key, "BridgeIfname") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(bridge_ifname);
- bridge_ifname = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- if (bridge_ifname == NULL)
- goto oom;
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- goto error;
- }
- }
-
- if (ifname == NULL)
- goto error; /* Required Ifname argument missing */
-
- /*
- * Try to get the wpa_supplicant record for this iface, return
- * an error if we already control it.
- */
- if (wpa_supplicant_get_iface(global, ifname) != NULL) {
- reply = dbus_message_new_error(
- message, WPAS_DBUS_ERROR_IFACE_EXISTS,
- "wpa_supplicant already controls this interface.");
- } else {
- struct wpa_supplicant *wpa_s;
- struct wpa_interface iface;
-
- os_memset(&iface, 0, sizeof(iface));
- iface.driver = driver;
- iface.ifname = ifname;
- iface.confname = confname;
- iface.bridge_ifname = bridge_ifname;
- /* Otherwise, have wpa_supplicant attach to it. */
- wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
- if (wpa_s && wpa_s->dbus_new_path) {
- const char *path = wpa_s->dbus_new_path;
-
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
- &path, DBUS_TYPE_INVALID);
- } else {
- reply = wpas_dbus_error_unknown_error(
- message,
- "wpa_supplicant couldn't grab this interface.");
- }
- }
-
-out:
- os_free(driver);
- os_free(ifname);
- os_free(confname);
- os_free(bridge_ifname);
- return reply;
-
-error:
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-oom:
- reply = wpas_dbus_error_no_memory(message);
- goto out;
-}
-
-
-/**
- * wpas_dbus_handler_remove_interface - Request deregistration of an interface
- * @message: Pointer to incoming dbus message
- * @global: wpa_supplicant global data structure
- * Returns: a dbus message containing a UINT32 indicating success (1) or
- * failure (0), or returns a dbus error message with more information
- *
- * Handler function for "removeInterface" method call. Handles requests
- * by dbus clients to deregister a network interface that wpa_supplicant
- * currently manages.
- */
-DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s;
- char *path;
- DBusMessage *reply = NULL;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
-
- wpa_s = get_iface_by_dbus_path(global, path);
- if (wpa_s == NULL)
- reply = wpas_dbus_error_iface_unknown(message);
- else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
- reply = wpas_dbus_error_unknown_error(
- message,
- "wpa_supplicant couldn't remove this interface.");
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_get_interface - Get the object path for an interface name
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: The object path of the interface object,
- * or a dbus error message with more information
- *
- * Handler function for "getInterface" method call.
- */
-DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
- struct wpa_global *global)
-{
- DBusMessage *reply = NULL;
- const char *ifname;
- const char *path;
- struct wpa_supplicant *wpa_s;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
- DBUS_TYPE_INVALID);
-
- wpa_s = wpa_supplicant_get_iface(global, ifname);
- if (wpa_s == NULL || wpa_s->dbus_new_path == NULL)
- return wpas_dbus_error_iface_unknown(message);
-
- path = wpa_s->dbus_new_path;
- reply = dbus_message_new_method_return(message);
- if (reply == NULL)
- return wpas_dbus_error_no_memory(message);
- if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- dbus_message_unref(reply);
- return wpas_dbus_error_no_memory(message);
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_getter_debug_level - Get debug level
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DebugLevel" property.
- */
-dbus_bool_t wpas_dbus_getter_debug_level(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- const char *str;
- int idx = wpa_debug_level;
-
- if (idx < 0)
- idx = 0;
- if (idx > 5)
- idx = 5;
- str = debug_strings[idx];
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &str, error);
-}
-
-
-/**
- * wpas_dbus_getter_debug_timestamp - Get debug timestamp
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DebugTimestamp" property.
- */
-dbus_bool_t wpas_dbus_getter_debug_timestamp(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &wpa_debug_timestamp, error);
-
-}
-
-
-/**
- * wpas_dbus_getter_debug_show_keys - Get debug show keys
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DebugShowKeys" property.
- */
-dbus_bool_t wpas_dbus_getter_debug_show_keys(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &wpa_debug_show_keys, error);
-
-}
-
-/**
- * wpas_dbus_setter_debug_level - Set debug level
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "DebugLevel" property.
- */
-dbus_bool_t wpas_dbus_setter_debug_level(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- const char *str = NULL;
- int i, val = -1;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &str))
- return FALSE;
-
- for (i = 0; debug_strings[i]; i++)
- if (os_strcmp(debug_strings[i], str) == 0) {
- val = i;
- break;
- }
-
- if (val < 0 ||
- wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
- wpa_debug_show_keys)) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "wrong debug level value");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_setter_debug_timestamp - Set debug timestamp
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "DebugTimestamp" property.
- */
-dbus_bool_t wpas_dbus_setter_debug_timestamp(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- dbus_bool_t val;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
- &val))
- return FALSE;
-
- wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
- wpa_debug_show_keys);
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_setter_debug_show_keys - Set debug show keys
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "DebugShowKeys" property.
- */
-dbus_bool_t wpas_dbus_setter_debug_show_keys(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- dbus_bool_t val;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
- &val))
- return FALSE;
-
- wpa_supplicant_set_debug_params(global, wpa_debug_level,
- wpa_debug_timestamp,
- val ? 1 : 0);
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_interfaces - Request registered interfaces list
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Interfaces" property. Handles requests
- * by dbus clients to return list of registered interfaces objects
- * paths
- */
-dbus_bool_t wpas_dbus_getter_interfaces(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- struct wpa_supplicant *wpa_s;
- const char **paths;
- unsigned int i = 0, num = 0;
- dbus_bool_t success;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->dbus_new_path)
- num++;
- }
-
- paths = os_calloc(num, sizeof(char *));
- if (!paths) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->dbus_new_path)
- paths[i++] = wpa_s->dbus_new_path;
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, num, error);
-
- os_free(paths);
- return success;
-}
-
-
-/**
- * wpas_dbus_getter_eap_methods - Request supported EAP methods list
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "EapMethods" property. Handles requests
- * by dbus clients to return list of strings with supported EAP methods
- */
-dbus_bool_t wpas_dbus_getter_eap_methods(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- char **eap_methods;
- size_t num_items = 0;
- dbus_bool_t success;
-
- eap_methods = eap_get_names_as_string_array(&num_items);
- if (!eap_methods) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_STRING,
- eap_methods,
- num_items, error);
-
- while (num_items)
- os_free(eap_methods[--num_items]);
- os_free(eap_methods);
- return success;
-}
-
-
-/**
- * wpas_dbus_getter_global_capabilities - Request supported global capabilities
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Capabilities" property. Handles requests by dbus clients to
- * return a list of strings with supported capabilities like AP, RSN IBSS,
- * and P2P that are determined at compile time.
- */
-dbus_bool_t wpas_dbus_getter_global_capabilities(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- const char *capabilities[13];
- size_t num_items = 0;
- struct wpa_global *global = user_data;
- struct wpa_supplicant *wpa_s;
-#ifdef CONFIG_FILS
- int fils_supported = 0, fils_sk_pfs_supported = 0;
-#endif /* CONFIG_FILS */
- int ext_key_id_supported = 0;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
-#ifdef CONFIG_FILS
- if (wpa_is_fils_supported(wpa_s))
- fils_supported = 1;
- if (wpa_is_fils_sk_pfs_supported(wpa_s))
- fils_sk_pfs_supported = 1;
-#endif /* CONFIG_FILS */
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_EXTENDED_KEY_ID)
- ext_key_id_supported = 1;
- }
-
-#ifdef CONFIG_AP
- capabilities[num_items++] = "ap";
-#endif /* CONFIG_AP */
-#ifdef CONFIG_IBSS_RSN
- capabilities[num_items++] = "ibss-rsn";
-#endif /* CONFIG_IBSS_RSN */
-#ifdef CONFIG_P2P
- capabilities[num_items++] = "p2p";
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_INTERWORKING
- capabilities[num_items++] = "interworking";
-#endif /* CONFIG_INTERWORKING */
- capabilities[num_items++] = "pmf";
-#ifdef CONFIG_MESH
- capabilities[num_items++] = "mesh";
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_FILS
- if (fils_supported)
- capabilities[num_items++] = "fils";
- if (fils_sk_pfs_supported)
- capabilities[num_items++] = "fils_sk_pfs";
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_IEEE80211R
- capabilities[num_items++] = "ft";
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_SHA384
- capabilities[num_items++] = "sha384";
-#endif /* CONFIG_SHA384 */
-#ifdef CONFIG_OWE
- capabilities[num_items++] = "owe";
-#endif /* CONFIG_OWE */
-#ifdef CONFIG_SUITEB192
- capabilities[num_items++] = "suiteb192";
-#endif /* CONFIG_SUITEB192 */
- if (ext_key_id_supported)
- capabilities[num_items++] = "extended_key_id";
-
- return wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_STRING,
- capabilities,
- num_items, error);
-}
-
-
-static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
- char **type, DBusMessage **reply)
-{
- if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
- wpa_printf(MSG_DEBUG, "%s[dbus]: Type must be a string",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message, "Wrong Type value type. String required");
- return -1;
- }
- dbus_message_iter_get_basic(var, type);
- return 0;
-}
-
-
-static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
- struct wpa_driver_scan_params *params,
- DBusMessage **reply)
-{
- struct wpa_driver_scan_ssid *ssids = params->ssids;
- size_t ssids_num = 0;
- u8 *ssid;
- DBusMessageIter array_iter, sub_array_iter;
- char *val;
- int len;
-
- if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: ssids must be an array of arrays of bytes",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong SSIDs value type. Array of arrays of bytes required");
- return -1;
- }
-
- dbus_message_iter_recurse(var, &array_iter);
-
- if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: ssids must be an array of arrays of bytes",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong SSIDs value type. Array of arrays of bytes required");
- return -1;
- }
-
- while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) {
- if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Too many ssids specified on scan dbus call",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Too many ssids specified. Specify at most four");
- return -1;
- }
-
- dbus_message_iter_recurse(&array_iter, &sub_array_iter);
-
- dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
-
- if (len > SSID_MAX_LEN) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: SSID too long (len=%d max_len=%d)",
- __func__, len, SSID_MAX_LEN);
- *reply = wpas_dbus_error_invalid_args(
- message, "Invalid SSID: too long");
- return -1;
- }
-
- if (len != 0) {
- ssid = os_memdup(val, len);
- if (ssid == NULL) {
- *reply = wpas_dbus_error_no_memory(message);
- return -1;
- }
- } else {
- /* Allow zero-length SSIDs */
- ssid = NULL;
- }
-
- ssids[ssids_num].ssid = ssid;
- ssids[ssids_num].ssid_len = len;
-
- dbus_message_iter_next(&array_iter);
- ssids_num++;
- }
-
- params->num_ssids = ssids_num;
- return 0;
-}
-
-
-static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
- struct wpa_driver_scan_params *params,
- DBusMessage **reply)
-{
- u8 *ies = NULL, *nies;
- size_t ies_len = 0;
- DBusMessageIter array_iter, sub_array_iter;
- char *val;
- int len;
-
- if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: ies must be an array of arrays of bytes",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong IEs value type. Array of arrays of bytes required");
- return -1;
- }
-
- dbus_message_iter_recurse(var, &array_iter);
-
- if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: ies must be an array of arrays of bytes",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message, "Wrong IEs value type. Array required");
- return -1;
- }
-
- while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY) {
- dbus_message_iter_recurse(&array_iter, &sub_array_iter);
-
- dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
- if (len <= 0) {
- dbus_message_iter_next(&array_iter);
- continue;
- }
-
- nies = os_realloc(ies, ies_len + len);
- if (nies == NULL) {
- os_free(ies);
- *reply = wpas_dbus_error_no_memory(message);
- return -1;
- }
- ies = nies;
- os_memcpy(ies + ies_len, val, len);
- ies_len += len;
-
- dbus_message_iter_next(&array_iter);
- }
-
- params->extra_ies = ies;
- params->extra_ies_len = ies_len;
- return 0;
-}
-
-
-static int wpas_dbus_get_scan_channels(DBusMessage *message,
- DBusMessageIter *var,
- struct wpa_driver_scan_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter array_iter, sub_array_iter;
- int *freqs = NULL, *nfreqs;
- size_t freqs_num = 0;
-
- if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Channels must be an array of structs",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong Channels value type. Array of structs required");
- return -1;
- }
-
- dbus_message_iter_recurse(var, &array_iter);
-
- if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Channels must be an array of structs",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong Channels value type. Array of structs required");
- return -1;
- }
-
- while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
- {
- int freq, width;
-
- dbus_message_iter_recurse(&array_iter, &sub_array_iter);
-
- if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
- DBUS_TYPE_UINT32) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Channel must by specified by struct of two UINT32s %c",
- __func__,
- dbus_message_iter_get_arg_type(
- &sub_array_iter));
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong Channel struct. Two UINT32s required");
- os_free(freqs);
- return -1;
- }
- dbus_message_iter_get_basic(&sub_array_iter, &freq);
-
- if (!dbus_message_iter_next(&sub_array_iter) ||
- dbus_message_iter_get_arg_type(&sub_array_iter) !=
- DBUS_TYPE_UINT32) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Channel must by specified by struct of two UINT32s",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message,
- "Wrong Channel struct. Two UINT32s required");
- os_free(freqs);
- return -1;
- }
-
- dbus_message_iter_get_basic(&sub_array_iter, &width);
-
-#define FREQS_ALLOC_CHUNK 32
- if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
- nfreqs = os_realloc_array(
- freqs, freqs_num + FREQS_ALLOC_CHUNK,
- sizeof(int));
- if (nfreqs == NULL)
- os_free(freqs);
- freqs = nfreqs;
- }
- if (freqs == NULL) {
- *reply = wpas_dbus_error_no_memory(message);
- return -1;
- }
-
- freqs[freqs_num] = freq;
-
- freqs_num++;
- dbus_message_iter_next(&array_iter);
- }
-
- nfreqs = os_realloc_array(freqs, freqs_num + 1, sizeof(int));
- if (nfreqs == NULL)
- os_free(freqs);
- freqs = nfreqs;
- if (freqs == NULL) {
- *reply = wpas_dbus_error_no_memory(message);
- return -1;
- }
- freqs[freqs_num] = 0;
-
- params->freqs = freqs;
- return 0;
-}
-
-
-static int wpas_dbus_get_scan_allow_roam(DBusMessage *message,
- DBusMessageIter *var,
- dbus_bool_t *allow,
- DBusMessage **reply)
-{
- if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN) {
- wpa_printf(MSG_DEBUG, "%s[dbus]: Type must be a boolean",
- __func__);
- *reply = wpas_dbus_error_invalid_args(
- message, "Wrong Type value type. Boolean required");
- return -1;
- }
- dbus_message_iter_get_basic(var, allow);
- return 0;
-}
-
-
-/**
- * wpas_dbus_handler_scan - Request a wireless scan on an interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "Scan" method call of a network device. Requests
- * that wpa_supplicant perform a wireless scan as soon as possible
- * on a particular wireless interface.
- */
-DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
- char *key = NULL, *type = NULL;
- struct wpa_driver_scan_params params;
- size_t i;
- dbus_bool_t allow_roam = 1;
-
- os_memset(&params, 0, sizeof(params));
-
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_recurse(&iter, &dict_iter);
-
- while (dbus_message_iter_get_arg_type(&dict_iter) ==
- DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(&dict_iter, &entry_iter);
- dbus_message_iter_get_basic(&entry_iter, &key);
- dbus_message_iter_next(&entry_iter);
- dbus_message_iter_recurse(&entry_iter, &variant_iter);
-
- if (os_strcmp(key, "Type") == 0) {
- if (wpas_dbus_get_scan_type(message, &variant_iter,
- &type, &reply) < 0)
- goto out;
- } else if (os_strcmp(key, "SSIDs") == 0) {
- if (wpas_dbus_get_scan_ssids(message, &variant_iter,
- &params, &reply) < 0)
- goto out;
- } else if (os_strcmp(key, "IEs") == 0) {
- if (wpas_dbus_get_scan_ies(message, &variant_iter,
- &params, &reply) < 0)
- goto out;
- } else if (os_strcmp(key, "Channels") == 0) {
- if (wpas_dbus_get_scan_channels(message, &variant_iter,
- &params, &reply) < 0)
- goto out;
- } else if (os_strcmp(key, "AllowRoam") == 0) {
- if (wpas_dbus_get_scan_allow_roam(message,
- &variant_iter,
- &allow_roam,
- &reply) < 0)
- goto out;
- } else {
- wpa_printf(MSG_DEBUG, "%s[dbus]: Unknown argument %s",
- __func__, key);
- reply = wpas_dbus_error_invalid_args(message, key);
- goto out;
- }
-
- dbus_message_iter_next(&dict_iter);
- }
-
- if (!type) {
- wpa_printf(MSG_DEBUG, "%s[dbus]: Scan type not specified",
- __func__);
- reply = wpas_dbus_error_invalid_args(message, key);
- goto out;
- }
-
- if (os_strcmp(type, "passive") == 0) {
- if (params.num_ssids || params.extra_ies_len) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: SSIDs or IEs specified for passive scan.",
- __func__);
- reply = wpas_dbus_error_invalid_args(
- message,
- "You can specify only Channels in passive scan");
- goto out;
- } else {
- if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
- __func__);
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
-
- if (params.freqs && params.freqs[0]) {
- wpa_s->last_scan_req = MANUAL_SCAN_REQ;
- if (wpa_supplicant_trigger_scan(wpa_s,
- &params)) {
- reply = wpas_dbus_error_scan_error(
- message,
- "Scan request rejected");
- }
- } else {
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
- }
- } else if (os_strcmp(type, "active") == 0) {
- if (!params.num_ssids) {
- /* Add wildcard ssid */
- params.num_ssids++;
- }
-#ifdef CONFIG_AUTOSCAN
- autoscan_deinit(wpa_s);
-#endif /* CONFIG_AUTOSCAN */
- if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed",
- __func__);
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
-
- wpa_s->last_scan_req = MANUAL_SCAN_REQ;
- if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
- reply = wpas_dbus_error_scan_error(
- message, "Scan request rejected");
- }
- } else {
- wpa_printf(MSG_DEBUG, "%s[dbus]: Unknown scan type: %s",
- __func__, type);
- reply = wpas_dbus_error_invalid_args(message,
- "Wrong scan type");
- goto out;
- }
-
- if (!allow_roam)
- wpa_s->scan_res_handler = scan_only_handler;
-
-out:
- for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
- os_free((u8 *) params.ssids[i].ssid);
- os_free((u8 *) params.extra_ies);
- os_free(params.freqs);
- return reply;
-}
-
-
-/*
- * wpas_dbus_handler_abort_scan - Request an ongoing scan to be aborted
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: Abort failed or no scan in progress DBus error message on failure
- * or NULL otherwise.
- *
- * Handler function for "AbortScan" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_abort_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpas_abort_ongoing_scan(wpa_s) < 0)
- return dbus_message_new_error(
- message, WPAS_DBUS_ERROR_IFACE_SCAN_ERROR,
- "Abort failed or no scan in progress");
-
- return NULL;
-}
-
-
-/**
- * wpas_dbus_new_iface_add_cred - Add a new credential
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing the object path of the new credential
- *
- * Handler function for "AddCred" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_cred *cred = NULL;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
- DBusError error;
-
- dbus_message_iter_init(message, &iter);
-
- if (wpa_s->dbus_new_path)
- cred = wpa_config_add_cred(wpa_s->conf);
- if (!cred) {
- wpa_printf(MSG_ERROR, "%s[dbus]: can't add new credential.",
- __func__);
- reply = wpas_dbus_error_unknown_error(
- message,
- "wpa_supplicant could not add a credential on this interface.");
- goto err;
- }
-
- dbus_error_init(&error);
- if (!set_cred_properties(wpa_s, cred, &iter, &error)) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: control interface couldn't set credential properties",
- __func__);
- reply = wpas_dbus_reply_new_from_error(message, &error,
- DBUS_ERROR_INVALID_ARGS,
- "Failed to add credential");
- dbus_error_free(&error);
- goto err;
- }
-
- /* Construct the object path for this network. */
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%d",
- wpa_s->dbus_new_path, cred->id);
-
- reply = dbus_message_new_method_return(message);
- if (!reply) {
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
- if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- dbus_message_unref(reply);
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
-
- return reply;
-
-err:
- if (cred)
- wpa_config_remove_cred(wpa_s->conf, cred->id);
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_remove_cred - Remove a configured credential
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "RemoveCred" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- char *iface, *cred_id;
- int id;
- struct wpa_cred *cred;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID);
-
- /* Extract the network ID and ensure the network is actually a child of
- * this interface */
- iface = wpas_dbus_new_decompose_object_path(
- op, WPAS_DBUS_NEW_CREDENTIALS_PART, &cred_id);
- if (!iface || !cred_id || !wpa_s->dbus_new_path ||
- os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- errno = 0;
- id = strtoul(cred_id, NULL, 10);
- if (errno != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- cred = wpa_config_get_cred(wpa_s->conf, id);
- if (!cred) {
- wpa_printf(MSG_ERROR, "%s[dbus]: could not find credential %s",
- __func__, op);
- reply = wpas_dbus_error_invalid_args(
- message, "could not find credential");
- goto out;
- }
-
- if (wpas_remove_cred(wpa_s, cred) < 0) {
- wpa_printf(MSG_ERROR,
- "%s[dbus]: error occurred when removing cred %d",
- __func__, id);
- reply = wpas_dbus_error_unknown_error(
- message,
- "error removing the specified credential on its interface.");
- goto out;
- }
-
-out:
- os_free(iface);
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_remove_all_creds - Remove all the configured credentials
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "RemoveAllCreds" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- int res;
- DBusMessage *reply = NULL;
-
- res = wpas_remove_all_creds(wpa_s);
- if (res < 0) {
- wpa_printf(MSG_ERROR,
- "%s[dbus]: failed to remove all credentials",
- __func__);
- reply = wpas_dbus_error_unknown_error(
- message, "failed to remove all credentials");
- }
-
- return reply;
-}
-
-
-DBusMessage *
-wpas_dbus_handler_interworking_select(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- int result;
- DBusMessage *reply = NULL;
-
- /* Automatic selection is disabled and no constraint on channels */
- result = interworking_select(wpa_s, 0, NULL);
- if (result < 0) {
- wpa_printf(MSG_ERROR,
- "%s[dbus]: failed to start Interworking selection",
- __func__);
- reply = wpas_dbus_error_scan_error(
- message,
- "error starting Interworking selection.");
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_signal_poll - Request immediate signal properties
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "SignalPoll" method call of a network device. Requests
- * that wpa_supplicant read signal properties like RSSI, noise, and link
- * speed and return them.
- */
-DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- struct wpa_signal_info si;
- DBusMessage *reply = NULL;
- DBusMessageIter iter, iter_dict, variant_iter;
- int ret;
-
- ret = wpa_drv_signal_poll(wpa_s, &si);
- if (ret) {
- return dbus_message_new_error(message, DBUS_ERROR_FAILED,
- "Failed to read signal");
- }
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL)
- goto nomem;
-
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter) ||
- !wpa_dbus_dict_open_write(&variant_iter, &iter_dict) ||
- !wpa_dbus_dict_append_int32(&iter_dict, "rssi",
- si.current_signal) ||
- !wpa_dbus_dict_append_int32(&iter_dict, "linkspeed",
- si.current_txrate / 1000) ||
- !wpa_dbus_dict_append_int32(&iter_dict, "noise",
- si.current_noise) ||
- !wpa_dbus_dict_append_uint32(&iter_dict, "frequency",
- si.frequency) ||
- (si.chanwidth != CHAN_WIDTH_UNKNOWN &&
- !wpa_dbus_dict_append_string(
- &iter_dict, "width",
- channel_width_to_string(si.chanwidth))) ||
- (si.center_frq1 > 0 && si.center_frq2 > 0 &&
- (!wpa_dbus_dict_append_int32(&iter_dict, "center-frq1",
- si.center_frq1) ||
- !wpa_dbus_dict_append_int32(&iter_dict, "center-frq2",
- si.center_frq2))) ||
- (si.avg_signal &&
- !wpa_dbus_dict_append_int32(&iter_dict, "avg-rssi",
- si.avg_signal)) ||
- !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
- !dbus_message_iter_close_container(&iter, &variant_iter))
- goto nomem;
-
- return reply;
-
-nomem:
- if (reply)
- dbus_message_unref(reply);
- return wpas_dbus_error_no_memory(message);
-}
-
-
-/*
- * wpas_dbus_handler_disconnect - Terminate the current connection
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NotConnected DBus error message if already not connected
- * or NULL otherwise.
- *
- * Handler function for "Disconnect" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->current_ssid != NULL) {
- wpas_request_disconnection(wpa_s);
- return NULL;
- }
-
- return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
- "This interface is not connected");
-}
-
-
-/**
- * wpas_dbus_new_iface_add_network - Add a new configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing the object path of the new network
- *
- * Handler function for "AddNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_ssid *ssid = NULL;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
- DBusError error;
-
- dbus_message_iter_init(message, &iter);
-
- if (wpa_s->dbus_new_path)
- ssid = wpa_supplicant_add_network(wpa_s);
- if (ssid == NULL) {
- wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.",
- __func__);
- reply = wpas_dbus_error_unknown_error(
- message,
- "wpa_supplicant could not add a network on this interface.");
- goto err;
- }
-
- dbus_error_init(&error);
- if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
- wpa_printf(MSG_DEBUG,
- "%s[dbus]: control interface couldn't set network properties",
- __func__);
- reply = wpas_dbus_reply_new_from_error(message, &error,
- DBUS_ERROR_INVALID_ARGS,
- "Failed to add network");
- dbus_error_free(&error);
- goto err;
- }
-
- /* Construct the object path for this network. */
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
- wpa_s->dbus_new_path, ssid->id);
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL) {
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
- if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- dbus_message_unref(reply);
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
-
- return reply;
-
-err:
- if (ssid) {
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- }
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_reassociate - Reassociate
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: InterfaceDisabled DBus error message if disabled
- * or NULL otherwise.
- *
- * Handler function for "Reassociate" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED) {
- wpas_request_connection(wpa_s);
- return NULL;
- }
-
- return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_DISABLED,
- "This interface is disabled");
-}
-
-
-/**
- * wpas_dbus_handler_expect_disconnect - ExpectDisconnect
- * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
- * Returns: NULL
- *
- * Handler function for notifying system there will be a expected disconnect.
- * This will prevent wpa_supplicant from adding the BSSID to the ignore list
- * upon next disconnect.
- */
-DBusMessage * wpas_dbus_handler_expect_disconnect(DBusMessage *message,
- struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s = global->ifaces;
-
- for (; wpa_s; wpa_s = wpa_s->next)
- if (wpa_s->wpa_state >= WPA_ASSOCIATED)
- wpa_s->own_disconnect_req = 1;
- return NULL;
-}
-
-
-/**
- * wpas_dbus_handler_reattach - Reattach to current AP
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NotConnected DBus error message if not connected
- * or NULL otherwise.
- *
- * Handler function for "Reattach" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->current_ssid != NULL) {
- wpa_s->reattach = 1;
- wpas_request_connection(wpa_s);
- return NULL;
- }
-
- return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
- "This interface is not connected");
-}
-
-
-/**
- * wpas_dbus_handler_reconnect - Reconnect if disconnected
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: InterfaceDisabled DBus error message if disabled
- * or NULL otherwise.
- *
- * Handler function for "Reconnect" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_reconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_IFACE_DISABLED,
- "This interface is disabled");
- }
-
- if (wpa_s->disconnected)
- wpas_request_connection(wpa_s);
- return NULL;
-}
-
-
-/**
- * wpas_dbus_handler_remove_network - Remove a configured network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "RemoveNetwork" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- char *iface, *net_id;
- int id;
- int result;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID);
-
- /* Extract the network ID and ensure the network */
- /* is actually a child of this interface */
- iface = wpas_dbus_new_decompose_object_path(op,
- WPAS_DBUS_NEW_NETWORKS_PART,
- &net_id);
- if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
- os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- errno = 0;
- id = strtoul(net_id, NULL, 10);
- if (errno != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- result = wpa_supplicant_remove_network(wpa_s, id);
- if (result == -1) {
- reply = wpas_dbus_error_network_unknown(message);
- goto out;
- }
- if (result == -2) {
- wpa_printf(MSG_ERROR,
- "%s[dbus]: error occurred when removing network %d",
- __func__, id);
- reply = wpas_dbus_error_unknown_error(
- message,
- "error removing the specified network on is interface.");
- goto out;
- }
-
-out:
- os_free(iface);
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_remove_all_networks - Remove all configured networks
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "RemoveAllNetworks" method call of a network interface.
- */
-DBusMessage * wpas_dbus_handler_remove_all_networks(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- /* NB: could check for failure and return an error */
- wpa_supplicant_remove_all_networks(wpa_s);
- return NULL;
-}
-
-
-/**
- * wpas_dbus_handler_select_network - Attempt association with a network
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "SelectNetwork" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- char *iface, *net_id;
- int id;
- struct wpa_ssid *ssid;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID);
-
- /* Extract the network ID and ensure the network */
- /* is actually a child of this interface */
- iface = wpas_dbus_new_decompose_object_path(op,
- WPAS_DBUS_NEW_NETWORKS_PART,
- &net_id);
- if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
- os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- errno = 0;
- id = strtoul(net_id, NULL, 10);
- if (errno != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- reply = wpas_dbus_error_network_unknown(message);
- goto out;
- }
-
- /* Finally, associate with the network */
- wpa_supplicant_select_network(wpa_s, ssid);
-
-out:
- os_free(iface);
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "NetworkReply" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
-#ifdef IEEE8021X_EAPOL
- DBusMessage *reply = NULL;
- const char *op, *field, *value;
- char *iface, *net_id;
- int id;
- struct wpa_ssid *ssid;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_STRING, &field,
- DBUS_TYPE_STRING, &value,
- DBUS_TYPE_INVALID))
- return wpas_dbus_error_invalid_args(message, NULL);
-
- /* Extract the network ID and ensure the network */
- /* is actually a child of this interface */
- iface = wpas_dbus_new_decompose_object_path(op,
- WPAS_DBUS_NEW_NETWORKS_PART,
- &net_id);
- if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path ||
- os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- errno = 0;
- id = strtoul(net_id, NULL, 10);
- if (errno != 0) {
- reply = wpas_dbus_error_invalid_args(message, net_id);
- goto out;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- reply = wpas_dbus_error_network_unknown(message);
- goto out;
- }
-
- if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid,
- field, value) < 0)
- reply = wpas_dbus_error_invalid_args(message, field);
- else {
- /* Tell EAP to retry immediately */
- eapol_sm_notify_ctrl_response(wpa_s->eapol);
- }
-
-out:
- os_free(iface);
- return reply;
-#else /* IEEE8021X_EAPOL */
- wpa_printf(MSG_DEBUG, "dbus: 802.1X not included");
- return wpas_dbus_error_unknown_error(message, "802.1X not included");
-#endif /* IEEE8021X_EAPOL */
-}
-
-
-/**
- * wpas_dbus_handler_roam - Initiate a roam to another BSS within the ESS
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "Roam" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_roam(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_NO_SCAN_PROCESSING
- return wpas_dbus_error_unknown_error(message,
- "scan processing not included");
-#else /* CONFIG_NO_SCAN_PROCESSING */
- u8 bssid[ETH_ALEN];
- struct wpa_bss *bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- char *addr;
- struct wpa_radio_work *already_connecting;
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &addr,
- DBUS_TYPE_INVALID))
- return wpas_dbus_error_invalid_args(message, NULL);
-
- if (hwaddr_aton(addr, bssid))
- return wpas_dbus_error_invalid_args(
- message, "Invalid hardware address format");
-
- wpa_printf(MSG_DEBUG, "dbus: Roam " MACSTR, MAC2STR(bssid));
-
- if (!ssid)
- return dbus_message_new_error(
- message, WPAS_DBUS_ERROR_NOT_CONNECTED,
- "This interface is not connected");
-
- bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "dbus: Roam: Target BSS not found");
- return wpas_dbus_error_invalid_args(
- message, "Target BSS not found");
- }
-
- already_connecting = radio_work_pending(wpa_s, "sme-connect");
- wpa_s->reassociate = 1;
- wpa_supplicant_connect(wpa_s, bss, ssid);
-
- /*
- * Indicate that an explicitly requested roam is in progress so scan
- * results that come in before the 'sme-connect' radio work gets
- * executed do not override the original connection attempt.
- */
- if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
- wpa_s->roam_in_progress = true;
-
- return NULL;
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-}
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-
-/**
- * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing an error on failure or NULL on success
- *
- * Asks wpa_supplicant to internally store a binary blobs.
- */
-DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, array_iter;
-
- char *blob_name;
- u8 *blob_data;
- int blob_len;
- struct wpa_config_blob *blob = NULL;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &blob_name);
-
- if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_BLOB_EXISTS,
- NULL);
- }
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &array_iter);
-
- dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
-
- blob = os_zalloc(sizeof(*blob));
- if (!blob) {
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
-
- blob->data = os_memdup(blob_data, blob_len);
- blob->name = os_strdup(blob_name);
- if (!blob->data || !blob->name) {
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
- blob->len = blob_len;
-
- wpa_config_set_blob(wpa_s->conf, blob);
- wpas_notify_blob_added(wpa_s, blob->name);
-
- return reply;
-
-err:
- if (blob) {
- os_free(blob->name);
- os_free(blob->data);
- os_free(blob);
- }
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing array of bytes (blob)
- *
- * Gets one wpa_supplicant's binary blobs.
- */
-DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, array_iter;
-
- char *blob_name;
- const struct wpa_config_blob *blob;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
- DBUS_TYPE_INVALID);
-
- blob = wpa_config_get_blob(wpa_s->conf, blob_name);
- if (!blob) {
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_BLOB_UNKNOWN,
- "Blob id not set");
- }
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return wpas_dbus_error_no_memory(message);
-
- dbus_message_iter_init_append(reply, &iter);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter) ||
- !dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
- &(blob->data), blob->len) ||
- !dbus_message_iter_close_container(&iter, &array_iter)) {
- dbus_message_unref(reply);
- reply = wpas_dbus_error_no_memory(message);
- }
-
- return reply;
-}
-
-
-/**
- * wpas_remove_handler_remove_blob - Remove named binary blob
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: NULL on success or dbus error
- *
- * Asks wpa_supplicant to internally remove a binary blobs.
- */
-DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- char *blob_name;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
- DBUS_TYPE_INVALID);
-
- if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_BLOB_UNKNOWN,
- "Blob id not set");
- }
- wpas_notify_blob_removed(wpa_s, blob_name);
-
- return reply;
-
-}
-
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-/*
- * wpas_dbus_handler_flush_bss - Flush the BSS cache
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
- *
- * Handler function for "FlushBSS" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- dbus_uint32_t age;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &age,
- DBUS_TYPE_INVALID);
-
- if (age == 0)
- wpa_bss_flush(wpa_s);
- else
- wpa_bss_flush_by_age(wpa_s, age);
-
- return NULL;
-}
-
-
-#ifdef CONFIG_AUTOSCAN
-/**
- * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
- *
- * Handler function for "AutoScan" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- enum wpa_states state = wpa_s->wpa_state;
- char *arg;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg,
- DBUS_TYPE_INVALID);
-
- if (arg != NULL && os_strlen(arg) > 0) {
- char *tmp;
-
- tmp = os_strdup(arg);
- if (tmp == NULL) {
- reply = wpas_dbus_error_no_memory(message);
- } else {
- os_free(wpa_s->conf->autoscan);
- wpa_s->conf->autoscan = tmp;
- if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
- autoscan_init(wpa_s, 1);
- else if (state == WPA_SCANNING)
- wpa_supplicant_reinit_autoscan(wpa_s);
- }
- } else if (arg != NULL && os_strlen(arg) == 0) {
- os_free(wpa_s->conf->autoscan);
- wpa_s->conf->autoscan = NULL;
- autoscan_deinit(wpa_s);
- } else
- reply = dbus_message_new_error(message,
- DBUS_ERROR_INVALID_ARGS,
- NULL);
-
- return reply;
-}
-#endif /* CONFIG_AUTOSCAN */
-
-
-/*
- * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
- *
- * Handler function for "EAPLogoff" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
- return NULL;
-}
-
-
-/*
- * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL
- *
- * Handler function for "EAPLogin" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
- return NULL;
-}
-
-
-#ifdef CONFIG_TDLS
-
-static int get_peer_hwaddr_helper(DBusMessage *message, const char *func_name,
- u8 *peer_address, DBusMessage **error)
-{
- const char *peer_string;
-
- *error = NULL;
-
- if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &peer_string,
- DBUS_TYPE_INVALID)) {
- *error = wpas_dbus_error_invalid_args(message, NULL);
- return -1;
- }
-
- if (hwaddr_aton(peer_string, peer_address)) {
- wpa_printf(MSG_DEBUG, "%s: invalid address '%s'",
- func_name, peer_string);
- *error = wpas_dbus_error_invalid_args(
- message, "Invalid hardware address format");
- return -1;
- }
-
- return 0;
-}
-
-
-/*
- * wpas_dbus_handler_tdls_discover - Discover TDLS peer
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "TDLSDiscover" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 peer[ETH_ALEN];
- DBusMessage *error_reply;
- int ret;
-
- if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
- return error_reply;
-
- wpa_printf(MSG_DEBUG, "DBUS TDLS_DISCOVER " MACSTR, MAC2STR(peer));
-
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
-
- if (ret) {
- return wpas_dbus_error_unknown_error(
- message, "error performing TDLS discovery");
- }
-
- return NULL;
-}
-
-
-/*
- * wpas_dbus_handler_tdls_setup - Setup TDLS session
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "TDLSSetup" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 peer[ETH_ALEN];
- DBusMessage *error_reply;
- int ret;
-
- if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
- return error_reply;
-
- wpa_printf(MSG_DEBUG, "DBUS TDLS_SETUP " MACSTR, MAC2STR(peer));
-
- wpa_tdls_remove(wpa_s->wpa, peer);
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_start(wpa_s->wpa, peer);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
-
- if (ret) {
- return wpas_dbus_error_unknown_error(
- message, "error performing TDLS setup");
- }
-
- return NULL;
-}
-
-
-/*
- * wpas_dbus_handler_tdls_status - Return TDLS session status
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A string representing the state of the link to this TDLS peer
- *
- * Handler function for "TDLSStatus" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 peer[ETH_ALEN];
- DBusMessage *reply;
- const char *tdls_status;
-
- if (get_peer_hwaddr_helper(message, __func__, peer, &reply) < 0)
- return reply;
-
- wpa_printf(MSG_DEBUG, "DBUS TDLS_STATUS " MACSTR, MAC2STR(peer));
-
- tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer);
-
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_STRING,
- &tdls_status, DBUS_TYPE_INVALID);
- return reply;
-}
-
-
-/*
- * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "TDLSTeardown" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 peer[ETH_ALEN];
- DBusMessage *error_reply;
- int ret;
-
- if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
- return error_reply;
-
- wpa_printf(MSG_DEBUG, "DBUS TDLS_TEARDOWN " MACSTR, MAC2STR(peer));
-
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- ret = wpa_tdls_teardown_link(
- wpa_s->wpa, peer,
- WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
- else
- ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
-
- if (ret) {
- return wpas_dbus_error_unknown_error(
- message, "error performing TDLS teardown");
- }
-
- return NULL;
-}
-
-/*
- * wpas_dbus_handler_tdls_channel_switch - Enable channel switching with TDLS peer
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "TDLSChannelSwitch" method call of network interface.
- */
-DBusMessage *
-wpas_dbus_handler_tdls_channel_switch(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter, iter_dict;
- struct wpa_dbus_dict_entry entry;
- u8 peer[ETH_ALEN];
- struct hostapd_freq_params freq_params;
- u8 oper_class = 0;
- int ret;
- int is_peer_present = 0;
-
- if (!wpa_tdls_is_external_setup(wpa_s->wpa)) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Only supported with external setup");
- return wpas_dbus_error_unknown_error(message, "TDLS is not using external setup");
- }
-
- os_memset(&freq_params, 0, sizeof(freq_params));
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- return wpas_dbus_error_invalid_args(message, NULL);
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- return wpas_dbus_error_invalid_args(message, NULL);
-
- if (os_strcmp(entry.key, "PeerAddress") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (hwaddr_aton(entry.str_value, peer)) {
- wpa_printf(MSG_DEBUG,
- "tdls_chanswitch: Invalid address '%s'",
- entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- return wpas_dbus_error_invalid_args(message,
- NULL);
- }
-
- is_peer_present = 1;
- } else if (os_strcmp(entry.key, "OperClass") == 0 &&
- entry.type == DBUS_TYPE_BYTE) {
- oper_class = entry.byte_value;
- } else if (os_strcmp(entry.key, "Frequency") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- freq_params.freq = entry.uint32_value;
- } else if (os_strcmp(entry.key, "SecChannelOffset") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- freq_params.sec_channel_offset = entry.uint32_value;
- } else if (os_strcmp(entry.key, "CenterFrequency1") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- freq_params.center_freq1 = entry.uint32_value;
- } else if (os_strcmp(entry.key, "CenterFrequency2") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- freq_params.center_freq2 = entry.uint32_value;
- } else if (os_strcmp(entry.key, "Bandwidth") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- freq_params.bandwidth = entry.uint32_value;
- } else if (os_strcmp(entry.key, "HT") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- freq_params.ht_enabled = entry.bool_value;
- } else if (os_strcmp(entry.key, "VHT") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- freq_params.vht_enabled = entry.bool_value;
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- return wpas_dbus_error_invalid_args(message, NULL);
- }
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (oper_class == 0) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Invalid op class provided");
- return wpas_dbus_error_invalid_args(
- message, "Invalid op class provided");
- }
-
- if (freq_params.freq == 0) {
- wpa_printf(MSG_INFO,
- "tdls_chanswitch: Invalid freq provided");
- return wpas_dbus_error_invalid_args(message,
- "Invalid freq provided");
- }
-
- if (is_peer_present == 0) {
- wpa_printf(MSG_DEBUG,
- "tdls_chanswitch: peer address not provided");
- return wpas_dbus_error_invalid_args(
- message, "peer address not provided");
- }
-
- wpa_printf(MSG_DEBUG, "dbus: TDLS_CHAN_SWITCH " MACSTR
- " OP CLASS %d FREQ %d CENTER1 %d CENTER2 %d BW %d SEC_OFFSET %d%s%s",
- MAC2STR(peer), oper_class, freq_params.freq,
- freq_params.center_freq1, freq_params.center_freq2,
- freq_params.bandwidth, freq_params.sec_channel_offset,
- freq_params.ht_enabled ? " HT" : "",
- freq_params.vht_enabled ? " VHT" : "");
-
- ret = wpa_tdls_enable_chan_switch(wpa_s->wpa, peer, oper_class,
- &freq_params);
- if (ret)
- return wpas_dbus_error_unknown_error(
- message, "error processing TDLS channel switch");
-
- return NULL;
-}
-
-/*
- * wpas_dbus_handler_tdls_cancel_channel_switch - Disable channel switching with TDLS peer
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL indicating success or DBus error message on failure
- *
- * Handler function for "TDLSCancelChannelSwitch" method call of network
- * interface.
- */
-DBusMessage *
-wpas_dbus_handler_tdls_cancel_channel_switch(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 peer[ETH_ALEN];
- DBusMessage *error_reply;
- int ret;
-
- if (get_peer_hwaddr_helper(message, __func__, peer, &error_reply) < 0)
- return error_reply;
-
- wpa_printf(MSG_DEBUG, "dbus: TDLS_CANCEL_CHAN_SWITCH " MACSTR,
- MAC2STR(peer));
-
- ret = wpa_tdls_disable_chan_switch(wpa_s->wpa, peer);
- if (ret)
- return wpas_dbus_error_unknown_error(
- message, "error canceling TDLS channel switch");
-
- return NULL;
-}
-
-#endif /* CONFIG_TDLS */
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-/**
- * wpas_dbus_handler_save_config - Save configuration to configuration file
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on Success, Otherwise error message
- *
- * Handler function for "SaveConfig" method call of network interface.
- */
-DBusMessage * wpas_dbus_handler_save_config(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- int ret;
-
- if (!wpa_s->conf->update_config) {
- return wpas_dbus_error_unknown_error(
- message,
- "Not allowed to update configuration (update_config=0)");
- }
-
- ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
- if (ret)
- return wpas_dbus_error_unknown_error(
- message, "Failed to update configuration");
- return NULL;
-}
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-/**
- * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: A dbus message containing an error on failure or NULL on success
- *
- * Sets the PKCS #11 engine and module path.
- */
-DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter;
- char *value = NULL;
- char *pkcs11_engine_path = NULL;
- char *pkcs11_module_path = NULL;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &value);
- if (value == NULL) {
- return dbus_message_new_error(
- message, DBUS_ERROR_INVALID_ARGS,
- "Invalid pkcs11_engine_path argument");
- }
- /* Empty path defaults to NULL */
- if (os_strlen(value))
- pkcs11_engine_path = value;
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_get_basic(&iter, &value);
- if (value == NULL) {
- os_free(pkcs11_engine_path);
- return dbus_message_new_error(
- message, DBUS_ERROR_INVALID_ARGS,
- "Invalid pkcs11_module_path argument");
- }
- /* Empty path defaults to NULL */
- if (os_strlen(value))
- pkcs11_module_path = value;
-
- if (wpas_set_pkcs11_engine_and_module_path(wpa_s, pkcs11_engine_path,
- pkcs11_module_path))
- return dbus_message_new_error(
- message, DBUS_ERROR_FAILED,
- "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed.");
-
- if (wpa_s->dbus_new_path) {
- wpa_dbus_mark_property_changed(
- wpa_s->global->dbus, wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath");
- wpa_dbus_mark_property_changed(
- wpa_s->global->dbus, wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath");
- }
-
- return NULL;
-}
-
-
-/**
- * wpas_dbus_getter_capabilities - Return interface capabilities
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Capabilities" property of an interface.
- */
-dbus_bool_t wpas_dbus_getter_capabilities(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_driver_capa capa;
- int res;
- DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array,
- variant_iter;
- const char *scans[] = { "active", "passive", "ssid" };
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter) ||
- !wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
- goto nomem;
-
- res = wpa_drv_get_capa(wpa_s, &capa);
-
- /***** pairwise cipher */
- if (res < 0) {
-#ifdef CONFIG_NO_TKIP
- const char *args[] = {"ccmp", "none"};
-#else /* CONFIG_NO_TKIP */
- const char *args[] = {"ccmp", "tkip", "none"};
-#endif /* CONFIG_NO_TKIP */
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "Pairwise", args,
- ARRAY_SIZE(args)))
- goto nomem;
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ccmp-256")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "gcmp-256")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ccmp")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "gcmp")) ||
-#ifndef CONFIG_NO_TKIP
- ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "tkip")) ||
-#endif /* CONFIG_NO_TKIP */
- ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "none")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- }
-
- /***** group cipher */
- if (res < 0) {
- const char *args[] = {
- "ccmp",
-#ifndef CONFIG_NO_TKIP
- "tkip",
-#endif /* CONFIG_NO_TKIP */
-#ifdef CONFIG_WEP
- "wep104", "wep40"
-#endif /* CONFIG_WEP */
- };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "Group", args,
- ARRAY_SIZE(args)))
- goto nomem;
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ccmp-256")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "gcmp-256")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ccmp")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "gcmp")) ||
-#ifndef CONFIG_NO_TKIP
- ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "tkip")) ||
-#endif /* CONFIG_NO_TKIP */
-#ifdef CONFIG_WEP
- ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "wep104")) ||
- ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "wep40")) ||
-#endif /* CONFIG_WEP */
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- }
-
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "GroupMgmt",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- (res == 0 && (capa.enc & WPA_DRIVER_CAPA_ENC_BIP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "aes-128-cmac")) ||
- (res == 0 && (capa.enc & WPA_DRIVER_CAPA_ENC_BIP_GMAC_128) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "bip-gmac-128")) ||
- (res == 0 && (capa.enc & WPA_DRIVER_CAPA_ENC_BIP_GMAC_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "bip-gmac-256")) ||
- (res == 0 && (capa.enc & WPA_DRIVER_CAPA_ENC_BIP_CMAC_256) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "bip-cmac-256")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
-
- /***** key management */
- if (res < 0) {
- const char *args[] = {
- "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
-#ifdef CONFIG_WPS
- "wps",
-#endif /* CONFIG_WPS */
- "none"
- };
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "KeyMgmt", args,
- ARRAY_SIZE(args)))
- goto nomem;
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- !wpa_dbus_dict_string_array_add_element(&iter_array,
- "none") ||
- !wpa_dbus_dict_string_array_add_element(&iter_array,
- "ieee8021x"))
- goto nomem;
-
- if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
- if (!wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-eap") ||
- ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-ft-eap")))
- goto nomem;
-
-/* TODO: Ensure that driver actually supports sha256 encryption. */
- if (!wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-eap-sha256"))
- goto nomem;
- }
-
- if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
- if (!wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-psk") ||
- ((capa.key_mgmt &
- WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-ft-psk")))
- goto nomem;
-
-/* TODO: Ensure that driver actually supports sha256 encryption. */
- if (!wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa-psk-sha256"))
- goto nomem;
- }
-
- if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
- !wpa_dbus_dict_string_array_add_element(&iter_array,
- "wpa-none"))
- goto nomem;
-
-
-#ifdef CONFIG_WPS
- if (!wpa_dbus_dict_string_array_add_element(&iter_array,
- "wps"))
- goto nomem;
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_SAE
- if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) &&
- !wpa_dbus_dict_string_array_add_element(&iter_array, "sae"))
- goto nomem;
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_OWE
- if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) &&
- !wpa_dbus_dict_string_array_add_element(&iter_array, "owe"))
- goto nomem;
-#endif /* CONFIG_OWE */
-
- if (!wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- }
-
- /***** WPA protocol */
- if (res < 0) {
- const char *args[] = { "rsn", "wpa" };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "Protocol", args,
- ARRAY_SIZE(args)))
- goto nomem;
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "rsn")) ||
- ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
- WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "wpa")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- }
-
- /***** auth alg */
- if (res < 0) {
- const char *args[] = { "open", "shared", "leap" };
-
- if (!wpa_dbus_dict_append_string_array(
- &iter_dict, "AuthAlg", args,
- ARRAY_SIZE(args)))
- goto nomem;
- } else {
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
-
- if (((capa.auth & WPA_DRIVER_AUTH_OPEN) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "open")) ||
- ((capa.auth & WPA_DRIVER_AUTH_SHARED) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "shared")) ||
- ((capa.auth & WPA_DRIVER_AUTH_LEAP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "leap")) ||
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- }
-
- /***** Scan */
- if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
- ARRAY_SIZE(scans)))
- goto nomem;
-
- /***** Modes */
- if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Modes",
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array) ||
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "infrastructure") ||
- (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_IBSS) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ad-hoc")) ||
- (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_AP) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "ap")) ||
- (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
- !wpa_s->conf->p2p_disabled &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "p2p")) ||
-#ifdef CONFIG_MESH
- (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_MESH) &&
- !wpa_dbus_dict_string_array_add_element(
- &iter_array, "mesh")) ||
-#endif /* CONFIG_MESH */
- !wpa_dbus_dict_end_string_array(&iter_dict,
- &iter_dict_entry,
- &iter_dict_val,
- &iter_array))
- goto nomem;
- /***** Modes end */
-
- if (res >= 0) {
- dbus_int32_t max_scan_ssid = capa.max_scan_ssids;
-
- if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxScanSSID",
- max_scan_ssid))
- goto nomem;
- }
-
- if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
- !dbus_message_iter_close_container(iter, &variant_iter))
- goto nomem;
-
- return TRUE;
-
-nomem:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
-}
-
-
-/**
- * wpas_dbus_getter_state - Get interface state
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "State" property.
- */
-dbus_bool_t wpas_dbus_getter_state(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *str_state;
- char *state_ls, *tmp;
- dbus_bool_t success = FALSE;
-
- str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
-
- /* make state string lowercase to fit new DBus API convention
- */
- state_ls = tmp = os_strdup(str_state);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
- while (*tmp) {
- *tmp = tolower(*tmp);
- tmp++;
- }
-
- success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &state_ls, error);
-
- os_free(state_ls);
-
- return success;
-}
-
-
-/**
- * wpas_dbus_new_iface_get_scanning - Get interface scanning state
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "scanning" property.
- */
-dbus_bool_t wpas_dbus_getter_scanning(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &scanning, error);
-}
-
-
-/**
- * wpas_dbus_getter_ap_scan - Control roaming mode
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "ApScan" property.
- */
-dbus_bool_t wpas_dbus_getter_ap_scan(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &ap_scan, error);
-}
-
-
-/**
- * wpas_dbus_setter_ap_scan - Control roaming mode
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "ApScan" property.
- */
-dbus_bool_t wpas_dbus_setter_ap_scan(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t ap_scan;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
- &ap_scan))
- return FALSE;
-
- if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "ap_scan must be 0, 1, or 2");
- return FALSE;
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_fast_reauth - Control fast
- * reauthentication (TLS session resumption)
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "FastReauth" property.
- */
-dbus_bool_t wpas_dbus_getter_fast_reauth(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t fast_reauth = wpa_s->conf->fast_reauth ? TRUE : FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &fast_reauth, error);
-}
-
-
-/**
- * wpas_dbus_setter_fast_reauth - Control fast
- * reauthentication (TLS session resumption)
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "FastReauth" property.
- */
-dbus_bool_t wpas_dbus_setter_fast_reauth(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t fast_reauth;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
- &fast_reauth))
- return FALSE;
-
- wpa_s->conf->fast_reauth = fast_reauth;
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DisconnectReason" property. The reason is negative if it is
- * locally generated.
- */
-dbus_bool_t wpas_dbus_getter_disconnect_reason(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_int32_t reason = wpa_s->disconnect_reason;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
- &reason, error);
-}
-
-
-/**
- * wpas_dbus_getter_auth_status_code - Get most recent auth status code
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "AuthStatusCode" property.
- */
-dbus_bool_t wpas_dbus_getter_auth_status_code(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_int32_t reason = wpa_s->auth_status_code;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
- &reason, error);
-}
-
-
-/**
- * wpas_dbus_getter_assoc_status_code - Get most recent failed assoc status code
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "AssocStatusCode" property.
- */
-dbus_bool_t wpas_dbus_getter_assoc_status_code(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_int32_t status_code = wpa_s->assoc_status_code;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
- &status_code, error);
-}
-
-
-/**
- * wpas_dbus_getter_roam_time - Get most recent roam time
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "RoamTime" property.
- */
-dbus_bool_t wpas_dbus_getter_roam_time(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t roam_time = wpa_s->roam_time.sec * 1000 +
- wpa_s->roam_time.usec / 1000;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &roam_time, error);
-}
-
-
-/**
- * wpas_dbus_getter_roam_complete - Get most recent roam success or failure
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "RoamComplete" property.
- */
-dbus_bool_t wpas_dbus_getter_roam_complete(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t roam_complete = os_reltime_initialized(&wpa_s->roam_time);
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &roam_complete, error);
-}
-
-
-/**
- * wpas_dbus_getter_session_length - Get most recent BSS session length
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "SessionLength" property.
- */
-dbus_bool_t wpas_dbus_getter_session_length(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t session_length = wpa_s->session_length.sec * 1000 +
- wpa_s->session_length.usec / 1000;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &session_length, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_tm_status - Get most BSS Transition Management request
- * status code
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "BSSTMStatus" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_tm_status(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_WNM
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t bss_tm_status = wpa_s->bss_tm_status;
-#else /* CONFIG_WNM */
- dbus_uint32_t bss_tm_status = 0;
-#endif /* CONFIG_WNM */
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &bss_tm_status, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "BSSExpireAge" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_expire_age(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &expire_age, error);
-}
-
-
-/**
- * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "BSSExpireAge" property.
- */
-dbus_bool_t wpas_dbus_setter_bss_expire_age(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t expire_age;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
- &expire_age))
- return FALSE;
-
- if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "BSSExpireAge must be >= 10");
- return FALSE;
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "BSSExpireCount" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_expire_count(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_scan_count;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
- &expire_count, error);
-}
-
-
-/**
- * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "BSSExpireCount" property.
- */
-dbus_bool_t wpas_dbus_setter_bss_expire_count(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_uint32_t expire_count;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
- &expire_count))
- return FALSE;
-
- if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "BSSExpireCount must be > 0");
- return FALSE;
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_country - Control country code
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "Country" property.
- */
-dbus_bool_t wpas_dbus_getter_country(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char country[3];
- char *str = country;
-
- country[0] = wpa_s->conf->country[0];
- country[1] = wpa_s->conf->country[1];
- country[2] = '\0';
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &str, error);
-}
-
-
-/**
- * wpas_dbus_setter_country - Control country code
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "Country" property.
- */
-dbus_bool_t wpas_dbus_setter_country(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *country;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &country))
- return FALSE;
-
- if (!country[0] || !country[1]) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "invalid country code");
- return FALSE;
- }
-
- if (wpa_s->drv_priv != NULL && wpa_drv_set_country(wpa_s, country)) {
- wpa_printf(MSG_DEBUG, "Failed to set country");
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "failed to set country code");
- return FALSE;
- }
-
- wpa_s->conf->country[0] = country[0];
- wpa_s->conf->country[1] = country[1];
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_scan_interval - Get scan interval
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter function for "ScanInterval" property.
- */
-dbus_bool_t wpas_dbus_getter_scan_interval(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_int32_t scan_interval = wpa_s->scan_interval;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
- &scan_interval, error);
-}
-
-
-/**
- * wpas_dbus_setter_scan_interval - Control scan interval
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter function for "ScanInterval" property.
- */
-dbus_bool_t wpas_dbus_setter_scan_interval(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_int32_t scan_interval;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_INT32,
- &scan_interval))
- return FALSE;
-
- if (wpa_supplicant_set_scan_interval(wpa_s, scan_interval)) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "scan_interval must be >= 0");
- return FALSE;
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_ifname - Get interface name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Ifname" property.
- */
-dbus_bool_t wpas_dbus_getter_ifname(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->ifname, error);
-}
-
-
-/**
- * wpas_dbus_getter_driver - Get interface name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Driver" property.
- */
-dbus_bool_t wpas_dbus_getter_driver(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
- wpa_printf(MSG_DEBUG, "%s[dbus]: wpa_s has no driver set",
- __func__);
- dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
- __func__);
- return FALSE;
- }
-
- return wpas_dbus_string_property_getter(iter, wpa_s->driver->name,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_current_bss - Get current bss object path
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "CurrentBSS" property.
- */
-dbus_bool_t wpas_dbus_getter_current_bss(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
-
- if (wpa_s->current_bss && wpa_s->dbus_new_path)
- os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, wpa_s->current_bss->id);
- else
- os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
- &bss_obj_path, error);
-}
-
-
-/**
- * wpas_dbus_getter_current_network - Get current network object path
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "CurrentNetwork" property.
- */
-dbus_bool_t wpas_dbus_getter_current_network(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
-
- if (wpa_s->current_ssid && wpa_s->dbus_new_path)
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
- wpa_s->dbus_new_path, wpa_s->current_ssid->id);
- else
- os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
- &net_obj_path, error);
-}
-
-
-/**
- * wpas_dbus_getter_current_auth_mode - Get current authentication type
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "CurrentAuthMode" property.
- */
-dbus_bool_t wpas_dbus_getter_current_auth_mode(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *eap_mode;
- const char *auth_mode;
- char eap_mode_buf[WPAS_DBUS_AUTH_MODE_MAX];
-
- if (wpa_s->wpa_state != WPA_COMPLETED) {
- auth_mode = "INACTIVE";
- } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- eap_mode = wpa_supplicant_get_eap_mode(wpa_s);
- os_snprintf(eap_mode_buf, WPAS_DBUS_AUTH_MODE_MAX,
- "EAP-%s", eap_mode);
- auth_mode = eap_mode_buf;
-
- } else if (wpa_s->current_ssid) {
- auth_mode = wpa_key_mgmt_txt(wpa_s->key_mgmt,
- wpa_s->current_ssid->proto);
- } else {
- auth_mode = "UNKNOWN";
- }
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &auth_mode, error);
-}
-
-
-/**
- * wpas_dbus_getter_bridge_ifname - Get interface name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "BridgeIfname" property.
- */
-dbus_bool_t wpas_dbus_getter_bridge_ifname(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->bridge_ifname,
- error);
-}
-
-
-dbus_bool_t wpas_dbus_setter_bridge_ifname(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *bridge_ifname = NULL;
- const char *msg;
- int r;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &bridge_ifname))
- return FALSE;
-
- r = wpa_supplicant_update_bridge_ifname(wpa_s, bridge_ifname);
- if (r != 0) {
- switch (r) {
- case -EINVAL:
- msg = "invalid interface name";
- break;
- case -EBUSY:
- msg = "interface is busy";
- break;
- case -EIO:
- msg = "socket error";
- break;
- default:
- msg = "unknown error";
- break;
- }
- dbus_set_error_const(error, DBUS_ERROR_FAILED, msg);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_config_file - Get interface configuration file path
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ConfigFile" property.
- */
-dbus_bool_t wpas_dbus_getter_config_file(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->confname, error);
-}
-
-
-/**
- * wpas_dbus_getter_bsss - Get array of BSSs objects
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "BSSs" property.
- */
-dbus_bool_t wpas_dbus_getter_bsss(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_bss *bss;
- char **paths;
- unsigned int i = 0;
- dbus_bool_t success = FALSE;
-
- if (!wpa_s->dbus_new_path) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: no D-Bus interface", __func__);
- return FALSE;
- }
-
- paths = os_calloc(wpa_s->num_bss, sizeof(char *));
- if (!paths) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- /* Loop through scan results and append each result's object path */
- dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
- paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (paths[i] == NULL) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- goto out;
- }
- /* Construct the object path for this BSS. */
- os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
- wpa_s->dbus_new_path, bss->id);
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, wpa_s->num_bss,
- error);
-
-out:
- while (i)
- os_free(paths[--i]);
- os_free(paths);
- return success;
-}
-
-
-/**
- * wpas_dbus_getter_networks - Get array of networks objects
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Networks" property.
- */
-dbus_bool_t wpas_dbus_getter_networks(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_ssid *ssid;
- char **paths;
- unsigned int i = 0, num = 0;
- dbus_bool_t success = FALSE;
-
- if (!wpa_s->dbus_new_path) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: no D-Bus interface", __func__);
- return FALSE;
- }
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
- if (!network_is_persistent_group(ssid))
- num++;
-
- paths = os_calloc(num, sizeof(char *));
- if (!paths) {
- dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- /* Loop through configured networks and append object path of each */
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (network_is_persistent_group(ssid))
- continue;
- paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (paths[i] == NULL) {
- dbus_set_error(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- goto out;
- }
-
- /* Construct the object path for this network. */
- os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
- wpa_s->dbus_new_path, ssid->id);
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, num, error);
-
-out:
- while (i)
- os_free(paths[--i]);
- os_free(paths);
- return success;
-}
-
-
-/**
- * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: A dbus message containing the PKCS #11 engine path
- *
- * Getter for "PKCS11EnginePath" property.
- */
-dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter,
- wpa_s->conf->pkcs11_engine_path,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: A dbus message containing the PKCS #11 module path
- *
- * Getter for "PKCS11ModulePath" property.
- */
-dbus_bool_t wpas_dbus_getter_pkcs11_module_path(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter,
- wpa_s->conf->pkcs11_module_path,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_blobs - Get all blobs defined for this interface
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Blobs" property.
- */
-dbus_bool_t wpas_dbus_getter_blobs(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
- struct wpa_config_blob *blob;
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{say}", &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- "{say}", &dict_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- blob = wpa_s->conf->blobs;
- while (blob) {
- if (!dbus_message_iter_open_container(&dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter) ||
- !dbus_message_iter_append_basic(&entry_iter,
- DBUS_TYPE_STRING,
- &(blob->name)) ||
- !dbus_message_iter_open_container(&entry_iter,
- DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter) ||
- !dbus_message_iter_append_fixed_array(&array_iter,
- DBUS_TYPE_BYTE,
- &(blob->data),
- blob->len) ||
- !dbus_message_iter_close_container(&entry_iter,
- &array_iter) ||
- !dbus_message_iter_close_container(&dict_iter,
- &entry_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- return FALSE;
- }
-
- blob = blob->next;
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_iface_global(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- int ret;
- char buf[250];
- char *p = buf;
-
- if (!property_desc->data) {
- dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
- "Unhandled interface property %s",
- property_desc->dbus_property);
- return FALSE;
- }
-
- ret = wpa_config_get_value(property_desc->data, wpa_s->conf, buf,
- sizeof(buf));
- if (ret < 0)
- *p = '\0';
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &p,
- error);
-}
-
-
-dbus_bool_t wpas_dbus_setter_iface_global(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- const char *new_value = NULL;
- char buf[250];
- size_t combined_len;
- int ret;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &new_value))
- return FALSE;
-
- combined_len = os_strlen(property_desc->data) + os_strlen(new_value) +
- 3;
- if (combined_len >= sizeof(buf)) {
- dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
- "Interface property %s value too large",
- property_desc->dbus_property);
- return FALSE;
- }
-
- if (!new_value[0])
- new_value = "NULL";
-
- ret = os_snprintf(buf, combined_len, "%s=%s", property_desc->data,
- new_value);
- if (os_snprintf_error(combined_len, ret)) {
- dbus_set_error(error, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
- "Failed to construct new interface property %s",
- property_desc->dbus_property);
- return FALSE;
- }
-
- ret = wpa_config_process_global(wpa_s->conf, buf, -1);
- if (ret < 0) {
- dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
- "Failed to set interface property %s",
- property_desc->dbus_property);
- return FALSE;
- } else if (ret == 0) {
- wpa_supplicant_update_config(wpa_s);
- }
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_stas - Get connected stations for an interface
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: a list of stations
- *
- * Getter for "Stations" property.
- */
-dbus_bool_t wpas_dbus_getter_stas(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct sta_info *sta = NULL;
- char **paths = NULL;
- unsigned int i = 0, num = 0;
- dbus_bool_t success = FALSE;
-
- if (!wpa_s->dbus_new_path) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: no D-Bus interface", __func__);
- return FALSE;
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- struct hostapd_data *hapd;
-
- hapd = wpa_s->ap_iface->bss[0];
- sta = hapd->sta_list;
- num = hapd->num_sta;
- }
-#endif /* CONFIG_AP */
-
- paths = os_calloc(num, sizeof(char *));
- if (!paths) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- /* Loop through scan results and append each result's object path */
- for (; sta; sta = sta->next) {
- paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (!paths[i]) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- goto out;
- }
- /* Construct the object path for this BSS. */
- os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
- wpa_s->dbus_new_path, MAC2STR(sta->addr));
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, num,
- error);
-
-out:
- while (i)
- os_free(paths[--i]);
- os_free(paths);
- return success;
-}
-
-
-/**
- * wpas_dbus_setter_mac_address_randomization_mask - Set masks used for
- * MAC address randomization
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "MACAddressRandomizationMask" property.
- */
-dbus_bool_t wpas_dbus_setter_mac_address_randomization_mask(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
- const char *key;
- unsigned int rand_type = 0;
- const u8 *mask;
- int mask_len;
- unsigned int rand_types_to_disable = MAC_ADDR_RAND_ALL;
-
- dbus_message_iter_recurse(iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) {
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
- }
- dbus_message_iter_recurse(&variant_iter, &dict_iter);
- while (dbus_message_iter_get_arg_type(&dict_iter) ==
- DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(&dict_iter, &entry_iter);
- if (dbus_message_iter_get_arg_type(&entry_iter) !=
- DBUS_TYPE_STRING) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: key not a string", __func__);
- return FALSE;
- }
- dbus_message_iter_get_basic(&entry_iter, &key);
- dbus_message_iter_next(&entry_iter);
- if (dbus_message_iter_get_arg_type(&entry_iter) !=
- DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&entry_iter) !=
- DBUS_TYPE_BYTE) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: mask was not a byte array",
- __func__);
- return FALSE;
- }
- dbus_message_iter_recurse(&entry_iter, &array_iter);
- dbus_message_iter_get_fixed_array(&array_iter, &mask,
- &mask_len);
-
- if (os_strcmp(key, "scan") == 0) {
- rand_type = MAC_ADDR_RAND_SCAN;
- } else if (os_strcmp(key, "sched_scan") == 0) {
- rand_type = MAC_ADDR_RAND_SCHED_SCAN;
- } else if (os_strcmp(key, "pno") == 0) {
- rand_type = MAC_ADDR_RAND_PNO;
- } else {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: bad scan type \"%s\"",
- __func__, key);
- return FALSE;
- }
-
- if (mask_len != ETH_ALEN) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: malformed MAC mask given",
- __func__);
- return FALSE;
- }
-
- if (wpas_enable_mac_addr_randomization(
- wpa_s, rand_type, wpa_s->perm_addr, mask)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to set up MAC address randomization for %s",
- __func__, key);
- return FALSE;
- }
-
- wpa_printf(MSG_DEBUG,
- "%s: Enabled MAC address randomization for %s with mask: "
- MACSTR, wpa_s->ifname, key, MAC2STR(mask));
- rand_types_to_disable &= ~rand_type;
- dbus_message_iter_next(&dict_iter);
- }
-
- if (rand_types_to_disable &&
- wpas_disable_mac_addr_randomization(wpa_s, rand_types_to_disable)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to disable MAC address randomization",
- __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_mac_address_randomization_mask(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
- unsigned int i;
- u8 mask_buf[ETH_ALEN];
- /* Read docs on dbus_message_iter_append_fixed_array() for why this
- * is necessary... */
- u8 *mask = mask_buf;
- static const struct {
- const char *key;
- unsigned int type;
- } types[] = {
- { "scan", MAC_ADDR_RAND_SCAN },
- { "sched_scan", MAC_ADDR_RAND_SCHED_SCAN },
- { "pno", MAC_ADDR_RAND_PNO }
- };
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{say}", &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- "{say}", &dict_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- for (i = 0; i < ARRAY_SIZE(types); i++) {
- if (wpas_mac_addr_rand_scan_get_mask(wpa_s, types[i].type,
- mask))
- continue;
-
- if (!dbus_message_iter_open_container(&dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter) ||
- !dbus_message_iter_append_basic(&entry_iter,
- DBUS_TYPE_STRING,
- &types[i].key) ||
- !dbus_message_iter_open_container(&entry_iter,
- DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter) ||
- !dbus_message_iter_append_fixed_array(&array_iter,
- DBUS_TYPE_BYTE,
- &mask,
- ETH_ALEN) ||
- !dbus_message_iter_close_container(&entry_iter,
- &array_iter) ||
- !dbus_message_iter_close_container(&dict_iter,
- &entry_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- return FALSE;
- }
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_sta_address - Return the address of a connected station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Address" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_address(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
-
- sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
- if (!sta)
- return FALSE;
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- sta->addr, ETH_ALEN,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_sta_aid - Return the AID of a connected station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "AID" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_aid(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
-
- sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
- if (!sta)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
- &sta->aid,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_sta_caps - Return the capabilities of a station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Capabilities" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_caps(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
-
- sta = ap_get_sta(args->wpa_s->ap_iface->bss[0], args->sta);
- if (!sta)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
- &sta->capability,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_rx_packets - Return the received packets for a station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "RxPackets" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_rx_packets(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
- struct hostap_sta_driver_data data;
- struct hostapd_data *hapd;
-
- if (!args->wpa_s->ap_iface)
- return FALSE;
-
- hapd = args->wpa_s->ap_iface->bss[0];
- sta = ap_get_sta(hapd, args->sta);
- if (!sta)
- return FALSE;
-
- if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
- &data.rx_packets,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_tx_packets - Return the transmitted packets for a station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "TxPackets" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_tx_packets(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
- struct hostap_sta_driver_data data;
- struct hostapd_data *hapd;
-
- if (!args->wpa_s->ap_iface)
- return FALSE;
-
- hapd = args->wpa_s->ap_iface->bss[0];
- sta = ap_get_sta(hapd, args->sta);
- if (!sta)
- return FALSE;
-
- if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
- &data.tx_packets,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_tx_bytes - Return the transmitted bytes for a station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "TxBytes" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_tx_bytes(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
- struct hostap_sta_driver_data data;
- struct hostapd_data *hapd;
-
- if (!args->wpa_s->ap_iface)
- return FALSE;
-
- hapd = args->wpa_s->ap_iface->bss[0];
- sta = ap_get_sta(hapd, args->sta);
- if (!sta)
- return FALSE;
-
- if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
- &data.tx_bytes,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-/**
- * wpas_dbus_getter_rx_bytes - Return the received bytes for a station
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "RxBytes" property.
- */
-dbus_bool_t wpas_dbus_getter_sta_rx_bytes(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
-#ifdef CONFIG_AP
- struct sta_handler_args *args = user_data;
- struct sta_info *sta;
- struct hostap_sta_driver_data data;
- struct hostapd_data *hapd;
-
- if (!args->wpa_s->ap_iface)
- return FALSE;
-
- hapd = args->wpa_s->ap_iface->bss[0];
- sta = ap_get_sta(hapd, args->sta);
- if (!sta)
- return FALSE;
-
- if (hostapd_drv_read_sta_data(hapd, &data, sta->addr) < 0)
- return FALSE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT64,
- &data.rx_bytes,
- error);
-#else /* CONFIG_AP */
- return FALSE;
-#endif /* CONFIG_AP */
-}
-
-
-static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
- DBusError *error, const char *func_name)
-{
- struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id);
-
- if (!res) {
- wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found",
- func_name, args->id);
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: BSS %d not found",
- func_name, args->id);
- }
-
- return res;
-}
-
-
-/**
- * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "BSSID" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_bssid(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- res->bssid, ETH_ALEN,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "SSID" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_ssid(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- res->ssid, res->ssid_len,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Privacy" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_privacy(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- dbus_bool_t privacy;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &privacy, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_mode - Return the mode of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Mode" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_mode(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- const char *mode;
- const u8 *mesh;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
- if (bss_is_dmg(res)) {
- switch (res->caps & IEEE80211_CAP_DMG_MASK) {
- case IEEE80211_CAP_DMG_PBSS:
- case IEEE80211_CAP_DMG_IBSS:
- mode = "ad-hoc";
- break;
- case IEEE80211_CAP_DMG_AP:
- mode = "infrastructure";
- break;
- default:
- mode = "";
- break;
- }
- } else {
- mesh = wpa_bss_get_ie(res, WLAN_EID_MESH_ID);
- if (mesh)
- mode = "mesh";
- else if (res->caps & IEEE80211_CAP_IBSS)
- mode = "ad-hoc";
- else
- mode = "infrastructure";
- }
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
- &mode, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Level" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_signal(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- s16 level;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- level = (s16) res->level;
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
- &level, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Frequency" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_frequency(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- u16 freq;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- freq = (u16) res->freq;
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
- &freq, error);
-}
-
-
-static int cmp_u8s_desc(const void *a, const void *b)
-{
- return (*(u8 *) b - *(u8 *) a);
-}
-
-
-/**
- * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Rates" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_rates(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- u8 *ie_rates = NULL;
- u32 *real_rates;
- int rates_num, i;
- dbus_bool_t success = FALSE;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
- if (rates_num < 0)
- return FALSE;
-
- qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
-
- real_rates = os_malloc(sizeof(u32) * rates_num);
- if (!real_rates) {
- os_free(ie_rates);
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- for (i = 0; i < rates_num; i++)
- real_rates[i] = ie_rates[i] * 500000;
-
- success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32,
- real_rates, rates_num,
- error);
-
- os_free(ie_rates);
- os_free(real_rates);
- return success;
-}
-
-
-static dbus_bool_t wpas_dbus_get_bss_security_prop(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, struct wpa_ie_data *ie_data, DBusError *error)
-{
- DBusMessageIter iter_dict, variant_iter;
- const char *group;
- const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
- const char *key_mgmt[16]; /* max 16 key managements may be supported */
- int n;
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter))
- goto nomem;
-
- if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
- goto nomem;
-
- /*
- * KeyMgmt
- *
- * When adding a new entry here, please take care to extend key_mgmt[]
- * and keep documentation in doc/dbus.doxygen up to date.
- */
- n = 0;
- if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
- key_mgmt[n++] = "wpa-psk";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
- key_mgmt[n++] = "wpa-ft-psk";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
- key_mgmt[n++] = "wpa-psk-sha256";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
- key_mgmt[n++] = "wpa-eap";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
- key_mgmt[n++] = "wpa-ft-eap";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
- key_mgmt[n++] = "wpa-eap-sha256";
-#ifdef CONFIG_SUITEB
- if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
- key_mgmt[n++] = "wpa-eap-suite-b";
-#endif /* CONFIG_SUITEB */
-#ifdef CONFIG_SUITEB192
- if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
- key_mgmt[n++] = "wpa-eap-suite-b-192";
-#endif /* CONFIG_SUITEB192 */
-#ifdef CONFIG_FILS
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FILS_SHA256)
- key_mgmt[n++] = "wpa-fils-sha256";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FILS_SHA384)
- key_mgmt[n++] = "wpa-fils-sha384";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256)
- key_mgmt[n++] = "wpa-ft-fils-sha256";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384)
- key_mgmt[n++] = "wpa-ft-fils-sha384";
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_SAE
- if (ie_data->key_mgmt & WPA_KEY_MGMT_SAE)
- key_mgmt[n++] = "sae";
- if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_SAE)
- key_mgmt[n++] = "ft-sae";
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_OWE
- if (ie_data->key_mgmt & WPA_KEY_MGMT_OWE)
- key_mgmt[n++] = "owe";
-#endif /* CONFIG_OWE */
- if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
- key_mgmt[n++] = "wpa-none";
-
- if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
- key_mgmt, n))
- goto nomem;
-
- /* Group */
- switch (ie_data->group_cipher) {
-#ifdef CONFIG_WEP
- case WPA_CIPHER_WEP40:
- group = "wep40";
- break;
- case WPA_CIPHER_WEP104:
- group = "wep104";
- break;
-#endif /* CONFIG_WEP */
-#ifndef CONFIG_NO_TKIP
- case WPA_CIPHER_TKIP:
- group = "tkip";
- break;
-#endif /* CONFIG_NO_TKIP */
- case WPA_CIPHER_CCMP:
- group = "ccmp";
- break;
- case WPA_CIPHER_GCMP:
- group = "gcmp";
- break;
- case WPA_CIPHER_CCMP_256:
- group = "ccmp-256";
- break;
- case WPA_CIPHER_GCMP_256:
- group = "gcmp-256";
- break;
- default:
- group = "";
- break;
- }
-
- if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
- goto nomem;
-
- /* Pairwise */
- n = 0;
-#ifndef CONFIG_NO_TKIP
- if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
- pairwise[n++] = "tkip";
-#endif /* CONFIG_NO_TKIP */
- if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
- pairwise[n++] = "ccmp";
- if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP)
- pairwise[n++] = "gcmp";
- if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP_256)
- pairwise[n++] = "ccmp-256";
- if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP_256)
- pairwise[n++] = "gcmp-256";
-
- if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
- pairwise, n))
- goto nomem;
-
- /* Management group (RSN only) */
- if (ie_data->proto == WPA_PROTO_RSN) {
- switch (ie_data->mgmt_group_cipher) {
- case WPA_CIPHER_AES_128_CMAC:
- group = "aes128cmac";
- break;
- default:
- group = "";
- break;
- }
-
- if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
- group))
- goto nomem;
- }
-
- if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
- !dbus_message_iter_close_container(iter, &variant_iter))
- goto nomem;
-
- return TRUE;
-
-nomem:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
-}
-
-
-/**
- * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "WPA" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_wpa(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- struct wpa_ie_data wpa_data;
- const u8 *ie;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- os_memset(&wpa_data, 0, sizeof(wpa_data));
- ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
- if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "failed to parse WPA IE");
- return FALSE;
- }
-
- return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "RSN" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_rsn(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- struct wpa_ie_data wpa_data;
- const u8 *ie;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- os_memset(&wpa_data, 0, sizeof(wpa_data));
- ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
- if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "failed to parse RSN IE");
- return FALSE;
- }
-
- return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "WPS" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_wps(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
-#ifdef CONFIG_WPS
- struct wpabuf *wps_ie;
-#endif /* CONFIG_WPS */
- DBusMessageIter iter_dict, variant_iter;
- int wps_support = 0;
- const char *type = "";
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter) ||
- !wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
- goto nomem;
-
-#ifdef CONFIG_WPS
- wps_ie = wpa_bss_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
- if (wps_ie) {
- wps_support = 1;
- if (wps_is_selected_pbc_registrar(wps_ie))
- type = "pbc";
- else if (wps_is_selected_pin_registrar(wps_ie))
- type = "pin";
-
- wpabuf_free(wps_ie);
- }
-#endif /* CONFIG_WPS */
-
- if ((wps_support && !wpa_dbus_dict_append_string(&iter_dict, "Type", type)) ||
- !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) ||
- !dbus_message_iter_close_container(iter, &variant_iter))
- goto nomem;
-
- return TRUE;
-
-nomem:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
-}
-
-
-/**
- * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "IEs" property.
- */
-dbus_bool_t wpas_dbus_getter_bss_ies(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- wpa_bss_ie_ptr(res),
- res->ie_len, error);
-}
-
-
-/**
- * wpas_dbus_getter_bss_age - Return time in seconds since BSS was last seen
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for BSS age
- */
-dbus_bool_t wpas_dbus_getter_bss_age(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct bss_handler_args *args = user_data;
- struct wpa_bss *res;
- struct os_reltime now, diff = { 0, 0 };
- u32 age;
-
- res = get_bss_helper(args, error, __func__);
- if (!res)
- return FALSE;
-
- os_get_reltime(&now);
- os_reltime_sub(&now, &res->last_update, &diff);
- age = diff.sec > 0 ? diff.sec : 0;
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, &age,
- error);
-}
-
-
-/**
- * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "enabled" property of a configured network.
- */
-dbus_bool_t wpas_dbus_getter_enabled(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
- dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &enabled, error);
-}
-
-
-/**
- * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "Enabled" property of a configured network.
- */
-dbus_bool_t wpas_dbus_setter_enabled(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
- struct wpa_supplicant *wpa_s;
- struct wpa_ssid *ssid;
- dbus_bool_t enable;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
- &enable))
- return FALSE;
-
- wpa_s = net->wpa_s;
- ssid = net->ssid;
-
- if (enable)
- wpa_supplicant_enable_network(wpa_s, ssid);
- else
- wpa_supplicant_disable_network(wpa_s, ssid);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_network_properties - Get options for a configured network
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Properties" property of a configured network.
- */
-dbus_bool_t wpas_dbus_getter_network_properties(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
- DBusMessageIter variant_iter, dict_iter;
- char **iterator;
- char **props = wpa_config_get_all(net->ssid, 1);
- dbus_bool_t success = FALSE;
-
- if (!props) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}",
- &variant_iter) ||
- !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- goto out;
- }
-
- iterator = props;
- while (*iterator) {
- if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
- *(iterator + 1))) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- goto out;
- }
- iterator += 2;
- }
-
-
- if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- goto out;
- }
-
- success = TRUE;
-
-out:
- iterator = props;
- while (*iterator) {
- os_free(*iterator);
- iterator++;
- }
- os_free(props);
- return success;
-}
-
-
-/**
- * wpas_dbus_setter_network_properties - Set options for a configured network
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "Properties" property of a configured network.
- */
-dbus_bool_t wpas_dbus_setter_network_properties(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
- struct wpa_ssid *ssid = net->ssid;
- DBusMessageIter variant_iter;
-
- dbus_message_iter_recurse(iter, &variant_iter);
- return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
-}
-
-
-#ifdef CONFIG_AP
-
-DBusMessage * wpas_dbus_handler_subscribe_preq(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *priv = wpa_s->global->dbus;
- char *name;
-
- if (wpa_s->preq_notify_peer != NULL) {
- if (os_strcmp(dbus_message_get_sender(message),
- wpa_s->preq_notify_peer) == 0)
- return NULL;
-
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE,
- "Another application is already subscribed");
- }
-
- name = os_strdup(dbus_message_get_sender(message));
- if (!name)
- return wpas_dbus_error_no_memory(message);
-
- wpa_s->preq_notify_peer = name;
-
- /* Subscribe to clean up if application closes socket */
- wpas_dbus_subscribe_noc(priv);
-
- /*
- * Double-check it's still alive to make sure that we didn't
- * miss the NameOwnerChanged signal, e.g. while strdup'ing.
- */
- if (!dbus_bus_name_has_owner(priv->con, name, NULL)) {
- /*
- * Application no longer exists, clean up.
- * The return value is irrelevant now.
- *
- * Need to check if the NameOwnerChanged handling
- * already cleaned up because we have processed
- * DBus messages while checking if the name still
- * has an owner.
- */
- if (!wpa_s->preq_notify_peer)
- return NULL;
- os_free(wpa_s->preq_notify_peer);
- wpa_s->preq_notify_peer = NULL;
- wpas_dbus_unsubscribe_noc(priv);
- }
-
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_unsubscribe_preq(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- struct wpas_dbus_priv *priv = wpa_s->global->dbus;
-
- if (!wpa_s->preq_notify_peer)
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_NO_SUBSCRIPTION,
- "Not subscribed");
-
- if (os_strcmp(wpa_s->preq_notify_peer,
- dbus_message_get_sender(message)))
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM,
- "Can't unsubscribe others");
-
- os_free(wpa_s->preq_notify_peer);
- wpa_s->preq_notify_peer = NULL;
- wpas_dbus_unsubscribe_noc(priv);
- return NULL;
-}
-
-
-void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len, u32 ssi_signal)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict_iter;
- struct wpas_dbus_priv *priv = wpa_s->global->dbus;
-
- /* Do nothing if the control interface is not turned on */
- if (priv == NULL || !wpa_s->dbus_new_path)
- return;
-
- if (wpa_s->preq_notify_peer == NULL)
- return;
-
- msg = dbus_message_new_signal(wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE,
- "ProbeRequest");
- if (msg == NULL)
- return;
-
- dbus_message_set_destination(msg, wpa_s->preq_notify_peer);
-
- dbus_message_iter_init_append(msg, &iter);
-
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- (addr && !wpa_dbus_dict_append_byte_array(&dict_iter, "addr",
- (const char *) addr,
- ETH_ALEN)) ||
- (dst && !wpa_dbus_dict_append_byte_array(&dict_iter, "dst",
- (const char *) dst,
- ETH_ALEN)) ||
- (bssid && !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
- (const char *) bssid,
- ETH_ALEN)) ||
- (ie && ie_len && !wpa_dbus_dict_append_byte_array(&dict_iter, "ies",
- (const char *) ie,
- ie_len)) ||
- (ssi_signal && !wpa_dbus_dict_append_int32(&dict_iter, "signal",
- ssi_signal)) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter))
- goto fail;
-
- dbus_connection_send(priv->con, msg, NULL);
- goto out;
-fail:
- wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
-out:
- dbus_message_unref(msg);
-}
-
-#endif /* CONFIG_AP */
-
-
-DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 *ielems;
- int len;
- struct ieee802_11_elems elems;
- dbus_int32_t frame_id;
- DBusMessageIter iter, array;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &frame_id);
- if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid ID");
- }
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &array);
- dbus_message_iter_get_fixed_array(&array, &ielems, &len);
- if (!ielems || len == 0) {
- return dbus_message_new_error(
- message, DBUS_ERROR_INVALID_ARGS, "Invalid value");
- }
-
- if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Parse error");
- }
-
- wpa_s = wpas_vendor_elem(wpa_s, frame_id);
- if (!wpa_s->vendor_elem[frame_id]) {
- wpa_s->vendor_elem[frame_id] = wpabuf_alloc_copy(ielems, len);
- wpas_vendor_elem_update(wpa_s);
- return NULL;
- }
-
- if (wpabuf_resize(&wpa_s->vendor_elem[frame_id], len) < 0) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Resize error");
- }
-
- wpabuf_put_data(wpa_s->vendor_elem[frame_id], ielems, len);
- wpas_vendor_elem_update(wpa_s);
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply;
- DBusMessageIter iter, array_iter;
- dbus_int32_t frame_id;
- const u8 *elem;
- size_t elem_len;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &frame_id);
-
- if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid ID");
- }
-
- wpa_s = wpas_vendor_elem(wpa_s, frame_id);
- if (!wpa_s->vendor_elem[frame_id]) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "ID value does not exist");
- }
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return wpas_dbus_error_no_memory(message);
-
- dbus_message_iter_init_append(reply, &iter);
-
- elem = wpabuf_head_u8(wpa_s->vendor_elem[frame_id]);
- elem_len = wpabuf_len(wpa_s->vendor_elem[frame_id]);
-
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter) ||
- !dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
- &elem, elem_len) ||
- !dbus_message_iter_close_container(&iter, &array_iter)) {
- dbus_message_unref(reply);
- reply = wpas_dbus_error_no_memory(message);
- }
-
- return reply;
-}
-
-
-DBusMessage * wpas_dbus_handler_vendor_elem_remove(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- u8 *ielems;
- int len;
- struct ieee802_11_elems elems;
- DBusMessageIter iter, array;
- dbus_int32_t frame_id;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &frame_id);
- if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid ID");
- }
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &array);
- dbus_message_iter_get_fixed_array(&array, &ielems, &len);
- if (!ielems || len == 0) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid value");
- }
-
- wpa_s = wpas_vendor_elem(wpa_s, frame_id);
-
- if (len == 1 && *ielems == '*') {
- wpabuf_free(wpa_s->vendor_elem[frame_id]);
- wpa_s->vendor_elem[frame_id] = NULL;
- wpas_vendor_elem_update(wpa_s);
- return NULL;
- }
-
- if (!wpa_s->vendor_elem[frame_id]) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "ID value does not exist");
- }
-
- if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Parse error");
- }
-
- if (wpas_vendor_elem_remove(wpa_s, frame_id, ielems, len) == 0)
- return NULL;
-
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Not found");
-}
-
-
-#ifdef CONFIG_MESH
-
-/**
- * wpas_dbus_getter_mesh_peers - Get connected mesh peers
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "MeshPeers" property.
- */
-dbus_bool_t wpas_dbus_getter_mesh_peers(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct hostapd_data *hapd;
- struct sta_info *sta;
- DBusMessageIter variant_iter, array_iter;
- int i;
- DBusMessageIter inner_array_iter;
-
- if (!wpa_s->ifmsh)
- return FALSE;
- hapd = wpa_s->ifmsh->bss[0];
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter))
- return FALSE;
-
- for (sta = hapd->sta_list; sta; sta = sta->next) {
- if (!dbus_message_iter_open_container(
- &array_iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &inner_array_iter))
- return FALSE;
-
- for (i = 0; i < ETH_ALEN; i++) {
- if (!dbus_message_iter_append_basic(&inner_array_iter,
- DBUS_TYPE_BYTE,
- &(sta->addr[i])))
- return FALSE;
- }
-
- if (!dbus_message_iter_close_container(
- &array_iter, &inner_array_iter))
- return FALSE;
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter))
- return FALSE;
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_mesh_group - Get mesh group
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "MeshGroup" property.
- */
-dbus_bool_t wpas_dbus_getter_mesh_group(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (!wpa_s->ifmsh || !ssid)
- return FALSE;
-
- if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- (char *) ssid->ssid,
- ssid->ssid_len, error)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: error constructing reply", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-#endif /* CONFIG_MESH */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
deleted file mode 100644
index a421083f7fe2..000000000000
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef CTRL_IFACE_DBUS_NEW_HANDLERS_H
-#define CTRL_IFACE_DBUS_NEW_HANDLERS_H
-
-#include "dbus_new_helpers.h"
-
-struct network_handler_args {
- struct wpa_supplicant *wpa_s;
- struct wpa_ssid *ssid;
-};
-
-struct bss_handler_args {
- struct wpa_supplicant *wpa_s;
- unsigned int id;
-};
-
-struct sta_handler_args {
- struct wpa_supplicant *wpa_s;
- const u8 *sta;
-};
-
-dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
- const int type,
- const void *val,
- DBusError *error);
-
-dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
- DBusError *error,
- const int type, void *val);
-
-dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
- const int type,
- const void *array,
- size_t array_len,
- DBusError *error);
-
-dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
- const int type,
- struct wpabuf **array,
- size_t array_len,
- DBusError *error);
-
-dbus_bool_t wpas_dbus_string_property_getter(DBusMessageIter *iter,
- const void *val,
- DBusError *error);
-
-DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
- struct wpa_global *global);
-
-DBusMessage * wpas_dbus_handler_expect_disconnect(DBusMessage *message,
- struct wpa_global *global);
-
-DECLARE_ACCESSOR(wpas_dbus_getter_debug_level);
-DECLARE_ACCESSOR(wpas_dbus_getter_debug_timestamp);
-DECLARE_ACCESSOR(wpas_dbus_getter_debug_show_keys);
-DECLARE_ACCESSOR(wpas_dbus_setter_debug_level);
-DECLARE_ACCESSOR(wpas_dbus_setter_debug_timestamp);
-DECLARE_ACCESSOR(wpas_dbus_setter_debug_show_keys);
-DECLARE_ACCESSOR(wpas_dbus_getter_interfaces);
-DECLARE_ACCESSOR(wpas_dbus_getter_eap_methods);
-DECLARE_ACCESSOR(wpas_dbus_getter_global_capabilities);
-DECLARE_ACCESSOR(wpas_dbus_getter_iface_global);
-DECLARE_ACCESSOR(wpas_dbus_setter_iface_global);
-
-DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_abort_scan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- DBusMessageIter *iter,
- DBusError *error);
-
-DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_reconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_all_networks(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_roam(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage *
-wpas_dbus_handler_interworking_select(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
-DECLARE_ACCESSOR(wpas_dbus_getter_state);
-DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
-DECLARE_ACCESSOR(wpas_dbus_getter_ap_scan);
-DECLARE_ACCESSOR(wpas_dbus_setter_ap_scan);
-DECLARE_ACCESSOR(wpas_dbus_getter_fast_reauth);
-DECLARE_ACCESSOR(wpas_dbus_setter_fast_reauth);
-DECLARE_ACCESSOR(wpas_dbus_getter_disconnect_reason);
-DECLARE_ACCESSOR(wpas_dbus_getter_disassociate_reason);
-DECLARE_ACCESSOR(wpas_dbus_getter_auth_status_code);
-DECLARE_ACCESSOR(wpas_dbus_getter_assoc_status_code);
-DECLARE_ACCESSOR(wpas_dbus_getter_roam_time);
-DECLARE_ACCESSOR(wpas_dbus_getter_roam_complete);
-DECLARE_ACCESSOR(wpas_dbus_getter_session_length);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_tm_status);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_age);
-DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_age);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_expire_count);
-DECLARE_ACCESSOR(wpas_dbus_setter_bss_expire_count);
-DECLARE_ACCESSOR(wpas_dbus_getter_country);
-DECLARE_ACCESSOR(wpas_dbus_setter_country);
-DECLARE_ACCESSOR(wpas_dbus_getter_scan_interval);
-DECLARE_ACCESSOR(wpas_dbus_setter_scan_interval);
-DECLARE_ACCESSOR(wpas_dbus_getter_ifname);
-DECLARE_ACCESSOR(wpas_dbus_getter_driver);
-DECLARE_ACCESSOR(wpas_dbus_getter_bridge_ifname);
-DECLARE_ACCESSOR(wpas_dbus_setter_bridge_ifname);
-DECLARE_ACCESSOR(wpas_dbus_getter_config_file);
-DECLARE_ACCESSOR(wpas_dbus_getter_current_bss);
-DECLARE_ACCESSOR(wpas_dbus_getter_current_network);
-DECLARE_ACCESSOR(wpas_dbus_getter_current_auth_mode);
-DECLARE_ACCESSOR(wpas_dbus_getter_bsss);
-DECLARE_ACCESSOR(wpas_dbus_getter_networks);
-DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_engine_path);
-DECLARE_ACCESSOR(wpas_dbus_getter_pkcs11_module_path);
-DECLARE_ACCESSOR(wpas_dbus_getter_blobs);
-DECLARE_ACCESSOR(wpas_dbus_getter_stas);
-DECLARE_ACCESSOR(wpas_dbus_getter_mac_address_randomization_mask);
-DECLARE_ACCESSOR(wpas_dbus_setter_mac_address_randomization_mask);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_address);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_aid);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_caps);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_packets);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_packets);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_tx_bytes);
-DECLARE_ACCESSOR(wpas_dbus_getter_sta_rx_bytes);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_bssid);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_ssid);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_privacy);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_mode);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_signal);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_frequency);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_rates);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_wpa);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_rsn);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_wps);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_ies);
-DECLARE_ACCESSOR(wpas_dbus_getter_bss_age);
-DECLARE_ACCESSOR(wpas_dbus_getter_enabled);
-DECLARE_ACCESSOR(wpas_dbus_setter_enabled);
-DECLARE_ACCESSOR(wpas_dbus_getter_network_properties);
-DECLARE_ACCESSOR(wpas_dbus_setter_network_properties);
-
-DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_wps_cancel(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DECLARE_ACCESSOR(wpas_dbus_getter_process_credentials);
-DECLARE_ACCESSOR(wpas_dbus_setter_process_credentials);
-DECLARE_ACCESSOR(wpas_dbus_getter_config_methods);
-DECLARE_ACCESSOR(wpas_dbus_setter_config_methods);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_device_name);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_device_name);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_manufacturer);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_manufacturer);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_device_model_name);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_device_model_name);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_device_model_number);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_device_model_number);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_device_serial_number);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_device_serial_number);
-DECLARE_ACCESSOR(wpas_dbus_getter_wps_device_device_type);
-DECLARE_ACCESSOR(wpas_dbus_setter_wps_device_device_type);
-
-DECLARE_ACCESSOR(wpas_dbus_getter_mesh_peers);
-DECLARE_ACCESSOR(wpas_dbus_getter_mesh_group);
-
-DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage *
-wpas_dbus_handler_tdls_channel_switch(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage *
-wpas_dbus_handler_tdls_cancel_channel_switch(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_vendor_elem_remove(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_save_config(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
- const char *arg);
-DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
- const char *arg);
-DBusMessage * wpas_dbus_error_no_memory(DBusMessage *message);
-
-DBusMessage * wpas_dbus_handler_subscribe_preq(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-DBusMessage * wpas_dbus_handler_unsubscribe_preq(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-#endif /* CTRL_IFACE_DBUS_HANDLERS_NEW_H */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
deleted file mode 100644
index de79178f4655..000000000000
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ /dev/null
@@ -1,3107 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface (P2P)
- * Copyright (c) 2011-2012, Intel Corporation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "utils/includes.h"
-#include "common.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../wps_supplicant.h"
-#include "../notify.h"
-#include "dbus_new_helpers.h"
-#include "dbus_new.h"
-#include "dbus_new_handlers.h"
-#include "dbus_new_handlers_p2p.h"
-#include "dbus_dict_helpers.h"
-#include "p2p/p2p.h"
-#include "common/ieee802_11_defs.h"
-#include "ap/hostapd.h"
-#include "ap/ap_config.h"
-#include "ap/wps_hostapd.h"
-
-#include "../p2p_supplicant.h"
-#include "../wifi_display.h"
-
-
-static int wpas_dbus_validate_dbus_ipaddr(struct wpa_dbus_dict_entry entry)
-{
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE ||
- entry.array_len != 4)
- return 0;
-
- return 1;
-}
-
-
-static dbus_bool_t no_p2p_mgmt_interface(DBusError *error)
-{
- dbus_set_error_const(error, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
- "Could not find P2P mgmt interface");
- return FALSE;
-}
-
-
-/**
- * Parses out the mac address from the peer object path.
- * @peer_path - object path of the form
- * /fi/w1/wpa_supplicant1/Interfaces/n/Peers/00112233445566 (no colons)
- * @addr - out param must be of ETH_ALEN size
- * Returns 0 if valid (including MAC), -1 otherwise
- */
-static int parse_peer_object_path(const char *peer_path, u8 addr[ETH_ALEN])
-{
- const char *p;
-
- if (!peer_path)
- return -1;
- p = os_strrchr(peer_path, '/');
- if (!p)
- return -1;
- p++;
- return hwaddr_compact_aton(p, addr);
-}
-
-
-/**
- * wpas_dbus_error_persistent_group_unknown - Return a new PersistentGroupUnknown
- * error message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an invalid persistent group error.
- */
-static DBusMessage *
-wpas_dbus_error_persistent_group_unknown(DBusMessage *message)
-{
- return dbus_message_new_error(
- message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
- "There is no such persistent group in this P2P device.");
-}
-
-
-/**
- * wpas_dbus_error_no_p2p_mgmt_iface - Return a new InterfaceUnknown error
- * message
- * @message: Pointer to incoming dbus message this error refers to
- * Returns: a dbus error message
- *
- * Convenience function to create and return an unknown interface error.
- */
-static DBusMessage * wpas_dbus_error_no_p2p_mgmt_iface(DBusMessage *message)
-{
- wpa_printf(MSG_DEBUG, "dbus: Could not find P2P mgmt interface");
- return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
- "Could not find P2P mgmt interface");
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- struct wpa_dbus_dict_entry entry;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- DBusMessageIter iter_dict;
- unsigned int timeout = 0;
- enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
- int num_req_dev_types = 0;
- unsigned int i;
- u8 *req_dev_types = NULL;
- unsigned int freq = 0;
-
- dbus_message_iter_init(message, &iter);
- entry.key = NULL;
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "Timeout") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- timeout = entry.uint32_value;
- } else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != WPAS_DBUS_TYPE_BINARRAY)
- goto error_clear;
-
- os_free(req_dev_types);
- req_dev_types =
- os_malloc(WPS_DEV_TYPE_LEN * entry.array_len);
- if (!req_dev_types)
- goto error_clear;
-
- for (i = 0; i < entry.array_len; i++) {
- if (wpabuf_len(entry.binarray_value[i]) !=
- WPS_DEV_TYPE_LEN)
- goto error_clear;
- os_memcpy(req_dev_types + i * WPS_DEV_TYPE_LEN,
- wpabuf_head(entry.binarray_value[i]),
- WPS_DEV_TYPE_LEN);
- }
- num_req_dev_types = entry.array_len;
- } else if (os_strcmp(entry.key, "DiscoveryType") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (os_strcmp(entry.str_value, "start_with_full") == 0)
- type = P2P_FIND_START_WITH_FULL;
- else if (os_strcmp(entry.str_value, "social") == 0)
- type = P2P_FIND_ONLY_SOCIAL;
- else if (os_strcmp(entry.str_value, "progressive") == 0)
- type = P2P_FIND_PROGRESSIVE;
- else
- goto error_clear;
- } else if (os_strcmp(entry.key, "freq") == 0 &&
- (entry.type == DBUS_TYPE_INT32 ||
- entry.type == DBUS_TYPE_UINT32)) {
- freq = entry.uint32_value;
- } else
- goto error_clear;
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s) {
- reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
- goto error_nop2p;
- }
-
- if (wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types,
- req_dev_types, NULL, 0, 0, NULL, freq, false))
- reply = wpas_dbus_error_unknown_error(
- message, "Could not start P2P find");
-
- os_free(req_dev_types);
- return reply;
-
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- reply = wpas_dbus_error_invalid_args(message, entry.key);
-error_nop2p:
- os_free(req_dev_types);
- return reply;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (wpa_s)
- wpas_p2p_stop_find(wpa_s);
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter;
- char *peer_object_path = NULL;
- u8 peer_addr[ETH_ALEN];
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &peer_object_path);
-
- if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
- return wpas_dbus_error_invalid_args(message, NULL);
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return wpas_dbus_error_no_p2p_mgmt_iface(message);
-
- if (wpas_p2p_reject(wpa_s, peer_addr) < 0)
- return wpas_dbus_error_unknown_error(message,
- "Failed to call wpas_p2p_reject method.");
-
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- dbus_int32_t timeout = 0;
-
- if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &timeout,
- DBUS_TYPE_INVALID))
- return wpas_dbus_error_no_memory(message);
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return wpas_dbus_error_no_p2p_mgmt_iface(message);
-
- if (wpas_p2p_listen(wpa_s, (unsigned int) timeout)) {
- return dbus_message_new_error(message,
- WPAS_DBUS_ERROR_UNKNOWN_ERROR,
- "Could not start P2P listen");
- }
-
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_extendedlisten(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- unsigned int period = 0, interval = 0;
- struct wpa_dbus_dict_entry entry;
- DBusMessageIter iter;
- DBusMessageIter iter_dict;
-
- dbus_message_iter_init(message, &iter);
- entry.key = NULL;
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "period") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- period = entry.uint32_value;
- else if (os_strcmp(entry.key, "interval") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- interval = entry.uint32_value;
- else
- goto error_clear;
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return wpas_dbus_error_no_p2p_mgmt_iface(message);
-
- if (wpas_p2p_ext_listen(wpa_s, period, interval))
- return wpas_dbus_error_unknown_error(
- message, "failed to initiate a p2p_ext_listen.");
-
- return NULL;
-
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- return wpas_dbus_error_invalid_args(message, entry.key);
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_presence_request(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
- struct wpa_dbus_dict_entry entry;
- DBusMessageIter iter;
- DBusMessageIter iter_dict;
-
- dbus_message_iter_init(message, &iter);
- entry.key = NULL;
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "duration1") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- dur1 = entry.uint32_value;
- else if (os_strcmp(entry.key, "interval1") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- int1 = entry.uint32_value;
- else if (os_strcmp(entry.key, "duration2") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- dur2 = entry.uint32_value;
- else if (os_strcmp(entry.key, "interval2") == 0 &&
- entry.type == DBUS_TYPE_INT32)
- int2 = entry.uint32_value;
- else
- goto error_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2) < 0)
- return wpas_dbus_error_unknown_error(message,
- "Failed to invoke presence request.");
-
- return NULL;
-
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- return wpas_dbus_error_invalid_args(message, entry.key);
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *pg_object_path = NULL;
- int persistent_group = 0;
- int freq = 0;
- char *iface = NULL;
- unsigned int group_id = 0;
- struct wpa_ssid *ssid;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto inv_args;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto inv_args;
-
- if (os_strcmp(entry.key, "persistent") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- persistent_group = entry.bool_value;
- } else if (os_strcmp(entry.key, "frequency") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- freq = entry.int32_value;
- if (freq <= 0)
- goto inv_args_clear;
- } else if (os_strcmp(entry.key, "persistent_group_object") ==
- 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH)
- pg_object_path = os_strdup(entry.str_value);
- else
- goto inv_args_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s) {
- reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
- goto out;
- }
-
- if (pg_object_path != NULL) {
- char *net_id_str;
-
- /*
- * A persistent group Object Path is defined meaning we want
- * to re-invoke a persistent group.
- */
-
- iface = wpas_dbus_new_decompose_object_path(
- pg_object_path, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
- &net_id_str);
- if (iface == NULL || net_id_str == NULL ||
- !wpa_s->parent->dbus_new_path ||
- os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
- reply =
- wpas_dbus_error_invalid_args(message,
- pg_object_path);
- goto out;
- }
-
- group_id = strtoul(net_id_str, NULL, 10);
- if (errno == EINVAL) {
- reply = wpas_dbus_error_invalid_args(
- message, pg_object_path);
- goto out;
- }
-
- /* Get the SSID structure from the persistent group id */
- ssid = wpa_config_get_network(wpa_s->conf, group_id);
- if (ssid == NULL || ssid->disabled != 2)
- goto inv_args;
-
- if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
- 0, 0, 0, 0, NULL, 0, 0,
- false)) {
- reply = wpas_dbus_error_unknown_error(
- message,
- "Failed to reinvoke a persistent group");
- goto out;
- }
- } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0, 0,
- 0, 0, 0, false))
- goto inv_args;
-
-out:
- os_free(pg_object_path);
- os_free(iface);
- return reply;
-inv_args_clear:
- wpa_dbus_dict_entry_clear(&entry);
-inv_args:
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpas_p2p_disconnect(wpa_s))
- return wpas_dbus_error_unknown_error(message,
- "failed to disconnect");
-
- return NULL;
-}
-
-
-static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s,
- DBusMessage *message,
- DBusMessage **out_reply,
- DBusError *error)
-{
- /* Return an error message or an error if P2P isn't available */
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
- if (out_reply) {
- *out_reply = dbus_message_new_error(
- message, DBUS_ERROR_FAILED,
- "P2P is not available for this interface");
- }
- dbus_set_error_const(error, DBUS_ERROR_FAILED,
- "P2P is not available for this interface");
- return FALSE;
- }
- if (!wpa_s->global->p2p_init_wpa_s) {
- if (out_reply)
- *out_reply = wpas_dbus_error_no_p2p_mgmt_iface(
- message);
- return no_p2p_mgmt_interface(error);
- }
- return TRUE;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_remove_client(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *peer_object_path = NULL;
- char *interface_addr = NULL;
- u8 peer_addr[ETH_ALEN];
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
- return reply;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto err;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto err;
-
- if (os_strcmp(entry.key, "peer") == 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- os_free(peer_object_path);
- peer_object_path = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- } else if (os_strcmp(entry.key, "iface") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(interface_addr);
- interface_addr = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- goto err;
- }
- }
-
- if ((!peer_object_path && !interface_addr) ||
- (peer_object_path &&
- (parse_peer_object_path(peer_object_path, peer_addr) < 0 ||
- !p2p_peer_known(wpa_s->global->p2p, peer_addr))) ||
- (interface_addr && hwaddr_aton(interface_addr, peer_addr) < 0))
- goto err;
-
- wpas_p2p_remove_client(wpa_s, peer_addr, interface_addr != NULL);
- reply = NULL;
-out:
- os_free(peer_object_path);
- os_free(interface_addr);
- return reply;
-err:
- reply = wpas_dbus_error_invalid_args(message, "Invalid address format");
- goto out;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
- return reply;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- wpas_p2p_stop_find(wpa_s);
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
- wpa_s->force_long_sd = 0;
- p2p_flush(wpa_s->global->p2p);
-
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *peer_object_path = NULL;
- int persistent_group = 0;
- int join = 0;
- int authorize_only = 0;
- int go_intent = -1;
- int freq = 0;
- u8 addr[ETH_ALEN];
- char *pin = NULL;
- enum p2p_wps_method wps_method = WPS_NOT_READY;
- int new_pin;
- char *err_msg = NULL;
- char *iface = NULL;
- int ret;
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
- return reply;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto inv_args;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto inv_args;
-
- if (os_strcmp(entry.key, "peer") == 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- peer_object_path = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "persistent") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- persistent_group = entry.bool_value;
- } else if (os_strcmp(entry.key, "join") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- join = entry.bool_value;
- } else if (os_strcmp(entry.key, "authorize_only") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- authorize_only = entry.bool_value;
- } else if (os_strcmp(entry.key, "frequency") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- freq = entry.int32_value;
- if (freq <= 0)
- goto inv_args_clear;
- } else if (os_strcmp(entry.key, "go_intent") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- go_intent = entry.int32_value;
- if ((go_intent < 0) || (go_intent > 15))
- goto inv_args_clear;
- } else if (os_strcmp(entry.key, "wps_method") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (os_strcmp(entry.str_value, "pbc") == 0)
- wps_method = WPS_PBC;
- else if (os_strcmp(entry.str_value, "pin") == 0)
- wps_method = WPS_PIN_DISPLAY;
- else if (os_strcmp(entry.str_value, "display") == 0)
- wps_method = WPS_PIN_DISPLAY;
- else if (os_strcmp(entry.str_value, "keypad") == 0)
- wps_method = WPS_PIN_KEYPAD;
- else
- goto inv_args_clear;
- } else if (os_strcmp(entry.key, "pin") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- pin = os_strdup(entry.str_value);
- } else
- goto inv_args_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (wps_method == WPS_NOT_READY ||
- parse_peer_object_path(peer_object_path, addr) < 0 ||
- !p2p_peer_known(wpa_s->global->p2p, addr))
- goto inv_args;
-
- /*
- * Validate the wps_method specified and the pin value.
- */
- if ((!pin || !pin[0]) && wps_method == WPS_PIN_KEYPAD)
- goto inv_args;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
- persistent_group, 0, join, authorize_only,
- go_intent, freq, 0, -1, 0, 0, 0, 0, 0, 0,
- NULL, 0, false);
-
- if (new_pin >= 0) {
- char npin[9];
- char *generated_pin;
-
- ret = os_snprintf(npin, sizeof(npin), "%08d", new_pin);
- if (os_snprintf_error(sizeof(npin), ret)) {
- reply = wpas_dbus_error_unknown_error(message,
- "invalid PIN");
- goto out;
- }
- generated_pin = npin;
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_STRING,
- &generated_pin, DBUS_TYPE_INVALID);
- } else {
- switch (new_pin) {
- case -2:
- err_msg =
- "connect failed due to channel unavailability.";
- iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE;
- break;
-
- case -3:
- err_msg = "connect failed due to unsupported channel.";
- iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED;
- break;
-
- default:
- err_msg = "connect failed due to unspecified error.";
- iface = WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR;
- break;
- }
-
- /*
- * TODO:
- * Do we need specialized errors corresponding to above
- * error conditions as against just returning a different
- * error message?
- */
- reply = dbus_message_new_error(message, iface, err_msg);
- }
-
-out:
- os_free(peer_object_path);
- os_free(pin);
- return reply;
-inv_args_clear:
- wpa_dbus_dict_entry_clear(&entry);
-inv_args:
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-}
-
-
-/**
- * wpas_dbus_handler_p2p_cancel - Cancel P2P group formation
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: NULL on success or DBus error on failure
- *
- * Handler for "Cancel" method call. Returns NULL if P2P cancel succeeds or DBus
- * error on P2P cancel failure
- */
-DBusMessage * wpas_dbus_handler_p2p_cancel(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpas_p2p_cancel(wpa_s))
- return wpas_dbus_error_unknown_error(message,
- "P2P cancel failed");
-
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *peer_object_path = NULL;
- char *pg_object_path = NULL;
- char *iface = NULL;
- u8 peer_addr[ETH_ALEN];
- unsigned int group_id = 0;
- int persistent = 0;
- struct wpa_ssid *ssid;
- const char *group_ifname;
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
- return reply;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto err;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto err;
-
- if (os_strcmp(entry.key, "peer") == 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- peer_object_path = os_strdup(entry.str_value);
- wpa_dbus_dict_entry_clear(&entry);
- } else if (os_strcmp(entry.key, "persistent_group_object") ==
- 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- pg_object_path = os_strdup(entry.str_value);
- persistent = 1;
- wpa_dbus_dict_entry_clear(&entry);
- } else {
- wpa_dbus_dict_entry_clear(&entry);
- goto err;
- }
- }
-
- if (parse_peer_object_path(peer_object_path, peer_addr) < 0 ||
- !p2p_peer_known(wpa_s->global->p2p, peer_addr))
- goto err;
-
- /* Capture the interface name for the group first */
- group_ifname = wpa_s->ifname;
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- if (persistent) {
- char *net_id_str;
- /*
- * A group ID is defined meaning we want to re-invoke a
- * persistent group
- */
-
- iface = wpas_dbus_new_decompose_object_path(
- pg_object_path,
- WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
- &net_id_str);
- if (iface == NULL || net_id_str == NULL ||
- !wpa_s->parent->dbus_new_path ||
- os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message,
- pg_object_path);
- goto out;
- }
-
- group_id = strtoul(net_id_str, NULL, 10);
- if (errno == EINVAL) {
- reply = wpas_dbus_error_invalid_args(
- message, pg_object_path);
- goto out;
- }
-
- /* Get the SSID structure from the persistent group id */
- ssid = wpa_config_get_network(wpa_s->conf, group_id);
- if (ssid == NULL || ssid->disabled != 2)
- goto err;
-
- if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0,
- 0, 0, 0, false) < 0) {
- reply = wpas_dbus_error_unknown_error(
- message,
- "Failed to reinvoke a persistent group");
- goto out;
- }
- } else {
- /*
- * No group ID means propose to a peer to join my active group
- */
- if (wpas_p2p_invite_group(wpa_s, group_ifname,
- peer_addr, NULL, false)) {
- reply = wpas_dbus_error_unknown_error(
- message, "Failed to join to an active group");
- goto out;
- }
- }
-
-out:
- os_free(iface);
- os_free(pg_object_path);
- os_free(peer_object_path);
- return reply;
-
-err:
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter;
- char *peer_object_path = NULL;
- char *config_method = NULL;
- u8 peer_addr[ETH_ALEN];
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &peer_object_path);
-
- if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
- return wpas_dbus_error_invalid_args(message, NULL);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_get_basic(&iter, &config_method);
-
- /*
- * Validation checks on config_method are being duplicated here
- * to be able to return invalid args reply since the error code
- * from p2p module are not granular enough (yet).
- */
- if (os_strcmp(config_method, "display") &&
- os_strcmp(config_method, "keypad") &&
- os_strcmp(config_method, "pbc") &&
- os_strcmp(config_method, "pushbutton"))
- return wpas_dbus_error_invalid_args(message, NULL);
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return wpas_dbus_error_no_p2p_mgmt_iface(message);
-
- if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
- WPAS_P2P_PD_FOR_GO_NEG, NULL) < 0)
- return wpas_dbus_error_unknown_error(message,
- "Failed to send provision discovery request");
-
- return NULL;
-}
-
-
-/*
- * P2P Device property accessor methods.
- */
-
-dbus_bool_t wpas_dbus_getter_p2p_device_config(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, dict_iter;
- DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
- iter_secdev_dict_array;
- const char *dev_name;
- int num_vendor_extensions = 0;
- int i;
- const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT];
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
- return FALSE;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a{sv}", &variant_iter) ||
- !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
- goto err_no_mem;
-
- /* DeviceName */
- dev_name = wpa_s->conf->device_name;
- if (dev_name &&
- !wpa_dbus_dict_append_string(&dict_iter, "DeviceName", dev_name))
- goto err_no_mem;
-
- /* Primary device type */
- if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType",
- (char *) wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN))
- goto err_no_mem;
-
- /* Secondary device types */
- if (wpa_s->conf->num_sec_device_types) {
- if (!wpa_dbus_dict_begin_array(&dict_iter,
- "SecondaryDeviceTypes",
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &iter_secdev_dict_entry,
- &iter_secdev_dict_val,
- &iter_secdev_dict_array))
- goto err_no_mem;
-
- for (i = 0; i < wpa_s->conf->num_sec_device_types; i++)
- wpa_dbus_dict_bin_array_add_element(
- &iter_secdev_dict_array,
- wpa_s->conf->sec_device_type[i],
- WPS_DEV_TYPE_LEN);
-
- if (!wpa_dbus_dict_end_array(&dict_iter,
- &iter_secdev_dict_entry,
- &iter_secdev_dict_val,
- &iter_secdev_dict_array))
- goto err_no_mem;
- }
-
- /* GO IP address */
- if (WPA_GET_BE32(wpa_s->conf->ip_addr_go) &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
- (char *) wpa_s->conf->ip_addr_go,
- 4))
- goto err_no_mem;
-
- /* IP address mask */
- if (WPA_GET_BE32(wpa_s->conf->ip_addr_mask) &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
- (char *) wpa_s->conf->ip_addr_mask,
- 4))
- goto err_no_mem;
-
- /* IP address start */
- if (WPA_GET_BE32(wpa_s->conf->ip_addr_start) &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrStart",
- (char *)
- wpa_s->conf->ip_addr_start,
- 4))
- goto err_no_mem;
-
- /* IP address end */
- if (WPA_GET_BE32(wpa_s->conf->ip_addr_end) &&
- !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrEnd",
- (char *) wpa_s->conf->ip_addr_end,
- 4))
- goto err_no_mem;
-
- /* Vendor Extensions */
- for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
- if (wpa_s->conf->wps_vendor_ext[i] == NULL)
- continue;
- vendor_ext[num_vendor_extensions++] =
- wpa_s->conf->wps_vendor_ext[i];
- }
-
- if ((num_vendor_extensions &&
- !wpa_dbus_dict_append_wpabuf_array(&dict_iter,
- "VendorExtension",
- vendor_ext,
- num_vendor_extensions)) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "GOIntent",
- wpa_s->conf->p2p_go_intent) ||
- !wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect",
- wpa_s->conf->persistent_reconnect) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "ListenRegClass",
- wpa_s->conf->p2p_listen_reg_class) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "ListenChannel",
- wpa_s->conf->p2p_listen_channel) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "OperRegClass",
- wpa_s->conf->p2p_oper_reg_class) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "OperChannel",
- wpa_s->conf->p2p_oper_channel) ||
- (wpa_s->conf->p2p_ssid_postfix &&
- !wpa_dbus_dict_append_string(&dict_iter, "SsidPostfix",
- wpa_s->conf->p2p_ssid_postfix)) ||
- !wpa_dbus_dict_append_bool(&dict_iter, "IntraBss",
- wpa_s->conf->p2p_intra_bss) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "GroupIdle",
- wpa_s->conf->p2p_group_idle) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "disassoc_low_ack",
- wpa_s->conf->disassoc_low_ack) ||
- !wpa_dbus_dict_append_bool(&dict_iter, "NoGroupIface",
- wpa_s->conf->p2p_no_group_iface) ||
- !wpa_dbus_dict_append_uint32(&dict_iter, "p2p_search_delay",
- wpa_s->conf->p2p_search_delay) ||
- !wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter))
- goto err_no_mem;
-
- return TRUE;
-
-err_no_mem:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
-}
-
-
-dbus_bool_t wpas_dbus_setter_p2p_device_config(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, iter_dict;
- struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
- unsigned int i;
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
- return FALSE;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- dbus_message_iter_recurse(iter, &variant_iter);
- if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
- return FALSE;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
- }
-
- if (os_strcmp(entry.key, "DeviceName") == 0) {
- char *devname;
-
- if (entry.type != DBUS_TYPE_STRING ||
- os_strlen(entry.str_value) > WPS_DEV_NAME_MAX_LEN)
- goto error;
-
- devname = os_strdup(entry.str_value);
- if (devname == NULL)
- goto err_no_mem_clear;
-
- os_free(wpa_s->conf->device_name);
- wpa_s->conf->device_name = devname;
-
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_DEVICE_NAME;
- } else if (os_strcmp(entry.key, "PrimaryDeviceType") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE ||
- entry.array_len != WPS_DEV_TYPE_LEN)
- goto error;
-
- os_memcpy(wpa_s->conf->device_type,
- entry.bytearray_value,
- WPS_DEV_TYPE_LEN);
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_DEVICE_TYPE;
- } else if (os_strcmp(entry.key, "SecondaryDeviceTypes") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
- entry.array_len > MAX_SEC_DEVICE_TYPES)
- goto error;
-
- for (i = 0; i < entry.array_len; i++)
- if (wpabuf_len(entry.binarray_value[i]) !=
- WPS_DEV_TYPE_LEN)
- goto err_no_mem_clear;
- for (i = 0; i < entry.array_len; i++)
- os_memcpy(wpa_s->conf->sec_device_type[i],
- wpabuf_head(entry.binarray_value[i]),
- WPS_DEV_TYPE_LEN);
- wpa_s->conf->num_sec_device_types = entry.array_len;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_SEC_DEVICE_TYPE;
- } else if (os_strcmp(entry.key, "VendorExtension") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
- (entry.array_len > P2P_MAX_WPS_VENDOR_EXT))
- goto error;
-
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_VENDOR_EXTENSION;
-
- for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
- wpabuf_free(wpa_s->conf->wps_vendor_ext[i]);
- if (i < entry.array_len) {
- wpa_s->conf->wps_vendor_ext[i] =
- entry.binarray_value[i];
- entry.binarray_value[i] = NULL;
- } else
- wpa_s->conf->wps_vendor_ext[i] = NULL;
- }
- } else if (os_strcmp(entry.key, "GOIntent") == 0 &&
- entry.type == DBUS_TYPE_UINT32 &&
- (entry.uint32_value <= 15))
- wpa_s->conf->p2p_go_intent = entry.uint32_value;
- else if (os_strcmp(entry.key, "PersistentReconnect") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN)
- wpa_s->conf->persistent_reconnect = entry.bool_value;
- else if (os_strcmp(entry.key, "ListenRegClass") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- wpa_s->conf->p2p_listen_reg_class = entry.uint32_value;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_LISTEN_CHANNEL;
- } else if (os_strcmp(entry.key, "ListenChannel") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- wpa_s->conf->p2p_listen_channel = entry.uint32_value;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_LISTEN_CHANNEL;
- } else if (os_strcmp(entry.key, "OperRegClass") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- wpa_s->conf->p2p_oper_reg_class = entry.uint32_value;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_OPER_CHANNEL;
- } else if (os_strcmp(entry.key, "OperChannel") == 0 &&
- entry.type == DBUS_TYPE_UINT32) {
- wpa_s->conf->p2p_oper_channel = entry.uint32_value;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_OPER_CHANNEL;
- } else if (os_strcmp(entry.key, "SsidPostfix") == 0) {
- char *postfix;
-
- if (entry.type != DBUS_TYPE_STRING)
- goto error;
-
- postfix = os_strdup(entry.str_value);
- if (!postfix)
- goto err_no_mem_clear;
-
- os_free(wpa_s->conf->p2p_ssid_postfix);
- wpa_s->conf->p2p_ssid_postfix = postfix;
-
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_SSID_POSTFIX;
- } else if (os_strcmp(entry.key, "IntraBss") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- wpa_s->conf->p2p_intra_bss = entry.bool_value;
- wpa_s->conf->changed_parameters |=
- CFG_CHANGED_P2P_INTRA_BSS;
- } else if (os_strcmp(entry.key, "IpAddrGo") == 0) {
- if (!wpas_dbus_validate_dbus_ipaddr(entry))
- goto error;
- os_memcpy(wpa_s->conf->ip_addr_go,
- entry.bytearray_value, 4);
- } else if (os_strcmp(entry.key, "IpAddrMask") == 0) {
- if (!wpas_dbus_validate_dbus_ipaddr(entry))
- goto error;
- os_memcpy(wpa_s->conf->ip_addr_mask,
- entry.bytearray_value, 4);
- } else if (os_strcmp(entry.key, "IpAddrStart") == 0) {
- if (!wpas_dbus_validate_dbus_ipaddr(entry))
- goto error;
- os_memcpy(wpa_s->conf->ip_addr_start,
- entry.bytearray_value, 4);
- } else if (os_strcmp(entry.key, "IpAddrEnd") == 0) {
- if (!wpas_dbus_validate_dbus_ipaddr(entry))
- goto error;
- os_memcpy(wpa_s->conf->ip_addr_end,
- entry.bytearray_value, 4);
- } else if (os_strcmp(entry.key, "GroupIdle") == 0 &&
- entry.type == DBUS_TYPE_UINT32)
- wpa_s->conf->p2p_group_idle = entry.uint32_value;
- else if (os_strcmp(entry.key, "disassoc_low_ack") == 0 &&
- entry.type == DBUS_TYPE_UINT32)
- wpa_s->conf->disassoc_low_ack = entry.uint32_value;
- else if (os_strcmp(entry.key, "NoGroupIface") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN)
- wpa_s->conf->p2p_no_group_iface = entry.bool_value;
- else if (os_strcmp(entry.key, "p2p_search_delay") == 0 &&
- entry.type == DBUS_TYPE_UINT32)
- wpa_s->conf->p2p_search_delay = entry.uint32_value;
- else
- goto error;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (wpa_s->conf->changed_parameters) {
- /* Some changed parameters requires to update config*/
- wpa_supplicant_update_config(wpa_s);
- }
-
- return TRUE;
-
- error:
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- wpa_dbus_dict_entry_clear(&entry);
- return FALSE;
-
- err_no_mem_clear:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- wpa_dbus_dict_entry_clear(&entry);
- return FALSE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peers(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct p2p_data *p2p = wpa_s->global->p2p;
- int next = 0, i = 0;
- int num = 0, out_of_mem = 0;
- const u8 *addr;
- const struct p2p_peer_info *peer_info = NULL;
- dbus_bool_t success = FALSE;
-
- struct dl_list peer_objpath_list;
- struct peer_objpath_node {
- struct dl_list list;
- char path[WPAS_DBUS_OBJECT_PATH_MAX];
- } *node, *tmp;
-
- char **peer_obj_paths = NULL;
-
- if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error) ||
- !wpa_s->parent->parent->dbus_new_path)
- return FALSE;
-
- dl_list_init(&peer_objpath_list);
-
- /* Get the first peer info */
- peer_info = p2p_get_peer_found(p2p, NULL, next);
-
- /* Get next and accumulate them */
- next = 1;
- while (peer_info != NULL) {
- node = os_zalloc(sizeof(struct peer_objpath_node));
- if (!node) {
- out_of_mem = 1;
- goto error;
- }
-
- addr = peer_info->p2p_device_addr;
- os_snprintf(node->path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
- "/" COMPACT_MACSTR,
- wpa_s->parent->parent->dbus_new_path,
- MAC2STR(addr));
- dl_list_add_tail(&peer_objpath_list, &node->list);
- num++;
-
- peer_info = p2p_get_peer_found(p2p, addr, next);
- }
-
- /*
- * Now construct the peer object paths in a form suitable for
- * array_property_getter helper below.
- */
- peer_obj_paths = os_calloc(num, sizeof(char *));
-
- if (!peer_obj_paths) {
- out_of_mem = 1;
- goto error;
- }
-
- dl_list_for_each_safe(node, tmp, &peer_objpath_list,
- struct peer_objpath_node, list)
- peer_obj_paths[i++] = node->path;
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- peer_obj_paths, num,
- error);
-
-error:
- if (peer_obj_paths)
- os_free(peer_obj_paths);
-
- dl_list_for_each_safe(node, tmp, &peer_objpath_list,
- struct peer_objpath_node, list) {
- dl_list_del(&node->list);
- os_free(node);
- }
- if (out_of_mem)
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
-
- return success;
-}
-
-
-enum wpas_p2p_role {
- WPAS_P2P_ROLE_DEVICE,
- WPAS_P2P_ROLE_GO,
- WPAS_P2P_ROLE_CLIENT,
-};
-
-static enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (!ssid)
- return WPAS_P2P_ROLE_DEVICE;
- if (wpa_s->wpa_state != WPA_COMPLETED)
- return WPAS_P2P_ROLE_DEVICE;
-
- switch (ssid->mode) {
- case WPAS_MODE_P2P_GO:
- case WPAS_MODE_P2P_GROUP_FORMATION:
- return WPAS_P2P_ROLE_GO;
- case WPAS_MODE_INFRA:
- if (ssid->p2p_group)
- return WPAS_P2P_ROLE_CLIENT;
- return WPAS_P2P_ROLE_DEVICE;
- default:
- return WPAS_P2P_ROLE_DEVICE;
- }
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_role(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *str;
-
- switch (wpas_get_p2p_role(wpa_s)) {
- case WPAS_P2P_ROLE_GO:
- str = "GO";
- break;
- case WPAS_P2P_ROLE_CLIENT:
- str = "client";
- break;
- default:
- str = "device";
- break;
- }
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
- error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
- char *dbus_groupobj_path = path_buf;
-
- if (wpa_s->dbus_groupobj_path == NULL)
- os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "/");
- else
- os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s", wpa_s->dbus_groupobj_path);
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
- &dbus_groupobj_path, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peergo(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
-
- if (!wpa_s->parent->parent->dbus_new_path)
- return FALSE;
-
- if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
- os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
- else
- os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
- COMPACT_MACSTR,
- wpa_s->parent->parent->dbus_new_path,
- MAC2STR(wpa_s->go_dev_addr));
-
- path = go_peer_obj_path;
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
- &path, error);
-}
-
-
-/*
- * Peer object properties accessor methods
- */
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_device_name(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- char *tmp;
-
- if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
- return FALSE;
-
- /* get the peer info */
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- tmp = os_strdup(info->device_name);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
- error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- os_free(tmp);
- return FALSE;
- }
-
- os_free(tmp);
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_manufacturer(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- char *tmp;
-
- if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
- return FALSE;
-
- /* get the peer info */
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- tmp = os_strdup(info->manufacturer);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
- error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- os_free(tmp);
- return FALSE;
- }
-
- os_free(tmp);
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_modelname(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- char *tmp;
-
- if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
- return FALSE;
-
- /* get the peer info */
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- tmp = os_strdup(info->model_name);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
- error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- os_free(tmp);
- return FALSE;
- }
-
- os_free(tmp);
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_modelnumber(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- char *tmp;
-
- if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
- return FALSE;
-
- /* get the peer info */
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- tmp = os_strdup(info->model_number);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
- error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- os_free(tmp);
- return FALSE;
- }
-
- os_free(tmp);
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_serialnumber(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- char *tmp;
-
- if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
- return FALSE;
-
- /* get the peer info */
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- tmp = os_strdup(info->serial_number);
- if (!tmp) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
- error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- os_free(tmp);
- return FALSE;
- }
-
- os_free(tmp);
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- (char *)
- info->pri_dev_type,
- WPS_DEV_TYPE_LEN, error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
- &info->config_methods, error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_level(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
- &info->level, error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
- &info->dev_capab, error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_group_capability(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
- &info->group_capab, error)) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- DBusMessageIter variant_iter, array_iter;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &variant_iter) ||
- !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING,
- &array_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message 1", __func__);
- return FALSE;
- }
-
- if (info->wps_sec_dev_type_list_len) {
- const u8 *sec_dev_type_list = info->wps_sec_dev_type_list;
- int num_sec_device_types =
- info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN;
- int i;
- DBusMessageIter inner_array_iter;
-
- for (i = 0; i < num_sec_device_types; i++) {
- if (!dbus_message_iter_open_container(
- &array_iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING,
- &inner_array_iter) ||
- !dbus_message_iter_append_fixed_array(
- &inner_array_iter, DBUS_TYPE_BYTE,
- &sec_dev_type_list, WPS_DEV_TYPE_LEN) ||
- !dbus_message_iter_close_container(
- &array_iter, &inner_array_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message 2 (%d)",
- __func__, i);
- return FALSE;
- }
-
- sec_dev_type_list += WPS_DEV_TYPE_LEN;
- }
- }
-
- if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
- !dbus_message_iter_close_container(iter, &variant_iter)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: failed to construct message 3", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
- unsigned int i, num = 0;
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- /* Add WPS vendor extensions attribute */
- os_memset(vendor_extension, 0, sizeof(vendor_extension));
- for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
- if (info->wps_vendor_ext[i] == NULL)
- continue;
- vendor_extension[num] = info->wps_vendor_ext[i];
- num++;
- }
-
- if (!wpas_dbus_simple_array_array_property_getter(iter, DBUS_TYPE_BYTE,
- vendor_extension,
- num, error))
- return FALSE;
-
- return TRUE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_ies(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- if (info->wfd_subelems == NULL)
- return wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_BYTE,
- NULL, 0, error);
-
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_BYTE, (char *) info->wfd_subelems->buf,
- info->wfd_subelems->used, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_device_address(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_BYTE, (char *) info->p2p_device_addr,
- ETH_ALEN, error);
-}
-
-
-struct peer_group_data {
- struct wpa_supplicant *wpa_s;
- const struct p2p_peer_info *info;
- char **paths;
- unsigned int nb_paths;
- int error;
-};
-
-
-static int match_group_where_peer_is_client(struct p2p_group *group,
- void *user_data)
-{
- struct peer_group_data *data = user_data;
- const struct p2p_group_config *cfg;
- struct wpa_supplicant *wpa_s_go;
- char **paths;
-
- if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
- return 1;
-
- cfg = p2p_group_get_config(group);
-
- wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
- cfg->ssid_len);
- if (wpa_s_go == NULL)
- return 1;
-
- paths = os_realloc_array(data->paths, data->nb_paths + 1,
- sizeof(char *));
- if (paths == NULL)
- goto out_of_memory;
-
- data->paths = paths;
- data->paths[data->nb_paths] = wpa_s_go->dbus_groupobj_path;
- data->nb_paths++;
-
- return 1;
-
-out_of_memory:
- data->error = ENOMEM;
- return 0;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_groups(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
- struct peer_group_data data;
- struct wpa_supplicant *wpa_s, *wpa_s_go;
- dbus_bool_t success = FALSE;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (info == NULL) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "failed to find peer");
- return FALSE;
- }
-
- os_memset(&data, 0, sizeof(data));
-
- wpa_s = peer_args->wpa_s;
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return no_p2p_mgmt_interface(error);
-
- wpa_s_go = wpas_get_p2p_client_iface(wpa_s, info->p2p_device_addr);
- if (wpa_s_go) {
- data.paths = os_calloc(1, sizeof(char *));
- if (data.paths == NULL)
- goto out_of_memory;
- data.paths[0] = wpa_s_go->dbus_groupobj_path;
- data.nb_paths = 1;
- }
-
- data.wpa_s = peer_args->wpa_s;
- data.info = info;
-
- p2p_loop_on_all_groups(peer_args->wpa_s->global->p2p,
- match_group_where_peer_is_client, &data);
- if (data.error)
- goto out_of_memory;
-
- if (data.paths == NULL) {
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- data.paths,
- data.nb_paths, error);
- goto out;
-
-out_of_memory:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
-out:
- os_free(data.paths);
- return success;
-}
-
-dbus_bool_t wpas_dbus_getter_p2p_peer_vsie(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct peer_handler_args *peer_args = user_data;
- const struct p2p_peer_info *info;
-
- info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
- peer_args->p2p_device_addr, 0);
- if (!info) {
- dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
- return FALSE;
- }
-
- if (!info->vendor_elems)
- return wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_BYTE,
- NULL, 0, error);
-
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_BYTE, (char *) info->vendor_elems->buf,
- info->vendor_elems->used, error);
-}
-
-
-/**
- * wpas_dbus_getter_persistent_groups - Get array of persistent group objects
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "PersistentGroups" property.
- */
-dbus_bool_t wpas_dbus_getter_persistent_groups(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_ssid *ssid;
- char **paths;
- unsigned int i = 0, num = 0;
- dbus_bool_t success = FALSE;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return no_p2p_mgmt_interface(error);
-
- if (!wpa_s->parent->dbus_new_path)
- return FALSE;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
- if (network_is_persistent_group(ssid))
- num++;
-
- paths = os_calloc(num, sizeof(char *));
- if (!paths) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
- }
-
- /* Loop through configured networks and append object path of each */
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (!network_is_persistent_group(ssid))
- continue;
- paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (paths[i] == NULL) {
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
- "no memory");
- goto out;
- }
- /* Construct the object path for this network. */
- os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
- wpa_s->parent->dbus_new_path, ssid->id);
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, num, error);
-
-out:
- while (i)
- os_free(paths[--i]);
- os_free(paths);
- return success;
-}
-
-
-/**
- * wpas_dbus_getter_persistent_group_properties - Get options for a persistent
- * group
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Properties" property of a persistent group.
- */
-dbus_bool_t wpas_dbus_getter_persistent_group_properties(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
-
- /* Leveraging the fact that persistent group object is still
- * represented in same manner as network within.
- */
- return wpas_dbus_getter_network_properties(property_desc, iter, error, net);
-}
-
-
-/**
- * wpas_dbus_setter_persistent_group_properties - Set options for a persistent
- * group
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "Properties" property of a persistent group.
- */
-dbus_bool_t wpas_dbus_setter_persistent_group_properties(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct network_handler_args *net = user_data;
- struct wpa_ssid *ssid = net->ssid;
- DBusMessageIter variant_iter;
-
- /*
- * Leveraging the fact that persistent group object is still
- * represented in same manner as network within.
- */
- dbus_message_iter_recurse(iter, &variant_iter);
- return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
-}
-
-
-/**
- * wpas_dbus_new_iface_add_persistent_group - Add a new configured
- * persistent_group
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: A dbus message containing the object path of the new
- * persistent group
- *
- * Handler function for "AddPersistentGroup" method call of a P2P Device
- * interface.
- */
-DBusMessage * wpas_dbus_handler_add_persistent_group(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_ssid *ssid = NULL;
- char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
- DBusError error;
-
- dbus_message_iter_init(message, &iter);
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s) {
- reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
- goto err;
- }
-
- if (wpa_s->parent->dbus_new_path)
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Cannot add new persistent group",
- __func__);
- reply = wpas_dbus_error_unknown_error(
- message,
- "wpa_supplicant could not add a persistent group on this interface.");
- goto err;
- }
-
- /* Mark the ssid as being a persistent group before the notification */
- ssid->disabled = 2;
- ssid->p2p_persistent_group = 1;
- wpas_notify_persistent_group_added(wpa_s, ssid);
-
- wpa_config_set_network_defaults(ssid);
-
- dbus_error_init(&error);
- if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
- wpa_printf(MSG_DEBUG,
- "dbus: %s: Control interface could not set persistent group properties",
- __func__);
- reply = wpas_dbus_reply_new_from_error(
- message, &error, DBUS_ERROR_INVALID_ARGS,
- "Failed to set network properties");
- dbus_error_free(&error);
- goto err;
- }
-
- /* Construct the object path for this network. */
- os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
- wpa_s->parent->dbus_new_path, ssid->id);
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL) {
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
- if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)) {
- dbus_message_unref(reply);
- reply = wpas_dbus_error_no_memory(message);
- goto err;
- }
-
- return reply;
-
-err:
- if (ssid) {
- wpas_notify_persistent_group_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- }
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_remove_persistent_group - Remove a configured persistent
- * group
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "RemovePersistentGroup" method call of a P2P Device
- * interface.
- */
-DBusMessage * wpas_dbus_handler_remove_persistent_group(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- const char *op;
- char *iface = NULL, *persistent_group_id;
- int id;
- struct wpa_ssid *ssid;
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
- DBUS_TYPE_INVALID);
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s) {
- reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
- goto out;
- }
-
- /*
- * Extract the network ID and ensure the network is actually a child of
- * this interface.
- */
- iface = wpas_dbus_new_decompose_object_path(
- op, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART,
- &persistent_group_id);
- if (iface == NULL || persistent_group_id == NULL ||
- !wpa_s->parent->dbus_new_path ||
- os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- id = strtoul(persistent_group_id, NULL, 10);
- if (errno == EINVAL) {
- reply = wpas_dbus_error_invalid_args(message, op);
- goto out;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL) {
- reply = wpas_dbus_error_persistent_group_unknown(message);
- goto out;
- }
-
- wpas_notify_persistent_group_removed(wpa_s, ssid);
-
- if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: error occurred when removing persistent group %d",
- __func__, id);
- reply = wpas_dbus_error_unknown_error(
- message,
- "error removing the specified persistent group on this interface.");
- goto out;
- }
-
-out:
- os_free(iface);
- return reply;
-}
-
-
-static void remove_persistent_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- wpas_notify_persistent_group_removed(wpa_s, ssid);
-
- if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: error occurred when removing persistent group %d",
- __func__, ssid->id);
- return;
- }
-}
-
-
-/**
- * wpas_dbus_handler_remove_all_persistent_groups - Remove all configured
- * persistent groups
- * @message: Pointer to incoming dbus message
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: NULL on success or dbus error on failure
- *
- * Handler function for "RemoveAllPersistentGroups" method call of a
- * P2P Device interface.
- */
-DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid, *next;
- struct wpa_config *config;
-
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- if (!wpa_s)
- return wpas_dbus_error_no_p2p_mgmt_iface(message);
-
- config = wpa_s->conf;
- ssid = config->ssid;
- while (ssid) {
- next = ssid->next;
- if (network_is_persistent_group(ssid))
- remove_persistent_group(wpa_s, ssid);
- ssid = next;
- }
- return NULL;
-}
-
-
-/*
- * Group object properties accessor methods
- */
-
-dbus_bool_t wpas_dbus_getter_p2p_group_members(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_ssid *ssid;
- unsigned int num_members;
- char **paths;
- unsigned int i;
- void *next = NULL;
- const u8 *addr;
- dbus_bool_t success = FALSE;
-
- if (!wpa_s->parent->parent->dbus_new_path)
- return FALSE;
-
- /* Verify correct role for this property */
- if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_GO) {
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
- }
-
- ssid = wpa_s->conf->ssid;
- /* At present WPAS P2P_GO mode only applicable for p2p_go */
- if (ssid->mode != WPAS_MODE_P2P_GO &&
- ssid->mode != WPAS_MODE_AP &&
- ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
- return FALSE;
-
- num_members = p2p_get_group_num_members(wpa_s->p2p_group);
-
- paths = os_calloc(num_members, sizeof(char *));
- if (!paths)
- goto out_of_memory;
-
- i = 0;
- while ((addr = p2p_iterate_group_members(wpa_s->p2p_group, &next))) {
- paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
- if (!paths[i])
- goto out_of_memory;
- os_snprintf(paths[i], WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
- "/" COMPACT_MACSTR,
- wpa_s->parent->parent->dbus_new_path,
- MAC2STR(addr));
- i++;
- }
-
- success = wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_OBJECT_PATH,
- paths, num_members,
- error);
-
- for (i = 0; i < num_members; i++)
- os_free(paths[i]);
- os_free(paths);
- return success;
-
-out_of_memory:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- if (paths) {
- for (i = 0; i < num_members; i++)
- os_free(paths[i]);
- os_free(paths);
- }
- return FALSE;
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_ssid(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- if (wpa_s->current_ssid == NULL)
- return FALSE;
- return wpas_dbus_simple_array_property_getter(
- iter, DBUS_TYPE_BYTE, wpa_s->current_ssid->ssid,
- wpa_s->current_ssid->ssid_len, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_bssid(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- u8 role = wpas_get_p2p_role(wpa_s);
- u8 *p_bssid;
-
- if (role == WPAS_P2P_ROLE_CLIENT) {
- if (wpa_s->current_ssid == NULL)
- return FALSE;
- p_bssid = wpa_s->current_ssid->bssid;
- } else {
- if (wpa_s->ap_iface == NULL)
- return FALSE;
- p_bssid = wpa_s->ap_iface->bss[0]->own_addr;
- }
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- p_bssid, ETH_ALEN,
- error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_frequency(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- u16 op_freq;
- u8 role = wpas_get_p2p_role(wpa_s);
-
- if (role == WPAS_P2P_ROLE_CLIENT) {
- if (wpa_s->go_params == NULL)
- return FALSE;
- op_freq = wpa_s->go_params->freq;
- } else {
- if (wpa_s->ap_iface == NULL)
- return FALSE;
- op_freq = wpa_s->ap_iface->freq;
- }
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
- &op_freq, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_passphrase(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL)
- return FALSE;
-
- return wpas_dbus_string_property_getter(iter, ssid->passphrase, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_psk(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- u8 *p_psk = NULL;
- u8 psk_len = 0;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL)
- return FALSE;
-
- if (ssid->psk_set) {
- p_psk = ssid->psk;
- psk_len = sizeof(ssid->psk);
- }
-
- return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- p_psk, psk_len, error);
-}
-
-
-dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- struct hostapd_data *hapd;
- struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
- unsigned int i, num_vendor_ext = 0;
-
- os_memset(vendor_ext, 0, sizeof(vendor_ext));
-
- /* Verify correct role for this property */
- if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO) {
- if (wpa_s->ap_iface == NULL)
- return FALSE;
- hapd = wpa_s->ap_iface->bss[0];
-
- /* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
- for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
- if (hapd->conf->wps_vendor_ext[i] == NULL)
- continue;
- vendor_ext[num_vendor_ext++] =
- hapd->conf->wps_vendor_ext[i];
- }
- }
-
- /* Return vendor extensions or no data */
- return wpas_dbus_simple_array_array_property_getter(iter,
- DBUS_TYPE_BYTE,
- vendor_ext,
- num_vendor_ext,
- error);
-}
-
-
-dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- DBusMessageIter variant_iter, iter_dict, array_iter, sub;
- struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
- unsigned int i;
- struct hostapd_data *hapd = NULL;
-
- if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO &&
- wpa_s->ap_iface != NULL)
- hapd = wpa_s->ap_iface->bss[0];
- else
- return FALSE;
-
- dbus_message_iter_recurse(iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY)
- return FALSE;
-
- /*
- * This is supposed to be array of bytearrays (aay), but the earlier
- * implementation used a dict with "WPSVendorExtensions" as the key in
- * this setter function which does not match the format used by the
- * getter function. For backwards compatibility, allow both formats to
- * be used in the setter.
- */
- if (dbus_message_iter_get_element_type(&variant_iter) ==
- DBUS_TYPE_ARRAY) {
- /* This is the proper format matching the getter */
- struct wpabuf *vals[MAX_WPS_VENDOR_EXTENSIONS];
-
- dbus_message_iter_recurse(&variant_iter, &array_iter);
-
- if (dbus_message_iter_get_arg_type(&array_iter) !=
- DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&array_iter) !=
- DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG,
- "dbus: Not an array of array of bytes");
- return FALSE;
- }
-
- i = 0;
- os_memset(vals, 0, sizeof(vals));
-
- while (dbus_message_iter_get_arg_type(&array_iter) ==
- DBUS_TYPE_ARRAY) {
- char *val;
- int len;
-
- if (i == MAX_WPS_VENDOR_EXTENSIONS) {
- wpa_printf(MSG_DEBUG,
- "dbus: Too many WPSVendorExtensions values");
- i = MAX_WPS_VENDOR_EXTENSIONS + 1;
- break;
- }
-
- dbus_message_iter_recurse(&array_iter, &sub);
- dbus_message_iter_get_fixed_array(&sub, &val, &len);
- wpa_hexdump(MSG_DEBUG, "dbus: WPSVendorExtentions[]",
- val, len);
- vals[i] = wpabuf_alloc_copy(val, len);
- if (vals[i] == NULL) {
- i = MAX_WPS_VENDOR_EXTENSIONS + 1;
- break;
- }
- i++;
- dbus_message_iter_next(&array_iter);
- }
-
- if (i > MAX_WPS_VENDOR_EXTENSIONS) {
- for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
- wpabuf_free(vals[i]);
- return FALSE;
- }
-
- for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
- wpabuf_free(hapd->conf->wps_vendor_ext[i]);
- hapd->conf->wps_vendor_ext[i] = vals[i];
- }
-
- hostapd_update_wps(hapd);
-
- return TRUE;
- }
-
- if (dbus_message_iter_get_element_type(&variant_iter) !=
- DBUS_TYPE_DICT_ENTRY)
- return FALSE;
-
- wpa_printf(MSG_DEBUG,
- "dbus: Try to use backwards compatibility version of WPSVendorExtensions setter");
- if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
- return FALSE;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
- }
-
- if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
- entry.array_len > MAX_WPS_VENDOR_EXTENSIONS)
- goto error;
-
- for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
- wpabuf_free(hapd->conf->wps_vendor_ext[i]);
- if (i < entry.array_len) {
- hapd->conf->wps_vendor_ext[i] =
- entry.binarray_value[i];
- entry.binarray_value[i] = NULL;
- } else
- hapd->conf->wps_vendor_ext[i] = NULL;
- }
-
- hostapd_update_wps(hapd);
- } else
- goto error;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- return TRUE;
-
-error:
- wpa_dbus_dict_entry_clear(&entry);
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- int upnp = 0;
- int bonjour = 0;
- char *service = NULL;
- struct wpabuf *query = NULL;
- struct wpabuf *resp = NULL;
- u8 version = 0;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "service_type") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (os_strcmp(entry.str_value, "upnp") == 0)
- upnp = 1;
- else if (os_strcmp(entry.str_value, "bonjour") == 0)
- bonjour = 1;
- else
- goto error_clear;
- } else if (os_strcmp(entry.key, "version") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- version = entry.uint32_value;
- } else if (os_strcmp(entry.key, "service") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(service);
- service = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "query") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- query = wpabuf_alloc_copy(
- entry.bytearray_value,
- entry.array_len);
- } else if (os_strcmp(entry.key, "response") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- resp = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
- }
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (upnp == 1) {
- if (version <= 0 || service == NULL)
- goto error;
-
- if (wpas_p2p_service_add_upnp(wpa_s, version, service) != 0)
- goto error;
-
- } else if (bonjour == 1) {
- if (query == NULL || resp == NULL)
- goto error;
-
- if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0)
- goto error;
- query = NULL;
- resp = NULL;
- } else
- goto error;
-
- os_free(service);
- return reply;
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- os_free(service);
- wpabuf_free(query);
- wpabuf_free(resp);
- return wpas_dbus_error_invalid_args(message, NULL);
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_delete_service(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- int upnp = 0;
- int bonjour = 0;
- int ret = 0;
- char *service = NULL;
- struct wpabuf *query = NULL;
- u8 version = 0;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "service_type") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (os_strcmp(entry.str_value, "upnp") == 0)
- upnp = 1;
- else if (os_strcmp(entry.str_value, "bonjour") == 0)
- bonjour = 1;
- else
- goto error_clear;
- } else if (os_strcmp(entry.key, "version") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- version = entry.uint32_value;
- } else if (os_strcmp(entry.key, "service") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- os_free(service);
- service = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "query") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- wpabuf_free(query);
- query = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
- } else {
- goto error_clear;
- }
-
- wpa_dbus_dict_entry_clear(&entry);
- }
- if (upnp == 1) {
- if (version <= 0 || service == NULL)
- goto error;
-
- ret = wpas_p2p_service_del_upnp(wpa_s, version, service);
- if (ret != 0)
- goto error;
- } else if (bonjour == 1) {
- if (query == NULL)
- goto error;
-
- ret = wpas_p2p_service_del_bonjour(wpa_s, query);
- if (ret != 0)
- goto error;
- } else
- goto error;
-
- wpabuf_free(query);
- os_free(service);
- return reply;
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- wpabuf_free(query);
- os_free(service);
- return wpas_dbus_error_invalid_args(message, NULL);
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_flush_service(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- wpas_p2p_service_flush(wpa_s);
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- int upnp = 0;
- char *service = NULL;
- char *peer_object_path = NULL;
- struct wpabuf *tlv = NULL;
- u8 version = 0;
- u64 ref = 0;
- u8 addr_buf[ETH_ALEN], *addr;
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
- if (os_strcmp(entry.key, "peer_object") == 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- peer_object_path = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "service_type") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- if (os_strcmp(entry.str_value, "upnp") == 0)
- upnp = 1;
- else
- goto error_clear;
- } else if (os_strcmp(entry.key, "version") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- version = entry.uint32_value;
- } else if (os_strcmp(entry.key, "service") == 0 &&
- entry.type == DBUS_TYPE_STRING) {
- service = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "tlv") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- tlv = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
- } else
- goto error_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
-
- if (!peer_object_path) {
- addr = NULL;
- } else {
- if (parse_peer_object_path(peer_object_path, addr_buf) < 0 ||
- !p2p_peer_known(wpa_s->global->p2p, addr_buf))
- goto error;
-
- addr = addr_buf;
- }
-
- if (upnp == 1) {
- if (version <= 0 || service == NULL)
- goto error;
-
- ref = wpas_p2p_sd_request_upnp(wpa_s, addr, version, service);
- } else {
- if (tlv == NULL)
- goto error;
- ref = wpas_p2p_sd_request(wpa_s, addr, tlv);
- wpabuf_free(tlv);
- }
-
- if (ref != 0) {
- reply = dbus_message_new_method_return(message);
- dbus_message_append_args(reply, DBUS_TYPE_UINT64,
- &ref, DBUS_TYPE_INVALID);
- } else {
- reply = wpas_dbus_error_unknown_error(
- message, "Unable to send SD request");
- }
-out:
- os_free(service);
- os_free(peer_object_path);
- return reply;
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- if (tlv)
- wpabuf_free(tlv);
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_service_sd_res(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter_dict;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- struct wpa_dbus_dict_entry entry;
- char *peer_object_path = NULL;
- struct wpabuf *tlv = NULL;
- int freq = 0;
- int dlg_tok = 0;
- u8 addr[ETH_ALEN];
-
- dbus_message_iter_init(message, &iter);
-
- if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
- goto error;
-
- while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
- if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
- goto error;
-
- if (os_strcmp(entry.key, "peer_object") == 0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH) {
- peer_object_path = os_strdup(entry.str_value);
- } else if (os_strcmp(entry.key, "frequency") == 0 &&
- entry.type == DBUS_TYPE_INT32) {
- freq = entry.uint32_value;
- } else if (os_strcmp(entry.key, "dialog_token") == 0 &&
- (entry.type == DBUS_TYPE_UINT32 ||
- entry.type == DBUS_TYPE_INT32)) {
- dlg_tok = entry.uint32_value;
- } else if (os_strcmp(entry.key, "tlvs") == 0) {
- if (entry.type != DBUS_TYPE_ARRAY ||
- entry.array_type != DBUS_TYPE_BYTE)
- goto error_clear;
- tlv = wpabuf_alloc_copy(entry.bytearray_value,
- entry.array_len);
- } else
- goto error_clear;
-
- wpa_dbus_dict_entry_clear(&entry);
- }
- if (parse_peer_object_path(peer_object_path, addr) < 0 ||
- !p2p_peer_known(wpa_s->global->p2p, addr) ||
- tlv == NULL)
- goto error;
-
- wpas_p2p_sd_response(wpa_s, freq, addr, (u8) dlg_tok, tlv);
- wpabuf_free(tlv);
-out:
- os_free(peer_object_path);
- return reply;
-error_clear:
- wpa_dbus_dict_entry_clear(&entry);
-error:
- reply = wpas_dbus_error_invalid_args(message, NULL);
- goto out;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter;
- u64 req = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &req);
-
- if (req == 0)
- goto error;
-
- if (wpas_p2p_sd_cancel_request(wpa_s, req) < 0)
- goto error;
-
- return NULL;
-error:
- return wpas_dbus_error_invalid_args(message, NULL);
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_service_update(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- wpas_p2p_sd_service_update(wpa_s);
- return NULL;
-}
-
-
-DBusMessage * wpas_dbus_handler_p2p_serv_disc_external(
- DBusMessage *message, struct wpa_supplicant *wpa_s)
-{
- DBusMessageIter iter;
- int ext = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_get_basic(&iter, &ext);
-
- wpa_s->p2p_sd_over_ctrl_iface = ext;
-
- return NULL;
-
-}
-
-
-#ifdef CONFIG_WIFI_DISPLAY
-
-dbus_bool_t wpas_dbus_getter_global_wfd_ies(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- struct wpabuf *ie;
- dbus_bool_t ret;
-
- ie = wifi_display_get_wfd_ie(global);
- if (ie == NULL)
- return wpas_dbus_simple_array_property_getter(iter,
- DBUS_TYPE_BYTE,
- NULL, 0, error);
-
- ret = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- wpabuf_head(ie),
- wpabuf_len(ie), error);
- wpabuf_free(ie);
-
- return ret;
-}
-
-
-dbus_bool_t wpas_dbus_setter_global_wfd_ies(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_global *global = user_data;
- DBusMessageIter variant, array;
- struct wpabuf *ie = NULL;
- const u8 *data;
- int len;
-
- if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
- goto err;
-
- dbus_message_iter_recurse(iter, &variant);
- if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY)
- goto err;
-
- dbus_message_iter_recurse(&variant, &array);
- dbus_message_iter_get_fixed_array(&array, &data, &len);
- if (len == 0) {
- wifi_display_enable(global, 0);
- wifi_display_deinit(global);
-
- return TRUE;
- }
-
- ie = wpabuf_alloc(len);
- if (ie == NULL)
- goto err;
-
- wpabuf_put_data(ie, data, len);
- if (wifi_display_subelem_set_from_ies(global, ie) != 0)
- goto err;
-
- if (global->wifi_display == 0)
- wifi_display_enable(global, 1);
-
- wpabuf_free(ie);
-
- return TRUE;
-err:
- wpabuf_free(ie);
-
- dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
- "invalid message format");
- return FALSE;
-}
-
-#endif /* CONFIG_WIFI_DISPLAY */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
deleted file mode 100644
index b3c45c11012c..000000000000
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface for p2p
- * Copyright (c) 2011-2012, Intel Corporation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DBUS_NEW_HANDLERS_P2P_H
-#define DBUS_NEW_HANDLERS_P2P_H
-
-struct peer_handler_args {
- struct wpa_supplicant *wpa_s;
- u8 p2p_device_addr[ETH_ALEN];
-};
-
-/*
- * P2P Device methods
- */
-
-DBusMessage *wpas_dbus_handler_p2p_find(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_stop_find(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_rejectpeer(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_listen(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_extendedlisten(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_presence_request(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_prov_disc_req(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_group_add(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_connect(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_p2p_cancel(DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_invite(
- DBusMessage *message,
- struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_disconnect(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_p2p_remove_client(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_flush(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_add_service(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_delete_service(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_flush_service(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_service_sd_req(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_service_sd_res(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_service_sd_cancel_req(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_service_update(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage *wpas_dbus_handler_p2p_serv_disc_external(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-/*
- * P2P Device property accessor methods.
- */
-DECLARE_ACCESSOR(wpas_dbus_setter_p2p_device_config);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_device_config);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peers);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_role);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peergo);
-
-/*
- * P2P Peer properties.
- */
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_device_name);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_manufacturer);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_modelname);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_modelnumber);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_serialnumber);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_primary_device_type);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_config_method);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_level);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_device_capability);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_group_capability);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_secondary_device_types);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_vendor_extension);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_ies);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_device_address);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_groups);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_peer_vsie);
-
-/*
- * P2P Group properties
- */
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_members);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_ssid);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_bssid);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_frequency);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_passphrase);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_psk);
-DECLARE_ACCESSOR(wpas_dbus_getter_p2p_group_vendor_ext);
-DECLARE_ACCESSOR(wpas_dbus_setter_p2p_group_vendor_ext);
-
-/*
- * P2P Persistent Groups and properties
- */
-DECLARE_ACCESSOR(wpas_dbus_getter_persistent_groups);
-DECLARE_ACCESSOR(wpas_dbus_getter_persistent_group_properties);
-DECLARE_ACCESSOR(wpas_dbus_setter_persistent_group_properties);
-
-DBusMessage * wpas_dbus_handler_add_persistent_group(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_persistent_group(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
- DBusMessage *message, struct wpa_supplicant *wpa_s);
-
-#ifdef CONFIG_WIFI_DISPLAY
-DECLARE_ACCESSOR(wpas_dbus_getter_global_wfd_ies);
-DECLARE_ACCESSOR(wpas_dbus_setter_global_wfd_ies);
-#endif /* CONFIG_WIFI_DISPLAY */
-
-#endif /* DBUS_NEW_HANDLERS_P2P_H */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
deleted file mode 100644
index 1594dafc7bb5..000000000000
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface (WPS)
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "../config.h"
-#include "../wpa_supplicant_i.h"
-#include "../wps_supplicant.h"
-#include "../driver_i.h"
-#include "../ap.h"
-#include "dbus_new_helpers.h"
-#include "dbus_new.h"
-#include "dbus_new_handlers.h"
-#include "dbus_dict_helpers.h"
-
-
-struct wps_start_params {
- int role; /* 0 - not set, 1 - enrollee, 2 - registrar */
- int type; /* 0 - not set, 1 - pin, 2 - pbc */
- u8 *bssid;
- char *pin;
- u8 *p2p_dev_addr;
-};
-
-
-static int wpas_dbus_handler_wps_role(DBusMessage *message,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter variant_iter;
- char *val;
-
- dbus_message_iter_recurse(entry_iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) !=
- DBUS_TYPE_STRING) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong Role type, string required");
- *reply = wpas_dbus_error_invalid_args(message,
- "Role must be a string");
- return -1;
- }
- dbus_message_iter_get_basic(&variant_iter, &val);
- if (os_strcmp(val, "enrollee") == 0)
- params->role = 1;
- else if (os_strcmp(val, "registrar") == 0)
- params->role = 2;
- else {
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown role %s", val);
- *reply = wpas_dbus_error_invalid_args(message, val);
- return -1;
- }
- return 0;
-}
-
-
-static int wpas_dbus_handler_wps_type(DBusMessage *message,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter variant_iter;
- char *val;
-
- dbus_message_iter_recurse(entry_iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong Type type, string required");
- *reply = wpas_dbus_error_invalid_args(message,
- "Type must be a string");
- return -1;
- }
- dbus_message_iter_get_basic(&variant_iter, &val);
- if (os_strcmp(val, "pin") == 0)
- params->type = 1;
- else if (os_strcmp(val, "pbc") == 0)
- params->type = 2;
- else {
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s",
- val);
- *reply = wpas_dbus_error_invalid_args(message, val);
- return -1;
- }
- return 0;
-}
-
-
-static int wpas_dbus_handler_wps_bssid(DBusMessage *message,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter variant_iter, array_iter;
- int len;
-
- dbus_message_iter_recurse(entry_iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&variant_iter) !=
- DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong Bssid type, byte array required");
- *reply = wpas_dbus_error_invalid_args(
- message, "Bssid must be a byte array");
- return -1;
- }
- dbus_message_iter_recurse(&variant_iter, &array_iter);
- dbus_message_iter_get_fixed_array(&array_iter, &params->bssid, &len);
- if (len != ETH_ALEN) {
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid length %d",
- len);
- *reply = wpas_dbus_error_invalid_args(message,
- "Bssid is wrong length");
- return -1;
- }
- return 0;
-}
-
-
-static int wpas_dbus_handler_wps_pin(DBusMessage *message,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter variant_iter;
-
- dbus_message_iter_recurse(entry_iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong Pin type, string required");
- *reply = wpas_dbus_error_invalid_args(message,
- "Pin must be a string");
- return -1;
- }
- dbus_message_iter_get_basic(&variant_iter, &params->pin);
- return 0;
-}
-
-
-#ifdef CONFIG_P2P
-static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- DBusMessageIter variant_iter, array_iter;
- int len;
-
- dbus_message_iter_recurse(entry_iter, &variant_iter);
- if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&variant_iter) !=
- DBUS_TYPE_BYTE) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong P2PDeviceAddress type, byte array required");
- *reply = wpas_dbus_error_invalid_args(
- message, "P2PDeviceAddress must be a byte array");
- return -1;
- }
- dbus_message_iter_recurse(&variant_iter, &array_iter);
- dbus_message_iter_get_fixed_array(&array_iter, &params->p2p_dev_addr,
- &len);
- if (len != ETH_ALEN) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Wrong P2PDeviceAddress length %d",
- len);
- *reply = wpas_dbus_error_invalid_args(
- message, "P2PDeviceAddress has wrong length");
- return -1;
- }
- return 0;
-}
-#endif /* CONFIG_P2P */
-
-
-static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
- DBusMessageIter *entry_iter,
- struct wps_start_params *params,
- DBusMessage **reply)
-{
- if (os_strcmp(key, "Role") == 0)
- return wpas_dbus_handler_wps_role(message, entry_iter,
- params, reply);
- else if (os_strcmp(key, "Type") == 0)
- return wpas_dbus_handler_wps_type(message, entry_iter,
- params, reply);
- else if (os_strcmp(key, "Bssid") == 0)
- return wpas_dbus_handler_wps_bssid(message, entry_iter,
- params, reply);
- else if (os_strcmp(key, "Pin") == 0)
- return wpas_dbus_handler_wps_pin(message, entry_iter,
- params, reply);
-#ifdef CONFIG_P2P
- else if (os_strcmp(key, "P2PDeviceAddress") == 0)
- return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter,
- params, reply);
-#endif /* CONFIG_P2P */
-
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
- *reply = wpas_dbus_error_invalid_args(message, key);
- return -1;
-}
-
-
-/**
- * wpas_dbus_handler_wps_start - Start WPS configuration
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: DBus message dictionary on success or DBus error on failure
- *
- * Handler for "Start" method call. DBus dictionary argument contains
- * information about role (enrollee or registrar), authorization method
- * (pin or push button) and optionally pin and bssid. Returned message
- * has a dictionary argument which may contain newly generated pin (optional).
- */
-DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- DBusMessage *reply = NULL;
- DBusMessageIter iter, dict_iter, entry_iter;
- struct wps_start_params params;
- char *key;
- char npin[9] = { '\0' };
- int ret;
-
- os_memset(&params, 0, sizeof(params));
- dbus_message_iter_init(message, &iter);
-
- dbus_message_iter_recurse(&iter, &dict_iter);
- while (dbus_message_iter_get_arg_type(&dict_iter) ==
- DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(&dict_iter, &entry_iter);
-
- dbus_message_iter_get_basic(&entry_iter, &key);
- dbus_message_iter_next(&entry_iter);
-
- if (wpas_dbus_handler_wps_start_entry(message, key,
- &entry_iter,
- &params, &reply))
- return reply;
-
- dbus_message_iter_next(&dict_iter);
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface && params.type == 1) {
- if (params.pin == NULL) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Pin required for registrar role");
- return wpas_dbus_error_invalid_args(
- message, "Pin required for registrar role.");
- }
- ret = wpa_supplicant_ap_wps_pin(wpa_s,
- params.bssid,
- params.pin,
- npin, sizeof(npin), 0);
- } else if (wpa_s->ap_iface) {
- ret = wpa_supplicant_ap_wps_pbc(wpa_s,
- params.bssid,
- params.p2p_dev_addr);
- } else
-#endif /* CONFIG_AP */
- if (params.role == 0) {
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified");
- return wpas_dbus_error_invalid_args(message,
- "Role not specified");
- } else if (params.role == 2) {
- if (params.pin == NULL) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start - Pin required for registrar role");
- return wpas_dbus_error_invalid_args(
- message, "Pin required for registrar role.");
- }
- ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
- NULL);
- } else if (params.type == 0) {
- wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified");
- return wpas_dbus_error_invalid_args(message,
- "Type not specified");
- } else if (params.type == 1) {
- ret = wpas_wps_start_pin(wpa_s, params.bssid,
- params.pin, 0,
- DEV_PW_DEFAULT);
- if (ret > 0) {
- ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
- if (os_snprintf_error(sizeof(npin), ret))
- return wpas_dbus_error_unknown_error(
- message, "invalid PIN");
- }
- } else {
- ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
- }
-
- if (ret < 0) {
- wpa_printf(MSG_DEBUG,
- "dbus: WPS.Start wpas_wps_failed in role %s and key %s",
- (params.role == 1 ? "enrollee" : "registrar"),
- (params.type == 0 ? "" :
- (params.type == 1 ? "pin" : "pbc")));
- return wpas_dbus_error_unknown_error(message,
- "WPS start failed");
- }
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return wpas_dbus_error_no_memory(message);
-
- dbus_message_iter_init_append(reply, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
- (os_strlen(npin) > 0 &&
- !wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) ||
- !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
- dbus_message_unref(reply);
- return wpas_dbus_error_no_memory(message);
- }
-
- return reply;
-}
-
-
-/**
- * wpas_dbus_handler_wps_cancel - Cancel ongoing WPS configuration
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: NULL on success or DBus error on failure
- *
- * Handler for "Cancel" method call. Returns NULL if WPS cancel successful
- * or DBus error on WPS cancel failure
- */
-DBusMessage * wpas_dbus_handler_wps_cancel(DBusMessage *message,
- struct wpa_supplicant *wpa_s)
-{
- if (wpas_wps_cancel(wpa_s))
- return wpas_dbus_error_unknown_error(message,
- "WPS cancel failed");
-
- return NULL;
-}
-
-
-/**
- * wpas_dbus_getter_process_credentials - Check if credentials are processed
- * @message: Pointer to incoming dbus message
- * @wpa_s: %wpa_supplicant data structure
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ProcessCredentials" property. Returns returned boolean will be
- * true if wps_cred_processing configuration field is not equal to 1 or false
- * if otherwise.
- */
-dbus_bool_t wpas_dbus_getter_process_credentials(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t process = wpa_s->conf->wps_cred_processing != 1;
-
- return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
- &process, error);
-}
-
-
-/**
- * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
- * if boolean argument is true or on 1 if otherwise.
- */
-dbus_bool_t wpas_dbus_setter_process_credentials(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- dbus_bool_t process_credentials, old_pc;
-
- if (!wpa_s->dbus_new_path)
- return FALSE;
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
- &process_credentials))
- return FALSE;
-
- old_pc = wpa_s->conf->wps_cred_processing != 1;
- wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
-
- if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
- wpa_dbus_mark_property_changed(wpa_s->global->dbus,
- wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS,
- "ProcessCredentials");
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_config_methods - Get current WPS configuration methods
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ConfigMethods" property. Returned boolean will be true if
- * providing the relevant string worked, or false otherwise.
- */
-dbus_bool_t wpas_dbus_getter_config_methods(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter,
- wpa_s->conf->config_methods,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_config_methods - Set WPS configuration methods
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "ConfigMethods" property. Sets the methods string, apply such
- * change and returns true on success. Returns false otherwise.
- */
-dbus_bool_t wpas_dbus_setter_config_methods(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *new_methods;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- new_methods = os_strdup(methods);
- if (!new_methods)
- return FALSE;
-
- os_free(wpa_s->conf->config_methods);
- wpa_s->conf->config_methods = new_methods;
-
- wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_device_name - Get current WPS device name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DeviceName" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_device_name(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->conf->device_name,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_wps_device_name - Set current WPS device name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "DeviceName" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_device_name(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *devname;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- if (os_strlen(methods) > WPS_DEV_NAME_MAX_LEN)
- return FALSE;
-
- devname = os_strdup(methods);
- if (!devname)
- return FALSE;
-
- os_free(wpa_s->conf->device_name);
- wpa_s->conf->device_name = devname;
- wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_NAME;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_manufacturer - Get current manufacturer name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "Manufacturer" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_manufacturer(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->conf->manufacturer,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_wps_manufacturer - Set current manufacturer name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "Manufacturer" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_manufacturer(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *manufacturer;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- if (os_strlen(methods) > WPS_MANUFACTURER_MAX_LEN)
- return FALSE;
-
- manufacturer = os_strdup(methods);
- if (!manufacturer)
- return FALSE;
-
- os_free(wpa_s->conf->manufacturer);
- wpa_s->conf->manufacturer = manufacturer;
- wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_device_model_name - Get current device model name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ModelName" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_device_model_name(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_name,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_wps_device_model_name - Set current device model name
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "ModelName" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_device_model_name(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *model_name;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- if (os_strlen(methods) > WPS_MODEL_NAME_MAX_LEN)
- return FALSE;
-
- model_name = os_strdup(methods);
- if (!model_name)
- return FALSE;
- os_free(wpa_s->conf->model_name);
- wpa_s->conf->model_name = model_name;
- wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_device_model_number - Get current device model number
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "ModelNumber" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_device_model_number(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_number,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_wps_device_model_number - Set current device model number
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "ModelNumber" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_device_model_number(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *model_number;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- if (os_strlen(methods) > WPS_MODEL_NUMBER_MAX_LEN)
- return FALSE;
-
- model_number = os_strdup(methods);
- if (!model_number)
- return FALSE;
-
- os_free(wpa_s->conf->model_number);
- wpa_s->conf->model_number = model_number;
- wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_device_serial_number - Get current device serial number
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "SerialNumber" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_device_serial_number(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- return wpas_dbus_string_property_getter(iter,
- wpa_s->conf->serial_number,
- error);
-}
-
-
-/**
- * wpas_dbus_setter_wps_device_serial_number - Set current device serial number
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "SerialNumber" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_device_serial_number(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- char *methods, *serial_number;
-
- if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
- &methods))
- return FALSE;
-
- if (os_strlen(methods) > WPS_SERIAL_NUMBER_MAX_LEN)
- return FALSE;
-
- serial_number = os_strdup(methods);
- if (!serial_number)
- return FALSE;
- os_free(wpa_s->conf->serial_number);
- wpa_s->conf->serial_number = serial_number;
- wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_getter_wps_device_device_type - Get current device type
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Getter for "DeviceType" property.
- */
-dbus_bool_t wpas_dbus_getter_wps_device_device_type(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
-
- if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
- (char *)
- wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN, error)) {
- dbus_set_error(error, DBUS_ERROR_FAILED,
- "%s: error constructing reply", __func__);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/**
- * wpas_dbus_setter_wps_device_device_type - Set current device type
- * @iter: Pointer to incoming dbus message iter
- * @error: Location to store error on failure
- * @user_data: Function specific data
- * Returns: TRUE on success, FALSE on failure
- *
- * Setter for "DeviceType" property.
- */
-dbus_bool_t wpas_dbus_setter_wps_device_device_type(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data)
-{
- struct wpa_supplicant *wpa_s = user_data;
- u8 *dev_type;
- int dev_len;
- DBusMessageIter variant, array_iter;
-
- if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
- return FALSE;
-
- dbus_message_iter_recurse(iter, &variant);
- if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY)
- return FALSE;
-
- dbus_message_iter_recurse(&variant, &array_iter);
- dbus_message_iter_get_fixed_array(&array_iter, &dev_type, &dev_len);
-
- if (dev_len != WPS_DEV_TYPE_LEN)
- return FALSE;
-
- os_memcpy(wpa_s->conf->device_type, dev_type, WPS_DEV_TYPE_LEN);
- wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_TYPE;
- wpa_supplicant_update_config(wpa_s);
-
- return TRUE;
-}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
deleted file mode 100644
index d9009ba85e9c..000000000000
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "dbus_common.h"
-#include "dbus_common_i.h"
-#include "dbus_new.h"
-#include "dbus_new_helpers.h"
-#include "dbus_new_handlers.h"
-#include "dbus_dict_helpers.h"
-
-
-static dbus_bool_t fill_dict_with_properties(
- DBusMessageIter *dict_iter,
- const struct wpa_dbus_property_desc *props,
- const char *interface, void *user_data, DBusError *error)
-{
- DBusMessageIter entry_iter;
- const struct wpa_dbus_property_desc *dsc;
-
- for (dsc = props; dsc && dsc->dbus_property; dsc++) {
- /* Only return properties for the requested D-Bus interface */
- if (os_strncmp(dsc->dbus_interface, interface,
- WPAS_DBUS_INTERFACE_MAX) != 0)
- continue;
-
- /* Skip write-only properties */
- if (dsc->getter == NULL)
- continue;
-
- if (!dbus_message_iter_open_container(dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter) ||
- !dbus_message_iter_append_basic(&entry_iter,
- DBUS_TYPE_STRING,
- &dsc->dbus_property))
- goto error;
-
- /* An error getting a property fails the request entirely */
- if (!dsc->getter(dsc, &entry_iter, error, user_data)) {
- wpa_printf(MSG_INFO,
- "dbus: %s dbus_interface=%s dbus_property=%s getter failed",
- __func__, dsc->dbus_interface,
- dsc->dbus_property);
- return FALSE;
- }
-
- if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
- goto error;
- }
-
- return TRUE;
-
-error:
- dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
- return FALSE;
-}
-
-
-/**
- * get_all_properties - Responds for GetAll properties calls on object
- * @message: Message with GetAll call
- * @interface: interface name which properties will be returned
- * @property_dsc: list of object's properties
- * Returns: Message with dict of variants as argument with properties values
- *
- * Iterates over all properties registered with object and execute getters
- * of those, which are readable and which interface matches interface
- * specified as argument. Returned message contains one dict argument
- * with properties names as keys and theirs values as values.
- */
-static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- DBusMessage *reply;
- DBusMessageIter iter, dict_iter;
- DBusError error;
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL)
- return wpas_dbus_error_no_memory(message);
-
- dbus_message_iter_init_append(reply, &iter);
- if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
- dbus_message_unref(reply);
- return wpas_dbus_error_no_memory(message);
- }
-
- dbus_error_init(&error);
- if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties,
- interface, obj_dsc->user_data, &error)) {
- wpa_dbus_dict_close_write(&iter, &dict_iter);
- dbus_message_unref(reply);
- reply = wpas_dbus_reply_new_from_error(
- message, &error, DBUS_ERROR_INVALID_ARGS,
- "No readable properties in this interface");
- dbus_error_free(&error);
- return reply;
- }
-
- if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
- dbus_message_unref(reply);
- return wpas_dbus_error_no_memory(message);
- }
-
- return reply;
-}
-
-
-static int is_signature_correct(DBusMessage *message,
- const struct wpa_dbus_method_desc *method_dsc)
-{
- /* According to DBus documentation max length of signature is 255 */
-#define MAX_SIG_LEN 256
- char registered_sig[MAX_SIG_LEN], *pos;
- const char *sig = dbus_message_get_signature(message);
- int ret;
- const struct wpa_dbus_argument *arg;
-
- pos = registered_sig;
- *pos = '\0';
-
- for (arg = method_dsc->args; arg && arg->name; arg++) {
- if (arg->dir == ARG_IN) {
- size_t blen = registered_sig + MAX_SIG_LEN - pos;
-
- ret = os_snprintf(pos, blen, "%s", arg->type);
- if (os_snprintf_error(blen, ret))
- return 0;
- pos += ret;
- }
- }
-
- return !os_strncmp(registered_sig, sig, MAX_SIG_LEN);
-}
-
-
-static DBusMessage * properties_get_all(DBusMessage *message, char *interface,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- if (os_strcmp(dbus_message_get_signature(message), "s") != 0)
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- NULL);
-
- return get_all_properties(message, interface, obj_dsc);
-}
-
-
-static DBusMessage * properties_get(DBusMessage *message,
- const struct wpa_dbus_property_desc *dsc,
- void *user_data)
-{
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusError error;
-
- if (os_strcmp(dbus_message_get_signature(message), "ss")) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- NULL);
- }
-
- if (dsc->getter == NULL) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Property is write-only");
- }
-
- reply = dbus_message_new_method_return(message);
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_error_init(&error);
- if (dsc->getter(dsc, &iter, &error, user_data) == FALSE) {
- dbus_message_unref(reply);
- reply = wpas_dbus_reply_new_from_error(
- message, &error, DBUS_ERROR_FAILED,
- "Failed to read property");
- dbus_error_free(&error);
- }
-
- return reply;
-}
-
-
-static DBusMessage * properties_set(DBusMessage *message,
- const struct wpa_dbus_property_desc *dsc,
- void *user_data)
-{
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusError error;
-
- if (os_strcmp(dbus_message_get_signature(message), "ssv")) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- NULL);
- }
-
- if (dsc->setter == NULL) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Property is read-only");
- }
-
- dbus_message_iter_init(message, &iter);
- /* Skip the interface name and the property name */
- dbus_message_iter_next(&iter);
- dbus_message_iter_next(&iter);
-
- /* Iter will now point to the property's new value */
- dbus_error_init(&error);
- if (dsc->setter(dsc, &iter, &error, user_data) == TRUE) {
- /* Success */
- reply = dbus_message_new_method_return(message);
- } else {
- reply = wpas_dbus_reply_new_from_error(
- message, &error, DBUS_ERROR_FAILED,
- "Failed to set property");
- dbus_error_free(&error);
- }
-
- return reply;
-}
-
-
-static DBusMessage *
-properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
- char *interface,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- const struct wpa_dbus_property_desc *property_dsc;
- char *property;
- const char *method;
-
- method = dbus_message_get_member(message);
- property_dsc = obj_dsc->properties;
-
- /* Second argument: property name (DBUS_TYPE_STRING) */
- if (!dbus_message_iter_next(iter) ||
- dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- NULL);
- }
- dbus_message_iter_get_basic(iter, &property);
-
- while (property_dsc && property_dsc->dbus_property) {
- /* compare property names and
- * interfaces */
- if (!os_strncmp(property_dsc->dbus_property, property,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
- !os_strncmp(property_dsc->dbus_interface, interface,
- WPAS_DBUS_INTERFACE_MAX))
- break;
-
- property_dsc++;
- }
- if (property_dsc == NULL || property_dsc->dbus_property == NULL) {
- wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s",
- interface, property,
- dbus_message_get_path(message));
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "No such property");
- }
-
- if (os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) == 0) {
- wpa_printf(MSG_MSGDUMP, "%s: Get(%s)", __func__, property);
- return properties_get(message, property_dsc,
- obj_dsc->user_data);
- }
-
- wpa_printf(MSG_MSGDUMP, "%s: Set(%s)", __func__, property);
- return properties_set(message, property_dsc, obj_dsc->user_data);
-}
-
-
-static DBusMessage * properties_handler(DBusMessage *message,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- DBusMessageIter iter;
- char *interface;
- const char *method;
-
- method = dbus_message_get_member(message);
- dbus_message_iter_init(message, &iter);
-
- if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
- !os_strncmp(WPA_DBUS_PROPERTIES_SET, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
- !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
- /* First argument: interface name (DBUS_TYPE_STRING) */
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
- return dbus_message_new_error(message,
- DBUS_ERROR_INVALID_ARGS,
- NULL);
- }
-
- dbus_message_iter_get_basic(&iter, &interface);
-
- if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
- /* GetAll */
- return properties_get_all(message, interface, obj_dsc);
- }
- /* Get or Set */
- return properties_get_or_set(message, &iter, interface,
- obj_dsc);
- }
- return dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD,
- NULL);
-}
-
-
-static DBusMessage * msg_method_handler(DBusMessage *message,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- const struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
- const char *method;
- const char *msg_interface;
-
- method = dbus_message_get_member(message);
- msg_interface = dbus_message_get_interface(message);
-
- /* try match call to any registered method */
- while (method_dsc && method_dsc->dbus_method) {
- /* compare method names and interfaces */
- if (!os_strncmp(method_dsc->dbus_method, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
- !os_strncmp(method_dsc->dbus_interface, msg_interface,
- WPAS_DBUS_INTERFACE_MAX))
- break;
-
- method_dsc++;
- }
- if (method_dsc == NULL || method_dsc->dbus_method == NULL) {
- wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s",
- msg_interface, method,
- dbus_message_get_path(message));
- return dbus_message_new_error(message,
- DBUS_ERROR_UNKNOWN_METHOD, NULL);
- }
-
- if (!is_signature_correct(message, method_dsc)) {
- return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- NULL);
- }
-
- return method_dsc->method_handler(message, obj_dsc->user_data);
-}
-
-
-/**
- * message_handler - Handles incoming DBus messages
- * @connection: DBus connection on which message was received
- * @message: Received message
- * @user_data: pointer to description of object to which message was sent
- * Returns: Returns information whether message was handled or not
- *
- * Reads message interface and method name, then checks if they matches one
- * of the special cases i.e. introspection call or properties get/getall/set
- * methods and handles it. Else it iterates over registered methods list
- * and tries to match method's name and interface to those read from message
- * If appropriate method was found its handler function is called and
- * response is sent. Otherwise, the DBUS_ERROR_UNKNOWN_METHOD error message
- * will be sent.
- */
-static DBusHandlerResult message_handler(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct wpa_dbus_object_desc *obj_dsc = user_data;
- const char *method;
- const char *path;
- const char *msg_interface;
- DBusMessage *reply;
-
- /* get method, interface and path the message is addressed to */
- method = dbus_message_get_member(message);
- path = dbus_message_get_path(message);
- msg_interface = dbus_message_get_interface(message);
- if (!method || !path || !msg_interface)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- wpa_printf(MSG_MSGDUMP, "dbus: %s.%s (%s) [%s]",
- msg_interface, method, path,
- dbus_message_get_signature(message));
-
- /* if message is introspection method call */
- if (!os_strncmp(WPA_DBUS_INTROSPECTION_METHOD, method,
- WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
- !os_strncmp(WPA_DBUS_INTROSPECTION_INTERFACE, msg_interface,
- WPAS_DBUS_INTERFACE_MAX)) {
-#ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
- reply = wpa_dbus_introspect(message, obj_dsc);
-#else /* CONFIG_CTRL_IFACE_DBUS_INTRO */
- reply = dbus_message_new_error(
- message, DBUS_ERROR_UNKNOWN_METHOD,
- "wpa_supplicant was compiled without introspection support.");
-#endif /* CONFIG_CTRL_IFACE_DBUS_INTRO */
- } else if (!os_strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface,
- WPAS_DBUS_INTERFACE_MAX)) {
- /* if message is properties method call */
- reply = properties_handler(message, obj_dsc);
- } else {
- reply = msg_method_handler(message, obj_dsc);
- }
-
- /* If handler succeed returning NULL, reply empty message */
- if (!reply)
- reply = dbus_message_new_method_return(message);
- if (reply) {
- if (!dbus_message_get_no_reply(message))
- dbus_connection_send(connection, reply, NULL);
- dbus_message_unref(reply);
- }
-
- wpa_dbus_flush_all_changed_properties(connection);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-
-/**
- * free_dbus_object_desc - Frees object description data structure
- * @connection: DBus connection
- * @obj_dsc: Object description to free
- *
- * Frees each of properties, methods and signals description lists and
- * the object description structure itself.
- */
-void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc)
-{
- if (!obj_dsc)
- return;
-
- /* free handler's argument */
- if (obj_dsc->user_data_free_func)
- obj_dsc->user_data_free_func(obj_dsc->user_data);
-
- os_free(obj_dsc->path);
- os_free(obj_dsc->prop_changed_flags);
- os_free(obj_dsc);
-}
-
-
-static void free_dbus_object_desc_cb(DBusConnection *connection, void *obj_dsc)
-{
- free_dbus_object_desc(obj_dsc);
-}
-
-
-/**
- * wpa_dbus_ctrl_iface_init - Initialize dbus control interface
- * @application_data: Pointer to application specific data structure
- * @dbus_path: DBus path to interface object
- * @dbus_service: DBus service name to register with
- * @messageHandler: a pointer to function which will handle dbus messages
- * coming on interface
- * Returns: 0 on success, -1 on failure
- *
- * Initialize the dbus control interface and start receiving commands from
- * external programs over the bus.
- */
-int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface,
- char *dbus_path, char *dbus_service,
- struct wpa_dbus_object_desc *obj_desc)
-{
- DBusError error;
- int ret = -1;
- DBusObjectPathVTable wpa_vtable = {
- &free_dbus_object_desc_cb, &message_handler,
- NULL, NULL, NULL, NULL
- };
-
- obj_desc->connection = iface->con;
- obj_desc->path = os_strdup(dbus_path);
-
- /* Register the message handler for the global dbus interface */
- if (!dbus_connection_register_object_path(iface->con, dbus_path,
- &wpa_vtable, obj_desc)) {
- wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
- return -1;
- }
-
- /* Register our service with the message bus */
- dbus_error_init(&error);
- switch (dbus_bus_request_name(iface->con, dbus_service, 0, &error)) {
- case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
- ret = 0;
- break;
- case DBUS_REQUEST_NAME_REPLY_EXISTS:
- case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
- case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
- wpa_printf(MSG_ERROR,
- "dbus: Could not request service name: already registered");
- break;
- default:
- wpa_printf(MSG_ERROR,
- "dbus: Could not request service name: %s %s",
- error.name, error.message);
- break;
- }
- dbus_error_free(&error);
-
- if (ret != 0)
- return -1;
-
- wpa_printf(MSG_DEBUG, "Providing DBus service '%s'.", dbus_service);
-
- return 0;
-}
-
-
-/**
- * wpa_dbus_register_object_per_iface - Register a new object with dbus
- * @ctrl_iface: pointer to dbus private data
- * @path: DBus path to object
- * @ifname: interface name
- * @obj_desc: description of object's methods, signals and properties
- * Returns: 0 on success, -1 on error
- *
- * Registers a new interface with dbus and assigns it a dbus object path.
- */
-int wpa_dbus_register_object_per_iface(struct wpas_dbus_priv *ctrl_iface,
- const char *path, const char *ifname,
- struct wpa_dbus_object_desc *obj_desc)
-{
- DBusConnection *con;
- DBusError error;
- DBusObjectPathVTable vtable = {
- &free_dbus_object_desc_cb, &message_handler,
- NULL, NULL, NULL, NULL
- };
-
- /* Do nothing if the control interface is not turned on */
- if (ctrl_iface == NULL)
- return 0;
-
- con = ctrl_iface->con;
- obj_desc->connection = con;
- obj_desc->path = os_strdup(path);
-
- dbus_error_init(&error);
- /* Register the message handler for the interface functions */
- if (!dbus_connection_try_register_object_path(con, path, &vtable,
- obj_desc, &error)) {
- if (os_strcmp(error.name, DBUS_ERROR_OBJECT_PATH_IN_USE) == 0) {
- wpa_printf(MSG_DEBUG, "dbus: %s", error.message);
- } else {
- wpa_printf(MSG_ERROR,
- "dbus: Could not set up message handler for interface %s object %s (error: %s message: %s)",
- ifname, path, error.name, error.message);
- }
- dbus_error_free(&error);
- return -1;
- }
-
- dbus_error_free(&error);
- return 0;
-}
-
-
-static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx);
-
-
-/**
- * wpa_dbus_unregister_object_per_iface - Unregisters DBus object
- * @ctrl_iface: Pointer to dbus private data
- * @path: DBus path to object which will be unregistered
- * Returns: Zero on success and -1 on failure
- *
- * Unregisters DBus object given by its path
- */
-int wpa_dbus_unregister_object_per_iface(
- struct wpas_dbus_priv *ctrl_iface, const char *path)
-{
- DBusConnection *con = ctrl_iface->con;
- struct wpa_dbus_object_desc *obj_desc = NULL;
-
- dbus_connection_get_object_path_data(con, path, (void **) &obj_desc);
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Could not obtain object's private data: %s",
- __func__, path);
- return 0;
- }
-
- eloop_cancel_timeout(flush_object_timeout_handler, con, obj_desc);
-
- if (!dbus_connection_unregister_object_path(con, path))
- return -1;
-
- return 0;
-}
-
-
-static dbus_bool_t put_changed_properties(
- const struct wpa_dbus_object_desc *obj_dsc, const char *interface,
- DBusMessageIter *dict_iter, int clear_changed)
-{
- DBusMessageIter entry_iter;
- const struct wpa_dbus_property_desc *dsc;
- int i;
- DBusError error;
-
- for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property;
- dsc++, i++) {
- if (obj_dsc->prop_changed_flags == NULL ||
- !obj_dsc->prop_changed_flags[i])
- continue;
- if (os_strcmp(dsc->dbus_interface, interface) != 0)
- continue;
- if (clear_changed)
- obj_dsc->prop_changed_flags[i] = 0;
-
- if (!dbus_message_iter_open_container(dict_iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &entry_iter) ||
- !dbus_message_iter_append_basic(&entry_iter,
- DBUS_TYPE_STRING,
- &dsc->dbus_property))
- return FALSE;
-
- dbus_error_init(&error);
- if (!dsc->getter(dsc, &entry_iter, &error, obj_dsc->user_data))
- {
- if (dbus_error_is_set(&error)) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Cannot get new value of property %s: (%s) %s",
- __func__, dsc->dbus_property,
- error.name, error.message);
- } else {
- wpa_printf(MSG_ERROR,
- "dbus: %s: Cannot get new value of property %s",
- __func__, dsc->dbus_property);
- }
- dbus_error_free(&error);
- return FALSE;
- }
-
- if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-static void do_send_prop_changed_signal(
- DBusConnection *con, const char *path, const char *interface,
- const struct wpa_dbus_object_desc *obj_dsc)
-{
- DBusMessage *msg;
- DBusMessageIter signal_iter, dict_iter;
-
- msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &signal_iter);
-
- if (!dbus_message_iter_append_basic(&signal_iter, DBUS_TYPE_STRING,
- &interface) ||
- /* Changed properties dict */
- !dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
- "{sv}", &dict_iter) ||
- !put_changed_properties(obj_dsc, interface, &dict_iter, 0) ||
- !dbus_message_iter_close_container(&signal_iter, &dict_iter) ||
- /* Invalidated properties array (empty) */
- !dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
- "s", &dict_iter) ||
- !dbus_message_iter_close_container(&signal_iter, &dict_iter)) {
- wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal",
- __func__);
- } else {
- dbus_connection_send(con, msg, NULL);
- }
-
- dbus_message_unref(msg);
-}
-
-
-static void do_send_deprecated_prop_changed_signal(
- DBusConnection *con, const char *path, const char *interface,
- const struct wpa_dbus_object_desc *obj_dsc)
-{
- DBusMessage *msg;
- DBusMessageIter signal_iter, dict_iter;
-
- msg = dbus_message_new_signal(path, interface, "PropertiesChanged");
- if (msg == NULL)
- return;
-
- dbus_message_iter_init_append(msg, &signal_iter);
-
- if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
- "{sv}", &dict_iter) ||
- !put_changed_properties(obj_dsc, interface, &dict_iter, 1) ||
- !dbus_message_iter_close_container(&signal_iter, &dict_iter)) {
- wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal",
- __func__);
- } else {
- dbus_connection_send(con, msg, NULL);
- }
-
- dbus_message_unref(msg);
-}
-
-
-static void send_prop_changed_signal(
- DBusConnection *con, const char *path, const char *interface,
- const struct wpa_dbus_object_desc *obj_dsc)
-{
- /*
- * First, send property change notification on the standardized
- * org.freedesktop.DBus.Properties interface. This call will not
- * clear the property change bits, so that they are preserved for
- * the call that follows.
- */
- do_send_prop_changed_signal(con, path, interface, obj_dsc);
-
- /*
- * Now send PropertiesChanged on our own interface for backwards
- * compatibility. This is deprecated and will be removed in a future
- * release.
- */
- do_send_deprecated_prop_changed_signal(con, path, interface, obj_dsc);
-
- /* Property change bits have now been cleared. */
-}
-
-
-static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx)
-{
- DBusConnection *con = eloop_ctx;
- struct wpa_dbus_object_desc *obj_desc = timeout_ctx;
-
- wpa_printf(MSG_MSGDUMP,
- "dbus: %s: Timeout - sending changed properties of object %s",
- __func__, obj_desc->path);
- wpa_dbus_flush_object_changed_properties(con, obj_desc->path);
-}
-
-
-static void recursive_flush_changed_properties(DBusConnection *con,
- const char *path)
-{
- char **objects = NULL;
- char subobj_path[WPAS_DBUS_OBJECT_PATH_MAX];
- int i;
-
- wpa_dbus_flush_object_changed_properties(con, path);
-
- if (!dbus_connection_list_registered(con, path, &objects))
- goto out;
-
- for (i = 0; objects[i]; i++) {
- os_snprintf(subobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
- "%s/%s", path, objects[i]);
- recursive_flush_changed_properties(con, subobj_path);
- }
-
-out:
- dbus_free_string_array(objects);
-}
-
-
-/**
- * wpa_dbus_flush_all_changed_properties - Send all PropertiesChanged signals
- * @con: DBus connection
- *
- * Traverses through all registered objects and sends PropertiesChanged for
- * each properties.
- */
-void wpa_dbus_flush_all_changed_properties(DBusConnection *con)
-{
- recursive_flush_changed_properties(con, WPAS_DBUS_NEW_PATH);
-}
-
-
-/**
- * wpa_dbus_flush_object_changed_properties - Send PropertiesChanged for object
- * @con: DBus connection
- * @path: path to a DBus object for which PropertiesChanged will be sent.
- *
- * Iterates over all properties registered with object and for each interface
- * containing properties marked as changed, sends a PropertiesChanged signal
- * containing names and new values of properties that have changed.
- *
- * You need to call this function after wpa_dbus_mark_property_changed()
- * if you want to send PropertiesChanged signal immediately (i.e., without
- * waiting timeout to expire). PropertiesChanged signal for an object is sent
- * automatically short time after first marking property as changed. All
- * PropertiesChanged signals are sent automatically after responding on DBus
- * message, so if you marked a property changed as a result of DBus call
- * (e.g., param setter), you usually do not need to call this function.
- */
-void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
- const char *path)
-{
- struct wpa_dbus_object_desc *obj_desc = NULL;
- const struct wpa_dbus_property_desc *dsc;
- int i;
-
- dbus_connection_get_object_path_data(con, path, (void **) &obj_desc);
- if (!obj_desc)
- return;
- eloop_cancel_timeout(flush_object_timeout_handler, con, obj_desc);
-
- for (dsc = obj_desc->properties, i = 0; dsc && dsc->dbus_property;
- dsc++, i++) {
- if (obj_desc->prop_changed_flags == NULL ||
- !obj_desc->prop_changed_flags[i])
- continue;
- send_prop_changed_signal(con, path, dsc->dbus_interface,
- obj_desc);
- }
-}
-
-
-#define WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT 5000
-
-
-/**
- * wpa_dbus_mark_property_changed - Mark a property as changed and
- * @iface: dbus priv struct
- * @path: path to DBus object which property has changed
- * @interface: interface containing changed property
- * @property: property name which has changed
- *
- * Iterates over all properties registered with an object and marks the one
- * given in parameters as changed. All parameters registered for an object
- * within a single interface will be aggregated together and sent in one
- * PropertiesChanged signal when function
- * wpa_dbus_flush_object_changed_properties() is called.
- */
-void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- const char *property)
-{
- struct wpa_dbus_object_desc *obj_desc = NULL;
- const struct wpa_dbus_property_desc *dsc;
- int i = 0;
-
- if (iface == NULL)
- return;
-
- dbus_connection_get_object_path_data(iface->con, path,
- (void **) &obj_desc);
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "dbus: wpa_dbus_property_changed: could not obtain object's private data: %s",
- path);
- return;
- }
-
- for (dsc = obj_desc->properties; dsc && dsc->dbus_property; dsc++, i++)
- if (os_strcmp(property, dsc->dbus_property) == 0 &&
- os_strcmp(interface, dsc->dbus_interface) == 0) {
- if (obj_desc->prop_changed_flags)
- obj_desc->prop_changed_flags[i] = 1;
- break;
- }
-
- if (!dsc || !dsc->dbus_property) {
- wpa_printf(MSG_ERROR,
- "dbus: wpa_dbus_property_changed: no property %s in object %s",
- property, path);
- return;
- }
-
- if (!eloop_is_timeout_registered(flush_object_timeout_handler,
- iface->con, obj_desc)) {
- eloop_register_timeout(0, WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT,
- flush_object_timeout_handler,
- iface->con, obj_desc);
- }
-}
-
-
-/**
- * wpa_dbus_get_object_properties - Put object's properties into dictionary
- * @iface: dbus priv struct
- * @path: path to DBus object which properties will be obtained
- * @interface: interface name which properties will be obtained
- * @iter: DBus message iter at which to append property dictionary.
- *
- * Iterates over all properties registered with object and execute getters
- * of those, which are readable and which interface matches interface
- * specified as argument. Obtained properties values are stored in
- * dict_iter dictionary.
- */
-dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
- const char *path,
- const char *interface,
- DBusMessageIter *iter)
-{
- struct wpa_dbus_object_desc *obj_desc = NULL;
- DBusMessageIter dict_iter;
- DBusError error;
-
- dbus_connection_get_object_path_data(iface->con, path,
- (void **) &obj_desc);
- if (!obj_desc) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: could not obtain object's private data: %s",
- __func__, path);
- return FALSE;
- }
-
- if (!wpa_dbus_dict_open_write(iter, &dict_iter)) {
- wpa_printf(MSG_ERROR, "dbus: %s: failed to open message dict",
- __func__);
- return FALSE;
- }
-
- dbus_error_init(&error);
- if (!fill_dict_with_properties(&dict_iter, obj_desc->properties,
- interface, obj_desc->user_data,
- &error)) {
- wpa_printf(MSG_ERROR,
- "dbus: %s: failed to get object properties: (%s) %s",
- __func__,
- dbus_error_is_set(&error) ? error.name : "none",
- dbus_error_is_set(&error) ? error.message : "none");
- dbus_error_free(&error);
- wpa_dbus_dict_close_write(iter, &dict_iter);
- return FALSE;
- }
-
- return wpa_dbus_dict_close_write(iter, &dict_iter);
-}
-
-/**
- * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
- * @path: The dbus object path
- * @sep: Separating part (e.g., "Networks" or "PersistentGroups")
- * @item: (out) The part following the specified separator, if any
- * Returns: The object path of the interface this path refers to
- *
- * For a given object path, decomposes the object path into object id and
- * requested part, if those parts exist. The caller is responsible for freeing
- * the returned value. The *item pointer points to that allocated value and must
- * not be freed separately.
- *
- * As an example, path = "/fi/w1/wpa_supplicant1/Interfaces/1/Networks/0" and
- * sep = "Networks" would result in "/fi/w1/wpa_supplicant1/Interfaces/1"
- * getting returned and *items set to point to "0".
- */
-char * wpas_dbus_new_decompose_object_path(const char *path, const char *sep,
- char **item)
-{
- const unsigned int dev_path_prefix_len =
- os_strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
- char *obj_path_only;
- char *pos;
- size_t sep_len;
-
- *item = NULL;
-
- /* Verify that this starts with our interface prefix */
- if (os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
- dev_path_prefix_len) != 0)
- return NULL; /* not our path */
-
- /* Ensure there's something at the end of the path */
- if ((path + dev_path_prefix_len)[0] == '\0')
- return NULL;
-
- obj_path_only = os_strdup(path);
- if (obj_path_only == NULL)
- return NULL;
-
- pos = obj_path_only + dev_path_prefix_len;
- pos = os_strchr(pos, '/');
- if (pos == NULL)
- return obj_path_only; /* no next item on the path */
-
- /* Separate network interface prefix from the path */
- *pos++ = '\0';
-
- sep_len = os_strlen(sep);
- if (os_strncmp(pos, sep, sep_len) != 0 || pos[sep_len] != '/')
- return obj_path_only; /* no match */
-
- /* return a pointer to the requested item */
- *item = pos + sep_len + 1;
- return obj_path_only;
-}
-
-
-/**
- * wpas_dbus_reply_new_from_error - Create a new D-Bus error message from a
- * dbus error structure
- * @message: The original request message for which the error is a reply
- * @error: The error containing a name and a descriptive error cause
- * @fallback_name: A generic error name if @error was not set
- * @fallback_string: A generic error string if @error was not set
- * Returns: A new D-Bus error message
- *
- * Given a DBusMessage structure, creates a new D-Bus error message using
- * the error name and string contained in that structure.
- */
-DBusMessage * wpas_dbus_reply_new_from_error(DBusMessage *message,
- DBusError *error,
- const char *fallback_name,
- const char *fallback_string)
-{
- if (error && error->name && error->message) {
- return dbus_message_new_error(message, error->name,
- error->message);
- }
- if (fallback_name && fallback_string) {
- return dbus_message_new_error(message, fallback_name,
- fallback_string);
- }
- return NULL;
-}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
deleted file mode 100644
index 7b63b28d7707..000000000000
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * WPA Supplicant / dbus-based control interface
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_DBUS_CTRL_H
-#define WPA_DBUS_CTRL_H
-
-#include <dbus/dbus.h>
-
-typedef DBusMessage * (*WPADBusMethodHandler)(DBusMessage *message,
- void *user_data);
-typedef void (*WPADBusArgumentFreeFunction)(void *handler_arg);
-
-struct wpa_dbus_property_desc;
-typedef dbus_bool_t (*WPADBusPropertyAccessor)(
- const struct wpa_dbus_property_desc *property_desc,
- DBusMessageIter *iter, DBusError *error, void *user_data);
-#define DECLARE_ACCESSOR(f) \
-dbus_bool_t f(const struct wpa_dbus_property_desc *property_desc, \
- DBusMessageIter *iter, DBusError *error, void *user_data)
-
-struct wpa_dbus_object_desc {
- DBusConnection *connection;
- char *path;
-
- /* list of methods, properties and signals registered with object */
- const struct wpa_dbus_method_desc *methods;
- const struct wpa_dbus_signal_desc *signals;
- const struct wpa_dbus_property_desc *properties;
-
- /* property changed flags */
- u8 *prop_changed_flags;
-
- /* argument for method handlers and properties
- * getter and setter functions */
- void *user_data;
- /* function used to free above argument */
- WPADBusArgumentFreeFunction user_data_free_func;
-};
-
-enum dbus_arg_direction { ARG_IN, ARG_OUT };
-
-struct wpa_dbus_argument {
- char *name;
- char *type;
- enum dbus_arg_direction dir;
-};
-
-#define END_ARGS { NULL, NULL, ARG_IN }
-
-/**
- * struct wpa_dbus_method_desc - DBus method description
- */
-struct wpa_dbus_method_desc {
- /* method name */
- const char *dbus_method;
- /* method interface */
- const char *dbus_interface;
- /* method handling function */
- WPADBusMethodHandler method_handler;
- /* array of arguments */
- struct wpa_dbus_argument args[4];
-};
-
-/**
- * struct wpa_dbus_signal_desc - DBus signal description
- */
-struct wpa_dbus_signal_desc {
- /* signal name */
- const char *dbus_signal;
- /* signal interface */
- const char *dbus_interface;
- /* array of arguments */
- struct wpa_dbus_argument args[4];
-};
-
-/**
- * struct wpa_dbus_property_desc - DBus property description
- */
-struct wpa_dbus_property_desc {
- /* property name */
- const char *dbus_property;
- /* property interface */
- const char *dbus_interface;
- /* property type signature in DBus type notation */
- const char *type;
- /* property getter function */
- WPADBusPropertyAccessor getter;
- /* property setter function */
- WPADBusPropertyAccessor setter;
- /* other data */
- const char *data;
-};
-
-
-#define WPAS_DBUS_OBJECT_PATH_MAX 150
-#define WPAS_DBUS_INTERFACE_MAX 150
-#define WPAS_DBUS_METHOD_SIGNAL_PROP_MAX 50
-#define WPAS_DBUS_AUTH_MODE_MAX 64
-
-#define WPA_DBUS_INTROSPECTION_INTERFACE "org.freedesktop.DBus.Introspectable"
-#define WPA_DBUS_INTROSPECTION_METHOD "Introspect"
-#define WPA_DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
-#define WPA_DBUS_PROPERTIES_GET "Get"
-#define WPA_DBUS_PROPERTIES_SET "Set"
-#define WPA_DBUS_PROPERTIES_GETALL "GetAll"
-
-void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc);
-
-int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface, char *dbus_path,
- char *dbus_service,
- struct wpa_dbus_object_desc *obj_desc);
-
-int wpa_dbus_register_object_per_iface(
- struct wpas_dbus_priv *ctrl_iface,
- const char *path, const char *ifname,
- struct wpa_dbus_object_desc *obj_desc);
-
-int wpa_dbus_unregister_object_per_iface(
- struct wpas_dbus_priv *ctrl_iface,
- const char *path);
-
-dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
- const char *path,
- const char *interface,
- DBusMessageIter *iter);
-
-
-void wpa_dbus_flush_all_changed_properties(DBusConnection *con);
-
-void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
- const char *path);
-
-void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- const char *property);
-
-DBusMessage * wpa_dbus_introspect(DBusMessage *message,
- struct wpa_dbus_object_desc *obj_dsc);
-
-char * wpas_dbus_new_decompose_object_path(const char *path, const char *sep,
- char **item);
-
-DBusMessage *wpas_dbus_reply_new_from_error(DBusMessage *message,
- DBusError *error,
- const char *fallback_name,
- const char *fallback_string);
-
-#endif /* WPA_DBUS_CTRL_H */
diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c
deleted file mode 100644
index 6c721bf556db..000000000000
--- a/wpa_supplicant/dbus/dbus_new_introspect.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * wpa_supplicant - D-Bus introspection
- * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/list.h"
-#include "utils/wpabuf.h"
-#include "dbus_common_i.h"
-#include "dbus_new_helpers.h"
-
-
-struct interfaces {
- struct dl_list list;
- char *dbus_interface;
- struct wpabuf *xml;
-};
-
-
-static struct interfaces * add_interface(struct dl_list *list,
- const char *dbus_interface)
-{
- struct interfaces *iface;
-
- dl_list_for_each(iface, list, struct interfaces, list) {
- if (os_strcmp(iface->dbus_interface, dbus_interface) == 0)
- return iface; /* already in the list */
- }
-
- iface = os_zalloc(sizeof(struct interfaces));
- if (!iface)
- return NULL;
- iface->dbus_interface = os_strdup(dbus_interface);
- iface->xml = wpabuf_alloc(15000);
- if (iface->dbus_interface == NULL || iface->xml == NULL) {
- os_free(iface->dbus_interface);
- wpabuf_free(iface->xml);
- os_free(iface);
- return NULL;
- }
- wpabuf_printf(iface->xml, "<interface name=\"%s\">", dbus_interface);
- dl_list_add_tail(list, &iface->list);
- return iface;
-}
-
-
-static void add_arg(struct wpabuf *xml, const char *name, const char *type,
- const char *direction)
-{
- wpabuf_printf(xml, "<arg name=\"%s\"", name);
- if (type)
- wpabuf_printf(xml, " type=\"%s\"", type);
- if (direction)
- wpabuf_printf(xml, " direction=\"%s\"", direction);
- wpabuf_put_str(xml, "/>");
-}
-
-
-static void add_entry(struct wpabuf *xml, const char *type, const char *name,
- const struct wpa_dbus_argument *args, int include_dir)
-{
- const struct wpa_dbus_argument *arg;
-
- if (args == NULL || args->name == NULL) {
- wpabuf_printf(xml, "<%s name=\"%s\"/>", type, name);
- return;
- }
- wpabuf_printf(xml, "<%s name=\"%s\">", type, name);
- for (arg = args; arg && arg->name; arg++) {
- add_arg(xml, arg->name, arg->type,
- include_dir ? (arg->dir == ARG_IN ? "in" : "out") :
- NULL);
- }
- wpabuf_printf(xml, "</%s>", type);
-}
-
-
-static void add_property(struct wpabuf *xml,
- const struct wpa_dbus_property_desc *dsc)
-{
- wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" "
- "access=\"%s%s\"/>",
- dsc->dbus_property, dsc->type,
- dsc->getter ? "read" : "",
- dsc->setter ? "write" : "");
-}
-
-
-static void extract_interfaces_methods(
- struct dl_list *list, const struct wpa_dbus_method_desc *methods)
-{
- const struct wpa_dbus_method_desc *dsc;
- struct interfaces *iface;
-
- for (dsc = methods; dsc && dsc->dbus_method; dsc++) {
- iface = add_interface(list, dsc->dbus_interface);
- if (iface)
- add_entry(iface->xml, "method", dsc->dbus_method,
- dsc->args, 1);
- }
-}
-
-
-static void extract_interfaces_signals(
- struct dl_list *list, const struct wpa_dbus_signal_desc *signals)
-{
- const struct wpa_dbus_signal_desc *dsc;
- struct interfaces *iface;
-
- for (dsc = signals; dsc && dsc->dbus_signal; dsc++) {
- iface = add_interface(list, dsc->dbus_interface);
- if (iface)
- add_entry(iface->xml, "signal", dsc->dbus_signal,
- dsc->args, 0);
- }
-}
-
-
-static void extract_interfaces_properties(
- struct dl_list *list, const struct wpa_dbus_property_desc *properties)
-{
- const struct wpa_dbus_property_desc *dsc;
- struct interfaces *iface;
-
- for (dsc = properties; dsc && dsc->dbus_property; dsc++) {
- iface = add_interface(list, dsc->dbus_interface);
- if (iface)
- add_property(iface->xml, dsc);
- }
-}
-
-
-/**
- * extract_interfaces - Extract interfaces from methods, signals and props
- * @list: Interface list to be filled
- * @obj_dsc: Description of object from which interfaces will be extracted
- *
- * Iterates over all methods, signals, and properties registered with an
- * object and collects all declared DBus interfaces and create interfaces'
- * node in XML root node for each. Returned list elements contain interface
- * name and XML node of corresponding interface.
- */
-static void extract_interfaces(struct dl_list *list,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- extract_interfaces_methods(list, obj_dsc->methods);
- extract_interfaces_signals(list, obj_dsc->signals);
- extract_interfaces_properties(list, obj_dsc->properties);
-}
-
-
-static void add_interfaces(struct dl_list *list, struct wpabuf *xml)
-{
- struct interfaces *iface, *n;
-
- dl_list_for_each_safe(iface, n, list, struct interfaces, list) {
- if (wpabuf_len(iface->xml) + 20 < wpabuf_tailroom(xml)) {
- wpabuf_put_buf(xml, iface->xml);
- wpabuf_put_str(xml, "</interface>");
- } else {
- wpa_printf(MSG_DEBUG,
- "dbus: Not enough room for add_interfaces inspect data: tailroom %u, add %u",
- (unsigned int) wpabuf_tailroom(xml),
- (unsigned int) wpabuf_len(iface->xml));
- }
- dl_list_del(&iface->list);
- wpabuf_free(iface->xml);
- os_free(iface->dbus_interface);
- os_free(iface);
- }
-}
-
-
-static void add_child_nodes(struct wpabuf *xml, DBusConnection *con,
- const char *path)
-{
- char **children;
- int i;
-
- /* add child nodes to introspection tree */
- dbus_connection_list_registered(con, path, &children);
- for (i = 0; children[i]; i++)
- wpabuf_printf(xml, "<node name=\"%s\"/>", children[i]);
- dbus_free_string_array(children);
-}
-
-
-static void add_introspectable_interface(struct wpabuf *xml)
-{
- wpabuf_printf(xml, "<interface name=\"%s\">"
- "<method name=\"%s\">"
- "<arg name=\"data\" type=\"s\" direction=\"out\"/>"
- "</method>"
- "</interface>",
- WPA_DBUS_INTROSPECTION_INTERFACE,
- WPA_DBUS_INTROSPECTION_METHOD);
-}
-
-
-static void add_properties_interface(struct wpabuf *xml)
-{
- wpabuf_printf(xml, "<interface name=\"%s\">",
- WPA_DBUS_PROPERTIES_INTERFACE);
-
- wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GET);
- add_arg(xml, "interface", "s", "in");
- add_arg(xml, "propname", "s", "in");
- add_arg(xml, "value", "v", "out");
- wpabuf_put_str(xml, "</method>");
-
- wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_GETALL);
- add_arg(xml, "interface", "s", "in");
- add_arg(xml, "props", "a{sv}", "out");
- wpabuf_put_str(xml, "</method>");
-
- wpabuf_printf(xml, "<method name=\"%s\">", WPA_DBUS_PROPERTIES_SET);
- add_arg(xml, "interface", "s", "in");
- add_arg(xml, "propname", "s", "in");
- add_arg(xml, "value", "v", "in");
- wpabuf_put_str(xml, "</method>");
-
- wpabuf_put_str(xml, "</interface>");
-}
-
-
-static void add_wpas_interfaces(struct wpabuf *xml,
- struct wpa_dbus_object_desc *obj_dsc)
-{
- struct dl_list ifaces;
-
- dl_list_init(&ifaces);
- extract_interfaces(&ifaces, obj_dsc);
- add_interfaces(&ifaces, xml);
-}
-
-
-/**
- * wpa_dbus_introspect - Responds for Introspect calls on object
- * @message: Message with Introspect call
- * @obj_dsc: Object description on which Introspect was called
- * Returns: Message with introspection result XML string as only argument
- *
- * Iterates over all methods, signals and properties registered with
- * object and generates introspection data for the object as XML string.
- */
-DBusMessage * wpa_dbus_introspect(DBusMessage *message,
- struct wpa_dbus_object_desc *obj_dsc)
-{
-
- DBusMessage *reply;
- struct wpabuf *xml;
-
- xml = wpabuf_alloc(30000);
- if (xml == NULL)
- return NULL;
-
- wpabuf_put_str(xml, "<?xml version=\"1.0\"?>\n");
- wpabuf_put_str(xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
- wpabuf_put_str(xml, "<node>");
-
- add_introspectable_interface(xml);
- add_properties_interface(xml);
- add_wpas_interfaces(xml, obj_dsc);
- add_child_nodes(xml, obj_dsc->connection,
- dbus_message_get_path(message));
-
- wpabuf_put_str(xml, "</node>\n");
-
- reply = dbus_message_new_method_return(message);
- if (reply) {
- const char *intro_str = wpabuf_head(xml);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &intro_str,
- DBUS_TYPE_INVALID);
- }
- wpabuf_free(xml);
-
- return reply;
-}
diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in
deleted file mode 100644
index d97ff392175d..000000000000
--- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in
+++ /dev/null
@@ -1,5 +0,0 @@
-[D-BUS Service]
-Name=fi.w1.wpa_supplicant1
-Exec=@BINDIR@/wpa_supplicant -u
-User=root
-SystemdService=wpa_supplicant.service
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
deleted file mode 100644
index a4719dbb543d..000000000000
--- a/wpa_supplicant/defconfig
+++ /dev/null
@@ -1,635 +0,0 @@
-# Example wpa_supplicant build time configuration
-#
-# This file lists the configuration options that are used when building the
-# wpa_supplicant binary. All lines starting with # are ignored. Configuration
-# option lines must be commented out complete, if they are not to be included,
-# i.e., just setting VARIABLE=n is not disabling that variable.
-#
-# This file is included in Makefile, so variables like CFLAGS and LIBS can also
-# be modified from here. In most cases, these lines should use += in order not
-# to override previous values of the variables.
-
-
-# Uncomment following two lines and fix the paths if you have installed OpenSSL
-# or GnuTLS in non-default location
-#CFLAGS += -I/usr/local/openssl/include
-#LIBS += -L/usr/local/openssl/lib
-
-# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
-# the kerberos files are not in the default include path. Following line can be
-# used to fix build issues on such systems (krb5.h not found).
-#CFLAGS += -I/usr/include/kerberos
-
-# Driver interface for generic Linux wireless extensions
-# Note: WEXT is deprecated in the current Linux kernel version and no new
-# functionality is added to it. nl80211-based interface is the new
-# replacement for WEXT and its use allows wpa_supplicant to properly control
-# the driver to improve existing functionality like roaming and to support new
-# functionality.
-CONFIG_DRIVER_WEXT=y
-
-# Driver interface for Linux drivers using the nl80211 kernel interface
-CONFIG_DRIVER_NL80211=y
-
-# QCA vendor extensions to nl80211
-#CONFIG_DRIVER_NL80211_QCA=y
-
-# driver_nl80211.c requires libnl. If you are compiling it yourself
-# you may need to point hostapd to your version of libnl.
-#
-#CFLAGS += -I$<path to libnl include files>
-#LIBS += -L$<path to libnl library files>
-
-# Use libnl v2.0 (or 3.0) libraries.
-#CONFIG_LIBNL20=y
-
-# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
-CONFIG_LIBNL32=y
-
-
-# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
-#CONFIG_DRIVER_BSD=y
-#CFLAGS += -I/usr/local/include
-#LIBS += -L/usr/local/lib
-#LIBS_p += -L/usr/local/lib
-#LIBS_c += -L/usr/local/lib
-
-# Driver interface for Windows NDIS
-#CONFIG_DRIVER_NDIS=y
-#CFLAGS += -I/usr/include/w32api/ddk
-#LIBS += -L/usr/local/lib
-# For native build using mingw
-#CONFIG_NATIVE_WINDOWS=y
-# Additional directories for cross-compilation on Linux host for mingw target
-#CFLAGS += -I/opt/mingw/mingw32/include/ddk
-#LIBS += -L/opt/mingw/mingw32/lib
-#CC=mingw32-gcc
-# By default, driver_ndis uses WinPcap for low-level operations. This can be
-# replaced with the following option which replaces WinPcap calls with NDISUIO.
-# However, this requires that WZC is disabled (net stop wzcsvc) before starting
-# wpa_supplicant.
-# CONFIG_USE_NDISUIO=y
-
-# Driver interface for wired Ethernet drivers
-CONFIG_DRIVER_WIRED=y
-
-# Driver interface for MACsec capable Qualcomm Atheros drivers
-#CONFIG_DRIVER_MACSEC_QCA=y
-
-# Driver interface for Linux MACsec drivers
-CONFIG_DRIVER_MACSEC_LINUX=y
-
-# Driver interface for the Broadcom RoboSwitch family
-#CONFIG_DRIVER_ROBOSWITCH=y
-
-# Driver interface for no driver (e.g., WPS ER only)
-#CONFIG_DRIVER_NONE=y
-
-# Solaris libraries
-#LIBS += -lsocket -ldlpi -lnsl
-#LIBS_c += -lsocket
-
-# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
-# MACsec is included)
-CONFIG_IEEE8021X_EAPOL=y
-
-# EAP-MD5
-CONFIG_EAP_MD5=y
-
-# EAP-MSCHAPv2
-CONFIG_EAP_MSCHAPV2=y
-
-# EAP-TLS
-CONFIG_EAP_TLS=y
-
-# EAL-PEAP
-CONFIG_EAP_PEAP=y
-
-# EAP-TTLS
-CONFIG_EAP_TTLS=y
-
-# EAP-FAST
-CONFIG_EAP_FAST=y
-
-# EAP-TEAP
-# Note: The current EAP-TEAP implementation is experimental and should not be
-# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
-# of conflicting statements and missing details and the implementation has
-# vendor specific workarounds for those and as such, may not interoperate with
-# any other implementation. This should not be used for anything else than
-# experimentation and interoperability testing until those issues has been
-# resolved.
-#CONFIG_EAP_TEAP=y
-
-# EAP-GTC
-CONFIG_EAP_GTC=y
-
-# EAP-OTP
-CONFIG_EAP_OTP=y
-
-# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
-#CONFIG_EAP_SIM=y
-
-# Enable SIM simulator (Milenage) for EAP-SIM
-#CONFIG_SIM_SIMULATOR=y
-
-# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
-#CONFIG_EAP_PSK=y
-
-# EAP-pwd (secure authentication using only a password)
-CONFIG_EAP_PWD=y
-
-# EAP-PAX
-CONFIG_EAP_PAX=y
-
-# LEAP
-CONFIG_EAP_LEAP=y
-
-# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
-#CONFIG_EAP_AKA=y
-
-# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
-# This requires CONFIG_EAP_AKA to be enabled, too.
-#CONFIG_EAP_AKA_PRIME=y
-
-# Enable USIM simulator (Milenage) for EAP-AKA
-#CONFIG_USIM_SIMULATOR=y
-
-# EAP-SAKE
-CONFIG_EAP_SAKE=y
-
-# EAP-GPSK
-CONFIG_EAP_GPSK=y
-# Include support for optional SHA256 cipher suite in EAP-GPSK
-CONFIG_EAP_GPSK_SHA256=y
-
-# EAP-TNC and related Trusted Network Connect support (experimental)
-CONFIG_EAP_TNC=y
-
-# Wi-Fi Protected Setup (WPS)
-CONFIG_WPS=y
-# Enable WPS external registrar functionality
-#CONFIG_WPS_ER=y
-# Disable credentials for an open network by default when acting as a WPS
-# registrar.
-#CONFIG_WPS_REG_DISABLE_OPEN=y
-# Enable WPS support with NFC config method
-#CONFIG_WPS_NFC=y
-
-# EAP-IKEv2
-CONFIG_EAP_IKEV2=y
-
-# EAP-EKE
-#CONFIG_EAP_EKE=y
-
-# MACsec
-CONFIG_MACSEC=y
-
-# PKCS#12 (PFX) support (used to read private key and certificate file from
-# a file that usually has extension .p12 or .pfx)
-CONFIG_PKCS12=y
-
-# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
-# engine.
-CONFIG_SMARTCARD=y
-
-# PC/SC interface for smartcards (USIM, GSM SIM)
-# Enable this if EAP-SIM or EAP-AKA is included
-#CONFIG_PCSC=y
-
-# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
-#CONFIG_HT_OVERRIDES=y
-
-# Support VHT overrides (disable VHT, mask MCS rates, etc.)
-#CONFIG_VHT_OVERRIDES=y
-
-# Development testing
-#CONFIG_EAPOL_TEST=y
-
-# Select control interface backend for external programs, e.g, wpa_cli:
-# unix = UNIX domain sockets (default for Linux/*BSD)
-# udp = UDP sockets using localhost (127.0.0.1)
-# udp6 = UDP IPv6 sockets using localhost (::1)
-# named_pipe = Windows Named Pipe (default for Windows)
-# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
-# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
-# y = use default (backwards compatibility)
-# If this option is commented out, control interface is not included in the
-# build.
-CONFIG_CTRL_IFACE=y
-
-# Include support for GNU Readline and History Libraries in wpa_cli.
-# When building a wpa_cli binary for distribution, please note that these
-# libraries are licensed under GPL and as such, BSD license may not apply for
-# the resulting binary.
-#CONFIG_READLINE=y
-
-# Include internal line edit mode in wpa_cli. This can be used as a replacement
-# for GNU Readline to provide limited command line editing and history support.
-#CONFIG_WPA_CLI_EDIT=y
-
-# Remove debugging code that is printing out debug message to stdout.
-# This can be used to reduce the size of the wpa_supplicant considerably
-# if debugging code is not needed. The size reduction can be around 35%
-# (e.g., 90 kB).
-#CONFIG_NO_STDOUT_DEBUG=y
-
-# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
-# 35-50 kB in code size.
-#CONFIG_NO_WPA=y
-
-# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
-# This option can be used to reduce code size by removing support for
-# converting ASCII passphrases into PSK. If this functionality is removed, the
-# PSK can only be configured as the 64-octet hexstring (e.g., from
-# wpa_passphrase). This saves about 0.5 kB in code size.
-#CONFIG_NO_WPA_PASSPHRASE=y
-
-# Simultaneous Authentication of Equals (SAE), WPA3-Personal
-CONFIG_SAE=y
-
-# Disable scan result processing (ap_scan=1) to save code size by about 1 kB.
-# This can be used if ap_scan=1 mode is never enabled.
-#CONFIG_NO_SCAN_PROCESSING=y
-
-# Select configuration backend:
-# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
-# path is given on command line, not here; this option is just used to
-# select the backend that allows configuration files to be used)
-# winreg = Windows registry (see win_example.reg for an example)
-CONFIG_BACKEND=file
-
-# Remove configuration write functionality (i.e., to allow the configuration
-# file to be updated based on runtime configuration changes). The runtime
-# configuration can still be changed, the changes are just not going to be
-# persistent over restarts. This option can be used to reduce code size by
-# about 3.5 kB.
-#CONFIG_NO_CONFIG_WRITE=y
-
-# Remove support for configuration blobs to reduce code size by about 1.5 kB.
-#CONFIG_NO_CONFIG_BLOBS=y
-
-# Select program entry point implementation:
-# main = UNIX/POSIX like main() function (default)
-# main_winsvc = Windows service (read parameters from registry)
-# main_none = Very basic example (development use only)
-#CONFIG_MAIN=main
-
-# Select wrapper for operating system and C library specific functions
-# unix = UNIX/POSIX like systems (default)
-# win32 = Windows systems
-# none = Empty template
-#CONFIG_OS=unix
-
-# Select event loop implementation
-# eloop = select() loop (default)
-# eloop_win = Windows events and WaitForMultipleObject() loop
-#CONFIG_ELOOP=eloop
-
-# Should we use poll instead of select? Select is used by default.
-#CONFIG_ELOOP_POLL=y
-
-# Should we use epoll instead of select? Select is used by default.
-#CONFIG_ELOOP_EPOLL=y
-
-# Should we use kqueue instead of select? Select is used by default.
-#CONFIG_ELOOP_KQUEUE=y
-
-# Select layer 2 packet implementation
-# linux = Linux packet socket (default)
-# pcap = libpcap/libdnet/WinPcap
-# freebsd = FreeBSD libpcap
-# winpcap = WinPcap with receive thread
-# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
-# none = Empty template
-#CONFIG_L2_PACKET=linux
-
-# Disable Linux packet socket workaround applicable for station interface
-# in a bridge for EAPOL frames. This should be uncommented only if the kernel
-# is known to not have the regression issue in packet socket behavior with
-# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
-#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
-
-# Support Operating Channel Validation
-#CONFIG_OCV=y
-
-# Select TLS implementation
-# openssl = OpenSSL (default)
-# gnutls = GnuTLS
-# internal = Internal TLSv1 implementation (experimental)
-# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
-# none = Empty template
-#CONFIG_TLS=openssl
-
-# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
-# can be enabled to get a stronger construction of messages when block ciphers
-# are used. It should be noted that some existing TLS v1.0 -based
-# implementation may not be compatible with TLS v1.1 message (ClientHello is
-# sent prior to negotiating which version will be used)
-#CONFIG_TLSV11=y
-
-# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
-# can be enabled to enable use of stronger crypto algorithms. It should be
-# noted that some existing TLS v1.0 -based implementation may not be compatible
-# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
-# will be used)
-#CONFIG_TLSV12=y
-
-# Select which ciphers to use by default with OpenSSL if the user does not
-# specify them.
-#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
-
-# If CONFIG_TLS=internal is used, additional library and include paths are
-# needed for LibTomMath. Alternatively, an integrated, minimal version of
-# LibTomMath can be used. See beginning of libtommath.c for details on benefits
-# and drawbacks of this option.
-#CONFIG_INTERNAL_LIBTOMMATH=y
-#ifndef CONFIG_INTERNAL_LIBTOMMATH
-#LTM_PATH=/usr/src/libtommath-0.39
-#CFLAGS += -I$(LTM_PATH)
-#LIBS += -L$(LTM_PATH)
-#LIBS_p += -L$(LTM_PATH)
-#endif
-# At the cost of about 4 kB of additional binary size, the internal LibTomMath
-# can be configured to include faster routines for exptmod, sqr, and div to
-# speed up DH and RSA calculation considerably
-#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
-
-# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
-# This is only for Windows builds and requires WMI-related header files and
-# WbemUuid.Lib from Platform SDK even when building with MinGW.
-#CONFIG_NDIS_EVENTS_INTEGRATED=y
-#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-
-# Add support for new DBus control interface
-# (fi.w1.wpa_supplicant1)
-CONFIG_CTRL_IFACE_DBUS_NEW=y
-
-# Add introspection support for new DBus control interface
-CONFIG_CTRL_IFACE_DBUS_INTRO=y
-
-# Add support for loading EAP methods dynamically as shared libraries.
-# When this option is enabled, each EAP method can be either included
-# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
-# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
-# be loaded in the beginning of the wpa_supplicant configuration file
-# (see load_dynamic_eap parameter in the example file) before being used in
-# the network blocks.
-#
-# Note that some shared parts of EAP methods are included in the main program
-# and in order to be able to use dynamic EAP methods using these parts, the
-# main program must have been build with the EAP method enabled (=y or =dyn).
-# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
-# unless at least one of them was included in the main build to force inclusion
-# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
-# in the main build to be able to load these methods dynamically.
-#
-# Please also note that using dynamic libraries will increase the total binary
-# size. Thus, it may not be the best option for targets that have limited
-# amount of memory/flash.
-#CONFIG_DYNAMIC_EAP_METHODS=y
-
-# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
-CONFIG_IEEE80211R=y
-
-# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
-CONFIG_DEBUG_FILE=y
-
-# Send debug messages to syslog instead of stdout
-CONFIG_DEBUG_SYSLOG=y
-# Set syslog facility for debug messages
-#CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
-
-# Add support for sending all debug messages (regardless of debug verbosity)
-# to the Linux kernel tracing facility. This helps debug the entire stack by
-# making it easy to record everything happening from the driver up into the
-# same file, e.g., using trace-cmd.
-#CONFIG_DEBUG_LINUX_TRACING=y
-
-# Add support for writing debug log to Android logcat instead of standard
-# output
-#CONFIG_ANDROID_LOG=y
-
-# Enable privilege separation (see README 'Privilege separation' for details)
-#CONFIG_PRIVSEP=y
-
-# Enable mitigation against certain attacks against TKIP by delaying Michael
-# MIC error reports by a random amount of time between 0 and 60 seconds
-#CONFIG_DELAYED_MIC_ERROR_REPORT=y
-
-# Enable tracing code for developer debugging
-# This tracks use of memory allocations and other registrations and reports
-# incorrect use with a backtrace of call (or allocation) location.
-#CONFIG_WPA_TRACE=y
-# For BSD, uncomment these.
-#LIBS += -lexecinfo
-#LIBS_p += -lexecinfo
-#LIBS_c += -lexecinfo
-
-# Use libbfd to get more details for developer debugging
-# This enables use of libbfd to get more detailed symbols for the backtraces
-# generated by CONFIG_WPA_TRACE=y.
-#CONFIG_WPA_TRACE_BFD=y
-# For BSD, uncomment these.
-#LIBS += -lbfd -liberty -lz
-#LIBS_p += -lbfd -liberty -lz
-#LIBS_c += -lbfd -liberty -lz
-
-# wpa_supplicant depends on strong random number generation being available
-# from the operating system. os_get_random() function is used to fetch random
-# data when needed, e.g., for key generation. On Linux and BSD systems, this
-# works by reading /dev/urandom. It should be noted that the OS entropy pool
-# needs to be properly initialized before wpa_supplicant is started. This is
-# important especially on embedded devices that do not have a hardware random
-# number generator and may by default start up with minimal entropy available
-# for random number generation.
-#
-# As a safety net, wpa_supplicant is by default trying to internally collect
-# additional entropy for generating random data to mix in with the data fetched
-# from the OS. This by itself is not considered to be very strong, but it may
-# help in cases where the system pool is not initialized properly. However, it
-# is very strongly recommended that the system pool is initialized with enough
-# entropy either by using hardware assisted random number generator or by
-# storing state over device reboots.
-#
-# wpa_supplicant can be configured to maintain its own entropy store over
-# restarts to enhance random number generation. This is not perfect, but it is
-# much more secure than using the same sequence of random numbers after every
-# reboot. This can be enabled with -e<entropy file> command line option. The
-# specified file needs to be readable and writable by wpa_supplicant.
-#
-# If the os_get_random() is known to provide strong random data (e.g., on
-# Linux/BSD, the board in question is known to have reliable source of random
-# data from /dev/urandom), the internal wpa_supplicant random pool can be
-# disabled. This will save some in binary size and CPU use. However, this
-# should only be considered for builds that are known to be used on devices
-# that meet the requirements described above.
-#CONFIG_NO_RANDOM_POOL=y
-
-# Should we attempt to use the getrandom(2) call that provides more reliable
-# yet secure randomness source than /dev/random on Linux 3.17 and newer.
-# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
-#CONFIG_GETRANDOM=y
-
-# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
-CONFIG_IEEE80211AC=y
-
-# Wireless Network Management (IEEE Std 802.11v-2011)
-# Note: This is experimental and not complete implementation.
-#CONFIG_WNM=y
-
-# Interworking (IEEE 802.11u)
-# This can be used to enable functionality to improve interworking with
-# external networks (GAS/ANQP to learn more about the networks and network
-# selection based on available credentials).
-CONFIG_INTERWORKING=y
-
-# Hotspot 2.0
-CONFIG_HS20=y
-
-# Enable interface matching in wpa_supplicant
-#CONFIG_MATCH_IFACE=y
-
-# Disable roaming in wpa_supplicant
-#CONFIG_NO_ROAMING=y
-
-# AP mode operations with wpa_supplicant
-# This can be used for controlling AP mode operations with wpa_supplicant. It
-# should be noted that this is mainly aimed at simple cases like
-# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
-# external RADIUS server can be supported with hostapd.
-CONFIG_AP=y
-
-# P2P (Wi-Fi Direct)
-# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
-# more information on P2P operations.
-CONFIG_P2P=y
-
-# Enable TDLS support
-CONFIG_TDLS=y
-
-# Wi-Fi Display
-# This can be used to enable Wi-Fi Display extensions for P2P using an external
-# program to control the additional information exchanges in the messages.
-CONFIG_WIFI_DISPLAY=y
-
-# Autoscan
-# This can be used to enable automatic scan support in wpa_supplicant.
-# See wpa_supplicant.conf for more information on autoscan usage.
-#
-# Enabling directly a module will enable autoscan support.
-# For exponential module:
-#CONFIG_AUTOSCAN_EXPONENTIAL=y
-# For periodic module:
-#CONFIG_AUTOSCAN_PERIODIC=y
-
-# Password (and passphrase, etc.) backend for external storage
-# These optional mechanisms can be used to add support for storing passwords
-# and other secrets in external (to wpa_supplicant) location. This allows, for
-# example, operating system specific key storage to be used
-#
-# External password backend for testing purposes (developer use)
-#CONFIG_EXT_PASSWORD_TEST=y
-# File-based backend to read passwords from an external file.
-#CONFIG_EXT_PASSWORD_FILE=y
-
-# Enable Fast Session Transfer (FST)
-#CONFIG_FST=y
-
-# Enable CLI commands for FST testing
-#CONFIG_FST_TEST=y
-
-# OS X builds. This is only for building eapol_test.
-#CONFIG_OSX=y
-
-# Automatic Channel Selection
-# This will allow wpa_supplicant to pick the channel automatically when channel
-# is set to "0".
-#
-# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
-# to "channel=0". This would enable us to eventually add other ACS algorithms in
-# similar way.
-#
-# Automatic selection is currently only done through initialization, later on
-# we hope to do background checks to keep us moving to more ideal channels as
-# time goes by. ACS is currently only supported through the nl80211 driver and
-# your driver must have survey dump capability that is filled by the driver
-# during scanning.
-#
-# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
-# a newly to create wpa_supplicant.conf variable acs_num_scans.
-#
-# Supported ACS drivers:
-# * ath9k
-# * ath5k
-# * ath10k
-#
-# For more details refer to:
-# http://wireless.kernel.org/en/users/Documentation/acs
-#CONFIG_ACS=y
-
-# Support Multi Band Operation
-#CONFIG_MBO=y
-
-# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-#CONFIG_FILS=y
-# FILS shared key authentication with PFS
-#CONFIG_FILS_SK_PFS=y
-
-# Support RSN on IBSS networks
-# This is needed to be able to use mode=1 network profile with proto=RSN and
-# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
-CONFIG_IBSS_RSN=y
-
-# External PMKSA cache control
-# This can be used to enable control interface commands that allow the current
-# PMKSA cache entries to be fetched and new entries to be added.
-#CONFIG_PMKSA_CACHE_EXTERNAL=y
-
-# Mesh Networking (IEEE 802.11s)
-#CONFIG_MESH=y
-
-# Background scanning modules
-# These can be used to request wpa_supplicant to perform background scanning
-# operations for roaming within an ESS (same SSID). See the bgscan parameter in
-# the wpa_supplicant.conf file for more details.
-# Periodic background scans based on signal strength
-CONFIG_BGSCAN_SIMPLE=y
-# Learn channels used by the network and try to avoid bgscans on other
-# channels (experimental)
-#CONFIG_BGSCAN_LEARN=y
-
-# Opportunistic Wireless Encryption (OWE)
-# Experimental implementation of draft-harkins-owe-07.txt
-#CONFIG_OWE=y
-
-# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)
-CONFIG_DPP=y
-# DPP version 2 support
-CONFIG_DPP2=y
-# DPP version 3 support (experimental and still changing; do not enable for
-# production use)
-#CONFIG_DPP3=y
-
-# Wired equivalent privacy (WEP)
-# WEP is an obsolete cryptographic data confidentiality algorithm that is not
-# considered secure. It should not be used for anything anymore. The
-# functionality needed to use WEP is available in the current wpa_supplicant
-# release under this optional build parameter. This functionality is subject to
-# be completely removed in a future release.
-#CONFIG_WEP=y
-
-# Remove all TKIP functionality
-# TKIP is an old cryptographic data confidentiality algorithm that is not
-# considered secure. It should not be used anymore for anything else than a
-# backwards compatibility option as a group cipher when connecting to APs that
-# use WPA+WPA2 mixed mode. For now, the default wpa_supplicant build includes
-# support for this by default, but that functionality is subject to be removed
-# in the future.
-#CONFIG_NO_TKIP=y
-
-# Pre-Association Security Negotiation (PASN)
-# Experimental implementation based on IEEE P802.11z/D2.6 and the protocol
-# design is still subject to change. As such, this should not yet be enabled in
-# production use.
-#CONFIG_PASN=y
diff --git a/wpa_supplicant/doc/docbook/.gitignore b/wpa_supplicant/doc/docbook/.gitignore
deleted file mode 100644
index dac35c5a5edd..000000000000
--- a/wpa_supplicant/doc/docbook/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-manpage.links
-manpage.refs
-manpage.log
-*.8
-*.5
-*.html
-*.pdf
diff --git a/wpa_supplicant/doc/docbook/Makefile b/wpa_supplicant/doc/docbook/Makefile
deleted file mode 100644
index 82f9de315dc5..000000000000
--- a/wpa_supplicant/doc/docbook/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-all: man html pdf
-
-FILES += wpa_background
-FILES += wpa_cli
-FILES += wpa_gui
-FILES += wpa_passphrase
-FILES += wpa_priv
-FILES += wpa_supplicant.conf
-FILES += wpa_supplicant
-FILES += eapol_test
-
-man:
- for i in $(FILES); do docbook2man $$i.sgml; done
-
-html:
- for i in $(FILES); do docbook2html $$i.sgml && \
- mv index.html $$i.html; done
-
-pdf:
- for i in $(FILES); do docbook2pdf $$i.sgml; done
-
-
-clean:
- rm -f wpa_background.8 wpa_cli.8 wpa_gui.8 wpa_passphrase.8 wpa_priv.8 wpa_supplicant.8 eapol_test.8
- rm -f wpa_supplicant.conf.5
- rm -f manpage.links manpage.refs
- rm -f $(FILES:%=%.pdf)
- rm -f $(FILES:%=%.html)
diff --git a/wpa_supplicant/doc/docbook/eapol_test.sgml b/wpa_supplicant/doc/docbook/eapol_test.sgml
deleted file mode 100644
index 4cfa3c1db384..000000000000
--- a/wpa_supplicant/doc/docbook/eapol_test.sgml
+++ /dev/null
@@ -1,209 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>eapol_test</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>eapol_test</refname>
-
- <refpurpose>EAP peer and RADIUS client testing</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>eapol_test</command>
- <arg>-nWS</arg>
- <arg>-c<replaceable>config file</replaceable></arg>
- <arg>-a<replaceable>server IP address</replaceable></arg>
- <arg>-A<replaceable>client IP address</replaceable></arg>
- <arg>-p<replaceable>UDP port</replaceable></arg>
- <arg>-s<replaceable>shared secret</replaceable></arg>
- <arg>-r<replaceable>re-authentications</replaceable></arg>
- <arg>-t<replaceable>timeout</replaceable></arg>
- <arg>-C<replaceable>Connect-Info</replaceable></arg>
- <arg>-M<replaceable>MAC address</replaceable></arg>
- <arg>-o<replaceable>file</replaceable></arg>
- <arg>-N<replaceable>attr spec</replaceable></arg>
- </cmdsynopsis>
- <cmdsynopsis>
- <command>eapol_test scard</command>
- </cmdsynopsis>
- <cmdsynopsis>
- <command>eapol_test sim</command>
- <arg>PIN</arg>
- <arg>num triplets</arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Overview</title>
-
- <para>eapol_test is a program that links together the same EAP
- peer implementation that wpa_supplicant is using and the RADIUS
- authentication client code from hostapd. In addition, it has
- minimal glue code to combine these two components in similar
- ways to IEEE 802.1X/EAPOL Authenticator state machines. In other
- words, it integrates IEEE 802.1X Authenticator (normally, an
- access point) and IEEE 802.1X Supplicant (normally, a wireless
- client) together to generate a single program that can be used to
- test EAP methods without having to setup an access point and a
- wireless client.</para>
-
- <para>The main uses for eapol_test are in interoperability testing
- of EAP methods against RADIUS servers and in development testing
- for new EAP methods. It can be easily used to automate EAP testing
- for interoperability and regression since the program can be run
- from shell scripts without require additional test components apart
- from a RADIUS server. For example, the automated EAP tests described
- in eap_testing.txt are implemented with eapol_test. Similarly,
- eapol_test could be used to implement an automated regression
- test suite for a RADIUS authentication server.</para>
-
-
- <para>As an example:</para>
-
-<blockquote><programlisting>
-eapol_test -ctest.conf -a127.0.0.1 -p1812 -ssecret -r1
-</programlisting></blockquote>
-
- <para>tries to complete EAP authentication based on the network
- configuration from test.conf against the RADIUS server running
- on the local host. A re-authentication is triggered to test fast
- re-authentication. The configuration file uses the same format for
- network blocks as wpa_supplicant.</para>
-
- </refsect1>
- <refsect1>
- <title>Command Arguments</title>
- <variablelist>
- <varlistentry>
- <term>-c configuration file path</term>
-
- <listitem><para>A configuration to use. The configuration should
- use the same format for network blocks as wpa_supplicant.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-a AS address</term>
-
- <listitem><para>IP address of the authentication server. The
- default is '127.0.0.1'.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-A client address</term>
-
- <listitem><para>IP address of the client. The default is to
- select an address automatically.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-p AS port</term>
-
- <listitem><para>UDP port of the authentication server. The
- default is '1812'.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-s AS secret</term>
-
- <listitem><para>Shared secret with the authentication server.
- The default is 'radius'.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-r count</term>
-
- <listitem><para>Number of reauthentications.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-t timeout</term>
-
- <listitem><para>Timeout in seconds. The default is 30.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-C info</term>
-
- <listitem><para>RADIUS Connect-Info. The default is
- 'CONNECT 11Mbps 802.11b'.</para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>-M mac address</term>
-
- <listitem><para>Client MAC address (Calling-Station-Id). The
- default is '02:00:00:00:00:01'.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-o file</term>
-
- <listitem><para>Location to write out server certificate.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-N attr spec</term>
-
- <listitem><para>Send arbitrary attribute specific by
- attr_id:syntax:value, or attr_id alone. attr_id should be the numeric
- ID of the attribute, and syntax should be one of 's' (string),
- 'd' (integer), or 'x' (octet string). The value is the attribute value
- to send. When attr_id is given alone, NULL is used as the attribute
- value. Multiple attributes can be specified by using the option
- several times.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-n</term>
-
- <listitem><para>Indicates that no MPPE keys are expected.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-W</term>
-
- <listitem><para>Wait for a control interface monitor before starting.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-S</term>
-
- <listitem><para>Save configuration after authentication.
- </para></listitem>
- </varlistentry>
-
- </variablelist>
- </refsect1>
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_background.sgml b/wpa_supplicant/doc/docbook/wpa_background.sgml
deleted file mode 100644
index 22241ccf9006..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_background.sgml
+++ /dev/null
@@ -1,105 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_background</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_background</refname>
- <refpurpose>Background information on Wi-Fi Protected Access and IEEE 802.11i</refpurpose>
- </refnamediv>
- <refsect1>
- <title>WPA</title>
-
- <para>The original security mechanism of IEEE 802.11 standard was
- not designed to be strong and has proven to be insufficient for
- most networks that require some kind of security. Task group I
- (Security) of IEEE 802.11 working group
- (http://www.ieee802.org/11/) has worked to address the flaws of
- the base standard and has in practice completed its work in May
- 2004. The IEEE 802.11i amendment to the IEEE 802.11 standard was
- approved in June 2004 and published in July 2004.</para>
-
- <para>Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version
- of the IEEE 802.11i work (draft 3.0) to define a subset of the
- security enhancements that can be implemented with existing wlan
- hardware. This is called Wi-Fi Protected Access&lt;TM&gt; (WPA). This
- has now become a mandatory component of interoperability testing
- and certification done by Wi-Fi Alliance. Wi-Fi provides
- information about WPA at its web site
- (http://www.wi-fi.org/OpenSection/protected_access.asp).</para>
-
- <para>IEEE 802.11 standard defined wired equivalent privacy (WEP)
- algorithm for protecting wireless networks. WEP uses RC4 with
- 40-bit keys, 24-bit initialization vector (IV), and CRC32 to
- protect against packet forgery. All these choices have proven to
- be insufficient: key space is too small against current attacks,
- RC4 key scheduling is insufficient (beginning of the pseudorandom
- stream should be skipped), IV space is too small and IV reuse
- makes attacks easier, there is no replay protection, and non-keyed
- authentication does not protect against bit flipping packet
- data.</para>
-
- <para>WPA is an intermediate solution for the security issues. It
- uses Temporal Key Integrity Protocol (TKIP) to replace WEP. TKIP
- is a compromise on strong security and possibility to use existing
- hardware. It still uses RC4 for the encryption like WEP, but with
- per-packet RC4 keys. In addition, it implements replay protection,
- keyed packet authentication mechanism (Michael MIC).</para>
-
- <para>Keys can be managed using two different mechanisms. WPA can
- either use an external authentication server (e.g., RADIUS) and
- EAP just like IEEE 802.1X is using or pre-shared keys without need
- for additional servers. Wi-Fi calls these "WPA-Enterprise" and
- "WPA-Personal", respectively. Both mechanisms will generate a
- master session key for the Authenticator (AP) and Supplicant
- (client station).</para>
-
- <para>WPA implements a new key handshake (4-Way Handshake and
- Group Key Handshake) for generating and exchanging data encryption
- keys between the Authenticator and Supplicant. This handshake is
- also used to verify that both Authenticator and Supplicant know
- the master session key. These handshakes are identical regardless
- of the selected key management mechanism (only the method for
- generating master session key changes).</para>
- </refsect1>
-
- <refsect1>
- <title>IEEE 802.11i / WPA2</title>
-
- <para>The design for parts of IEEE 802.11i that were not included
- in WPA has finished (May 2004) and this amendment to IEEE 802.11
- was approved in June 2004. Wi-Fi Alliance is using the final IEEE
- 802.11i as a new version of WPA called WPA2. This includes, e.g.,
- support for more robust encryption algorithm (CCMP: AES in Counter
- mode with CBC-MAC) to replace TKIP and optimizations for handoff
- (reduced number of messages in initial key handshake,
- pre-authentication, and PMKSA caching).</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
-
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_cli.sgml b/wpa_supplicant/doc/docbook/wpa_cli.sgml
deleted file mode 100644
index 2ba1fe42236a..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ /dev/null
@@ -1,360 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_cli</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_cli</refname>
-
- <refpurpose>WPA command line client</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>wpa_cli</command>
- <arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
- <arg>-g <replaceable>path to global ctrl_interface socket</replaceable></arg>
- <arg>-i <replaceable>ifname</replaceable></arg>
- <arg>-hvB</arg>
- <arg>-a <replaceable>action file</replaceable></arg>
- <arg>-P <replaceable>pid file</replaceable></arg>
- <arg>-G <replaceable>ping interval</replaceable></arg>
- <arg><replaceable>command ...</replaceable></arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Overview</title>
-
- <para>wpa_cli is a text-based frontend program for interacting
- with wpa_supplicant. It is used to query current status, change
- configuration, trigger events, and request interactive user
- input.</para>
-
- <para>wpa_cli can show the current authentication status, selected
- security mode, dot11 and dot1x MIBs, etc. In addition, it can
- configure some variables like EAPOL state machine parameters and
- trigger events like reassociation and IEEE 802.1X
- logoff/logon. wpa_cli provides a user interface to request
- authentication information, like username and password, if these
- are not included in the configuration. This can be used to
- implement, e.g., one-time-passwords or generic token card
- authentication where the authentication is based on a
- challenge-response that uses an external device for generating the
- response.</para>
-
- <para>The control interface of wpa_supplicant can be configured to
- allow non-root user access (ctrl_interface GROUP= parameter in the
- configuration file). This makes it possible to run wpa_cli with a
- normal user account.</para>
-
- <para>wpa_cli supports two modes: interactive and command
- line. Both modes share the same command set and the main
- difference is in interactive mode providing access to unsolicited
- messages (event messages, username/password requests).</para>
-
- <para>Interactive mode is started when wpa_cli is executed without
- including the command as a command line parameter. Commands are
- then entered on the wpa_cli prompt. In command line mode, the same
- commands are entered as command line arguments for wpa_cli.</para>
- </refsect1>
- <refsect1>
- <title>Interactive authentication parameters request</title>
-
- <para>When wpa_supplicant need authentication parameters, like
- username and password, which are not present in the configuration
- file, it sends a request message to all attached frontend programs,
- e.g., wpa_cli in interactive mode. wpa_cli shows these requests
- with "CTRL-REQ-&lt;type&gt;-&lt;id&gt;:&lt;text&gt;"
- prefix. &lt;type&gt; is IDENTITY, PASSWORD, or OTP
- (one-time-password). &lt;id&gt; is a unique identifier for the
- current network. &lt;text&gt; is description of the request. In
- case of OTP request, it includes the challenge from the
- authentication server.</para>
-
- <para>The reply to these requests can be given with
- <emphasis>identity</emphasis>, <emphasis>password</emphasis>, and
- <emphasis>otp</emphasis> commands. &lt;id&gt; needs to be copied from
- the matching request. <emphasis>password</emphasis> and
- <emphasis>otp</emphasis> commands can be used regardless of whether
- the request was for PASSWORD or OTP. The main difference between these
- two commands is that values given with <emphasis>password</emphasis> are
- remembered as long as wpa_supplicant is running whereas values given
- with <emphasis>otp</emphasis> are used only once and then forgotten,
- i.e., wpa_supplicant will ask frontend for a new value for every use.
- This can be used to implement one-time-password lists and generic token
- card -based authentication.</para>
-
- <para>Example request for password and a matching reply:</para>
-
-<blockquote><programlisting>
-CTRL-REQ-PASSWORD-1:Password needed for SSID foobar
-> password 1 mysecretpassword
-</programlisting></blockquote>
-
- <para>Example request for generic token card challenge-response:</para>
-
-<blockquote><programlisting>
-CTRL-REQ-OTP-2:Challenge 1235663 needed for SSID foobar
-> otp 2 9876
-</programlisting></blockquote>
-
- </refsect1>
- <refsect1>
- <title>Command Arguments</title>
- <variablelist>
- <varlistentry>
- <term>-p path</term>
-
- <listitem><para>Change the path where control sockets should
- be found.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-g control socket path</term>
-
- <listitem><para>Connect to the global control socket at the
- indicated path rather than an interface-specific control
- socket.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-i ifname</term>
-
- <listitem><para>Specify the interface that is being
- configured. By default, choose the first interface found with
- a control socket in the socket path.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-h</term>
- <listitem><para>Help. Show a usage message.</para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>-v</term>
- <listitem><para>Show version information.</para></listitem>
- </varlistentry>
-
-
- <varlistentry>
- <term>-B</term>
- <listitem><para>Run as a daemon in the background.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-a file</term>
-
- <listitem><para>Run in daemon mode executing the action file
- based on events from wpa_supplicant. The specified file will
- be executed with the first argument set to interface name and
- second to "CONNECTED" or "DISCONNECTED" depending on the event.
- This can be used to execute networking tools required to configure
- the interface.</para>
-
- <para>Additionally, three environmental variables are available to
- the file: WPA_CTRL_DIR, WPA_ID, and WPA_ID_STR. WPA_CTRL_DIR
- contains the absolute path to the ctrl_interface socket. WPA_ID
- contains the unique network_id identifier assigned to the active
- network, and WPA_ID_STR contains the content of the id_str option.
- </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-P file</term>
-
- <listitem><para>Set the location of the PID
- file.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-G ping interval</term>
-
- <listitem><para>Set the interval (in seconds) at which
- wpa_cli pings the supplicant.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>command</term>
-
- <listitem><para>Run a command. The available commands are
- listed in the next section.</para></listitem>
-
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>Commands</title>
- <para>The following commands are available:</para>
-
- <variablelist>
- <varlistentry>
- <term>status</term>
- <listitem>
- <para>get current WPA/EAPOL/EAP status</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>mib</term>
- <listitem>
- <para>get MIB variables (dot1x, dot11)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>help</term>
- <listitem>
- <para>show this usage help</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>interface [ifname]</term>
- <listitem>
- <para>show interfaces/select interface</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>level &lt;debug level&gt;</term>
- <listitem>
- <para>change debug level</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>license</term>
- <listitem>
- <para>show full wpa_cli license</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>logoff</term>
- <listitem>
- <para>IEEE 802.1X EAPOL state machine logoff</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>logon</term>
- <listitem>
- <para>IEEE 802.1X EAPOL state machine logon</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>set</term>
- <listitem>
- <para>set variables (shows list of variables when run without arguments)</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>pmksa</term>
- <listitem>
- <para>show PMKSA cache</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>reassociate</term>
- <listitem>
- <para>force reassociation</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>reconfigure</term>
- <listitem>
- <para>force wpa_supplicant to re-read its configuration file</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>preauthenticate &lt;BSSID&gt;</term>
- <listitem>
- <para>force preauthentication</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>identity &lt;network id&gt; &lt;identity&gt;</term>
- <listitem>
- <para>configure identity for an SSID</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>password &lt;network id&gt; &lt;password&gt;</term>
- <listitem>
- <para>configure password for an SSID</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>pin &lt;network id&gt; &lt;pin&gt;</term>
- <listitem>
- <para>configure pin for an SSID</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>otp &lt;network id&gt; &lt;password&gt;</term>
- <listitem>
- <para>configure one-time-password for an SSID</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>bssid &lt;network id&gt; &lt;BSSID&gt;</term>
- <listitem>
- <para>set preferred BSSID for an SSID</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>list_networks</term>
- <listitem>
- <para>list configured networks</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>terminate</term>
- <listitem>
- <para>terminate <command>wpa_supplicant</command></para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>quit</term>
- <listitem><para>exit wpa_cli</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_gui.sgml b/wpa_supplicant/doc/docbook/wpa_gui.sgml
deleted file mode 100644
index cb0c735e4ce7..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_gui.sgml
+++ /dev/null
@@ -1,106 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_gui</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_gui</refname>
-
- <refpurpose>WPA Graphical User Interface</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>wpa_gui</command>
- <arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
- <arg>-i <replaceable>ifname</replaceable></arg>
- <arg>-m <replaceable>seconds</replaceable></arg>
- <arg>-t</arg>
- <arg>-q</arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Overview</title>
-
- <para>wpa_gui is a QT graphical frontend program for interacting
- with wpa_supplicant. It is used to query current status, change
- configuration and request interactive user input.</para>
-
- <para>wpa_gui supports (almost) all of the interactive status and
- configuration features of the command line client, wpa_cli. Refer
- to the wpa_cli manpage for a comprehensive list of the
- interactive mode features.</para>
- </refsect1>
- <refsect1>
- <title>Command Arguments</title>
- <variablelist>
- <varlistentry>
- <term>-p path</term>
-
- <listitem><para>Change the path where control sockets should
- be found.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-i ifname</term>
-
- <listitem><para>Specify the interface that is being
- configured. By default, choose the first interface found with
- a control socket in the socket path.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-m seconds</term>
-
- <listitem><para>Set the update interval in seconds for the signal
- strength meter. This value must be a positive integer, otherwise
- meter is not enabled (default behavior).</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-t</term>
-
- <listitem><para>Start program in the system tray only (if the window
- manager supports it). By default the main status window is
- shown.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-q</term>
-
- <listitem><para>Run program in the quiet mode - do not display tray
- icon pop-up messages.</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_cli</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
deleted file mode 100644
index 077296904f89..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
+++ /dev/null
@@ -1,77 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_passphrase</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_passphrase</refname>
- <refpurpose>Generate a WPA PSK from an ASCII passphrase for a SSID</refpurpose>
- </refnamediv>
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>wpa_passphrase</command>
- <arg><replaceable>ssid</replaceable></arg>
- <arg><replaceable>passphrase</replaceable></arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Overview</title>
-
- <para><command>wpa_passphrase</command> pre-computes PSK entries for
- network configuration blocks of a
- <filename>wpa_supplicant.conf</filename> file. An ASCII passphrase
- and SSID are used to generate a 256-bit PSK.</para>
- </refsect1>
-
- <refsect1>
- <title>Options</title>
- <variablelist>
- <varlistentry>
- <term>ssid</term>
- <listitem>
- <para>The SSID whose passphrase should be derived.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>passphrase</term>
- <listitem>
- <para>The passphrase to use. If not included on the command line,
- passphrase will be read from standard input.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
-
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_priv.sgml b/wpa_supplicant/doc/docbook/wpa_priv.sgml
deleted file mode 100644
index 0d5c94a9f776..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_priv.sgml
+++ /dev/null
@@ -1,152 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_priv</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_priv</refname>
-
- <refpurpose>wpa_supplicant privilege separation helper</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>wpa_priv</command>
- <arg>-c <replaceable>ctrl path</replaceable></arg>
- <arg>-Bdd</arg>
- <arg>-P <replaceable>pid file</replaceable></arg>
- <arg>driver:ifname <replaceable>[driver:ifname ...]</replaceable></arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Overview</title>
-
- <para><command>wpa_priv</command> is a privilege separation helper that
- minimizes the size of <command>wpa_supplicant</command> code that needs
- to be run with root privileges.</para>
-
- <para>If enabled, privileged operations are done in the wpa_priv process
- while leaving rest of the code (e.g., EAP authentication and WPA
- handshakes) to operate in an unprivileged process (wpa_supplicant) that
- can be run as non-root user. Privilege separation restricts the effects
- of potential software errors by containing the majority of the code in an
- unprivileged process to avoid the possibility of a full system
- compromise.</para>
-
- <para><command>wpa_priv</command> needs to be run with network admin
- privileges (usually, root user). It opens a UNIX domain socket for each
- interface that is included on the command line; any other interface will
- be off limits for <command>wpa_supplicant</command> in this kind of
- configuration. After this, <command>wpa_supplicant</command> can be run as
- a non-root user (e.g., all standard users on a laptop or as a special
- non-privileged user account created just for this purpose to limit access
- to user files even further).</para>
- </refsect1>
- <refsect1>
- <title>Example configuration</title>
-
- <para>The following steps are an example of how to configure
- <command>wpa_priv</command> to allow users in the
- <emphasis>wpapriv</emphasis> group to communicate with
- <command>wpa_supplicant</command> with privilege separation:</para>
-
- <para>Create user group (e.g., wpapriv) and assign users that
- should be able to use wpa_supplicant into that group.</para>
-
- <para>Create /var/run/wpa_priv directory for UNIX domain sockets and
- control user access by setting it accessible only for the wpapriv
- group:</para>
-
-<blockquote><programlisting>
-mkdir /var/run/wpa_priv
-chown root:wpapriv /var/run/wpa_priv
-chmod 0750 /var/run/wpa_priv
-</programlisting></blockquote>
-
- <para>Start <command>wpa_priv</command> as root (e.g., from system
- startup scripts) with the enabled interfaces configured on the
- command line:</para>
-
-<blockquote><programlisting>
-wpa_priv -B -c /var/run/wpa_priv -P /var/run/wpa_priv.pid wext:wlan0
-</programlisting></blockquote>
-
- <para>Run <command>wpa_supplicant</command> as non-root with a user
- that is in the wpapriv group:</para>
-
-<blockquote><programlisting>
-wpa_supplicant -i ath0 -c wpa_supplicant.conf
-</programlisting></blockquote>
-
- </refsect1>
- <refsect1>
- <title>Command Arguments</title>
- <variablelist>
- <varlistentry>
- <term>-c ctrl path</term>
-
- <listitem><para>Specify the path to wpa_priv control directory
- (Default: /var/run/wpa_priv/).</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-B</term>
- <listitem><para>Run as a daemon in the background.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-P file</term>
-
- <listitem><para>Set the location of the PID
- file.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>driver:ifname [driver:ifname ...]</term>
-
- <listitem><para>The &lt;driver&gt; string dictates which of the
- supported <command>wpa_supplicant</command> driver backends is to be
- used. To get a list of supported driver types see wpa_supplicant help
- (e.g, wpa_supplicant -h). The driver backend supported by most good
- drivers is <emphasis>wext</emphasis>.</para>
-
- <para>The &lt;ifname&gt; string specifies which network
- interface is to be managed by <command>wpa_supplicant</command>
- (e.g., wlan0 or ath0).</para>
-
- <para><command>wpa_priv</command> does not use the network interface
- before <command>wpa_supplicant</command> is started, so it is fine to
- include network interfaces that are not available at the time wpa_priv
- is started. wpa_priv can control multiple interfaces with one process,
- but it is also possible to run multiple <command>wpa_priv</command>
- processes at the same time, if desired.</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
deleted file mode 100644
index 8a0314e8fb98..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
+++ /dev/null
@@ -1,243 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_supplicant.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_supplicant.conf</refname>
- <refpurpose>configuration file for wpa_supplicant</refpurpose>
- </refnamediv>
- <refsect1>
- <title>Overview</title>
-
- <para><command>wpa_supplicant</command> is configured using a text
- file that lists all accepted networks and security policies,
- including pre-shared keys. See the example configuration file,
- probably in <command>/usr/share/doc/wpa_supplicant/</command>, for
- detailed information about the configuration format and supported
- fields.</para>
-
- <para>All file paths in this configuration file should use full
- (absolute, not relative to working directory) path in order to allow
- working directory to be changed. This can happen if wpa_supplicant is
- run in the background.</para>
-
- <para>Changes to configuration file can be reloaded be sending
- SIGHUP signal to <command>wpa_supplicant</command> ('killall -HUP
- wpa_supplicant'). Similarly, reloading can be triggered with
- the <emphasis>wpa_cli reconfigure</emphasis> command.</para>
-
- <para>Configuration file can include one or more network blocks,
- e.g., one for each used SSID. wpa_supplicant will automatically
- select the best network based on the order of network blocks in
- the configuration file, network security level (WPA/WPA2 is
- preferred), and signal strength.</para>
- </refsect1>
-
- <refsect1>
- <title>Quick Examples</title>
-
- <orderedlist>
- <listitem>
-
- <para>WPA-Personal (PSK) as home network and WPA-Enterprise with
- EAP-TLS as work network.</para>
-
-<blockquote><programlisting>
-# allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-#
-# home network; allow all valid ciphers
-network={
- ssid="home"
- scan_ssid=1
- key_mgmt=WPA-PSK
- psk="very secret passphrase"
-}
-#
-# work network; use EAP-TLS with WPA; allow only CCMP and TKIP ciphers
-network={
- ssid="work"
- scan_ssid=1
- key_mgmt=WPA-EAP
- pairwise=CCMP TKIP
- group=CCMP TKIP
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
-}
-</programlisting></blockquote>
- </listitem>
-
- <listitem>
- <para>WPA-RADIUS/EAP-PEAP/MSCHAPv2 with RADIUS servers that
- use old peaplabel (e.g., Funk Odyssey and SBR, Meetinghouse
- Aegis, Interlink RAD-Series)</para>
-
-<blockquote><programlisting>
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP
- eap=PEAP
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase1="peaplabel=0"
- phase2="auth=MSCHAPV2"
-}
-</programlisting></blockquote>
- </listitem>
-
- <listitem>
- <para>EAP-TTLS/EAP-MD5-Challenge configuration with anonymous
- identity for the unencrypted use. Real identity is sent only
- within an encrypted TLS tunnel.</para>
-
-
-<blockquote><programlisting>
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP
- eap=TTLS
- identity="user@example.com"
- anonymous_identity="anonymous@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase2="auth=MD5"
-}
-</programlisting></blockquote>
-
- </listitem>
-
- <listitem>
- <para>IEEE 802.1X (i.e., no WPA) with dynamic WEP keys
- (require both unicast and broadcast); use EAP-TLS for
- authentication</para>
-
-<blockquote><programlisting>
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-network={
- ssid="1x-test"
- scan_ssid=1
- key_mgmt=IEEE8021X
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- eapol_flags=3
-}
-</programlisting></blockquote>
- </listitem>
-
-
- <listitem>
- <para>Catch all example that allows more or less all
- configuration modes. The configuration options are used based
- on what security policy is used in the selected SSID. This is
- mostly for testing and is not recommended for normal
- use.</para>
-
-<blockquote><programlisting>
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
- pairwise=CCMP TKIP
- group=CCMP TKIP WEP104 WEP40
- psk="very secret passphrase"
- eap=TTLS PEAP TLS
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- phase1="peaplabel=0"
- ca_cert2="/etc/cert/ca2.pem"
- client_cert2="/etc/cer/user.pem"
- private_key2="/etc/cer/user.prv"
- private_key2_passwd="password"
-}
-</programlisting></blockquote>
- </listitem>
-
- <listitem>
- <para>Authentication for wired Ethernet. This can be used with
- <emphasis>wired</emphasis> or <emphasis>roboswitch</emphasis> interface
- (-Dwired or -Droboswitch on command line).</para>
-
-<blockquote><programlisting>
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
-ap_scan=0
-network={
- key_mgmt=IEEE8021X
- eap=MD5
- identity="user"
- password="password"
- eapol_flags=0
-}
-</programlisting></blockquote>
- </listitem>
- </orderedlist>
-
-
-
-
-
- </refsect1>
- <refsect1>
- <title>Certificates</title>
-
- <para>Some EAP authentication methods require use of
- certificates. EAP-TLS uses both server side and client
- certificates whereas EAP-PEAP and EAP-TTLS only require the server
- side certificate. When client certificate is used, a matching
- private key file has to also be included in configuration. If the
- private key uses a passphrase, this has to be configured in
- wpa_supplicant.conf ("private_key_passwd").</para>
-
- <para>wpa_supplicant supports X.509 certificates in PEM and DER
- formats. User certificate and private key can be included in the
- same file.</para>
-
- <para>If the user certificate and private key is received in
- PKCS#12/PFX format, they need to be converted to suitable PEM/DER
- format for wpa_supplicant. This can be done, e.g., with following
- commands:</para>
-<blockquote><programlisting>
-# convert client certificate and private key to PEM format
-openssl pkcs12 -in example.pfx -out user.pem -clcerts
-# convert CA certificate (if included in PFX file) to PEM format
-openssl pkcs12 -in example.pfx -out ca.pem -cacerts -nokeys
-</programlisting></blockquote>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>openssl</refentrytitle>
- <manvolnum>1</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
deleted file mode 100644
index e4a83698393a..000000000000
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ /dev/null
@@ -1,764 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<refentry>
- <refentryinfo>
- <date>07 August 2019</date>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>wpa_supplicant</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
- <refnamediv>
- <refname>wpa_supplicant</refname>
- <refpurpose>Wi-Fi Protected Access client and IEEE 802.1X supplicant</refpurpose>
- </refnamediv>
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>wpa_supplicant</command>
- <arg>-BddfhKLqqsTtuvW</arg>
- <arg>-i<replaceable>ifname</replaceable></arg>
- <arg>-c<replaceable>config file</replaceable></arg>
- <arg>-D<replaceable>driver</replaceable></arg>
- <arg>-P<replaceable>PID_file</replaceable></arg>
- <arg>-f<replaceable>output file</replaceable></arg>
- </cmdsynopsis>
- </refsynopsisdiv>
- <refsect1>
- <title>Overview</title>
-
- <para>
- Wireless networks do not require physical access to the network equipment
- in the same way as wired networks. This makes it easier for unauthorized
- users to passively monitor a network and capture all transmitted frames.
- In addition, unauthorized use of the network is much easier. In many cases,
- this can happen even without user's explicit knowledge since the wireless
- LAN adapter may have been configured to automatically join any available
- network.
- </para>
-
- <para>
- Link-layer encryption can be used to provide a layer of security for
- wireless networks. The original wireless LAN standard, IEEE 802.11,
- included a simple encryption mechanism, WEP. However, that proved to
- be flawed in many areas and network protected with WEP cannot be consider
- secure. IEEE 802.1X authentication and frequently changed dynamic WEP keys
- can be used to improve the network security, but even that has inherited
- security issues due to the use of WEP for encryption. Wi-Fi Protected
- Access and IEEE 802.11i amendment to the wireless LAN standard introduce
- a much improved mechanism for securing wireless networks. IEEE 802.11i
- enabled networks that are using CCMP (encryption mechanism based on strong
- cryptographic algorithm AES) can finally be called secure used for
- applications which require efficient protection against unauthorized
- access.
- </para>
-
- <para><command>wpa_supplicant</command> is an implementation of
- the WPA Supplicant component, i.e., the part that runs in the
- client stations. It implements WPA key negotiation with a WPA
- Authenticator and EAP authentication with Authentication
- Server. In addition, it controls the roaming and IEEE 802.11
- authentication/association of the wireless LAN driver.</para>
-
- <para><command>wpa_supplicant</command> is designed to be a
- "daemon" program that runs in the background and acts as the
- backend component controlling the wireless
- connection. <command>wpa_supplicant</command> supports separate
- frontend programs and an example text-based frontend,
- <command>wpa_cli</command>, is included with
- wpa_supplicant.</para>
-
- <para>Before wpa_supplicant can do its work, the network interface
- must be available. That means that the physical device must be
- present and enabled, and the driver for the device must be
- loaded. The daemon will exit immediately if the device is not already
- available.</para>
-
- <para>After <command>wpa_supplicant</command> has configured the
- network device, higher level configuration such as DHCP may
- proceed. There are a variety of ways to integrate wpa_supplicant
- into a machine's networking scripts, a few of which are described
- in sections below.</para>
-
- <para>The following steps are used when associating with an AP
- using WPA:</para>
-
- <itemizedlist>
- <listitem>
- <para><command>wpa_supplicant</command> requests the kernel
- driver to scan neighboring BSSes</para>
- </listitem>
-
- <listitem>
- <para><command>wpa_supplicant</command> selects a BSS based on
- its configuration</para>
- </listitem>
-
- <listitem>
- <para><command>wpa_supplicant</command> requests the kernel
- driver to associate with the chosen BSS</para>
- </listitem>
-
- <listitem>
- <para>If WPA-EAP: integrated IEEE 802.1X Supplicant
- completes EAP authentication with the
- authentication server (proxied by the Authenticator in the
- AP)</para>
- </listitem>
-
- <listitem>
- <para>If WPA-EAP: master key is received from the IEEE 802.1X
- Supplicant</para>
- </listitem>
-
- <listitem>
- <para>If WPA-PSK: <command>wpa_supplicant</command> uses PSK
- as the master session key</para>
- </listitem>
-
- <listitem>
- <para><command>wpa_supplicant</command> completes WPA 4-Way
- Handshake and Group Key Handshake with the Authenticator
- (AP)</para>
- </listitem>
-
- <listitem>
- <para><command>wpa_supplicant</command> configures encryption
- keys for unicast and broadcast</para>
- </listitem>
-
- <listitem>
- <para>normal data packets can be transmitted and received</para>
- </listitem>
- </itemizedlist>
- </refsect1>
-
- <refsect1>
- <title>Supported Features</title>
- <para>Supported WPA/IEEE 802.11i features:</para>
- <itemizedlist>
- <listitem>
- <para>WPA-PSK ("WPA-Personal")</para>
- </listitem>
-
- <listitem>
- <para>WPA with EAP (e.g., with RADIUS authentication server)
- ("WPA-Enterprise") Following authentication methods are
- supported with an integrate IEEE 802.1X Supplicant:</para>
-
- <itemizedlist>
- <listitem>
- <para>EAP-TLS</para>
- </listitem>
- </itemizedlist>
-
- <itemizedlist>
- <listitem>
- <para>EAP-PEAP/MSCHAPv2 (both PEAPv0 and PEAPv1)</para>
- </listitem>
-
-
- <listitem>
- <para>EAP-PEAP/TLS (both PEAPv0 and PEAPv1)</para>
- </listitem>
-
- <listitem>
- <para>EAP-PEAP/GTC (both PEAPv0 and PEAPv1)</para>
- </listitem>
-
- <listitem>
- <para>EAP-PEAP/OTP (both PEAPv0 and PEAPv1)</para>
- </listitem>
-
- <listitem>
- <para>EAP-PEAP/MD5-Challenge (both PEAPv0 and PEAPv1)</para>
- </listitem>
-
- <listitem>
- <para>EAP-TTLS/EAP-MD5-Challenge</para>
- </listitem>
-
- <listitem>
- <para>EAP-TTLS/EAP-GTC</para>
- </listitem>
-
- <listitem><para>EAP-TTLS/EAP-OTP</para></listitem>
-
- <listitem><para>EAP-TTLS/EAP-MSCHAPv2</para></listitem>
-
- <listitem><para>EAP-TTLS/EAP-TLS</para></listitem>
-
- <listitem><para>EAP-TTLS/MSCHAPv2</para></listitem>
-
- <listitem><para>EAP-TTLS/MSCHAP</para></listitem>
-
- <listitem><para>EAP-TTLS/PAP</para></listitem>
-
- <listitem><para>EAP-TTLS/CHAP</para></listitem>
-
- <listitem><para>EAP-SIM</para></listitem>
-
- <listitem><para>EAP-AKA</para></listitem>
-
- <listitem><para>EAP-PSK</para></listitem>
-
- <listitem><para>EAP-PAX</para></listitem>
-
- <listitem><para>LEAP (note: requires special support from
- the driver for IEEE 802.11 authentication)</para></listitem>
-
- <listitem><para>(following methods are supported, but since
- they do not generate keying material, they cannot be used
- with WPA or IEEE 802.1X WEP keying)</para></listitem>
-
- <listitem><para>EAP-MD5-Challenge </para></listitem>
-
- <listitem><para>EAP-MSCHAPv2</para></listitem>
-
- <listitem><para>EAP-GTC</para></listitem>
-
- <listitem><para>EAP-OTP</para></listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>key management for CCMP, TKIP, WEP104, WEP40</para>
- </listitem>
-
- <listitem>
- <para>RSN/WPA2 (IEEE 802.11i)</para>
- <itemizedlist>
- <listitem>
- <para>pre-authentication</para>
- </listitem>
-
- <listitem>
- <para>PMKSA caching</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </refsect1>
-
- <refsect1>
- <title>Available Drivers</title>
- <para>A summary of available driver backends is below. Support for each
- of the driver backends is chosen at wpa_supplicant compile time. For a
- list of supported driver backends that may be used with the -D option on
- your system, refer to the help output of wpa_supplicant
- (<emphasis>wpa_supplicant -h</emphasis>).</para>
-
- <variablelist>
- <varlistentry>
- <term>nl80211</term>
- <listitem>
- <para>Uses the modern Linux nl80211/cfg80211 netlink-based
- interface (most new drivers).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>wext</term>
- <listitem>
- <para>Uses the legacy Linux wireless extensions ioctl-based
- interface (older hardware/drivers).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>wired</term>
- <listitem>
- <para>wpa_supplicant wired Ethernet driver</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>roboswitch</term>
- <listitem>
- <para>wpa_supplicant Broadcom switch driver</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>bsd</term>
- <listitem>
- <para>BSD 802.11 support (Atheros, etc.).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>ndis</term>
- <listitem>
- <para>Windows NDIS driver.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Command Line Options</title>
- <para>Most command line options have global scope. Some are given per
- interface, and are only valid if at least one <option>-i</option> option
- is specified, otherwise they're ignored. Option groups for different
- interfaces must be separated by <option>-N</option> option.</para>
- <variablelist>
- <varlistentry>
- <term>-b br_ifname</term>
- <listitem>
- <para>Optional bridge interface name. (Per interface)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-B</term>
- <listitem>
- <para>Run daemon in the background.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-c filename</term>
- <listitem>
- <para>Path to configuration file. (Per interface)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-C ctrl_interface</term>
- <listitem>
- <para>Path to ctrl_interface socket (Per interface. Only used if
- <option>-c</option> is not).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-i ifname</term>
- <listitem>
- <para>Interface to listen on. Multiple instances of this option can
- be present, one per interface, separated by <option>-N</option>
- option (see below).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-d</term>
- <listitem>
- <para>Increase debugging verbosity (<option>-dd</option> even
- more).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-D driver</term>
- <listitem>
- <para>Driver to use (can be multiple drivers: nl80211,wext).
- (Per interface, see the available options below.)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-e entropy file</term>
- <listitem>
- <para>File for <command>wpa_supplicant</command> to use to
- maintain its internal entropy store in over restarts.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-f output file</term>
- <listitem>
- <para>Log output to specified file instead of stdout. (This
- is only available if <command>wpa_supplicant</command> was
- built with the <literal>CONFIG_DEBUG_FILE</literal>
- option.)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-g global ctrl_interface</term>
- <listitem>
- <para>Path to global ctrl_interface socket. If specified, interface
- definitions may be omitted.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-K</term>
- <listitem>
- <para>Include keys (passwords, etc.) in debug output.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-h</term>
- <listitem>
- <para>Help. Show a usage message.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-L</term>
- <listitem>
- <para>Show license (BSD).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-o override driver</term>
- <listitem>
- <para>Override the driver parameter for new
- interfaces.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-O override ctrl_interface</term>
- <listitem>
- <para>Override the ctrl_interface parameter for new
- interfaces.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-p</term>
- <listitem>
- <para>Driver parameters. (Per interface)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-P PID_file</term>
- <listitem>
- <para>Path to PID file.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-q</term>
- <listitem>
- <para>Decrease debugging verbosity (<option>-qq</option> even
- less).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-s</term>
- <listitem>
- <para>Log output to syslog instead of stdout. (This is only
- available if <command>wpa_supplicant</command> was built
- with the <literal>CONFIG_DEBUG_SYSLOG</literal>
- option.)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-T</term>
- <listitem>
- <para>Log output to Linux tracing in addition to any other
- destinations. (This is only available
- if <command>wpa_supplicant</command> was built with
- the <literal>CONFIG_DEBUG_LINUX_TRACING</literal>
- option.)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-t</term>
- <listitem>
- <para>Include timestamp in debug messages.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-u</term>
- <listitem>
- <para>Enable DBus control interface. If enabled, interface
- definitions may be omitted. (This is only available
- if <command>wpa_supplicant</command> was built with
- the <literal>CONFIG_CTRL_IFACE_DBUS_NEW</literal> option.)</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-v</term>
- <listitem>
- <para>Show version.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-W</term>
- <listitem>
- <para>Wait for a control interface monitor before starting.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>-N</term>
- <listitem>
- <para>Start describing new interface.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Examples</title>
-
- <para>In most common cases, <command>wpa_supplicant</command> is
- started with:</para>
-
-<blockquote><programlisting>
-wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0
-</programlisting></blockquote>
-
- <para>This makes the process fork into background.</para>
-
- <para>The easiest way to debug problems, and to get debug log for
- bug reports, is to start <command>wpa_supplicant</command> on
- foreground with debugging enabled:</para>
-
-<blockquote><programlisting>
-wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0 -d
-</programlisting></blockquote>
-
- <para>If the specific driver wrapper is not known beforehand, it is
- possible to specify multiple comma separated driver wrappers on the command
- line. <command>wpa_supplicant</command> will use the first driver
- wrapper that is able to initialize the interface.</para>
-
-<blockquote><programlisting>
-wpa_supplicant -Dnl80211,wext -c/etc/wpa_supplicant.conf -iwlan0
-</programlisting></blockquote>
-
- <para><command>wpa_supplicant</command> can control multiple
- interfaces (radios) either by running one process for each
- interface separately or by running just one process and list of
- options at command line. Each interface is separated with -N
- argument. As an example, following command would start
- wpa_supplicant for two interfaces:</para>
-
-<blockquote><programlisting>
-wpa_supplicant \
- -c wpa1.conf -i wlan0 -D nl80211 -N \
- -c wpa2.conf -i ath0 -D wext
-</programlisting></blockquote>
- </refsect1>
-
- <refsect1>
- <title>OS Requirements</title>
- <para>Current hardware/software requirements:</para>
-
- <itemizedlist>
- <listitem>
- <para>Linux kernel 2.6.30 or higher with
- nl80211/cfg80211 support</para>
- </listitem>
-
- <listitem>
- <para>Linux kernel 2.4.x or higher with Linux Wireless
- Extensions v15 or newer</para>
- </listitem>
-
- <listitem>
- <para>FreeBSD 6-CURRENT</para>
- </listitem>
-
- <listitem>
- <para>Microsoft Windows with WinPcap (at least WinXP, may work
- with other versions)</para>
- </listitem>
- </itemizedlist>
- </refsect1>
-
- <refsect1>
- <title>Supported Drivers</title>
- <variablelist>
- <varlistentry>
- <term>Linux nl80211/cfg80211</term>
- <listitem>
- <para>This is the preferred driver for Linux.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Linux wireless extensions</term>
- <listitem>
- <para>In theory, any driver that supports Linux wireless
- extensions can be used with IEEE 802.1X (i.e., not WPA) when
- using ap_scan=0 option in configuration file.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Wired Ethernet drivers</term>
- <listitem>
- <para>Use ap_scan=0.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>BSD net80211 layer (e.g., Atheros driver)</term>
- <listitem>
- <para>At the moment, this is for FreeBSD 6-CURRENT branch.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Windows NDIS</term>
- <listitem>
- <para>The current Windows port requires WinPcap
- (http://winpcap.polito.it/). See README-Windows.txt for more
- information.</para>
- </listitem>
- </varlistentry>
- </variablelist>
-
-
- <para>wpa_supplicant was designed to be portable for different
- drivers and operating systems. Hopefully, support for more wlan
- cards and OSes will be added in the future. See developer.txt for
- more information about the design of wpa_supplicant and porting to
- other drivers. One main goal is to add full WPA/WPA2 support to
- Linux wireless extensions to allow new drivers to be supported
- without having to implement new driver-specific interface code in
- wpa_supplicant.</para>
- </refsect1>
-
- <refsect1>
- <title>Architecture</title> <para>The
- <command>wpa_supplicant</command> system consists of the following
- components:</para>
-
- <variablelist>
- <varlistentry>
- <term><filename>wpa_supplicant.conf</filename> </term>
- <listitem>
- <para>the configuration file describing all networks that the
- user wants the computer to connect to. </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>wpa_supplicant</command></term>
- <listitem><para>the program that directly interacts with the
- network interface. </para></listitem>
- </varlistentry>
- <varlistentry>
- <term><command>wpa_cli</command></term> <listitem><para> the
- client program that provides a high-level interface to the
- functionality of the daemon. </para></listitem>
- </varlistentry>
- <varlistentry>
- <term><command>wpa_passphrase</command></term>
- <listitem><para>a utility needed to construct
- <filename>wpa_supplicant.conf</filename> files that include
- encrypted passwords.</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Quick Start</title>
-
- <para>First, make a configuration file, e.g.
- <filename>/etc/wpa_supplicant.conf</filename>, that describes the networks
- you are interested in. See <citerefentry>
- <refentrytitle>wpa_supplicant.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- </citerefentry>
- for details.</para>
-
- <para>Once the configuration is ready, you can test whether the
- configuration works by running <command>wpa_supplicant</command>
- with following command to start it on foreground with debugging
- enabled:</para>
-
- <blockquote><programlisting>
-wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -d
- </programlisting></blockquote>
-
- <para>Assuming everything goes fine, you can start using following
- command to start <command>wpa_supplicant</command> on background
- without debugging:</para>
-
- <blockquote><programlisting>
-wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B
- </programlisting></blockquote>
-
- <para>Please note that if you included more than one driver
- interface in the build time configuration (.config), you may need
- to specify which interface to use by including -D&lt;driver
- name&gt; option on the command line.</para>
-
- <!-- XXX at this point, the page could include a little script
- based on wpa_cli to wait for a connection and then run
- dhclient -->
-
- </refsect1>
-
- <refsect1>
- <title>Interface to pcmcia-cs/cardmrg</title>
-
- <para>For example, following small changes to pcmcia-cs scripts
- can be used to enable WPA support:</para>
-
- <para>Add MODE="Managed" and WPA="y" to the network scheme in
- <filename>/etc/pcmcia/wireless.opts</filename>.</para>
-
- <para>Add the following block to the end of <emphasis>start</emphasis>
- action handler in <filename>/etc/pcmcia/wireless</filename>:</para>
-
- <blockquote><programlisting>
-if [ "$WPA" = "y" -a -x /usr/local/bin/wpa_supplicant ]; then
- /usr/local/bin/wpa_supplicant -B -c/etc/wpa_supplicant.conf -i$DEVICE
-fi
- </programlisting></blockquote>
-
-
- <para>Add the following block to the end of <emphasis>stop</emphasis>
- action handler (may need to be separated from other actions) in
- <filename>/etc/pcmcia/wireless</filename>:</para>
-
- <blockquote><programlisting>
-if [ "$WPA" = "y" -a -x /usr/local/bin/wpa_supplicant ]; then
- killall wpa_supplicant
-fi
- </programlisting></blockquote>
-
- <para>This will make <command>cardmgr</command> start
- <command>wpa_supplicant</command> when the card is plugged
- in.</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry>
- <refentrytitle>wpa_background</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>wpa_supplicant.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>wpa_cli</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- <citerefentry>
- <refentrytitle>wpa_passphrase</refentrytitle>
- <manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
- <refsect1>
- <title>Legal</title>
- <para>wpa_supplicant is copyright (c) 2003-2019,
- Jouni Malinen <email>j@w1.fi</email> and
- contributors.
- All Rights Reserved.</para>
-
- <para>This program is licensed under the BSD license (the one with
- advertisement clause removed).</para>
- </refsect1>
-</refentry>
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
deleted file mode 100644
index 584654a6cb2c..000000000000
--- a/wpa_supplicant/dpp_supplicant.c
+++ /dev/null
@@ -1,3995 +0,0 @@
-/*
- * wpa_supplicant - DPP
- * Copyright (c) 2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018-2020, The Linux Foundation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/ip_addr.h"
-#include "utils/base64.h"
-#include "common/dpp.h"
-#include "common/gas.h"
-#include "common/gas_server.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "driver_i.h"
-#include "offchannel.h"
-#include "gas_query.h"
-#include "bss.h"
-#include "scan.h"
-#include "notify.h"
-#include "dpp_supplicant.h"
-
-
-static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
- unsigned int freq);
-static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
-static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx);
-static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator);
-static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result);
-static void wpas_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
-static int wpas_dpp_auth_init_next(struct wpa_supplicant *wpa_s);
-static void
-wpas_dpp_tx_pkex_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result);
-#ifdef CONFIG_DPP2
-static void wpas_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
- void *timeout_ctx);
-static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s);
-static int wpas_dpp_process_conf_obj(void *ctx,
- struct dpp_authentication *auth);
-#endif /* CONFIG_DPP2 */
-
-static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-/* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
- * a single transaction in progress at any point in time. */
-static const u8 TRANSACTION_ID = 1;
-
-
-/**
- * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
- * @wpa_s: Pointer to wpa_supplicant data
- * @cmd: DPP URI read from a QR Code
- * Returns: Identifier of the stored info or -1 on failure
- */
-int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct dpp_bootstrap_info *bi;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- bi = dpp_add_qr_code(wpa_s->dpp, cmd);
- if (!bi)
- return -1;
-
- if (auth && auth->response_pending &&
- dpp_notify_new_qr_code(auth, bi) == 1) {
- wpa_printf(MSG_DEBUG,
- "DPP: Sending out pending authentication response");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
- " freq=%u type=%d",
- MAC2STR(auth->peer_mac_addr), auth->curr_freq,
- DPP_PA_AUTHENTICATION_RESP);
- offchannel_send_action(wpa_s, auth->curr_freq,
- auth->peer_mac_addr, wpa_s->own_addr,
- broadcast,
- wpabuf_head(auth->resp_msg),
- wpabuf_len(auth->resp_msg),
- 500, wpas_dpp_tx_status, 0);
- }
-
-#ifdef CONFIG_DPP2
- dpp_controller_new_qr_code(wpa_s->dpp, bi);
-#endif /* CONFIG_DPP2 */
-
- return bi->id;
-}
-
-
-/**
- * wpas_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
- * @wpa_s: Pointer to wpa_supplicant data
- * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
- * Returns: Identifier of the stored info or -1 on failure
- */
-int wpas_dpp_nfc_uri(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct dpp_bootstrap_info *bi;
-
- bi = dpp_add_nfc_uri(wpa_s->dpp, cmd);
- if (!bi)
- return -1;
-
- return bi->id;
-}
-
-
-int wpas_dpp_nfc_handover_req(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos;
- struct dpp_bootstrap_info *peer_bi, *own_bi;
-
- pos = os_strstr(cmd, " own=");
- if (!pos)
- return -1;
- pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!own_bi)
- return -1;
- own_bi->nfc_negotiated = 1;
-
- pos = os_strstr(cmd, " uri=");
- if (!pos)
- return -1;
- pos += 5;
- peer_bi = dpp_add_nfc_uri(wpa_s->dpp, pos);
- if (!peer_bi) {
- wpa_printf(MSG_INFO,
- "DPP: Failed to parse URI from NFC Handover Request");
- return -1;
- }
-
- if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
- return -1;
-
- return peer_bi->id;
-}
-
-
-int wpas_dpp_nfc_handover_sel(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos;
- struct dpp_bootstrap_info *peer_bi, *own_bi;
-
- pos = os_strstr(cmd, " own=");
- if (!pos)
- return -1;
- pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!own_bi)
- return -1;
- own_bi->nfc_negotiated = 1;
-
- pos = os_strstr(cmd, " uri=");
- if (!pos)
- return -1;
- pos += 5;
- peer_bi = dpp_add_nfc_uri(wpa_s->dpp, pos);
- if (!peer_bi) {
- wpa_printf(MSG_INFO,
- "DPP: Failed to parse URI from NFC Handover Select");
- return -1;
- }
-
- if (peer_bi->curve != own_bi->curve) {
- wpa_printf(MSG_INFO,
- "DPP: Peer (NFC Handover Selector) used different curve");
- return -1;
- }
-
- return peer_bi->id;
-}
-
-
-static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth || !auth->resp_msg)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Retry Authentication Response after timeout");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
- " freq=%u type=%d",
- MAC2STR(auth->peer_mac_addr), auth->curr_freq,
- DPP_PA_AUTHENTICATION_RESP);
- offchannel_send_action(wpa_s, auth->curr_freq, auth->peer_mac_addr,
- wpa_s->own_addr, broadcast,
- wpabuf_head(auth->resp_msg),
- wpabuf_len(auth->resp_msg),
- 500, wpas_dpp_tx_status, 0);
-}
-
-
-static void wpas_dpp_auth_resp_retry(struct wpa_supplicant *wpa_s)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- unsigned int wait_time, max_tries;
-
- if (!auth || !auth->resp_msg)
- return;
-
- if (wpa_s->dpp_resp_max_tries)
- max_tries = wpa_s->dpp_resp_max_tries;
- else
- max_tries = 5;
- auth->auth_resp_tries++;
- if (auth->auth_resp_tries >= max_tries) {
- wpa_printf(MSG_INFO, "DPP: No confirm received from initiator - stopping exchange");
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
-
- if (wpa_s->dpp_resp_retry_time)
- wait_time = wpa_s->dpp_resp_retry_time;
- else
- wait_time = 1000;
- wpa_printf(MSG_DEBUG,
- "DPP: Schedule retransmission of Authentication Response frame in %u ms",
- wait_time);
- eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
- eloop_register_timeout(wait_time / 1000,
- (wait_time % 1000) * 1000,
- wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
-}
-
-
-static void wpas_dpp_try_to_connect(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
- wpa_s->suitable_network = 0;
- wpa_s->no_suitable_network = 0;
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- wpa_s->scan_runs = 0;
- wpa_s->normal_scans = 0;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-#ifdef CONFIG_DPP2
-
-static void wpas_dpp_stop_listen_for_tx(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- unsigned int wait_time)
-{
- struct os_reltime now, res;
- unsigned int remaining;
-
- if (!wpa_s->dpp_listen_freq)
- return;
-
- os_get_reltime(&now);
- if (os_reltime_before(&now, &wpa_s->dpp_listen_end)) {
- os_reltime_sub(&wpa_s->dpp_listen_end, &now, &res);
- remaining = res.sec * 1000 + res.usec / 1000;
- } else {
- remaining = 0;
- }
- if (wpa_s->dpp_listen_freq == freq && remaining > wait_time)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Stop listen on %u MHz ending in %u ms to allow immediate TX on %u MHz for %u ms",
- wpa_s->dpp_listen_freq, remaining, freq, wait_time);
- wpas_dpp_listen_stop(wpa_s);
-
- /* TODO: Restart listen in some cases after TX? */
-}
-
-
-static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- enum dpp_status_error result;
-
- if (!auth || !auth->conn_status_requested)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Connection timeout - report Connection Status Result");
- if (wpa_s->suitable_network)
- result = DPP_STATUS_AUTH_FAILURE;
- else if (wpa_s->no_suitable_network)
- result = DPP_STATUS_NO_AP;
- else
- result = 255; /* What to report here for unexpected state? */
- if (wpa_s->wpa_state == WPA_SCANNING)
- wpas_abort_ongoing_scan(wpa_s);
- wpas_dpp_send_conn_status_result(wpa_s, result);
-}
-
-
-static char * wpas_dpp_scan_channel_list(struct wpa_supplicant *wpa_s)
-{
- char *str, *end, *pos;
- size_t len;
- unsigned int i;
- u8 last_op_class = 0;
- int res;
-
- if (!wpa_s->last_scan_freqs || !wpa_s->num_last_scan_freqs)
- return NULL;
-
- len = wpa_s->num_last_scan_freqs * 8;
- str = os_zalloc(len);
- if (!str)
- return NULL;
- end = str + len;
- pos = str;
-
- for (i = 0; i < wpa_s->num_last_scan_freqs; i++) {
- enum hostapd_hw_mode mode;
- u8 op_class, channel;
-
- mode = ieee80211_freq_to_channel_ext(wpa_s->last_scan_freqs[i],
- 0, 0, &op_class, &channel);
- if (mode == NUM_HOSTAPD_MODES)
- continue;
- if (op_class == last_op_class)
- res = os_snprintf(pos, end - pos, ",%d", channel);
- else
- res = os_snprintf(pos, end - pos, "%s%d/%d",
- pos == str ? "" : ",",
- op_class, channel);
- if (os_snprintf_error(end - pos, res)) {
- *pos = '\0';
- break;
- }
- pos += res;
- last_op_class = op_class;
- }
-
- if (pos == str) {
- os_free(str);
- str = NULL;
- }
- return str;
-}
-
-
-void wpas_dpp_send_conn_status_result(struct wpa_supplicant *wpa_s,
- enum dpp_status_error result)
-{
- struct wpabuf *msg;
- const char *channel_list = NULL;
- char *channel_list_buf = NULL;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
-
- if (!auth || !auth->conn_status_requested)
- return;
- auth->conn_status_requested = 0;
- wpa_printf(MSG_DEBUG, "DPP: Report connection status result %d",
- result);
-
- if (result == DPP_STATUS_NO_AP) {
- channel_list_buf = wpas_dpp_scan_channel_list(wpa_s);
- channel_list = channel_list_buf;
- }
-
- msg = dpp_build_conn_status_result(auth, result,
- ssid ? ssid->ssid :
- wpa_s->dpp_last_ssid,
- ssid ? ssid->ssid_len :
- wpa_s->dpp_last_ssid_len,
- channel_list);
- os_free(channel_list_buf);
- if (!msg) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
-
- wpa_msg(wpa_s, MSG_INFO,
- DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(auth->peer_mac_addr), auth->curr_freq,
- DPP_PA_CONNECTION_STATUS_RESULT);
- offchannel_send_action(wpa_s, auth->curr_freq,
- auth->peer_mac_addr, wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- 500, wpas_dpp_tx_status, 0);
- wpabuf_free(msg);
-
- /* This exchange will be terminated in the TX status handler */
- auth->remove_on_tx_status = 1;
-
- return;
-}
-
-
-void wpas_dpp_connected(struct wpa_supplicant *wpa_s)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (auth && auth->conn_status_requested)
- wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_OK);
-}
-
-#endif /* CONFIG_DPP2 */
-
-
-static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- const char *res_txt;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- res_txt = result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
- (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
- "FAILED");
- wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
- " result=%s", freq, MAC2STR(dst), res_txt);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
- " freq=%u result=%s", MAC2STR(dst), freq, res_txt);
-
- if (!wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore TX status since there is no ongoing authentication exchange");
- return;
- }
-
-#ifdef CONFIG_DPP2
- if (auth->connect_on_tx_status) {
- auth->connect_on_tx_status = 0;
- wpa_printf(MSG_DEBUG,
- "DPP: Try to connect after completed configuration result");
- wpas_dpp_try_to_connect(wpa_s);
- if (auth->conn_status_requested) {
- wpa_printf(MSG_DEBUG,
- "DPP: Start 15 second timeout for reporting connection status result");
- eloop_cancel_timeout(
- wpas_dpp_conn_status_result_timeout,
- wpa_s, NULL);
- eloop_register_timeout(
- 15, 0, wpas_dpp_conn_status_result_timeout,
- wpa_s, NULL);
- } else {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- }
- return;
- }
-#endif /* CONFIG_DPP2 */
-
- if (wpa_s->dpp_auth->remove_on_tx_status) {
- wpa_printf(MSG_DEBUG,
- "DPP: Terminate authentication exchange due to a request to do so on TX status");
- eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
- NULL);
- eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
- NULL);
-#ifdef CONFIG_DPP2
- eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
- wpa_s, NULL);
-#endif /* CONFIG_DPP2 */
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
-
- if (wpa_s->dpp_auth_ok_on_ack)
- wpas_dpp_auth_success(wpa_s, 1);
-
- if (!is_broadcast_ether_addr(dst) &&
- result != OFFCHANNEL_SEND_ACTION_SUCCESS) {
- wpa_printf(MSG_DEBUG,
- "DPP: Unicast DPP Action frame was not ACKed");
- if (auth->waiting_auth_resp) {
- /* In case of DPP Authentication Request frame, move to
- * the next channel immediately. */
- offchannel_send_action_done(wpa_s);
- wpas_dpp_auth_init_next(wpa_s);
- return;
- }
- if (auth->waiting_auth_conf) {
- wpas_dpp_auth_resp_retry(wpa_s);
- return;
- }
- }
-
- if (auth->waiting_auth_conf &&
- auth->auth_resp_status == DPP_STATUS_OK) {
- /* Make sure we do not get stuck waiting for Auth Confirm
- * indefinitely after successfully transmitted Auth Response to
- * allow new authentication exchanges to be started. */
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
- NULL);
- eloop_register_timeout(1, 0, wpas_dpp_auth_conf_wait_timeout,
- wpa_s, NULL);
- }
-
- if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp &&
- result == OFFCHANNEL_SEND_ACTION_SUCCESS) {
- /* Allow timeout handling to stop iteration if no response is
- * received from a peer that has ACKed a request. */
- auth->auth_req_ack = 1;
- }
-
- if (!wpa_s->dpp_auth_ok_on_ack && wpa_s->dpp_auth->neg_freq > 0 &&
- wpa_s->dpp_auth->curr_freq != wpa_s->dpp_auth->neg_freq) {
- wpa_printf(MSG_DEBUG,
- "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
- wpa_s->dpp_auth->curr_freq,
- wpa_s->dpp_auth->neg_freq);
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->neg_freq);
- }
-
- if (wpa_s->dpp_auth_ok_on_ack)
- wpa_s->dpp_auth_ok_on_ack = 0;
-}
-
-
-static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- unsigned int freq;
- struct os_reltime now, diff;
- unsigned int wait_time, diff_ms;
-
- if (!auth || !auth->waiting_auth_resp)
- return;
-
- wait_time = wpa_s->dpp_resp_wait_time ?
- wpa_s->dpp_resp_wait_time : 2000;
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->dpp_last_init, &diff);
- diff_ms = diff.sec * 1000 + diff.usec / 1000;
- wpa_printf(MSG_DEBUG,
- "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
- wait_time, diff_ms);
-
- if (auth->auth_req_ack && diff_ms >= wait_time) {
- /* Peer ACK'ed Authentication Request frame, but did not reply
- * with Authentication Response frame within two seconds. */
- wpa_printf(MSG_INFO,
- "DPP: No response received from responder - stopping initiation attempt");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
-
- if (diff_ms >= wait_time) {
- /* Authentication Request frame was not ACK'ed and no reply
- * was receiving within two seconds. */
- wpa_printf(MSG_DEBUG,
- "DPP: Continue Initiator channel iteration");
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- wpas_dpp_auth_init_next(wpa_s);
- return;
- }
-
- /* Driver did not support 2000 ms long wait_time with TX command, so
- * schedule listen operation to continue waiting for the response.
- *
- * DPP listen operations continue until stopped, so simply schedule a
- * new call to this function at the point when the two second reply
- * wait has expired. */
- wait_time -= diff_ms;
-
- freq = auth->curr_freq;
- if (auth->neg_freq > 0)
- freq = auth->neg_freq;
- wpa_printf(MSG_DEBUG,
- "DPP: Continue reply wait on channel %u MHz for %u ms",
- freq, wait_time);
- wpa_s->dpp_in_response_listen = 1;
- wpas_dpp_listen_start(wpa_s, freq);
-
- eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
- wpas_dpp_reply_wait_timeout, wpa_s, NULL);
-}
-
-
-static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth || !auth->waiting_auth_conf)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Terminate authentication exchange due to Auth Confirm timeout");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL "No Auth Confirm received");
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
-}
-
-
-static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
-{
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->dpp_config_obj_override)
- auth->config_obj_override =
- os_strdup(wpa_s->dpp_config_obj_override);
- if (wpa_s->dpp_discovery_override)
- auth->discovery_override =
- os_strdup(wpa_s->dpp_discovery_override);
- if (wpa_s->dpp_groups_override)
- auth->groups_override =
- os_strdup(wpa_s->dpp_groups_override);
- auth->ignore_netaccesskey_mismatch =
- wpa_s->dpp_ignore_netaccesskey_mismatch;
-#endif /* CONFIG_TESTING_OPTIONS */
-}
-
-
-static void wpas_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (!wpa_s->dpp_auth)
- return;
- wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
- wpas_dpp_auth_init_next(wpa_s);
-}
-
-
-static int wpas_dpp_auth_init_next(struct wpa_supplicant *wpa_s)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- const u8 *dst;
- unsigned int wait_time, max_wait_time, freq, max_tries, used;
- struct os_reltime now, diff;
-
- wpa_s->dpp_in_response_listen = 0;
- if (!auth)
- return -1;
-
- if (auth->freq_idx == 0)
- os_get_reltime(&wpa_s->dpp_init_iter_start);
-
- if (auth->freq_idx >= auth->num_freq) {
- auth->num_freq_iters++;
- if (wpa_s->dpp_init_max_tries)
- max_tries = wpa_s->dpp_init_max_tries;
- else
- max_tries = 5;
- if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
- wpa_printf(MSG_INFO,
- "DPP: No response received from responder - stopping initiation attempt");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout,
- wpa_s, NULL);
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return -1;
- }
- auth->freq_idx = 0;
- eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
- if (wpa_s->dpp_init_retry_time)
- wait_time = wpa_s->dpp_init_retry_time;
- else
- wait_time = 10000;
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->dpp_init_iter_start, &diff);
- used = diff.sec * 1000 + diff.usec / 1000;
- if (used > wait_time)
- wait_time = 0;
- else
- wait_time -= used;
- wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
- wait_time);
- eloop_register_timeout(wait_time / 1000,
- (wait_time % 1000) * 1000,
- wpas_dpp_init_timeout, wpa_s,
- NULL);
- return 0;
- }
- freq = auth->freq[auth->freq_idx++];
- auth->curr_freq = freq;
-
- if (!is_zero_ether_addr(auth->peer_mac_addr))
- dst = auth->peer_mac_addr;
- else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
- dst = broadcast;
- else
- dst = auth->peer_bi->mac_addr;
- wpa_s->dpp_auth_ok_on_ack = 0;
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
- wait_time = wpa_s->max_remain_on_chan;
- max_wait_time = wpa_s->dpp_resp_wait_time ?
- wpa_s->dpp_resp_wait_time : 2000;
- if (wait_time > max_wait_time)
- wait_time = max_wait_time;
- wait_time += 10; /* give the driver some extra time to complete */
- eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
- wpas_dpp_reply_wait_timeout,
- wpa_s, NULL);
- wait_time -= 10;
- if (auth->neg_freq > 0 && freq != auth->neg_freq) {
- wpa_printf(MSG_DEBUG,
- "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
- freq, auth->neg_freq);
- }
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
- auth->auth_req_ack = 0;
- os_get_reltime(&wpa_s->dpp_last_init);
- return offchannel_send_action(wpa_s, freq, dst,
- wpa_s->own_addr, broadcast,
- wpabuf_head(auth->req_msg),
- wpabuf_len(auth->req_msg),
- wait_time, wpas_dpp_tx_status, 0);
-}
-
-
-int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos;
- struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
- struct dpp_authentication *auth;
- u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
- unsigned int neg_freq = 0;
- int tcp = 0;
-#ifdef CONFIG_DPP2
- int tcp_port = DPP_TCP_PORT;
- struct hostapd_ip_addr ipaddr;
- char *addr;
-#endif /* CONFIG_DPP2 */
-
- wpa_s->dpp_gas_client = 0;
-
- pos = os_strstr(cmd, " peer=");
- if (!pos)
- return -1;
- pos += 6;
- peer_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!peer_bi) {
- wpa_printf(MSG_INFO,
- "DPP: Could not find bootstrapping info for the identified peer");
- return -1;
- }
-
-#ifdef CONFIG_DPP2
- pos = os_strstr(cmd, " tcp_port=");
- if (pos) {
- pos += 10;
- tcp_port = atoi(pos);
- }
-
- addr = get_param(cmd, " tcp_addr=");
- if (addr) {
- int res;
-
- res = hostapd_parse_ip_addr(addr, &ipaddr);
- os_free(addr);
- if (res)
- return -1;
- tcp = 1;
- }
-#endif /* CONFIG_DPP2 */
-
- pos = os_strstr(cmd, " own=");
- if (pos) {
- pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!own_bi) {
- wpa_printf(MSG_INFO,
- "DPP: Could not find bootstrapping info for the identified local entry");
- return -1;
- }
-
- if (peer_bi->curve != own_bi->curve) {
- wpa_printf(MSG_INFO,
- "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
- peer_bi->curve->name, own_bi->curve->name);
- return -1;
- }
- }
-
- pos = os_strstr(cmd, " role=");
- if (pos) {
- pos += 6;
- if (os_strncmp(pos, "configurator", 12) == 0)
- allowed_roles = DPP_CAPAB_CONFIGURATOR;
- else if (os_strncmp(pos, "enrollee", 8) == 0)
- allowed_roles = DPP_CAPAB_ENROLLEE;
- else if (os_strncmp(pos, "either", 6) == 0)
- allowed_roles = DPP_CAPAB_CONFIGURATOR |
- DPP_CAPAB_ENROLLEE;
- else
- goto fail;
- }
-
- pos = os_strstr(cmd, " netrole=");
- if (pos) {
- pos += 9;
- if (os_strncmp(pos, "ap", 2) == 0)
- wpa_s->dpp_netrole = DPP_NETROLE_AP;
- else if (os_strncmp(pos, "configurator", 12) == 0)
- wpa_s->dpp_netrole = DPP_NETROLE_CONFIGURATOR;
- else
- wpa_s->dpp_netrole = DPP_NETROLE_STA;
- } else {
- wpa_s->dpp_netrole = DPP_NETROLE_STA;
- }
-
- pos = os_strstr(cmd, " neg_freq=");
- if (pos)
- neg_freq = atoi(pos + 10);
-
- if (!tcp && wpa_s->dpp_auth) {
- eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
- NULL);
- eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
- NULL);
-#ifdef CONFIG_DPP2
- eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
- wpa_s, NULL);
-#endif /* CONFIG_DPP2 */
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- }
-
- auth = dpp_auth_init(wpa_s->dpp, wpa_s, peer_bi, own_bi, allowed_roles,
- neg_freq, wpa_s->hw.modes, wpa_s->hw.num_modes);
- if (!auth)
- goto fail;
- wpas_dpp_set_testing_options(wpa_s, auth);
- if (dpp_set_configurator(auth, cmd) < 0) {
- dpp_auth_deinit(auth);
- goto fail;
- }
-
- auth->neg_freq = neg_freq;
-
- if (!is_zero_ether_addr(peer_bi->mac_addr))
- os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
-
-#ifdef CONFIG_DPP2
- if (tcp)
- return dpp_tcp_init(wpa_s->dpp, auth, &ipaddr, tcp_port,
- wpa_s->conf->dpp_name, DPP_NETROLE_STA,
- wpa_s, wpa_s, wpas_dpp_process_conf_obj);
-#endif /* CONFIG_DPP2 */
-
- wpa_s->dpp_auth = auth;
- return wpas_dpp_auth_init_next(wpa_s);
-fail:
- return -1;
-}
-
-
-struct wpas_dpp_listen_work {
- unsigned int freq;
- unsigned int duration;
- struct wpabuf *probe_resp_ie;
-};
-
-
-static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work *lwork)
-{
- if (!lwork)
- return;
- os_free(lwork);
-}
-
-
-static void wpas_dpp_listen_work_done(struct wpa_supplicant *wpa_s)
-{
- struct wpas_dpp_listen_work *lwork;
-
- if (!wpa_s->dpp_listen_work)
- return;
-
- lwork = wpa_s->dpp_listen_work->ctx;
- wpas_dpp_listen_work_free(lwork);
- radio_work_done(wpa_s->dpp_listen_work);
- wpa_s->dpp_listen_work = NULL;
-}
-
-
-static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpas_dpp_listen_work *lwork = work->ctx;
-
- if (deinit) {
- if (work->started) {
- wpa_s->dpp_listen_work = NULL;
- wpas_dpp_listen_stop(wpa_s);
- }
- wpas_dpp_listen_work_free(lwork);
- return;
- }
-
- wpa_s->dpp_listen_work = work;
-
- wpa_s->dpp_pending_listen_freq = lwork->freq;
-
- if (wpa_drv_remain_on_channel(wpa_s, lwork->freq,
- wpa_s->max_remain_on_chan) < 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
- lwork->freq);
- wpa_s->dpp_listen_freq = 0;
- wpas_dpp_listen_work_done(wpa_s);
- wpa_s->dpp_pending_listen_freq = 0;
- return;
- }
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = lwork->freq;
- wpa_drv_dpp_listen(wpa_s, true);
-}
-
-
-static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- struct wpas_dpp_listen_work *lwork;
-
- if (wpa_s->dpp_listen_work) {
- wpa_printf(MSG_DEBUG,
- "DPP: Reject start_listen since dpp_listen_work already exists");
- return -1;
- }
-
- if (wpa_s->dpp_listen_freq)
- wpas_dpp_listen_stop(wpa_s);
- wpa_s->dpp_listen_freq = freq;
-
- lwork = os_zalloc(sizeof(*lwork));
- if (!lwork)
- return -1;
- lwork->freq = freq;
-
- if (radio_add_work(wpa_s, freq, "dpp-listen", 0, dpp_start_listen_cb,
- lwork) < 0) {
- wpas_dpp_listen_work_free(lwork);
- return -1;
- }
-
- return 0;
-}
-
-
-int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- int freq;
-
- freq = atoi(cmd);
- if (freq <= 0)
- return -1;
-
- if (os_strstr(cmd, " role=configurator"))
- wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
- else if (os_strstr(cmd, " role=enrollee"))
- wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
- else
- wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
- DPP_CAPAB_ENROLLEE;
- wpa_s->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
- if (os_strstr(cmd, " netrole=ap"))
- wpa_s->dpp_netrole = DPP_NETROLE_AP;
- else if (os_strstr(cmd, " netrole=configurator"))
- wpa_s->dpp_netrole = DPP_NETROLE_CONFIGURATOR;
- else
- wpa_s->dpp_netrole = DPP_NETROLE_STA;
- if (wpa_s->dpp_listen_freq == (unsigned int) freq) {
- wpa_printf(MSG_DEBUG, "DPP: Already listening on %u MHz",
- freq);
- return 0;
- }
-
- return wpas_dpp_listen_start(wpa_s, freq);
-}
-
-
-void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s)
-{
- wpa_s->dpp_in_response_listen = 0;
- if (!wpa_s->dpp_listen_freq)
- return;
-
- wpa_printf(MSG_DEBUG, "DPP: Stop listen on %u MHz",
- wpa_s->dpp_listen_freq);
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_drv_dpp_listen(wpa_s, false);
- wpa_s->dpp_listen_freq = 0;
- wpas_dpp_listen_work_done(wpa_s);
- radio_remove_works(wpa_s, "dpp-listen", 0);
-}
-
-
-void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration)
-{
- if (wpa_s->dpp_listen_freq != freq)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Remain-on-channel started for listen on %u MHz for %u ms",
- freq, duration);
- os_get_reltime(&wpa_s->dpp_listen_end);
- wpa_s->dpp_listen_end.usec += duration * 1000;
- while (wpa_s->dpp_listen_end.usec >= 1000000) {
- wpa_s->dpp_listen_end.sec++;
- wpa_s->dpp_listen_end.usec -= 1000000;
- }
-}
-
-
-void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- wpas_dpp_listen_work_done(wpa_s);
-
- if (wpa_s->dpp_auth && wpa_s->dpp_in_response_listen) {
- unsigned int new_freq;
-
- /* Continue listen with a new remain-on-channel */
- if (wpa_s->dpp_auth->neg_freq > 0)
- new_freq = wpa_s->dpp_auth->neg_freq;
- else
- new_freq = wpa_s->dpp_auth->curr_freq;
- wpa_printf(MSG_DEBUG,
- "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
- new_freq);
- wpas_dpp_listen_start(wpa_s, new_freq);
- return;
- }
-
- if (wpa_s->dpp_listen_freq) {
- /* Continue listen with a new remain-on-channel */
- wpas_dpp_listen_start(wpa_s, wpa_s->dpp_listen_freq);
- }
-}
-
-
-static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- const u8 *r_bootstrap, *i_bootstrap;
- u16 r_bootstrap_len, i_bootstrap_len;
- struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
-
- if (!wpa_s->dpp)
- return;
-
- wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
- MAC2STR(src));
-
-#ifdef CONFIG_DPP2
- wpas_dpp_chirp_stop(wpa_s);
-#endif /* CONFIG_DPP2 */
-
- r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
- &r_bootstrap_len);
- if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Missing or invalid required Responder Bootstrapping Key Hash attribute");
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
- r_bootstrap, r_bootstrap_len);
-
- i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
- &i_bootstrap_len);
- if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
- i_bootstrap, i_bootstrap_len);
-
- /* Try to find own and peer bootstrapping key matches based on the
- * received hash values */
- dpp_bootstrap_find_pair(wpa_s->dpp, i_bootstrap, r_bootstrap,
- &own_bi, &peer_bi);
- if (!own_bi) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "No matching own bootstrapping key found - ignore message");
- return;
- }
-
- if (wpa_s->dpp_auth) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Already in DPP authentication exchange - ignore new one");
- return;
- }
-
- wpa_s->dpp_gas_client = 0;
- wpa_s->dpp_auth_ok_on_ack = 0;
- wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s->dpp, wpa_s,
- wpa_s->dpp_allowed_roles,
- wpa_s->dpp_qr_mutual,
- peer_bi, own_bi, freq, hdr, buf, len);
- if (!wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG, "DPP: No response generated");
- return;
- }
- wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
- if (dpp_set_configurator(wpa_s->dpp_auth,
- wpa_s->dpp_configurator_params) < 0) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
- os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
-
- if (wpa_s->dpp_listen_freq &&
- wpa_s->dpp_listen_freq != wpa_s->dpp_auth->curr_freq) {
- wpa_printf(MSG_DEBUG,
- "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
- wpa_s->dpp_listen_freq, wpa_s->dpp_auth->curr_freq);
- wpas_dpp_listen_stop(wpa_s);
- }
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), wpa_s->dpp_auth->curr_freq,
- DPP_PA_AUTHENTICATION_RESP);
- offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
- src, wpa_s->own_addr, broadcast,
- wpabuf_head(wpa_s->dpp_auth->resp_msg),
- wpabuf_len(wpa_s->dpp_auth->resp_msg),
- 500, wpas_dpp_tx_status, 0);
-}
-
-
-static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s)
-{
- /* TODO: stop wait and start ROC */
-}
-
-
-static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth,
- struct dpp_config_obj *conf)
-{
- struct wpa_ssid *ssid;
-
-#ifdef CONFIG_DPP2
- if (conf->akm == DPP_AKM_SAE) {
-#ifdef CONFIG_SAE
- struct wpa_driver_capa capa;
- int res;
-
- res = wpa_drv_get_capa(wpa_s, &capa);
- if (res == 0 &&
- !(capa.key_mgmt_iftype[WPA_IF_STATION] &
- WPA_DRIVER_CAPA_KEY_MGMT_SAE) &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
- wpa_printf(MSG_DEBUG,
- "DPP: SAE not supported by the driver");
- return NULL;
- }
-#else /* CONFIG_SAE */
- wpa_printf(MSG_DEBUG, "DPP: SAE not supported in the build");
- return NULL;
-#endif /* CONFIG_SAE */
- }
-#endif /* CONFIG_DPP2 */
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (!ssid)
- return NULL;
- wpas_notify_network_added(wpa_s, ssid);
- wpa_config_set_network_defaults(ssid);
- ssid->disabled = 1;
-
- ssid->ssid = os_malloc(conf->ssid_len);
- if (!ssid->ssid)
- goto fail;
- os_memcpy(ssid->ssid, conf->ssid, conf->ssid_len);
- ssid->ssid_len = conf->ssid_len;
-
- if (conf->connector) {
- if (dpp_akm_dpp(conf->akm)) {
- ssid->key_mgmt = WPA_KEY_MGMT_DPP;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
- }
- ssid->dpp_connector = os_strdup(conf->connector);
- if (!ssid->dpp_connector)
- goto fail;
- }
-
- if (conf->c_sign_key) {
- ssid->dpp_csign = os_malloc(wpabuf_len(conf->c_sign_key));
- if (!ssid->dpp_csign)
- goto fail;
- os_memcpy(ssid->dpp_csign, wpabuf_head(conf->c_sign_key),
- wpabuf_len(conf->c_sign_key));
- ssid->dpp_csign_len = wpabuf_len(conf->c_sign_key);
- }
-
- if (conf->pp_key) {
- ssid->dpp_pp_key = os_malloc(wpabuf_len(conf->pp_key));
- if (!ssid->dpp_pp_key)
- goto fail;
- os_memcpy(ssid->dpp_pp_key, wpabuf_head(conf->pp_key),
- wpabuf_len(conf->pp_key));
- ssid->dpp_pp_key_len = wpabuf_len(conf->pp_key);
- }
-
- if (auth->net_access_key) {
- ssid->dpp_netaccesskey =
- os_malloc(wpabuf_len(auth->net_access_key));
- if (!ssid->dpp_netaccesskey)
- goto fail;
- os_memcpy(ssid->dpp_netaccesskey,
- wpabuf_head(auth->net_access_key),
- wpabuf_len(auth->net_access_key));
- ssid->dpp_netaccesskey_len = wpabuf_len(auth->net_access_key);
- ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
- }
-
- if (!conf->connector || dpp_akm_psk(conf->akm) ||
- dpp_akm_sae(conf->akm)) {
- if (!conf->connector || !dpp_akm_dpp(conf->akm))
- ssid->key_mgmt = 0;
- if (dpp_akm_psk(conf->akm))
- ssid->key_mgmt |= WPA_KEY_MGMT_PSK |
- WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK;
- if (dpp_akm_sae(conf->akm))
- ssid->key_mgmt |= WPA_KEY_MGMT_SAE |
- WPA_KEY_MGMT_FT_SAE;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
- if (conf->passphrase[0]) {
- if (wpa_config_set_quoted(ssid, "psk",
- conf->passphrase) < 0)
- goto fail;
- wpa_config_update_psk(ssid);
- ssid->export_keys = 1;
- } else {
- ssid->psk_set = conf->psk_set;
- os_memcpy(ssid->psk, conf->psk, PMK_LEN);
- }
- }
-
-#if defined(CONFIG_DPP2) && defined(IEEE8021X_EAPOL)
- if (conf->akm == DPP_AKM_DOT1X) {
- int i;
- char name[100], blobname[128];
- struct wpa_config_blob *blob;
-
- ssid->key_mgmt = WPA_KEY_MGMT_IEEE8021X |
- WPA_KEY_MGMT_IEEE8021X_SHA256 |
- WPA_KEY_MGMT_IEEE8021X_SHA256;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
-
- if (conf->cacert) {
- /* caCert is DER-encoded X.509v3 certificate for the
- * server certificate if that is different from the
- * trust root included in certBag. */
- /* TODO: ssid->eap.cert.ca_cert */
- }
-
- if (conf->certs) {
- for (i = 0; ; i++) {
- os_snprintf(name, sizeof(name), "dpp-certs-%d",
- i);
- if (!wpa_config_get_blob(wpa_s->conf, name))
- break;
- }
-
- blob = os_zalloc(sizeof(*blob));
- if (!blob)
- goto fail;
- blob->len = wpabuf_len(conf->certs);
- blob->name = os_strdup(name);
- blob->data = os_malloc(blob->len);
- if (!blob->name || !blob->data) {
- wpa_config_free_blob(blob);
- goto fail;
- }
- os_memcpy(blob->data, wpabuf_head(conf->certs),
- blob->len);
- os_snprintf(blobname, sizeof(blobname), "blob://%s",
- name);
- wpa_config_set_blob(wpa_s->conf, blob);
- wpa_printf(MSG_DEBUG, "DPP: Added certificate blob %s",
- name);
- ssid->eap.cert.client_cert = os_strdup(blobname);
- if (!ssid->eap.cert.client_cert)
- goto fail;
-
- /* TODO: ssid->eap.identity from own certificate */
- if (wpa_config_set(ssid, "identity", "\"dpp-ent\"",
- 0) < 0)
- goto fail;
- }
-
- if (auth->priv_key) {
- for (i = 0; ; i++) {
- os_snprintf(name, sizeof(name), "dpp-key-%d",
- i);
- if (!wpa_config_get_blob(wpa_s->conf, name))
- break;
- }
-
- blob = os_zalloc(sizeof(*blob));
- if (!blob)
- goto fail;
- blob->len = wpabuf_len(auth->priv_key);
- blob->name = os_strdup(name);
- blob->data = os_malloc(blob->len);
- if (!blob->name || !blob->data) {
- wpa_config_free_blob(blob);
- goto fail;
- }
- os_memcpy(blob->data, wpabuf_head(auth->priv_key),
- blob->len);
- os_snprintf(blobname, sizeof(blobname), "blob://%s",
- name);
- wpa_config_set_blob(wpa_s->conf, blob);
- wpa_printf(MSG_DEBUG, "DPP: Added private key blob %s",
- name);
- ssid->eap.cert.private_key = os_strdup(blobname);
- if (!ssid->eap.cert.private_key)
- goto fail;
- }
-
- if (conf->server_name) {
- ssid->eap.cert.domain_suffix_match =
- os_strdup(conf->server_name);
- if (!ssid->eap.cert.domain_suffix_match)
- goto fail;
- }
-
- /* TODO: Use entCreds::eapMethods */
- if (wpa_config_set(ssid, "eap", "TLS", 0) < 0)
- goto fail;
- }
-#endif /* CONFIG_DPP2 && IEEE8021X_EAPOL */
-
- os_memcpy(wpa_s->dpp_last_ssid, conf->ssid, conf->ssid_len);
- wpa_s->dpp_last_ssid_len = conf->ssid_len;
-
- return ssid;
-fail:
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return NULL;
-}
-
-
-static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth,
- struct dpp_config_obj *conf)
-{
- struct wpa_ssid *ssid;
-
- if (wpa_s->conf->dpp_config_processing < 1)
- return 0;
-
- ssid = wpas_dpp_add_network(wpa_s, auth, conf);
- if (!ssid)
- return -1;
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
- if (wpa_s->conf->dpp_config_processing == 2)
- ssid->disabled = 0;
-
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf))
- wpa_printf(MSG_DEBUG, "DPP: Failed to update configuration");
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
- return 0;
-}
-
-
-static void wpas_dpp_post_process_config(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth)
-{
-#ifdef CONFIG_DPP2
- if (auth->reconfig && wpa_s->dpp_reconfig_ssid &&
- wpa_config_get_network(wpa_s->conf, wpa_s->dpp_reconfig_ssid_id) ==
- wpa_s->dpp_reconfig_ssid) {
- wpa_printf(MSG_DEBUG,
- "DPP: Remove reconfigured network profile");
- wpas_notify_network_removed(wpa_s, wpa_s->dpp_reconfig_ssid);
- wpa_config_remove_network(wpa_s->conf,
- wpa_s->dpp_reconfig_ssid_id);
- wpa_s->dpp_reconfig_ssid = NULL;
- wpa_s->dpp_reconfig_ssid_id = -1;
- }
-#endif /* CONFIG_DPP2 */
-
- if (wpa_s->conf->dpp_config_processing < 2)
- return;
-
-#ifdef CONFIG_DPP2
- if (auth->peer_version >= 2) {
- wpa_printf(MSG_DEBUG,
- "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
- auth->connect_on_tx_status = 1;
- return;
- }
-#endif /* CONFIG_DPP2 */
-
- wpas_dpp_try_to_connect(wpa_s);
-}
-
-
-static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth,
- struct dpp_config_obj *conf)
-{
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
- dpp_akm_str(conf->akm));
- if (conf->ssid_len)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
- wpa_ssid_txt(conf->ssid, conf->ssid_len));
- if (conf->ssid_charset)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID_CHARSET "%d",
- conf->ssid_charset);
- if (conf->connector) {
- /* TODO: Save the Connector and consider using a command
- * to fetch the value instead of sending an event with
- * it. The Connector could end up being larger than what
- * most clients are ready to receive as an event
- * message. */
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
- conf->connector);
- }
- if (conf->passphrase[0]) {
- char hex[64 * 2 + 1];
-
- wpa_snprintf_hex(hex, sizeof(hex),
- (const u8 *) conf->passphrase,
- os_strlen(conf->passphrase));
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
- hex);
- } else if (conf->psk_set) {
- char hex[PMK_LEN * 2 + 1];
-
- wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
- hex);
- }
- if (conf->c_sign_key) {
- char *hex;
- size_t hexlen;
-
- hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
- hex = os_malloc(hexlen);
- if (hex) {
- wpa_snprintf_hex(hex, hexlen,
- wpabuf_head(conf->c_sign_key),
- wpabuf_len(conf->c_sign_key));
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s",
- hex);
- os_free(hex);
- }
- }
- if (conf->pp_key) {
- char *hex;
- size_t hexlen;
-
- hexlen = 2 * wpabuf_len(conf->pp_key) + 1;
- hex = os_malloc(hexlen);
- if (hex) {
- wpa_snprintf_hex(hex, hexlen,
- wpabuf_head(conf->pp_key),
- wpabuf_len(conf->pp_key));
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PP_KEY "%s", hex);
- os_free(hex);
- }
- }
- if (auth->net_access_key) {
- char *hex;
- size_t hexlen;
-
- hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
- hex = os_malloc(hexlen);
- if (hex) {
- wpa_snprintf_hex(hex, hexlen,
- wpabuf_head(auth->net_access_key),
- wpabuf_len(auth->net_access_key));
- if (auth->net_access_key_expiry)
- wpa_msg(wpa_s, MSG_INFO,
- DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
- (long unsigned)
- auth->net_access_key_expiry);
- else
- wpa_msg(wpa_s, MSG_INFO,
- DPP_EVENT_NET_ACCESS_KEY "%s", hex);
- os_free(hex);
- }
- }
-
-#ifdef CONFIG_DPP2
- if (conf->certbag) {
- char *b64;
-
- b64 = base64_encode_no_lf(wpabuf_head(conf->certbag),
- wpabuf_len(conf->certbag), NULL);
- if (b64)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CERTBAG "%s", b64);
- os_free(b64);
- }
-
- if (conf->cacert) {
- char *b64;
-
- b64 = base64_encode_no_lf(wpabuf_head(conf->cacert),
- wpabuf_len(conf->cacert), NULL);
- if (b64)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CACERT "%s", b64);
- os_free(b64);
- }
-
- if (conf->server_name)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_SERVER_NAME "%s",
- conf->server_name);
-#endif /* CONFIG_DPP2 */
-
- return wpas_dpp_process_config(wpa_s, auth, conf);
-}
-
-
-static int wpas_dpp_handle_key_pkg(struct wpa_supplicant *wpa_s,
- struct dpp_asymmetric_key *key)
-{
-#ifdef CONFIG_DPP2
- int res;
-
- if (!key)
- return 0;
-
- wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
- wpa_s->dpp_conf_backup_received = true;
-
- while (key) {
- res = dpp_configurator_from_backup(wpa_s->dpp, key);
- if (res < 0)
- return -1;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
- res);
- key = key->next;
- }
-#endif /* CONFIG_DPP2 */
-
- return 0;
-}
-
-
-#ifdef CONFIG_DPP2
-static void wpas_dpp_build_csr(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth || !auth->csrattrs)
- return;
-
- wpa_printf(MSG_DEBUG, "DPP: Build CSR");
- wpabuf_free(auth->csr);
- /* TODO: Additional information needed for CSR based on csrAttrs */
- auth->csr = dpp_build_csr(auth, wpa_s->conf->dpp_name ?
- wpa_s->conf->dpp_name : "Test");
- if (!auth->csr) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
-
- wpas_dpp_start_gas_client(wpa_s);
-}
-#endif /* CONFIG_DPP2 */
-
-
-static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const u8 *pos;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- int res;
- enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
- unsigned int i;
-
- wpa_s->dpp_gas_dialog_token = -1;
-
- if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
- os_memcmp(addr, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
- return;
- }
- if (result != GAS_QUERY_SUCCESS ||
- !resp || status_code != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
- goto fail;
- }
-
- wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
- adv_proto);
- wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
- resp);
-
- if (wpabuf_len(adv_proto) != 10 ||
- !(pos = wpabuf_head(adv_proto)) ||
- pos[0] != WLAN_EID_ADV_PROTO ||
- pos[1] != 8 ||
- pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
- pos[4] != 5 ||
- WPA_GET_BE24(&pos[5]) != OUI_WFA ||
- pos[8] != 0x1a ||
- pos[9] != 1) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not a DPP Advertisement Protocol ID");
- goto fail;
- }
-
- res = dpp_conf_resp_rx(auth, resp);
-#ifdef CONFIG_DPP2
- if (res == -2) {
- wpa_printf(MSG_DEBUG, "DPP: CSR needed");
- eloop_register_timeout(0, 0, wpas_dpp_build_csr, wpa_s, NULL);
- return;
- }
-#endif /* CONFIG_DPP2 */
- if (res < 0) {
- wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
- goto fail;
- }
-
- wpa_s->dpp_conf_backup_received = false;
- for (i = 0; i < auth->num_conf_obj; i++) {
- res = wpas_dpp_handle_config_obj(wpa_s, auth,
- &auth->conf_obj[i]);
- if (res < 0)
- goto fail;
- }
- if (auth->num_conf_obj)
- wpas_dpp_post_process_config(wpa_s, auth);
- if (wpas_dpp_handle_key_pkg(wpa_s, auth->conf_key_pkg) < 0)
- goto fail;
-
- status = DPP_STATUS_OK;
-#ifdef CONFIG_TESTING_OPTIONS
- if (dpp_test == DPP_TEST_REJECT_CONFIG) {
- wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
- status = DPP_STATUS_CONFIG_REJECTED;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-fail:
- if (status != DPP_STATUS_OK)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
-#ifdef CONFIG_DPP2
- if (auth->peer_version >= 2 &&
- auth->conf_resp_status == DPP_STATUS_OK) {
- struct wpabuf *msg;
-
- wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
- msg = dpp_build_conf_result(auth, status);
- if (!msg)
- goto fail2;
-
- wpa_msg(wpa_s, MSG_INFO,
- DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(addr), auth->curr_freq,
- DPP_PA_CONFIGURATION_RESULT);
- offchannel_send_action(wpa_s, auth->curr_freq,
- addr, wpa_s->own_addr, broadcast,
- wpabuf_head(msg),
- wpabuf_len(msg),
- 500, wpas_dpp_tx_status, 0);
- wpabuf_free(msg);
-
- /* This exchange will be terminated in the TX status handler */
- if (wpa_s->conf->dpp_config_processing < 2 ||
- wpa_s->dpp_conf_backup_received)
- auth->remove_on_tx_status = 1;
- return;
- }
-fail2:
-#endif /* CONFIG_DPP2 */
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
-}
-
-
-static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- struct wpabuf *buf;
- int res;
- int *supp_op_classes;
-
- wpa_s->dpp_gas_client = 1;
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
-
- supp_op_classes = wpas_supp_op_classes(wpa_s);
- buf = dpp_build_conf_req_helper(auth, wpa_s->conf->dpp_name,
- wpa_s->dpp_netrole,
- wpa_s->conf->dpp_mud_url,
- supp_op_classes);
- os_free(supp_op_classes);
- if (!buf) {
- wpa_printf(MSG_DEBUG,
- "DPP: No configuration request data available");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
- MAC2STR(auth->peer_mac_addr), auth->curr_freq);
-
- res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq,
- 1, 1, buf, wpas_dpp_gas_resp_cb, wpa_s);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
- wpabuf_free(buf);
- } else {
- wpa_printf(MSG_DEBUG,
- "DPP: GAS query started with dialog token %u", res);
- wpa_s->dpp_gas_dialog_token = res;
- }
-}
-
-
-static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator)
-{
- wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", initiator);
-#ifdef CONFIG_TESTING_OPTIONS
- if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
- wpa_printf(MSG_INFO,
- "DPP: TESTING - stop at Authentication Confirm");
- if (wpa_s->dpp_auth->configurator) {
- /* Prevent GAS response */
- wpa_s->dpp_auth->auth_success = 0;
- }
- return;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->dpp_auth->configurator)
- wpas_dpp_start_gas_server(wpa_s);
- else
- wpas_dpp_start_gas_client(wpa_s);
-}
-
-
-static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- struct wpabuf *msg;
-
- wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR
- " (freq %u MHz)", MAC2STR(src), freq);
-
- if (!auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Authentication in progress - drop");
- return;
- }
-
- if (!is_zero_ether_addr(auth->peer_mac_addr) &&
- os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
- MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
- return;
- }
-
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
-
- if (auth->curr_freq != freq && auth->neg_freq == freq) {
- wpa_printf(MSG_DEBUG,
- "DPP: Responder accepted request for different negotiation channel");
- auth->curr_freq = freq;
- }
-
- eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
- msg = dpp_auth_resp_rx(auth, hdr, buf, len);
- if (!msg) {
- if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
- wpa_printf(MSG_DEBUG,
- "DPP: Start wait for full response");
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_start(wpa_s, auth->curr_freq);
- return;
- }
- wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
- return;
- }
- os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), auth->curr_freq, DPP_PA_AUTHENTICATION_CONF);
- offchannel_send_action(wpa_s, auth->curr_freq,
- src, wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- 500, wpas_dpp_tx_status, 0);
- wpabuf_free(msg);
- wpa_s->dpp_auth_ok_on_ack = 1;
-}
-
-
-static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
- MAC2STR(src));
-
- if (!auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Authentication in progress - drop");
- return;
- }
-
- if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
- MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
- return;
- }
-
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
-
- if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
- wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
- return;
- }
-
- wpas_dpp_auth_success(wpa_s, 0);
-}
-
-
-#ifdef CONFIG_DPP2
-
-static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth || !auth->waiting_conf_result)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Timeout while waiting for Configuration Result");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
-}
-
-
-static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth || !auth->waiting_conn_status_result)
- return;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Timeout while waiting for Connection Status Result");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT "timeout");
- wpas_dpp_listen_stop(wpa_s);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
-}
-
-
-static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- enum dpp_status_error status;
-
- wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
- MAC2STR(src));
-
- if (!auth || !auth->waiting_conf_result) {
- if (auth &&
- os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) == 0 &&
- gas_server_response_sent(wpa_s->gas_server,
- auth->gas_server_ctx)) {
- /* This could happen if the TX status event gets delayed
- * long enough for the Enrollee to have time to send
- * the next frame before the TX status gets processed
- * locally. */
- wpa_printf(MSG_DEBUG,
- "DPP: GAS response was sent but TX status not yet received - assume it was ACKed since the Enrollee sent the next frame in the sequence");
- auth->waiting_conf_result = 1;
- } else {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Configuration waiting for result - drop");
- return;
- }
- }
-
- if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
- MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
- return;
- }
-
- status = dpp_conf_result_rx(auth, hdr, buf, len);
-
- if (status == DPP_STATUS_OK && auth->send_conn_status) {
- wpa_msg(wpa_s, MSG_INFO,
- DPP_EVENT_CONF_SENT "wait_conn_status=1");
- wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
- eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
- wpa_s, NULL);
- auth->waiting_conn_status_result = 1;
- eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
- wpa_s, NULL);
- eloop_register_timeout(16, 0,
- wpas_dpp_conn_status_result_wait_timeout,
- wpa_s, NULL);
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_start(wpa_s, auth->neg_freq ? auth->neg_freq :
- auth->curr_freq);
- return;
- }
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- if (status == DPP_STATUS_OK)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
- else
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
- eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
-}
-
-
-static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *hdr,
- const u8 *buf, size_t len)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- enum dpp_status_error status;
- u8 ssid[SSID_MAX_LEN];
- size_t ssid_len = 0;
- char *channel_list = NULL;
-
- wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
-
- if (!auth || !auth->waiting_conn_status_result) {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Configuration waiting for connection status result - drop");
- return;
- }
-
- status = dpp_conn_status_result_rx(auth, hdr, buf, len,
- ssid, &ssid_len, &channel_list);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
- "result=%d ssid=%s channel_list=%s",
- status, wpa_ssid_txt(ssid, ssid_len),
- channel_list ? channel_list : "N/A");
- os_free(channel_list);
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
- eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
- wpa_s, NULL);
-}
-
-
-static int wpas_dpp_process_conf_obj(void *ctx,
- struct dpp_authentication *auth)
-{
- struct wpa_supplicant *wpa_s = ctx;
- unsigned int i;
- int res = -1;
-
- for (i = 0; i < auth->num_conf_obj; i++) {
- res = wpas_dpp_handle_config_obj(wpa_s, auth,
- &auth->conf_obj[i]);
- if (res)
- break;
- }
- if (!res)
- wpas_dpp_post_process_config(wpa_s, auth);
-
- return res;
-}
-
-
-static void wpas_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (bi == wpa_s->dpp_chirp_bi)
- wpas_dpp_chirp_stop(wpa_s);
-}
-
-
-static void
-wpas_dpp_rx_presence_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- const u8 *r_bootstrap;
- u16 r_bootstrap_len;
- struct dpp_bootstrap_info *peer_bi;
- struct dpp_authentication *auth;
-
- if (!wpa_s->dpp)
- return;
-
- if (wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore Presence Announcement during ongoing Authentication");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
- MAC2STR(src));
-
- r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
- &r_bootstrap_len);
- if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Missing or invalid required Responder Bootstrapping Key Hash attribute");
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
- r_bootstrap, r_bootstrap_len);
- peer_bi = dpp_bootstrap_find_chirp(wpa_s->dpp, r_bootstrap);
- dpp_notify_chirp_received(wpa_s, peer_bi ? (int) peer_bi->id : -1, src,
- freq, r_bootstrap);
- if (!peer_bi) {
- wpa_printf(MSG_DEBUG,
- "DPP: No matching bootstrapping information found");
- return;
- }
-
- auth = dpp_auth_init(wpa_s->dpp, wpa_s, peer_bi, NULL,
- DPP_CAPAB_CONFIGURATOR, freq, NULL, 0);
- if (!auth)
- return;
- wpas_dpp_set_testing_options(wpa_s, auth);
- if (dpp_set_configurator(auth, wpa_s->dpp_configurator_params) < 0) {
- dpp_auth_deinit(auth);
- return;
- }
-
- auth->neg_freq = freq;
-
- /* The source address of the Presence Announcement frame overrides any
- * MAC address information from the bootstrapping information. */
- os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
-
- wpa_s->dpp_auth = auth;
- if (wpas_dpp_auth_init_next(wpa_s) < 0) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- }
-}
-
-
-static void wpas_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth)
- return;
-
- wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- dpp_auth_deinit(auth);
- wpa_s->dpp_auth = NULL;
-}
-
-
-static void
-wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
- u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
- struct dpp_configurator *conf;
- struct dpp_authentication *auth;
- unsigned int wait_time, max_wait_time;
- u16 group;
-
- if (!wpa_s->dpp)
- return;
-
- if (wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore Reconfig Announcement during ongoing Authentication");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR,
- MAC2STR(src));
-
- csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
- &csign_hash_len);
- if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Missing or invalid required Configurator C-sign key Hash attribute");
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
- csign_hash, csign_hash_len);
- conf = dpp_configurator_find_kid(wpa_s->dpp, csign_hash);
- if (!conf) {
- wpa_printf(MSG_DEBUG,
- "DPP: No matching Configurator information found");
- return;
- }
-
- fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
- &fcgroup_len);
- if (!fcgroup || fcgroup_len != 2) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "Missing or invalid required Finite Cyclic Group attribute");
- return;
- }
- group = WPA_GET_LE16(fcgroup);
- wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
-
- a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
- e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
-
- auth = dpp_reconfig_init(wpa_s->dpp, wpa_s, conf, freq, group,
- a_nonce, a_nonce_len, e_id, e_id_len);
- if (!auth)
- return;
- wpas_dpp_set_testing_options(wpa_s, auth);
- if (dpp_set_configurator(auth, wpa_s->dpp_configurator_params) < 0) {
- dpp_auth_deinit(auth);
- return;
- }
-
- os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
- wpa_s->dpp_auth = auth;
-
- wpa_s->dpp_in_response_listen = 0;
- wpa_s->dpp_auth_ok_on_ack = 0;
- wait_time = wpa_s->max_remain_on_chan;
- max_wait_time = wpa_s->dpp_resp_wait_time ?
- wpa_s->dpp_resp_wait_time : 2000;
- if (wait_time > max_wait_time)
- wait_time = max_wait_time;
- wait_time += 10; /* give the driver some extra time to complete */
- eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
- wpas_dpp_reconfig_reply_wait_timeout,
- wpa_s, NULL);
- wait_time -= 10;
-
- wpas_dpp_stop_listen_for_tx(wpa_s, freq, wait_time);
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
- if (offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
- wpabuf_head(auth->reconfig_req_msg),
- wpabuf_len(auth->reconfig_req_msg),
- wait_time, wpas_dpp_tx_status, 0) < 0) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- }
-}
-
-
-static void
-wpas_dpp_rx_reconfig_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct wpa_ssid *ssid;
- struct dpp_authentication *auth;
-
- wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Request from "
- MACSTR, MAC2STR(src));
-
- if (!wpa_s->dpp)
- return;
- if (wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not ready for reconfiguration - pending authentication exchange in progress");
- return;
- }
- if (!wpa_s->dpp_reconfig_ssid) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not ready for reconfiguration - not requested");
- return;
- }
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid == wpa_s->dpp_reconfig_ssid &&
- ssid->id == wpa_s->dpp_reconfig_ssid_id)
- break;
- }
- if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey ||
- !ssid->dpp_csign) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not ready for reconfiguration - no matching network profile with Connector found");
- return;
- }
-
- auth = dpp_reconfig_auth_req_rx(wpa_s->dpp, wpa_s, ssid->dpp_connector,
- ssid->dpp_netaccesskey,
- ssid->dpp_netaccesskey_len,
- ssid->dpp_csign, ssid->dpp_csign_len,
- freq, hdr, buf, len);
- if (!auth)
- return;
- os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
- wpa_s->dpp_auth = auth;
-
- wpas_dpp_chirp_stop(wpa_s);
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_RESP);
- if (offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
- wpabuf_head(auth->reconfig_resp_msg),
- wpabuf_len(auth->reconfig_resp_msg),
- 500, wpas_dpp_tx_status, 0) < 0) {
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- }
-}
-
-
-static void
-wpas_dpp_rx_reconfig_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- struct wpabuf *conf;
-
- wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
- MACSTR, MAC2STR(src));
-
- if (!auth || !auth->reconfig || !auth->configurator) {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Reconfig Authentication in progress - drop");
- return;
- }
-
- if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
- MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
- return;
- }
-
- conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
- if (!conf)
- return;
-
- eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout, wpa_s, NULL);
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
- if (offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
- wpabuf_head(conf), wpabuf_len(conf),
- 500, wpas_dpp_tx_status, 0) < 0) {
- wpabuf_free(conf);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- return;
- }
- wpabuf_free(conf);
-
- wpas_dpp_start_gas_server(wpa_s);
-}
-
-
-static void
-wpas_dpp_rx_reconfig_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Confirm from "
- MACSTR, MAC2STR(src));
-
- if (!auth || !auth->reconfig || auth->configurator) {
- wpa_printf(MSG_DEBUG,
- "DPP: No DPP Reconfig Authentication in progress - drop");
- return;
- }
-
- if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
- MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
- return;
- }
-
- if (dpp_reconfig_auth_conf_rx(auth, hdr, buf, len) < 0)
- return;
-
- wpas_dpp_start_gas_client(wpa_s);
-}
-
-#endif /* CONFIG_DPP2 */
-
-
-static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
- const u8 *src,
- const u8 *buf, size_t len)
-{
- struct wpa_ssid *ssid;
- const u8 *connector, *trans_id, *status;
- u16 connector_len, trans_id_len, status_len;
-#ifdef CONFIG_DPP2
- const u8 *version;
- u16 version_len;
-#endif /* CONFIG_DPP2 */
- u8 peer_version = 1;
- struct dpp_introduction intro;
- struct rsn_pmksa_cache_entry *entry;
- struct os_time now;
- struct os_reltime rnow;
- os_time_t expiry;
- unsigned int seconds;
- enum dpp_status_error res;
-
- wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response from " MACSTR,
- MAC2STR(src));
- if (is_zero_ether_addr(wpa_s->dpp_intro_bssid) ||
- os_memcmp(src, wpa_s->dpp_intro_bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: Not waiting for response from "
- MACSTR " - drop", MAC2STR(src));
- return;
- }
- offchannel_send_action_done(wpa_s);
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid == wpa_s->dpp_intro_network)
- break;
- }
- if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey ||
- !ssid->dpp_csign) {
- wpa_printf(MSG_DEBUG,
- "DPP: Profile not found for network introduction");
- return;
- }
-
- trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
- &trans_id_len);
- if (!trans_id || trans_id_len != 1) {
- wpa_printf(MSG_DEBUG,
- "DPP: Peer did not include Transaction ID");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " fail=missing_transaction_id", MAC2STR(src));
- goto fail;
- }
- if (trans_id[0] != TRANSACTION_ID) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore frame with unexpected Transaction ID %u",
- trans_id[0]);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " fail=transaction_id_mismatch", MAC2STR(src));
- goto fail;
- }
-
- status = dpp_get_attr(buf, len, DPP_ATTR_STATUS, &status_len);
- if (!status || status_len != 1) {
- wpa_printf(MSG_DEBUG, "DPP: Peer did not include Status");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " fail=missing_status", MAC2STR(src));
- goto fail;
- }
- if (status[0] != DPP_STATUS_OK) {
- wpa_printf(MSG_DEBUG,
- "DPP: Peer rejected network introduction: Status %u",
- status[0]);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " status=%u", MAC2STR(src), status[0]);
-#ifdef CONFIG_DPP2
- wpas_dpp_send_conn_status_result(wpa_s, status[0]);
-#endif /* CONFIG_DPP2 */
- goto fail;
- }
-
- connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
- if (!connector) {
- wpa_printf(MSG_DEBUG,
- "DPP: Peer did not include its Connector");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " fail=missing_connector", MAC2STR(src));
- goto fail;
- }
-
- res = dpp_peer_intro(&intro, ssid->dpp_connector,
- ssid->dpp_netaccesskey,
- ssid->dpp_netaccesskey_len,
- ssid->dpp_csign,
- ssid->dpp_csign_len,
- connector, connector_len, &expiry);
- if (res != DPP_STATUS_OK) {
- wpa_printf(MSG_INFO,
- "DPP: Network Introduction protocol resulted in failure");
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " fail=peer_connector_validation_failed", MAC2STR(src));
-#ifdef CONFIG_DPP2
- wpas_dpp_send_conn_status_result(wpa_s, res);
-#endif /* CONFIG_DPP2 */
- goto fail;
- }
-
- entry = os_zalloc(sizeof(*entry));
- if (!entry)
- goto fail;
- os_memcpy(entry->aa, src, ETH_ALEN);
- os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN);
- os_memcpy(entry->pmk, intro.pmk, intro.pmk_len);
- entry->pmk_len = intro.pmk_len;
- entry->akmp = WPA_KEY_MGMT_DPP;
-#ifdef CONFIG_DPP2
- version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
- &version_len);
- if (version && version_len >= 1)
- peer_version = version[0];
-#ifdef CONFIG_DPP3
- if (intro.peer_version && intro.peer_version >= 2 &&
- peer_version != intro.peer_version) {
- wpa_printf(MSG_INFO,
- "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
- intro.peer_version, peer_version);
- wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_NO_MATCH);
- goto fail;
- }
-#endif /* CONFIG_DPP3 */
- entry->dpp_pfs = peer_version >= 2;
-#endif /* CONFIG_DPP2 */
- if (expiry) {
- os_get_time(&now);
- seconds = expiry - now.sec;
- } else {
- seconds = 86400 * 7;
- }
- os_get_reltime(&rnow);
- entry->expiration = rnow.sec + seconds;
- entry->reauth_time = rnow.sec + seconds;
- entry->network_ctx = ssid;
- wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
-
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
- " status=%u version=%u", MAC2STR(src), status[0], peer_version);
-
- wpa_printf(MSG_DEBUG,
- "DPP: Try connection again after successful network introduction");
- if (wpa_supplicant_fast_associate(wpa_s) != 1) {
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-fail:
- os_memset(&intro, 0, sizeof(intro));
-}
-
-
-static int wpas_dpp_allow_ir(struct wpa_supplicant *wpa_s, unsigned int freq)
-{
- int i, j;
-
- if (!wpa_s->hw.modes)
- return -1;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
-
- for (j = 0; j < mode->num_channels; j++) {
- struct hostapd_channel_data *chan = &mode->channels[j];
-
- if (chan->freq != (int) freq)
- continue;
-
- if (chan->flag & (HOSTAPD_CHAN_DISABLED |
- HOSTAPD_CHAN_NO_IR |
- HOSTAPD_CHAN_RADAR))
- continue;
-
- return 1;
- }
- }
-
- wpa_printf(MSG_DEBUG,
- "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
- freq);
-
- return 0;
-}
-
-
-static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
- struct dpp_pkex *pkex)
-{
- if (pkex->freq == 2437)
- pkex->freq = 5745;
- else if (pkex->freq == 5745)
- pkex->freq = 5220;
- else if (pkex->freq == 5220)
- pkex->freq = 60480;
- else
- return -1; /* no more channels to try */
-
- if (wpas_dpp_allow_ir(wpa_s, pkex->freq) == 1) {
- wpa_printf(MSG_DEBUG, "DPP: Try to initiate on %u MHz",
- pkex->freq);
- return 0;
- }
-
- /* Could not use this channel - try the next one */
- return wpas_dpp_pkex_next_channel(wpa_s, pkex);
-}
-
-
-static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct dpp_pkex *pkex = wpa_s->dpp_pkex;
-
- if (!pkex || !pkex->exchange_req)
- return;
- if (pkex->exch_req_tries >= 5) {
- if (wpas_dpp_pkex_next_channel(wpa_s, pkex) < 0) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
- "No response from PKEX peer");
- dpp_pkex_free(pkex);
- wpa_s->dpp_pkex = NULL;
- return;
- }
- pkex->exch_req_tries = 0;
- }
-
- pkex->exch_req_tries++;
- wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
- pkex->exch_req_tries);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(broadcast), pkex->freq,
- pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
- DPP_PA_PKEX_V1_EXCHANGE_REQ);
- offchannel_send_action(wpa_s, pkex->freq, broadcast,
- wpa_s->own_addr, broadcast,
- wpabuf_head(pkex->exchange_req),
- wpabuf_len(pkex->exchange_req),
- pkex->exch_req_wait_time,
- wpas_dpp_tx_pkex_status, 0);
-}
-
-
-static void
-wpas_dpp_tx_pkex_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- const char *res_txt;
- struct dpp_pkex *pkex = wpa_s->dpp_pkex;
-
- res_txt = result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
- (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
- "FAILED");
- wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
- " result=%s (PKEX)",
- freq, MAC2STR(dst), res_txt);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
- " freq=%u result=%s", MAC2STR(dst), freq, res_txt);
-
- if (!pkex) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore TX status since there is no ongoing PKEX exchange");
- return;
- }
-
- if (pkex->failed) {
- wpa_printf(MSG_DEBUG,
- "DPP: Terminate PKEX exchange due to an earlier error");
- if (pkex->t > pkex->own_bi->pkex_t)
- pkex->own_bi->pkex_t = pkex->t;
- dpp_pkex_free(pkex);
- wpa_s->dpp_pkex = NULL;
- return;
- }
-
- if (pkex->exch_req_wait_time && pkex->exchange_req) {
- /* Wait for PKEX Exchange Response frame and retry request if
- * no response is seen. */
- eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
- eloop_register_timeout(pkex->exch_req_wait_time / 1000,
- (pkex->exch_req_wait_time % 1000) * 1000,
- wpas_dpp_pkex_retry_timeout, wpa_s,
- NULL);
- }
-}
-
-
-static void
-wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *buf, size_t len, unsigned int freq,
- bool v2)
-{
- struct wpabuf *msg;
- unsigned int wait_time;
-
- wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
- MAC2STR(src));
-
- /* TODO: Support multiple PKEX codes by iterating over all the enabled
- * values here */
-
- if (!wpa_s->dpp_pkex_code || !wpa_s->dpp_pkex_bi) {
- wpa_printf(MSG_DEBUG,
- "DPP: No PKEX code configured - ignore request");
- return;
- }
-
- if (wpa_s->dpp_pkex) {
- /* TODO: Support parallel operations */
- wpa_printf(MSG_DEBUG,
- "DPP: Already in PKEX session - ignore new request");
- return;
- }
-
- wpa_s->dpp_pkex = dpp_pkex_rx_exchange_req(wpa_s, wpa_s->dpp_pkex_bi,
- wpa_s->own_addr, src,
- wpa_s->dpp_pkex_identifier,
- wpa_s->dpp_pkex_code,
- buf, len, v2);
- if (!wpa_s->dpp_pkex) {
- wpa_printf(MSG_DEBUG,
- "DPP: Failed to process the request - ignore it");
- return;
- }
-
- msg = wpa_s->dpp_pkex->exchange_resp;
- wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_PKEX_EXCHANGE_RESP);
- offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
- broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- wait_time, wpas_dpp_tx_pkex_status, 0);
-}
-
-
-static void
-wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *buf, size_t len, unsigned int freq)
-{
- struct wpabuf *msg;
- unsigned int wait_time;
-
- wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
- MAC2STR(src));
-
- /* TODO: Support multiple PKEX codes by iterating over all the enabled
- * values here */
-
- if (!wpa_s->dpp_pkex || !wpa_s->dpp_pkex->initiator ||
- wpa_s->dpp_pkex->exchange_done) {
- wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
- return;
- }
-
- eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
- wpa_s->dpp_pkex->exch_req_wait_time = 0;
-
- msg = dpp_pkex_rx_exchange_resp(wpa_s->dpp_pkex, src, buf, len);
- if (!msg) {
- wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
- MAC2STR(src));
-
- wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_PKEX_COMMIT_REVEAL_REQ);
- offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
- broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- wait_time, wpas_dpp_tx_pkex_status, 0);
- wpabuf_free(msg);
-}
-
-
-static struct dpp_bootstrap_info *
-wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
- unsigned int freq)
-{
- struct dpp_bootstrap_info *bi;
-
- bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
- if (!bi)
- return NULL;
- wpa_s->dpp_pkex = NULL;
- return bi;
-}
-
-
-static void
-wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct wpabuf *msg;
- unsigned int wait_time;
- struct dpp_pkex *pkex = wpa_s->dpp_pkex;
-
- wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
- MAC2STR(src));
-
- if (!pkex || pkex->initiator || !pkex->exchange_done) {
- wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
- return;
- }
-
- msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
- if (!msg) {
- wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
- if (pkex->failed) {
- wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
- if (pkex->t > pkex->own_bi->pkex_t)
- pkex->own_bi->pkex_t = pkex->t;
- dpp_pkex_free(wpa_s->dpp_pkex);
- wpa_s->dpp_pkex = NULL;
- }
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
- MACSTR, MAC2STR(src));
-
- wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, DPP_PA_PKEX_COMMIT_REVEAL_RESP);
- offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
- broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- wait_time, wpas_dpp_tx_pkex_status, 0);
- wpabuf_free(msg);
-
- wpas_dpp_pkex_finish(wpa_s, src, freq);
-}
-
-
-static void
-wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *hdr, const u8 *buf, size_t len,
- unsigned int freq)
-{
- int res;
- struct dpp_bootstrap_info *bi;
- struct dpp_pkex *pkex = wpa_s->dpp_pkex;
- char cmd[500];
-
- wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
- MAC2STR(src));
-
- if (!pkex || !pkex->initiator || !pkex->exchange_done) {
- wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
- return;
- }
-
- res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
- if (res < 0) {
- wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
- return;
- }
-
- bi = wpas_dpp_pkex_finish(wpa_s, src, freq);
- if (!bi)
- return;
-
- os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
- bi->id,
- wpa_s->dpp_pkex_auth_cmd ? wpa_s->dpp_pkex_auth_cmd : "");
- wpa_printf(MSG_DEBUG,
- "DPP: Start authentication after PKEX with parameters: %s",
- cmd);
- if (wpas_dpp_auth_init(wpa_s, cmd) < 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Authentication initialization failed");
- offchannel_send_action_done(wpa_s);
- return;
- }
-}
-
-
-void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *buf, size_t len, unsigned int freq)
-{
- u8 crypto_suite;
- enum dpp_public_action_frame_type type;
- const u8 *hdr;
- unsigned int pkex_t;
-
- if (len < DPP_HDR_LEN)
- return;
- if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
- return;
- hdr = buf;
- buf += 4;
- len -= 4;
- crypto_suite = *buf++;
- type = *buf++;
- len -= 2;
-
- wpa_printf(MSG_DEBUG,
- "DPP: Received DPP Public Action frame crypto suite %u type %d from "
- MACSTR " freq=%u",
- crypto_suite, type, MAC2STR(src), freq);
- if (crypto_suite != 1) {
- wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
- crypto_suite);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
- " freq=%u type=%d ignore=unsupported-crypto-suite",
- MAC2STR(src), freq, type);
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
- if (dpp_check_attrs(buf, len) < 0) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
- " freq=%u type=%d ignore=invalid-attributes",
- MAC2STR(src), freq, type);
- return;
- }
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_RX "src=" MACSTR " freq=%u type=%d",
- MAC2STR(src), freq, type);
-
- switch (type) {
- case DPP_PA_AUTHENTICATION_REQ:
- wpas_dpp_rx_auth_req(wpa_s, src, hdr, buf, len, freq);
- break;
- case DPP_PA_AUTHENTICATION_RESP:
- wpas_dpp_rx_auth_resp(wpa_s, src, hdr, buf, len, freq);
- break;
- case DPP_PA_AUTHENTICATION_CONF:
- wpas_dpp_rx_auth_conf(wpa_s, src, hdr, buf, len);
- break;
- case DPP_PA_PEER_DISCOVERY_RESP:
- wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
- break;
-#ifdef CONFIG_DPP3
- case DPP_PA_PKEX_EXCHANGE_REQ:
- /* This is for PKEXv2, but for now, process only with
- * CONFIG_DPP3 to avoid issues with a capability that has not
- * been tested with other implementations. */
- wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq, true);
- break;
-#endif /* CONFIG_DPP3 */
- case DPP_PA_PKEX_V1_EXCHANGE_REQ:
- wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq,
- false);
- break;
- case DPP_PA_PKEX_EXCHANGE_RESP:
- wpas_dpp_rx_pkex_exchange_resp(wpa_s, src, buf, len, freq);
- break;
- case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
- wpas_dpp_rx_pkex_commit_reveal_req(wpa_s, src, hdr, buf, len,
- freq);
- break;
- case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
- wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s, src, hdr, buf, len,
- freq);
- break;
-#ifdef CONFIG_DPP2
- case DPP_PA_CONFIGURATION_RESULT:
- wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len);
- break;
- case DPP_PA_CONNECTION_STATUS_RESULT:
- wpas_dpp_rx_conn_status_result(wpa_s, src, hdr, buf, len);
- break;
- case DPP_PA_PRESENCE_ANNOUNCEMENT:
- wpas_dpp_rx_presence_announcement(wpa_s, src, hdr, buf, len,
- freq);
- break;
- case DPP_PA_RECONFIG_ANNOUNCEMENT:
- wpas_dpp_rx_reconfig_announcement(wpa_s, src, hdr, buf, len,
- freq);
- break;
- case DPP_PA_RECONFIG_AUTH_REQ:
- wpas_dpp_rx_reconfig_auth_req(wpa_s, src, hdr, buf, len, freq);
- break;
- case DPP_PA_RECONFIG_AUTH_RESP:
- wpas_dpp_rx_reconfig_auth_resp(wpa_s, src, hdr, buf, len, freq);
- break;
- case DPP_PA_RECONFIG_AUTH_CONF:
- wpas_dpp_rx_reconfig_auth_conf(wpa_s, src, hdr, buf, len, freq);
- break;
-#endif /* CONFIG_DPP2 */
- default:
- wpa_printf(MSG_DEBUG,
- "DPP: Ignored unsupported frame subtype %d", type);
- break;
- }
-
- if (wpa_s->dpp_pkex)
- pkex_t = wpa_s->dpp_pkex->t;
- else if (wpa_s->dpp_pkex_bi)
- pkex_t = wpa_s->dpp_pkex_bi->pkex_t;
- else
- pkex_t = 0;
- if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
- wpas_dpp_pkex_remove(wpa_s, "*");
- }
-}
-
-
-static struct wpabuf *
-wpas_dpp_gas_req_handler(void *ctx, void *resp_ctx, const u8 *sa,
- const u8 *query, size_t query_len, u16 *comeback_delay)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- struct wpabuf *resp;
-
- wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR,
- MAC2STR(sa));
- if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
- os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
- return NULL;
- }
-
- if (wpa_s->dpp_auth_ok_on_ack && auth->configurator) {
- wpa_printf(MSG_DEBUG,
- "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
- /* wpas_dpp_auth_success() would normally have been called from
- * TX status handler, but since there was no such handler call
- * yet, simply send out the event message and proceed with
- * exchange. */
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=1");
- wpa_s->dpp_auth_ok_on_ack = 0;
- }
-
- wpa_hexdump(MSG_DEBUG,
- "DPP: Received Configuration Request (GAS Query Request)",
- query, query_len);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
- MAC2STR(sa));
- resp = dpp_conf_req_rx(auth, query, query_len);
-
-#ifdef CONFIG_DPP2
- if (!resp && auth->waiting_cert) {
- wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
- auth->cert_resp_ctx = resp_ctx;
- *comeback_delay = 500;
- return NULL;
- }
-#endif /* CONFIG_DPP2 */
-
- if (!resp)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- auth->conf_resp = resp;
- auth->gas_server_ctx = resp_ctx;
- return resp;
-}
-
-
-static void
-wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
-
- if (!auth) {
- wpabuf_free(resp);
- return;
- }
- if (auth->conf_resp != resp) {
- wpa_printf(MSG_DEBUG,
- "DPP: Ignore GAS status report (ok=%d) for unknown response",
- ok);
- wpabuf_free(resp);
- return;
- }
-
-#ifdef CONFIG_DPP2
- if (auth->waiting_csr && ok) {
- wpa_printf(MSG_DEBUG, "DPP: Waiting for CSR");
- wpabuf_free(resp);
- return;
- }
-#endif /* CONFIG_DPP2 */
-
- wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
- ok);
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
-#ifdef CONFIG_DPP2
- if (ok && auth->peer_version >= 2 &&
- auth->conf_resp_status == DPP_STATUS_OK &&
- !auth->waiting_conf_result) {
- wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
- auth->waiting_conf_result = 1;
- auth->conf_resp = NULL;
- wpabuf_free(resp);
- eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
- wpa_s, NULL);
- eloop_register_timeout(2, 0,
- wpas_dpp_config_result_wait_timeout,
- wpa_s, NULL);
- return;
- }
-#endif /* CONFIG_DPP2 */
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- if (ok)
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
- else
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- wpabuf_free(resp);
-}
-
-
-int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct dpp_authentication *auth;
- int ret = -1;
- char *curve = NULL;
-
- auth = dpp_alloc_auth(wpa_s->dpp, wpa_s);
- if (!auth)
- return -1;
-
- curve = get_param(cmd, " curve=");
- wpas_dpp_set_testing_options(wpa_s, auth);
- if (dpp_set_configurator(auth, cmd) == 0 &&
- dpp_configurator_own_config(auth, curve, 0) == 0)
- ret = wpas_dpp_handle_config_obj(wpa_s, auth,
- &auth->conf_obj[0]);
- if (!ret)
- wpas_dpp_post_process_config(wpa_s, auth);
-
- dpp_auth_deinit(auth);
- os_free(curve);
-
- return ret;
-}
-
-
-static void
-wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- const char *res_txt;
-
- res_txt = result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
- (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
- "FAILED");
- wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
- " result=%s (DPP Peer Discovery Request)",
- freq, MAC2STR(dst), res_txt);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
- " freq=%u result=%s", MAC2STR(dst), freq, res_txt);
- /* TODO: Time out wait for response more quickly in error cases? */
-}
-
-
-int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_bss *bss)
-{
- struct os_time now;
- struct wpabuf *msg;
- unsigned int wait_time;
- const u8 *rsn;
- struct wpa_ie_data ied;
- size_t len;
-
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
- return 0; /* Not using DPP AKM - continue */
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
- !(ied.key_mgmt & WPA_KEY_MGMT_DPP))
- return 0; /* AP does not support DPP AKM - continue */
- if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid))
- return 0; /* PMKSA exists for DPP AKM - continue */
-
- if (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
- !ssid->dpp_csign) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR
- "missing %s",
- !ssid->dpp_connector ? "Connector" :
- (!ssid->dpp_netaccesskey ? "netAccessKey" :
- "C-sign-key"));
- return -1;
- }
-
- os_get_time(&now);
-
- if (ssid->dpp_netaccesskey_expiry &&
- (os_time_t) ssid->dpp_netaccesskey_expiry < now.sec) {
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR
- "netAccessKey expired");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG,
- "DPP: Starting network introduction protocol to derive PMKSA for "
- MACSTR, MAC2STR(bss->bssid));
-
- len = 5 + 4 + os_strlen(ssid->dpp_connector);
-#ifdef CONFIG_DPP2
- len += 5;
-#endif /* CONFIG_DPP2 */
- msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ, len);
- if (!msg)
- return -1;
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ) {
- wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
- goto skip_trans_id;
- }
- if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ) {
- wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
- wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
- wpabuf_put_le16(msg, 0);
- goto skip_trans_id;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- /* Transaction ID */
- wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
- wpabuf_put_le16(msg, 1);
- wpabuf_put_u8(msg, TRANSACTION_ID);
-
-#ifdef CONFIG_TESTING_OPTIONS
-skip_trans_id:
- if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ) {
- wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
- goto skip_connector;
- }
- if (dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ) {
- char *connector;
-
- wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
- connector = dpp_corrupt_connector_signature(
- ssid->dpp_connector);
- if (!connector) {
- wpabuf_free(msg);
- return -1;
- }
- wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
- wpabuf_put_le16(msg, os_strlen(connector));
- wpabuf_put_str(msg, connector);
- os_free(connector);
- goto skip_connector;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- /* DPP Connector */
- wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
- wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector));
- wpabuf_put_str(msg, ssid->dpp_connector);
-
-#ifdef CONFIG_TESTING_OPTIONS
-skip_connector:
- if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_REQ) {
- wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
- goto skip_proto_ver;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
-#ifdef CONFIG_DPP2
- if (DPP_VERSION > 1) {
- u8 ver = DPP_VERSION;
-#ifdef CONFIG_DPP3
- int conn_ver;
-
- conn_ver = dpp_get_connector_version(ssid->dpp_connector);
- if (conn_ver > 0 && ver != conn_ver) {
- wpa_printf(MSG_DEBUG,
- "DPP: Use Connector version %d instead of current protocol version %d",
- conn_ver, ver);
- ver = conn_ver;
- }
-#endif /* CONFIG_DPP3 */
-
- /* Protocol Version */
- wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
- wpabuf_put_le16(msg, 1);
- wpabuf_put_u8(msg, ver);
- }
-#endif /* CONFIG_DPP2 */
-
-#ifdef CONFIG_TESTING_OPTIONS
-skip_proto_ver:
-#endif /* CONFIG_TESTING_OPTIONS */
-
- /* TODO: Timeout on AP response */
- wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(bss->bssid), bss->freq, DPP_PA_PEER_DISCOVERY_REQ);
- offchannel_send_action(wpa_s, bss->freq, bss->bssid, wpa_s->own_addr,
- broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- wait_time, wpas_dpp_tx_introduction_status, 0);
- wpabuf_free(msg);
-
- /* Request this connection attempt to terminate - new one will be
- * started when network introduction protocol completes */
- os_memcpy(wpa_s->dpp_intro_bssid, bss->bssid, ETH_ALEN);
- wpa_s->dpp_intro_network = ssid;
- return 1;
-}
-
-
-int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct dpp_bootstrap_info *own_bi;
- const char *pos, *end;
- unsigned int wait_time;
-
- pos = os_strstr(cmd, " own=");
- if (!pos)
- return -1;
- pos += 5;
- own_bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!own_bi) {
- wpa_printf(MSG_DEBUG,
- "DPP: Identified bootstrap info not found");
- return -1;
- }
- if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
- wpa_printf(MSG_DEBUG,
- "DPP: Identified bootstrap info not for PKEX");
- return -1;
- }
- wpa_s->dpp_pkex_bi = own_bi;
- own_bi->pkex_t = 0; /* clear pending errors on new code */
-
- os_free(wpa_s->dpp_pkex_identifier);
- wpa_s->dpp_pkex_identifier = NULL;
- pos = os_strstr(cmd, " identifier=");
- if (pos) {
- pos += 12;
- end = os_strchr(pos, ' ');
- if (!end)
- return -1;
- wpa_s->dpp_pkex_identifier = os_malloc(end - pos + 1);
- if (!wpa_s->dpp_pkex_identifier)
- return -1;
- os_memcpy(wpa_s->dpp_pkex_identifier, pos, end - pos);
- wpa_s->dpp_pkex_identifier[end - pos] = '\0';
- }
-
- pos = os_strstr(cmd, " code=");
- if (!pos)
- return -1;
- os_free(wpa_s->dpp_pkex_code);
- wpa_s->dpp_pkex_code = os_strdup(pos + 6);
- if (!wpa_s->dpp_pkex_code)
- return -1;
-
- if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
- struct dpp_pkex *pkex;
- struct wpabuf *msg;
- bool v2 = os_strstr(cmd, " init=2") != NULL;
-
- wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
- dpp_pkex_free(wpa_s->dpp_pkex);
- wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, own_bi, wpa_s->own_addr,
- wpa_s->dpp_pkex_identifier,
- wpa_s->dpp_pkex_code, v2);
- pkex = wpa_s->dpp_pkex;
- if (!pkex)
- return -1;
-
- msg = pkex->exchange_req;
- wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
- pkex->freq = 2437;
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
- " freq=%u type=%d",
- MAC2STR(broadcast), pkex->freq,
- v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
- DPP_PA_PKEX_V1_EXCHANGE_REQ);
- offchannel_send_action(wpa_s, pkex->freq, broadcast,
- wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- wait_time, wpas_dpp_tx_pkex_status, 0);
- if (wait_time == 0)
- wait_time = 2000;
- pkex->exch_req_wait_time = wait_time;
- pkex->exch_req_tries = 1;
- }
-
- /* TODO: Support multiple PKEX info entries */
-
- os_free(wpa_s->dpp_pkex_auth_cmd);
- wpa_s->dpp_pkex_auth_cmd = os_strdup(cmd);
-
- return 1;
-}
-
-
-int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id)
-{
- unsigned int id_val;
-
- if (os_strcmp(id, "*") == 0) {
- id_val = 0;
- } else {
- id_val = atoi(id);
- if (id_val == 0)
- return -1;
- }
-
- if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
- return -1;
-
- /* TODO: Support multiple PKEX entries */
- os_free(wpa_s->dpp_pkex_code);
- wpa_s->dpp_pkex_code = NULL;
- os_free(wpa_s->dpp_pkex_identifier);
- wpa_s->dpp_pkex_identifier = NULL;
- os_free(wpa_s->dpp_pkex_auth_cmd);
- wpa_s->dpp_pkex_auth_cmd = NULL;
- wpa_s->dpp_pkex_bi = NULL;
- /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
- dpp_pkex_free(wpa_s->dpp_pkex);
- wpa_s->dpp_pkex = NULL;
- return 0;
-}
-
-
-void wpas_dpp_stop(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->dpp_auth || wpa_s->dpp_pkex)
- offchannel_send_action_done(wpa_s);
- dpp_auth_deinit(wpa_s->dpp_auth);
- wpa_s->dpp_auth = NULL;
- dpp_pkex_free(wpa_s->dpp_pkex);
- wpa_s->dpp_pkex = NULL;
- if (wpa_s->dpp_gas_client && wpa_s->dpp_gas_dialog_token >= 0)
- gas_query_stop(wpa_s->gas, wpa_s->dpp_gas_dialog_token);
-}
-
-
-int wpas_dpp_init(struct wpa_supplicant *wpa_s)
-{
- struct dpp_global_config config;
- u8 adv_proto_id[7];
-
- adv_proto_id[0] = WLAN_EID_VENDOR_SPECIFIC;
- adv_proto_id[1] = 5;
- WPA_PUT_BE24(&adv_proto_id[2], OUI_WFA);
- adv_proto_id[5] = DPP_OUI_TYPE;
- adv_proto_id[6] = 0x01;
-
- if (gas_server_register(wpa_s->gas_server, adv_proto_id,
- sizeof(adv_proto_id), wpas_dpp_gas_req_handler,
- wpas_dpp_gas_status_handler, wpa_s) < 0)
- return -1;
-
- os_memset(&config, 0, sizeof(config));
- config.cb_ctx = wpa_s;
-#ifdef CONFIG_DPP2
- config.remove_bi = wpas_dpp_remove_bi;
-#endif /* CONFIG_DPP2 */
- wpa_s->dpp = dpp_global_init(&config);
- return wpa_s->dpp ? 0 : -1;
-}
-
-
-void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_TESTING_OPTIONS
- os_free(wpa_s->dpp_config_obj_override);
- wpa_s->dpp_config_obj_override = NULL;
- os_free(wpa_s->dpp_discovery_override);
- wpa_s->dpp_discovery_override = NULL;
- os_free(wpa_s->dpp_groups_override);
- wpa_s->dpp_groups_override = NULL;
- wpa_s->dpp_ignore_netaccesskey_mismatch = 0;
-#endif /* CONFIG_TESTING_OPTIONS */
- if (!wpa_s->dpp)
- return;
- eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
-#ifdef CONFIG_DPP2
- eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
- wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
- wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_build_csr, wpa_s, NULL);
- dpp_pfs_free(wpa_s->dpp_pfs);
- wpa_s->dpp_pfs = NULL;
- wpas_dpp_chirp_stop(wpa_s);
- dpp_free_reconfig_id(wpa_s->dpp_reconfig_id);
- wpa_s->dpp_reconfig_id = NULL;
-#endif /* CONFIG_DPP2 */
- offchannel_send_action_done(wpa_s);
- wpas_dpp_listen_stop(wpa_s);
- wpas_dpp_stop(wpa_s);
- wpas_dpp_pkex_remove(wpa_s, "*");
- os_memset(wpa_s->dpp_intro_bssid, 0, ETH_ALEN);
- os_free(wpa_s->dpp_configurator_params);
- wpa_s->dpp_configurator_params = NULL;
- dpp_global_clear(wpa_s->dpp);
-}
-
-
-#ifdef CONFIG_DPP2
-
-int wpas_dpp_controller_start(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct dpp_controller_config config;
- const char *pos;
-
- os_memset(&config, 0, sizeof(config));
- config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
- config.netrole = DPP_NETROLE_STA;
- config.msg_ctx = wpa_s;
- config.cb_ctx = wpa_s;
- config.process_conf_obj = wpas_dpp_process_conf_obj;
- if (cmd) {
- pos = os_strstr(cmd, " tcp_port=");
- if (pos) {
- pos += 10;
- config.tcp_port = atoi(pos);
- }
-
- pos = os_strstr(cmd, " role=");
- if (pos) {
- pos += 6;
- if (os_strncmp(pos, "configurator", 12) == 0)
- config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
- else if (os_strncmp(pos, "enrollee", 8) == 0)
- config.allowed_roles = DPP_CAPAB_ENROLLEE;
- else if (os_strncmp(pos, "either", 6) == 0)
- config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
- DPP_CAPAB_ENROLLEE;
- else
- return -1;
- }
-
- config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
- }
- config.configurator_params = wpa_s->dpp_configurator_params;
- return dpp_controller_start(wpa_s->dpp, &config);
-}
-
-
-static void wpas_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
-
-static void wpas_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
- offchannel_send_action_done(wpa_s);
- wpas_dpp_chirp_next(wpa_s, NULL);
-}
-
-
-static void wpas_dpp_chirp_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- if (result == OFFCHANNEL_SEND_ACTION_FAILED) {
- wpa_printf(MSG_DEBUG, "DPP: Failed to send chirp on %d MHz",
- wpa_s->dpp_chirp_freq);
- if (eloop_register_timeout(0, 0, wpas_dpp_chirp_next,
- wpa_s, NULL) < 0)
- wpas_dpp_chirp_stop(wpa_s);
- return;
- }
-
- wpa_printf(MSG_DEBUG, "DPP: Chirp send completed - wait for response");
- if (eloop_register_timeout(2, 0, wpas_dpp_chirp_timeout,
- wpa_s, NULL) < 0)
- wpas_dpp_chirp_stop(wpa_s);
-}
-
-
-static void wpas_dpp_chirp_start(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *msg, *announce = NULL;
- int type;
-
- msg = wpa_s->dpp_presence_announcement;
- type = DPP_PA_PRESENCE_ANNOUNCEMENT;
- if (!msg) {
- struct wpa_ssid *ssid = wpa_s->dpp_reconfig_ssid;
-
- if (ssid && wpa_s->dpp_reconfig_id &&
- wpa_config_get_network(wpa_s->conf,
- wpa_s->dpp_reconfig_ssid_id) ==
- ssid) {
- announce = dpp_build_reconfig_announcement(
- ssid->dpp_csign,
- ssid->dpp_csign_len,
- ssid->dpp_netaccesskey,
- ssid->dpp_netaccesskey_len,
- wpa_s->dpp_reconfig_id);
- msg = announce;
- }
- if (!msg)
- return;
- type = DPP_PA_RECONFIG_ANNOUNCEMENT;
- }
- wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", wpa_s->dpp_chirp_freq);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(broadcast), wpa_s->dpp_chirp_freq, type);
- if (offchannel_send_action(
- wpa_s, wpa_s->dpp_chirp_freq, broadcast,
- wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- 2000, wpas_dpp_chirp_tx_status, 0) < 0)
- wpas_dpp_chirp_stop(wpa_s);
-
- wpabuf_free(announce);
-}
-
-
-static void wpas_dpp_chirp_scan_res_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- struct dpp_bootstrap_info *bi = wpa_s->dpp_chirp_bi;
- unsigned int i;
- struct hostapd_hw_modes *mode;
- int c;
- struct wpa_bss *bss;
- bool chan6 = wpa_s->hw.modes == NULL;
-
- if (!bi && !wpa_s->dpp_reconfig_ssid)
- return;
-
- wpa_s->dpp_chirp_scan_done = 1;
-
- os_free(wpa_s->dpp_chirp_freqs);
- wpa_s->dpp_chirp_freqs = NULL;
-
- /* Channels from own bootstrapping info */
- if (bi) {
- for (i = 0; i < bi->num_freq; i++)
- int_array_add_unique(&wpa_s->dpp_chirp_freqs,
- bi->freq[i]);
- }
-
- /* Preferred chirping channels */
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211G, false);
- if (mode) {
- for (c = 0; c < mode->num_channels; c++) {
- struct hostapd_channel_data *chan = &mode->channels[c];
-
- if ((chan->flag & HOSTAPD_CHAN_DISABLED) ||
- chan->freq != 2437)
- continue;
- chan6 = true;
- break;
- }
- }
- if (chan6)
- int_array_add_unique(&wpa_s->dpp_chirp_freqs, 2437);
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211A, false);
- if (mode) {
- int chan44 = 0, chan149 = 0;
-
- for (c = 0; c < mode->num_channels; c++) {
- struct hostapd_channel_data *chan = &mode->channels[c];
-
- if (chan->flag & (HOSTAPD_CHAN_DISABLED |
- HOSTAPD_CHAN_RADAR))
- continue;
- if (chan->freq == 5220)
- chan44 = 1;
- if (chan->freq == 5745)
- chan149 = 1;
- }
- if (chan149)
- int_array_add_unique(&wpa_s->dpp_chirp_freqs, 5745);
- else if (chan44)
- int_array_add_unique(&wpa_s->dpp_chirp_freqs, 5220);
- }
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211AD, false);
- if (mode) {
- for (c = 0; c < mode->num_channels; c++) {
- struct hostapd_channel_data *chan = &mode->channels[c];
-
- if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
- HOSTAPD_CHAN_RADAR)) ||
- chan->freq != 60480)
- continue;
- int_array_add_unique(&wpa_s->dpp_chirp_freqs, 60480);
- break;
- }
- }
-
- /* Add channels from scan results for APs that advertise Configurator
- * Connectivity element */
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (wpa_bss_get_vendor_ie(bss, DPP_CC_IE_VENDOR_TYPE))
- int_array_add_unique(&wpa_s->dpp_chirp_freqs,
- bss->freq);
- }
-
- if (!wpa_s->dpp_chirp_freqs ||
- eloop_register_timeout(0, 0, wpas_dpp_chirp_next, wpa_s, NULL) < 0)
- wpas_dpp_chirp_stop(wpa_s);
-}
-
-
-static void wpas_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- int i;
-
- if (wpa_s->dpp_chirp_listen)
- wpas_dpp_listen_stop(wpa_s);
-
- if (wpa_s->dpp_chirp_freq == 0) {
- if (wpa_s->dpp_chirp_round % 4 == 0 &&
- !wpa_s->dpp_chirp_scan_done) {
- if (wpas_scan_scheduled(wpa_s)) {
- wpa_printf(MSG_DEBUG,
- "DPP: Deferring chirp scan because another scan is planned already");
- if (eloop_register_timeout(1, 0,
- wpas_dpp_chirp_next,
- wpa_s, NULL) < 0) {
- wpas_dpp_chirp_stop(wpa_s);
- return;
- }
- return;
- }
- wpa_printf(MSG_DEBUG,
- "DPP: Update channel list for chirping");
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_s->scan_res_handler =
- wpas_dpp_chirp_scan_res_handler;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- return;
- }
- wpa_s->dpp_chirp_freq = wpa_s->dpp_chirp_freqs[0];
- wpa_s->dpp_chirp_round++;
- wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
- wpa_s->dpp_chirp_round);
- } else {
- for (i = 0; wpa_s->dpp_chirp_freqs[i]; i++)
- if (wpa_s->dpp_chirp_freqs[i] == wpa_s->dpp_chirp_freq)
- break;
- if (!wpa_s->dpp_chirp_freqs[i]) {
- wpa_printf(MSG_DEBUG,
- "DPP: Previous chirp freq %d not found",
- wpa_s->dpp_chirp_freq);
- return;
- }
- i++;
- if (wpa_s->dpp_chirp_freqs[i]) {
- wpa_s->dpp_chirp_freq = wpa_s->dpp_chirp_freqs[i];
- } else {
- wpa_s->dpp_chirp_iter--;
- if (wpa_s->dpp_chirp_iter <= 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Chirping iterations completed");
- wpas_dpp_chirp_stop(wpa_s);
- return;
- }
- wpa_s->dpp_chirp_freq = 0;
- wpa_s->dpp_chirp_scan_done = 0;
- if (eloop_register_timeout(30, 0, wpas_dpp_chirp_next,
- wpa_s, NULL) < 0) {
- wpas_dpp_chirp_stop(wpa_s);
- return;
- }
- if (wpa_s->dpp_chirp_listen) {
- wpa_printf(MSG_DEBUG,
- "DPP: Listen on %d MHz during chirp 30 second wait",
- wpa_s->dpp_chirp_listen);
- wpas_dpp_listen_start(wpa_s,
- wpa_s->dpp_chirp_listen);
- } else {
- wpa_printf(MSG_DEBUG,
- "DPP: Wait 30 seconds before starting the next chirping round");
- }
- return;
- }
- }
-
- wpas_dpp_chirp_start(wpa_s);
-}
-
-
-int wpas_dpp_chirp(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- const char *pos;
- int iter = 1, listen_freq = 0;
- struct dpp_bootstrap_info *bi;
-
- pos = os_strstr(cmd, " own=");
- if (!pos)
- return -1;
- pos += 5;
- bi = dpp_bootstrap_get_id(wpa_s->dpp, atoi(pos));
- if (!bi) {
- wpa_printf(MSG_DEBUG,
- "DPP: Identified bootstrap info not found");
- return -1;
- }
-
- pos = os_strstr(cmd, " iter=");
- if (pos) {
- iter = atoi(pos + 6);
- if (iter <= 0)
- return -1;
- }
-
- pos = os_strstr(cmd, " listen=");
- if (pos) {
- listen_freq = atoi(pos + 8);
- if (listen_freq <= 0)
- return -1;
- }
-
- wpas_dpp_chirp_stop(wpa_s);
- wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
- wpa_s->dpp_qr_mutual = 0;
- wpa_s->dpp_chirp_bi = bi;
- wpa_s->dpp_presence_announcement = dpp_build_presence_announcement(bi);
- if (!wpa_s->dpp_presence_announcement)
- return -1;
- wpa_s->dpp_chirp_iter = iter;
- wpa_s->dpp_chirp_round = 0;
- wpa_s->dpp_chirp_scan_done = 0;
- wpa_s->dpp_chirp_listen = listen_freq;
-
- return eloop_register_timeout(0, 0, wpas_dpp_chirp_next, wpa_s, NULL);
-}
-
-
-void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->dpp_presence_announcement ||
- wpa_s->dpp_reconfig_ssid) {
- offchannel_send_action_done(wpa_s);
- wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
- }
- wpa_s->dpp_chirp_bi = NULL;
- wpabuf_free(wpa_s->dpp_presence_announcement);
- wpa_s->dpp_presence_announcement = NULL;
- if (wpa_s->dpp_chirp_listen)
- wpas_dpp_listen_stop(wpa_s);
- wpa_s->dpp_chirp_listen = 0;
- wpa_s->dpp_chirp_freq = 0;
- os_free(wpa_s->dpp_chirp_freqs);
- wpa_s->dpp_chirp_freqs = NULL;
- eloop_cancel_timeout(wpas_dpp_chirp_next, wpa_s, NULL);
- eloop_cancel_timeout(wpas_dpp_chirp_timeout, wpa_s, NULL);
- if (wpa_s->scan_res_handler == wpas_dpp_chirp_scan_res_handler) {
- wpas_abort_ongoing_scan(wpa_s);
- wpa_s->scan_res_handler = NULL;
- }
-}
-
-
-int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct wpa_ssid *ssid;
- int iter = 1;
- const char *pos;
-
- ssid = wpa_config_get_network(wpa_s->conf, atoi(cmd));
- if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey ||
- !ssid->dpp_csign) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not a valid network profile for reconfiguration");
- return -1;
- }
-
- pos = os_strstr(cmd, " iter=");
- if (pos) {
- iter = atoi(pos + 6);
- if (iter <= 0)
- return -1;
- }
-
- if (wpa_s->dpp_auth) {
- wpa_printf(MSG_DEBUG,
- "DPP: Not ready to start reconfiguration - pending authentication exchange in progress");
- return -1;
- }
-
- dpp_free_reconfig_id(wpa_s->dpp_reconfig_id);
- wpa_s->dpp_reconfig_id = dpp_gen_reconfig_id(ssid->dpp_csign,
- ssid->dpp_csign_len,
- ssid->dpp_pp_key,
- ssid->dpp_pp_key_len);
- if (!wpa_s->dpp_reconfig_id) {
- wpa_printf(MSG_DEBUG,
- "DPP: Failed to generate E-id for reconfiguration");
- return -1;
- }
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- wpa_printf(MSG_DEBUG, "DPP: Disconnect for reconfiguration");
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
- wpas_dpp_chirp_stop(wpa_s);
- wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
- wpa_s->dpp_qr_mutual = 0;
- wpa_s->dpp_reconfig_ssid = ssid;
- wpa_s->dpp_reconfig_ssid_id = ssid->id;
- wpa_s->dpp_chirp_iter = iter;
- wpa_s->dpp_chirp_round = 0;
- wpa_s->dpp_chirp_scan_done = 0;
- wpa_s->dpp_chirp_listen = 0;
-
- return eloop_register_timeout(0, 0, wpas_dpp_chirp_next, wpa_s, NULL);
-}
-
-
-static int wpas_dpp_build_conf_resp(struct wpa_supplicant *wpa_s,
- struct dpp_authentication *auth, bool tcp)
-{
- struct wpabuf *resp;
-
- resp = dpp_build_conf_resp(auth, auth->e_nonce, auth->curve->nonce_len,
- auth->e_netrole, true);
- if (!resp)
- return -1;
-
- if (tcp) {
- auth->conf_resp_tcp = resp;
- return 0;
- }
-
- if (gas_server_set_resp(wpa_s->gas_server, auth->cert_resp_ctx,
- resp) < 0) {
- wpa_printf(MSG_DEBUG,
- "DPP: Could not find pending GAS response");
- wpabuf_free(resp);
- return -1;
- }
- auth->conf_resp = resp;
- return 0;
-}
-
-
-int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- int peer = -1;
- const char *pos, *value;
- struct dpp_authentication *auth = wpa_s->dpp_auth;
- u8 *bin;
- size_t bin_len;
- struct wpabuf *buf;
- bool tcp = false;
-
- pos = os_strstr(cmd, " peer=");
- if (pos) {
- peer = atoi(pos + 6);
- if (!auth || !auth->waiting_cert ||
- (auth->peer_bi &&
- (unsigned int) peer != auth->peer_bi->id)) {
- auth = dpp_controller_get_auth(wpa_s->dpp, peer);
- tcp = true;
- }
- }
-
- if (!auth || !auth->waiting_cert) {
- wpa_printf(MSG_DEBUG,
- "DPP: No authentication exchange waiting for certificate information");
- return -1;
- }
-
- if (peer >= 0 &&
- (!auth->peer_bi ||
- (unsigned int) peer != auth->peer_bi->id) &&
- (!auth->tmp_peer_bi ||
- (unsigned int) peer != auth->tmp_peer_bi->id)) {
- wpa_printf(MSG_DEBUG, "DPP: Peer mismatch");
- return -1;
- }
-
- pos = os_strstr(cmd, " value=");
- if (!pos)
- return -1;
- value = pos + 7;
-
- pos = os_strstr(cmd, " name=");
- if (!pos)
- return -1;
- pos += 6;
-
- if (os_strncmp(pos, "status ", 7) == 0) {
- auth->force_conf_resp_status = atoi(value);
- return wpas_dpp_build_conf_resp(wpa_s, auth, tcp);
- }
-
- if (os_strncmp(pos, "trustedEapServerName ", 21) == 0) {
- os_free(auth->trusted_eap_server_name);
- auth->trusted_eap_server_name = os_strdup(value);
- return auth->trusted_eap_server_name ? 0 : -1;
- }
-
- bin = base64_decode(value, os_strlen(value), &bin_len);
- if (!bin)
- return -1;
- buf = wpabuf_alloc_copy(bin, bin_len);
- os_free(bin);
-
- if (os_strncmp(pos, "caCert ", 7) == 0) {
- wpabuf_free(auth->cacert);
- auth->cacert = buf;
- return 0;
- }
-
- if (os_strncmp(pos, "certBag ", 8) == 0) {
- wpabuf_free(auth->certbag);
- auth->certbag = buf;
- return wpas_dpp_build_conf_resp(wpa_s, auth, tcp);
- }
-
- wpabuf_free(buf);
- return -1;
-}
-
-#endif /* CONFIG_DPP2 */
diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h
deleted file mode 100644
index b0d5fcf18835..000000000000
--- a/wpa_supplicant/dpp_supplicant.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * wpa_supplicant - DPP
- * Copyright (c) 2017, Qualcomm Atheros, Inc.
- * Copyright (c) 2018-2020, The Linux Foundation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DPP_SUPPLICANT_H
-#define DPP_SUPPLICANT_H
-
-enum dpp_status_error;
-
-int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_nfc_uri(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_nfc_handover_req(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_nfc_handover_sel(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd);
-void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s);
-void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration);
-void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq);
-void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *buf, size_t len, unsigned int freq);
-int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id);
-void wpas_dpp_stop(struct wpa_supplicant *wpa_s);
-int wpas_dpp_init(struct wpa_supplicant *wpa_s);
-void wpas_dpp_deinit(struct wpa_supplicant *wpa_s);
-int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_bss *bss);
-int wpas_dpp_controller_start(struct wpa_supplicant *wpa_s, const char *cmd);
-void wpas_dpp_connected(struct wpa_supplicant *wpa_s);
-void wpas_dpp_send_conn_status_result(struct wpa_supplicant *wpa_s,
- enum dpp_status_error result);
-int wpas_dpp_chirp(struct wpa_supplicant *wpa_s, const char *cmd);
-void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s);
-int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd);
-
-#endif /* DPP_SUPPLICANT_H */
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
deleted file mode 100644
index 237f4e08516f..000000000000
--- a/wpa_supplicant/driver_i.h
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- * wpa_supplicant - Internal driver interface wrappers
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef DRIVER_I_H
-#define DRIVER_I_H
-
-#include "drivers/driver.h"
-
-/* driver_ops */
-static inline void * wpa_drv_init(struct wpa_supplicant *wpa_s,
- const char *ifname)
-{
- if (wpa_s->driver->init2)
- return wpa_s->driver->init2(wpa_s, ifname,
- wpa_s->global_drv_priv);
- if (wpa_s->driver->init) {
- return wpa_s->driver->init(wpa_s, ifname);
- }
- return NULL;
-}
-
-static inline void wpa_drv_deinit(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->deinit)
- wpa_s->driver->deinit(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_set_param(struct wpa_supplicant *wpa_s,
- const char *param)
-{
- if (wpa_s->driver->set_param)
- return wpa_s->driver->set_param(wpa_s->drv_priv, param);
- return 0;
-}
-
-static inline int wpa_drv_set_countermeasures(struct wpa_supplicant *wpa_s,
- int enabled)
-{
- if (wpa_s->driver->set_countermeasures) {
- return wpa_s->driver->set_countermeasures(wpa_s->drv_priv,
- enabled);
- }
- return -1;
-}
-
-static inline int wpa_drv_authenticate(struct wpa_supplicant *wpa_s,
- struct wpa_driver_auth_params *params)
-{
- if (wpa_s->driver->authenticate)
- return wpa_s->driver->authenticate(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,
- struct wpa_driver_associate_params *params)
-{
- if (wpa_s->driver->associate) {
- return wpa_s->driver->associate(wpa_s->drv_priv, params);
- }
- return -1;
-}
-
-static inline int wpa_drv_init_mesh(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->init_mesh)
- return wpa_s->driver->init_mesh(wpa_s->drv_priv);
- return -1;
-}
-
-static inline int wpa_drv_join_mesh(struct wpa_supplicant *wpa_s,
- struct wpa_driver_mesh_join_params *params)
-{
- if (wpa_s->driver->join_mesh)
- return wpa_s->driver->join_mesh(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_leave_mesh(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->leave_mesh)
- return wpa_s->driver->leave_mesh(wpa_s->drv_priv);
- return -1;
-}
-
-static inline int wpa_drv_mesh_link_probe(struct wpa_supplicant *wpa_s,
- const u8 *addr,
- const u8 *eth, size_t len)
-{
- if (wpa_s->driver->probe_mesh_link)
- return wpa_s->driver->probe_mesh_link(wpa_s->drv_priv, addr,
- eth, len);
- return -1;
-}
-
-static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->test_failure == WPAS_TEST_FAILURE_SCAN_TRIGGER)
- return -EBUSY;
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_s->driver->scan2)
- return wpa_s->driver->scan2(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_sched_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- if (wpa_s->driver->sched_scan)
- return wpa_s->driver->sched_scan(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_stop_sched_scan(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->stop_sched_scan)
- return wpa_s->driver->stop_sched_scan(wpa_s->drv_priv);
- return -1;
-}
-
-struct wpa_scan_results *
-wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s);
-
-static inline int wpa_drv_get_bssid(struct wpa_supplicant *wpa_s, u8 *bssid)
-{
- if (wpa_s->driver->get_bssid) {
- return wpa_s->driver->get_bssid(wpa_s->drv_priv, bssid);
- }
- return -1;
-}
-
-static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid)
-{
- if (wpa_s->driver->get_ssid) {
- return wpa_s->driver->get_ssid(wpa_s->drv_priv, ssid);
- }
- return -1;
-}
-
-static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
- enum wpa_alg alg, const u8 *addr,
- int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len,
- enum key_flag key_flag)
-{
- struct wpa_driver_set_key_params params;
-
- os_memset(&params, 0, sizeof(params));
- params.ifname = wpa_s->ifname;
- params.alg = alg;
- params.addr = addr;
- params.key_idx = key_idx;
- params.set_tx = set_tx;
- params.seq = seq;
- params.seq_len = seq_len;
- params.key = key;
- params.key_len = key_len;
- params.key_flag = key_flag;
-
- if (alg != WPA_ALG_NONE) {
- /* keyidx = 1 can be either a broadcast or--with
- * Extended Key ID--a unicast key. Use bit 15 for
- * the pairwise keyidx 1 which is hopefully high enough
- * to not clash with future extensions.
- */
- if (key_idx == 1 && (key_flag & KEY_FLAG_PAIRWISE))
- wpa_s->keys_cleared &= ~BIT(15);
- else if (key_idx >= 0 && key_idx <= 5)
- wpa_s->keys_cleared &= ~BIT(key_idx);
- else
- wpa_s->keys_cleared = 0;
- }
- if (wpa_s->driver->set_key) {
- return wpa_s->driver->set_key(wpa_s->drv_priv, &params);
- }
- return -1;
-}
-
-static inline int wpa_drv_get_seqnum(struct wpa_supplicant *wpa_s,
- const u8 *addr, int idx, u8 *seq)
-{
- if (wpa_s->driver->get_seqnum)
- return wpa_s->driver->get_seqnum(wpa_s->ifname, wpa_s->drv_priv,
- addr, idx, seq);
- return -1;
-}
-
-static inline int wpa_drv_sta_deauth(struct wpa_supplicant *wpa_s,
- const u8 *addr, u16 reason_code)
-{
- if (wpa_s->driver->sta_deauth) {
- return wpa_s->driver->sta_deauth(wpa_s->drv_priv,
- wpa_s->own_addr, addr,
- reason_code);
- }
- return -1;
-}
-
-static inline int wpa_drv_deauthenticate(struct wpa_supplicant *wpa_s,
- const u8 *addr, u16 reason_code)
-{
- if (wpa_s->driver->deauthenticate) {
- return wpa_s->driver->deauthenticate(wpa_s->drv_priv, addr,
- reason_code);
- }
- return -1;
-}
-
-static inline int wpa_drv_add_pmkid(struct wpa_supplicant *wpa_s,
- struct wpa_pmkid_params *params)
-{
- if (wpa_s->driver->add_pmkid) {
- return wpa_s->driver->add_pmkid(wpa_s->drv_priv, params);
- }
- return -1;
-}
-
-static inline int wpa_drv_remove_pmkid(struct wpa_supplicant *wpa_s,
- struct wpa_pmkid_params *params)
-{
- if (wpa_s->driver->remove_pmkid) {
- return wpa_s->driver->remove_pmkid(wpa_s->drv_priv, params);
- }
- return -1;
-}
-
-static inline int wpa_drv_flush_pmkid(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->flush_pmkid) {
- return wpa_s->driver->flush_pmkid(wpa_s->drv_priv);
- }
- return -1;
-}
-
-static inline int wpa_drv_get_capa(struct wpa_supplicant *wpa_s,
- struct wpa_driver_capa *capa)
-{
- if (wpa_s->driver->get_capa) {
- return wpa_s->driver->get_capa(wpa_s->drv_priv, capa);
- }
- return -1;
-}
-
-static inline void wpa_drv_poll(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->poll) {
- wpa_s->driver->poll(wpa_s->drv_priv);
- }
-}
-
-static inline const char * wpa_drv_get_ifname(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->get_ifname) {
- return wpa_s->driver->get_ifname(wpa_s->drv_priv);
- }
- return NULL;
-}
-
-static inline const char *
-wpa_driver_get_radio_name(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->get_radio_name)
- return wpa_s->driver->get_radio_name(wpa_s->drv_priv);
- return NULL;
-}
-
-static inline const u8 * wpa_drv_get_mac_addr(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->get_mac_addr) {
- return wpa_s->driver->get_mac_addr(wpa_s->drv_priv);
- }
- return NULL;
-}
-
-static inline int wpa_drv_set_operstate(struct wpa_supplicant *wpa_s,
- int state)
-{
- if (wpa_s->driver->set_operstate)
- return wpa_s->driver->set_operstate(wpa_s->drv_priv, state);
- return 0;
-}
-
-static inline int wpa_drv_mlme_setprotection(struct wpa_supplicant *wpa_s,
- const u8 *addr, int protect_type,
- int key_type)
-{
- if (wpa_s->driver->mlme_setprotection)
- return wpa_s->driver->mlme_setprotection(wpa_s->drv_priv, addr,
- protect_type,
- key_type);
- return 0;
-}
-
-static inline struct hostapd_hw_modes *
-wpa_drv_get_hw_feature_data(struct wpa_supplicant *wpa_s, u16 *num_modes,
- u16 *flags, u8 *dfs_domain)
-{
- if (wpa_s->driver->get_hw_feature_data)
- return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv,
- num_modes, flags,
- dfs_domain);
- return NULL;
-}
-
-static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
- const char *alpha2)
-{
- if (wpa_s->driver->set_country)
- return wpa_s->driver->set_country(wpa_s->drv_priv, alpha2);
- return 0;
-}
-
-static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t data_len, int noack,
- unsigned int freq, unsigned int wait)
-{
- if (wpa_s->driver->send_mlme)
- return wpa_s->driver->send_mlme(wpa_s->drv_priv,
- data, data_len, noack,
- freq, NULL, 0, 0, wait);
- return -1;
-}
-
-static inline int wpa_drv_update_ft_ies(struct wpa_supplicant *wpa_s,
- const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- if (wpa_s->driver->update_ft_ies)
- return wpa_s->driver->update_ft_ies(wpa_s->drv_priv, md,
- ies, ies_len);
- return -1;
-}
-
-static inline int wpa_drv_set_ap(struct wpa_supplicant *wpa_s,
- struct wpa_driver_ap_params *params)
-{
- if (wpa_s->driver->set_ap)
- return wpa_s->driver->set_ap(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_sta_add(struct wpa_supplicant *wpa_s,
- struct hostapd_sta_add_params *params)
-{
- if (wpa_s->driver->sta_add)
- return wpa_s->driver->sta_add(wpa_s->drv_priv, params);
- return -1;
-}
-
-static inline int wpa_drv_sta_remove(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- if (wpa_s->driver->sta_remove)
- return wpa_s->driver->sta_remove(wpa_s->drv_priv, addr);
- return -1;
-}
-
-static inline int wpa_drv_tx_control_port(struct wpa_supplicant *wpa_s,
- const u8 *dest, u16 proto,
- const u8 *buf, size_t len,
- int no_encrypt)
-{
- if (!wpa_s->driver->tx_control_port)
- return -1;
- return wpa_s->driver->tx_control_port(wpa_s->drv_priv, dest, proto,
- buf, len, no_encrypt);
-}
-
-static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *data,
- size_t data_len, int encrypt,
- const u8 *own_addr, u32 flags)
-{
- if (wpa_s->driver->hapd_send_eapol)
- return wpa_s->driver->hapd_send_eapol(wpa_s->drv_priv, addr,
- data, data_len, encrypt,
- own_addr, flags);
- return -1;
-}
-
-static inline int wpa_drv_sta_set_flags(struct wpa_supplicant *wpa_s,
- const u8 *addr, int total_flags,
- int flags_or, int flags_and)
-{
- if (wpa_s->driver->sta_set_flags)
- return wpa_s->driver->sta_set_flags(wpa_s->drv_priv, addr,
- total_flags, flags_or,
- flags_and);
- return -1;
-}
-
-static inline int wpa_drv_set_supp_port(struct wpa_supplicant *wpa_s,
- int authorized)
-{
- if (wpa_s->driver->set_supp_port) {
- return wpa_s->driver->set_supp_port(wpa_s->drv_priv,
- authorized);
- }
- return 0;
-}
-
-static inline int wpa_drv_send_action(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- unsigned int wait,
- const u8 *dst, const u8 *src,
- const u8 *bssid,
- const u8 *data, size_t data_len,
- int no_cck)
-{
- if (wpa_s->driver->send_action)
- return wpa_s->driver->send_action(wpa_s->drv_priv, freq,
- wait, dst, src, bssid,
- data, data_len, no_cck);
- return -1;
-}
-
-static inline void wpa_drv_send_action_cancel_wait(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->send_action_cancel_wait)
- wpa_s->driver->send_action_cancel_wait(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_set_freq(struct wpa_supplicant *wpa_s,
- struct hostapd_freq_params *freq)
-{
- if (wpa_s->driver->set_freq)
- return wpa_s->driver->set_freq(wpa_s->drv_priv, freq);
- return -1;
-}
-
-static inline int wpa_drv_if_add(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type type,
- const char *ifname, const u8 *addr,
- void *bss_ctx, char *force_ifname,
- u8 *if_addr, const char *bridge)
-{
- if (wpa_s->driver->if_add)
- return wpa_s->driver->if_add(wpa_s->drv_priv, type, ifname,
- addr, bss_ctx, NULL, force_ifname,
- if_addr, bridge, 0, 0);
- return -1;
-}
-
-static inline int wpa_drv_if_remove(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type type,
- const char *ifname)
-{
- if (wpa_s->driver->if_remove)
- return wpa_s->driver->if_remove(wpa_s->drv_priv, type, ifname);
- return -1;
-}
-
-static inline int wpa_drv_remain_on_channel(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- unsigned int duration)
-{
- if (wpa_s->driver->remain_on_channel)
- return wpa_s->driver->remain_on_channel(wpa_s->drv_priv, freq,
- duration);
- return -1;
-}
-
-static inline int wpa_drv_cancel_remain_on_channel(
- struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->cancel_remain_on_channel)
- return wpa_s->driver->cancel_remain_on_channel(
- wpa_s->drv_priv);
- return -1;
-}
-
-static inline int wpa_drv_probe_req_report(struct wpa_supplicant *wpa_s,
- int report)
-{
- if (wpa_s->driver->probe_req_report)
- return wpa_s->driver->probe_req_report(wpa_s->drv_priv,
- report);
- return -1;
-}
-
-static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->deinit_ap)
- return wpa_s->driver->deinit_ap(wpa_s->drv_priv);
- return 0;
-}
-
-static inline int wpa_drv_deinit_p2p_cli(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->deinit_p2p_cli)
- return wpa_s->driver->deinit_p2p_cli(wpa_s->drv_priv);
- return 0;
-}
-
-static inline void wpa_drv_suspend(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->suspend)
- wpa_s->driver->suspend(wpa_s->drv_priv);
-}
-
-static inline void wpa_drv_resume(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver->resume)
- wpa_s->driver->resume(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_signal_monitor(struct wpa_supplicant *wpa_s,
- int threshold, int hysteresis)
-{
- if (wpa_s->driver->signal_monitor)
- return wpa_s->driver->signal_monitor(wpa_s->drv_priv,
- threshold, hysteresis);
- return -1;
-}
-
-int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
- struct wpa_signal_info *si);
-
-static inline int wpa_drv_channel_info(struct wpa_supplicant *wpa_s,
- struct wpa_channel_info *ci)
-{
- if (wpa_s->driver->channel_info)
- return wpa_s->driver->channel_info(wpa_s->drv_priv, ci);
- return -1;
-}
-
-static inline int wpa_drv_pktcnt_poll(struct wpa_supplicant *wpa_s,
- struct hostap_sta_driver_data *sta)
-{
- if (wpa_s->driver->read_sta_data)
- return wpa_s->driver->read_sta_data(wpa_s->drv_priv, sta,
- wpa_s->bssid);
- return -1;
-}
-
-static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
- const struct wpabuf *beacon,
- const struct wpabuf *proberesp,
- const struct wpabuf *assocresp)
-{
- if (!wpa_s->driver->set_ap_wps_ie)
- return -1;
- return wpa_s->driver->set_ap_wps_ie(wpa_s->drv_priv, beacon,
- proberesp, assocresp);
-}
-
-static inline int wpa_drv_get_noa(struct wpa_supplicant *wpa_s,
- u8 *buf, size_t buf_len)
-{
- if (!wpa_s->driver->get_noa)
- return -1;
- return wpa_s->driver->get_noa(wpa_s->drv_priv, buf, buf_len);
-}
-
-static inline int wpa_drv_set_p2p_powersave(struct wpa_supplicant *wpa_s,
- int legacy_ps, int opp_ps,
- int ctwindow)
-{
- if (!wpa_s->driver->set_p2p_powersave)
- return -1;
- return wpa_s->driver->set_p2p_powersave(wpa_s->drv_priv, legacy_ps,
- opp_ps, ctwindow);
-}
-
-static inline int wpa_drv_ampdu(struct wpa_supplicant *wpa_s, int ampdu)
-{
- if (!wpa_s->driver->ampdu)
- return -1;
- return wpa_s->driver->ampdu(wpa_s->drv_priv, ampdu);
-}
-
-static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
- const u8 *dst, u8 action_code,
- u8 dialog_token, u16 status_code,
- u32 peer_capab, int initiator,
- const u8 *buf, size_t len)
-{
- if (wpa_s->driver->send_tdls_mgmt) {
- return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
- action_code, dialog_token,
- status_code, peer_capab,
- initiator, buf, len);
- }
- return -1;
-}
-
-static inline int wpa_drv_tdls_oper(struct wpa_supplicant *wpa_s,
- enum tdls_oper oper, const u8 *peer)
-{
- if (!wpa_s->driver->tdls_oper)
- return -1;
- return wpa_s->driver->tdls_oper(wpa_s->drv_priv, oper, peer);
-}
-
-#ifdef ANDROID
-static inline int wpa_drv_driver_cmd(struct wpa_supplicant *wpa_s,
- char *cmd, char *buf, size_t buf_len)
-{
- if (!wpa_s->driver->driver_cmd)
- return -1;
- return wpa_s->driver->driver_cmd(wpa_s->drv_priv, cmd, buf, buf_len);
-}
-#endif /* ANDROID */
-
-static inline void wpa_drv_set_rekey_info(struct wpa_supplicant *wpa_s,
- const u8 *kek, size_t kek_len,
- const u8 *kck, size_t kck_len,
- const u8 *replay_ctr)
-{
- if (!wpa_s->driver->set_rekey_info)
- return;
- wpa_s->driver->set_rekey_info(wpa_s->drv_priv, kek, kek_len,
- kck, kck_len, replay_ctr);
-}
-
-static inline int wpa_drv_radio_disable(struct wpa_supplicant *wpa_s,
- int disabled)
-{
- if (!wpa_s->driver->radio_disable)
- return -1;
- return wpa_s->driver->radio_disable(wpa_s->drv_priv, disabled);
-}
-
-static inline int wpa_drv_switch_channel(struct wpa_supplicant *wpa_s,
- struct csa_settings *settings)
-{
- if (!wpa_s->driver->switch_channel)
- return -1;
- return wpa_s->driver->switch_channel(wpa_s->drv_priv, settings);
-}
-
-static inline int wpa_drv_add_ts(struct wpa_supplicant *wpa_s, u8 tsid,
- const u8 *address, u8 user_priority,
- u16 admitted_time)
-{
- if (!wpa_s->driver->add_tx_ts)
- return -1;
- return wpa_s->driver->add_tx_ts(wpa_s->drv_priv, tsid, address,
- user_priority, admitted_time);
-}
-
-static inline int wpa_drv_del_ts(struct wpa_supplicant *wpa_s, u8 tid,
- const u8 *address)
-{
- if (!wpa_s->driver->del_tx_ts)
- return -1;
- return wpa_s->driver->del_tx_ts(wpa_s->drv_priv, tid, address);
-}
-
-static inline int wpa_drv_tdls_enable_channel_switch(
- struct wpa_supplicant *wpa_s, const u8 *addr, u8 oper_class,
- const struct hostapd_freq_params *freq_params)
-{
- if (!wpa_s->driver->tdls_enable_channel_switch)
- return -1;
- return wpa_s->driver->tdls_enable_channel_switch(wpa_s->drv_priv, addr,
- oper_class,
- freq_params);
-}
-
-static inline int
-wpa_drv_tdls_disable_channel_switch(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- if (!wpa_s->driver->tdls_disable_channel_switch)
- return -1;
- return wpa_s->driver->tdls_disable_channel_switch(wpa_s->drv_priv,
- addr);
-}
-
-static inline int wpa_drv_wnm_oper(struct wpa_supplicant *wpa_s,
- enum wnm_oper oper, const u8 *peer,
- u8 *buf, u16 *buf_len)
-{
- if (!wpa_s->driver->wnm_oper)
- return -1;
- return wpa_s->driver->wnm_oper(wpa_s->drv_priv, oper, peer, buf,
- buf_len);
-}
-
-static inline int wpa_drv_status(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
- if (!wpa_s->driver->status)
- return -1;
- return wpa_s->driver->status(wpa_s->drv_priv, buf, buflen);
-}
-
-static inline int wpa_drv_set_qos_map(struct wpa_supplicant *wpa_s,
- const u8 *qos_map_set, u8 qos_map_set_len)
-{
- if (!wpa_s->driver->set_qos_map)
- return -1;
- return wpa_s->driver->set_qos_map(wpa_s->drv_priv, qos_map_set,
- qos_map_set_len);
-}
-
-static inline int wpa_drv_get_wowlan(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->driver->get_wowlan)
- return 0;
- return wpa_s->driver->get_wowlan(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_wowlan(struct wpa_supplicant *wpa_s,
- const struct wowlan_triggers *triggers)
-{
- if (!wpa_s->driver->set_wowlan)
- return -1;
- return wpa_s->driver->set_wowlan(wpa_s->drv_priv, triggers);
-}
-
-static inline int wpa_drv_vendor_cmd(struct wpa_supplicant *wpa_s,
- int vendor_id, int subcmd, const u8 *data,
- size_t data_len,
- enum nested_attr nested_attr_flag,
- struct wpabuf *buf)
-{
- if (!wpa_s->driver->vendor_cmd)
- return -1;
- return wpa_s->driver->vendor_cmd(wpa_s->drv_priv, vendor_id, subcmd,
- data, data_len, nested_attr_flag, buf);
-}
-
-static inline int wpa_drv_roaming(struct wpa_supplicant *wpa_s, int allowed,
- const u8 *bssid)
-{
- if (!wpa_s->driver->roaming)
- return -1;
- return wpa_s->driver->roaming(wpa_s->drv_priv, allowed, bssid);
-}
-
-static inline int wpa_drv_disable_fils(struct wpa_supplicant *wpa_s,
- int disable)
-{
- if (!wpa_s->driver->disable_fils)
- return -1;
- return wpa_s->driver->disable_fils(wpa_s->drv_priv, disable);
-}
-
-static inline int wpa_drv_set_mac_addr(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- if (!wpa_s->driver->set_mac_addr)
- return -1;
- return wpa_s->driver->set_mac_addr(wpa_s->drv_priv, addr);
-}
-
-
-#ifdef CONFIG_MACSEC
-
-static inline int wpa_drv_macsec_init(struct wpa_supplicant *wpa_s,
- struct macsec_init_params *params)
-{
- if (!wpa_s->driver->macsec_init)
- return -1;
- return wpa_s->driver->macsec_init(wpa_s->drv_priv, params);
-}
-
-static inline int wpa_drv_macsec_deinit(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->driver->macsec_deinit)
- return -1;
- return wpa_s->driver->macsec_deinit(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_macsec_get_capability(struct wpa_supplicant *wpa_s,
- enum macsec_cap *cap)
-{
- if (!wpa_s->driver->macsec_get_capability)
- return -1;
- return wpa_s->driver->macsec_get_capability(wpa_s->drv_priv, cap);
-}
-
-static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s,
- bool enabled)
-{
- if (!wpa_s->driver->enable_protect_frames)
- return -1;
- return wpa_s->driver->enable_protect_frames(wpa_s->drv_priv, enabled);
-}
-
-static inline int wpa_drv_enable_encrypt(struct wpa_supplicant *wpa_s,
- bool enabled)
-{
- if (!wpa_s->driver->enable_encrypt)
- return -1;
- return wpa_s->driver->enable_encrypt(wpa_s->drv_priv, enabled);
-}
-
-static inline int wpa_drv_set_replay_protect(struct wpa_supplicant *wpa_s,
- bool enabled, u32 window)
-{
- if (!wpa_s->driver->set_replay_protect)
- return -1;
- return wpa_s->driver->set_replay_protect(wpa_s->drv_priv, enabled,
- window);
-}
-
-static inline int wpa_drv_set_current_cipher_suite(struct wpa_supplicant *wpa_s,
- u64 cs)
-{
- if (!wpa_s->driver->set_current_cipher_suite)
- return -1;
- return wpa_s->driver->set_current_cipher_suite(wpa_s->drv_priv, cs);
-}
-
-static inline int wpa_drv_enable_controlled_port(struct wpa_supplicant *wpa_s,
- bool enabled)
-{
- if (!wpa_s->driver->enable_controlled_port)
- return -1;
- return wpa_s->driver->enable_controlled_port(wpa_s->drv_priv, enabled);
-}
-
-static inline int wpa_drv_get_receive_lowest_pn(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->get_receive_lowest_pn)
- return -1;
- return wpa_s->driver->get_receive_lowest_pn(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_get_transmit_next_pn(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->get_transmit_next_pn)
- return -1;
- return wpa_s->driver->get_transmit_next_pn(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_set_transmit_next_pn(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->set_transmit_next_pn)
- return -1;
- return wpa_s->driver->set_transmit_next_pn(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_set_receive_lowest_pn(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->set_receive_lowest_pn)
- return -1;
- return wpa_s->driver->set_receive_lowest_pn(wpa_s->drv_priv, sa);
-}
-
-static inline int
-wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, struct receive_sc *sc,
- unsigned int conf_offset, int validation)
-{
- if (!wpa_s->driver->create_receive_sc)
- return -1;
- return wpa_s->driver->create_receive_sc(wpa_s->drv_priv, sc,
- conf_offset, validation);
-}
-
-static inline int wpa_drv_delete_receive_sc(struct wpa_supplicant *wpa_s,
- struct receive_sc *sc)
-{
- if (!wpa_s->driver->delete_receive_sc)
- return -1;
- return wpa_s->driver->delete_receive_sc(wpa_s->drv_priv, sc);
-}
-
-static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->create_receive_sa)
- return -1;
- return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_delete_receive_sa(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->delete_receive_sa)
- return -1;
- return wpa_s->driver->delete_receive_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_enable_receive_sa(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->enable_receive_sa)
- return -1;
- return wpa_s->driver->enable_receive_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_disable_receive_sa(struct wpa_supplicant *wpa_s,
- struct receive_sa *sa)
-{
- if (!wpa_s->driver->disable_receive_sa)
- return -1;
- return wpa_s->driver->disable_receive_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int
-wpa_drv_create_transmit_sc(struct wpa_supplicant *wpa_s, struct transmit_sc *sc,
- unsigned int conf_offset)
-{
- if (!wpa_s->driver->create_transmit_sc)
- return -1;
- return wpa_s->driver->create_transmit_sc(wpa_s->drv_priv, sc,
- conf_offset);
-}
-
-static inline int wpa_drv_delete_transmit_sc(struct wpa_supplicant *wpa_s,
- struct transmit_sc *sc)
-{
- if (!wpa_s->driver->delete_transmit_sc)
- return -1;
- return wpa_s->driver->delete_transmit_sc(wpa_s->drv_priv, sc);
-}
-
-static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->create_transmit_sa)
- return -1;
- return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_delete_transmit_sa(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->delete_transmit_sa)
- return -1;
- return wpa_s->driver->delete_transmit_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_enable_transmit_sa(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->enable_transmit_sa)
- return -1;
- return wpa_s->driver->enable_transmit_sa(wpa_s->drv_priv, sa);
-}
-
-static inline int wpa_drv_disable_transmit_sa(struct wpa_supplicant *wpa_s,
- struct transmit_sa *sa)
-{
- if (!wpa_s->driver->disable_transmit_sa)
- return -1;
- return wpa_s->driver->disable_transmit_sa(wpa_s->drv_priv, sa);
-}
-#endif /* CONFIG_MACSEC */
-
-static inline int wpa_drv_setband(struct wpa_supplicant *wpa_s,
- u32 band_mask)
-{
- if (!wpa_s->driver->set_band)
- return -1;
- return wpa_s->driver->set_band(wpa_s->drv_priv, band_mask);
-}
-
-static inline int wpa_drv_get_pref_freq_list(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type if_type,
- unsigned int *num,
- unsigned int *freq_list)
-{
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->get_pref_freq_list_override)
- return wpas_ctrl_iface_get_pref_freq_list_override(
- wpa_s, if_type, num, freq_list);
-#endif /* CONFIG_TESTING_OPTIONS */
- if (!wpa_s->driver->get_pref_freq_list)
- return -1;
- return wpa_s->driver->get_pref_freq_list(wpa_s->drv_priv, if_type,
- num, freq_list);
-}
-
-static inline int wpa_drv_set_prob_oper_freq(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- if (!wpa_s->driver->set_prob_oper_freq)
- return 0;
- return wpa_s->driver->set_prob_oper_freq(wpa_s->drv_priv, freq);
-}
-
-static inline int wpa_drv_abort_scan(struct wpa_supplicant *wpa_s,
- u64 scan_cookie)
-{
- if (!wpa_s->driver->abort_scan)
- return -1;
- return wpa_s->driver->abort_scan(wpa_s->drv_priv, scan_cookie);
-}
-
-static inline int wpa_drv_configure_frame_filters(struct wpa_supplicant *wpa_s,
- u32 filters)
-{
- if (!wpa_s->driver->configure_data_frame_filters)
- return -1;
- return wpa_s->driver->configure_data_frame_filters(wpa_s->drv_priv,
- filters);
-}
-
-static inline int wpa_drv_get_ext_capa(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type type)
-{
- if (!wpa_s->driver->get_ext_capab)
- return -1;
- return wpa_s->driver->get_ext_capab(wpa_s->drv_priv, type,
- &wpa_s->extended_capa,
- &wpa_s->extended_capa_mask,
- &wpa_s->extended_capa_len);
-}
-
-static inline int wpa_drv_p2p_lo_start(struct wpa_supplicant *wpa_s,
- unsigned int channel,
- unsigned int period,
- unsigned int interval,
- unsigned int count,
- const u8 *device_types,
- size_t dev_types_len,
- const u8 *ies, size_t ies_len)
-{
- if (!wpa_s->driver->p2p_lo_start)
- return -1;
- return wpa_s->driver->p2p_lo_start(wpa_s->drv_priv, channel, period,
- interval, count, device_types,
- dev_types_len, ies, ies_len);
-}
-
-static inline int wpa_drv_p2p_lo_stop(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->driver->p2p_lo_stop)
- return -1;
- return wpa_s->driver->p2p_lo_stop(wpa_s->drv_priv);
-}
-
-static inline int wpa_drv_set_default_scan_ies(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t len)
-{
- if (!wpa_s->driver->set_default_scan_ies)
- return -1;
- return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
-}
-
-static inline int wpa_drv_set_tdls_mode(struct wpa_supplicant *wpa_s,
- int tdls_external_control)
-{
- if (!wpa_s->driver->set_tdls_mode)
- return -1;
- return wpa_s->driver->set_tdls_mode(wpa_s->drv_priv,
- tdls_external_control);
-}
-
-static inline struct wpa_bss_candidate_info *
-wpa_drv_get_bss_trans_status(struct wpa_supplicant *wpa_s,
- struct wpa_bss_trans_info *params)
-{
- if (!wpa_s->driver->get_bss_transition_status)
- return NULL;
- return wpa_s->driver->get_bss_transition_status(wpa_s->drv_priv,
- params);
-}
-
-static inline int wpa_drv_ignore_assoc_disallow(struct wpa_supplicant *wpa_s,
- int val)
-{
- if (!wpa_s->driver->ignore_assoc_disallow)
- return -1;
- return wpa_s->driver->ignore_assoc_disallow(wpa_s->drv_priv, val);
-}
-
-static inline int wpa_drv_set_bssid_tmp_disallow(struct wpa_supplicant *wpa_s,
- unsigned int num_bssid,
- const u8 *bssids)
-{
- if (!wpa_s->driver->set_bssid_tmp_disallow)
- return -1;
- return wpa_s->driver->set_bssid_tmp_disallow(wpa_s->drv_priv, num_bssid,
- bssids);
-}
-
-static inline int wpa_drv_update_connect_params(
- struct wpa_supplicant *wpa_s,
- struct wpa_driver_associate_params *params,
- enum wpa_drv_update_connect_params_mask mask)
-{
- if (!wpa_s->driver->update_connect_params)
- return -1;
- return wpa_s->driver->update_connect_params(wpa_s->drv_priv, params,
- mask);
-}
-
-static inline int
-wpa_drv_send_external_auth_status(struct wpa_supplicant *wpa_s,
- struct external_auth *params)
-{
- if (!wpa_s->driver->send_external_auth_status)
- return -1;
- return wpa_s->driver->send_external_auth_status(wpa_s->drv_priv,
- params);
-}
-
-static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val)
-{
- if (!wpa_s->driver->set_4addr_mode)
- return -1;
- return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv,
- wpa_s->bridge_ifname, val);
-}
-
-static inline int wpa_drv_dpp_listen(struct wpa_supplicant *wpa_s, bool enable)
-{
- if (!wpa_s->driver->dpp_listen)
- return 0;
- return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
-}
-
-#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/eap_proxy_dummy.mak b/wpa_supplicant/eap_proxy_dummy.mak
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/wpa_supplicant/eap_proxy_dummy.mak
+++ /dev/null
diff --git a/wpa_supplicant/eap_proxy_dummy.mk b/wpa_supplicant/eap_proxy_dummy.mk
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/wpa_supplicant/eap_proxy_dummy.mk
+++ /dev/null
diff --git a/wpa_supplicant/eap_register.c b/wpa_supplicant/eap_register.c
deleted file mode 100644
index 3f018c4b3c32..000000000000
--- a/wpa_supplicant/eap_register.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * EAP method registration
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eap_peer/eap_methods.h"
-#include "eap_server/eap_methods.h"
-#include "wpa_supplicant_i.h"
-
-
-/**
- * eap_register_methods - Register statically linked EAP methods
- * Returns: 0 on success, -1 or -2 on failure
- *
- * This function is called at program initialization to register all EAP
- * methods that were linked in statically.
- */
-int eap_register_methods(void)
-{
- int ret = 0;
-
-#ifdef EAP_MD5
- if (ret == 0)
- ret = eap_peer_md5_register();
-#endif /* EAP_MD5 */
-
-#ifdef EAP_TLS
- if (ret == 0)
- ret = eap_peer_tls_register();
-#endif /* EAP_TLS */
-
-#ifdef EAP_UNAUTH_TLS
- if (ret == 0)
- ret = eap_peer_unauth_tls_register();
-#endif /* EAP_UNAUTH_TLS */
-
-#ifdef EAP_TLS
-#ifdef CONFIG_HS20
- if (ret == 0)
- ret = eap_peer_wfa_unauth_tls_register();
-#endif /* CONFIG_HS20 */
-#endif /* EAP_TLS */
-
-#ifdef EAP_MSCHAPv2
- if (ret == 0)
- ret = eap_peer_mschapv2_register();
-#endif /* EAP_MSCHAPv2 */
-
-#ifdef EAP_PEAP
- if (ret == 0)
- ret = eap_peer_peap_register();
-#endif /* EAP_PEAP */
-
-#ifdef EAP_TTLS
- if (ret == 0)
- ret = eap_peer_ttls_register();
-#endif /* EAP_TTLS */
-
-#ifdef EAP_GTC
- if (ret == 0)
- ret = eap_peer_gtc_register();
-#endif /* EAP_GTC */
-
-#ifdef EAP_OTP
- if (ret == 0)
- ret = eap_peer_otp_register();
-#endif /* EAP_OTP */
-
-#ifdef EAP_SIM
- if (ret == 0)
- ret = eap_peer_sim_register();
-#endif /* EAP_SIM */
-
-#ifdef EAP_LEAP
- if (ret == 0)
- ret = eap_peer_leap_register();
-#endif /* EAP_LEAP */
-
-#ifdef EAP_PSK
- if (ret == 0)
- ret = eap_peer_psk_register();
-#endif /* EAP_PSK */
-
-#ifdef EAP_AKA
- if (ret == 0)
- ret = eap_peer_aka_register();
-#endif /* EAP_AKA */
-
-#ifdef EAP_AKA_PRIME
- if (ret == 0)
- ret = eap_peer_aka_prime_register();
-#endif /* EAP_AKA_PRIME */
-
-#ifdef EAP_FAST
- if (ret == 0)
- ret = eap_peer_fast_register();
-#endif /* EAP_FAST */
-
-#ifdef EAP_TEAP
- if (ret == 0)
- ret = eap_peer_teap_register();
-#endif /* EAP_TEAP */
-
-#ifdef EAP_PAX
- if (ret == 0)
- ret = eap_peer_pax_register();
-#endif /* EAP_PAX */
-
-#ifdef EAP_SAKE
- if (ret == 0)
- ret = eap_peer_sake_register();
-#endif /* EAP_SAKE */
-
-#ifdef EAP_GPSK
- if (ret == 0)
- ret = eap_peer_gpsk_register();
-#endif /* EAP_GPSK */
-
-#ifdef EAP_WSC
- if (ret == 0)
- ret = eap_peer_wsc_register();
-#endif /* EAP_WSC */
-
-#ifdef EAP_IKEV2
- if (ret == 0)
- ret = eap_peer_ikev2_register();
-#endif /* EAP_IKEV2 */
-
-#ifdef EAP_VENDOR_TEST
- if (ret == 0)
- ret = eap_peer_vendor_test_register();
-#endif /* EAP_VENDOR_TEST */
-
-#ifdef EAP_TNC
- if (ret == 0)
- ret = eap_peer_tnc_register();
-#endif /* EAP_TNC */
-
-#ifdef EAP_PWD
- if (ret == 0)
- ret = eap_peer_pwd_register();
-#endif /* EAP_PWD */
-
-#ifdef EAP_EKE
- if (ret == 0)
- ret = eap_peer_eke_register();
-#endif /* EAP_EKE */
-
-#ifdef EAP_SERVER_IDENTITY
- if (ret == 0)
- ret = eap_server_identity_register();
-#endif /* EAP_SERVER_IDENTITY */
-
-#ifdef EAP_SERVER_MD5
- if (ret == 0)
- ret = eap_server_md5_register();
-#endif /* EAP_SERVER_MD5 */
-
-#ifdef EAP_SERVER_TLS
- if (ret == 0)
- ret = eap_server_tls_register();
-#endif /* EAP_SERVER_TLS */
-
-#ifdef EAP_SERVER_UNAUTH_TLS
- if (ret == 0)
- ret = eap_server_unauth_tls_register();
-#endif /* EAP_SERVER_UNAUTH_TLS */
-
-#ifdef EAP_SERVER_MSCHAPV2
- if (ret == 0)
- ret = eap_server_mschapv2_register();
-#endif /* EAP_SERVER_MSCHAPV2 */
-
-#ifdef EAP_SERVER_PEAP
- if (ret == 0)
- ret = eap_server_peap_register();
-#endif /* EAP_SERVER_PEAP */
-
-#ifdef EAP_SERVER_TLV
- if (ret == 0)
- ret = eap_server_tlv_register();
-#endif /* EAP_SERVER_TLV */
-
-#ifdef EAP_SERVER_GTC
- if (ret == 0)
- ret = eap_server_gtc_register();
-#endif /* EAP_SERVER_GTC */
-
-#ifdef EAP_SERVER_TTLS
- if (ret == 0)
- ret = eap_server_ttls_register();
-#endif /* EAP_SERVER_TTLS */
-
-#ifdef EAP_SERVER_SIM
- if (ret == 0)
- ret = eap_server_sim_register();
-#endif /* EAP_SERVER_SIM */
-
-#ifdef EAP_SERVER_AKA
- if (ret == 0)
- ret = eap_server_aka_register();
-#endif /* EAP_SERVER_AKA */
-
-#ifdef EAP_SERVER_AKA_PRIME
- if (ret == 0)
- ret = eap_server_aka_prime_register();
-#endif /* EAP_SERVER_AKA_PRIME */
-
-#ifdef EAP_SERVER_PAX
- if (ret == 0)
- ret = eap_server_pax_register();
-#endif /* EAP_SERVER_PAX */
-
-#ifdef EAP_SERVER_PSK
- if (ret == 0)
- ret = eap_server_psk_register();
-#endif /* EAP_SERVER_PSK */
-
-#ifdef EAP_SERVER_SAKE
- if (ret == 0)
- ret = eap_server_sake_register();
-#endif /* EAP_SERVER_SAKE */
-
-#ifdef EAP_SERVER_GPSK
- if (ret == 0)
- ret = eap_server_gpsk_register();
-#endif /* EAP_SERVER_GPSK */
-
-#ifdef EAP_SERVER_VENDOR_TEST
- if (ret == 0)
- ret = eap_server_vendor_test_register();
-#endif /* EAP_SERVER_VENDOR_TEST */
-
-#ifdef EAP_SERVER_FAST
- if (ret == 0)
- ret = eap_server_fast_register();
-#endif /* EAP_SERVER_FAST */
-
-#ifdef EAP_SERVER_TEAP
- if (ret == 0)
- ret = eap_server_teap_register();
-#endif /* EAP_SERVER_TEAP */
-
-#ifdef EAP_SERVER_WSC
- if (ret == 0)
- ret = eap_server_wsc_register();
-#endif /* EAP_SERVER_WSC */
-
-#ifdef EAP_SERVER_IKEV2
- if (ret == 0)
- ret = eap_server_ikev2_register();
-#endif /* EAP_SERVER_IKEV2 */
-
-#ifdef EAP_SERVER_TNC
- if (ret == 0)
- ret = eap_server_tnc_register();
-#endif /* EAP_SERVER_TNC */
-
-#ifdef EAP_SERVER_PWD
- if (ret == 0)
- ret = eap_server_pwd_register();
-#endif /* EAP_SERVER_PWD */
-
- return ret;
-}
diff --git a/wpa_supplicant/eap_testing.txt b/wpa_supplicant/eap_testing.txt
deleted file mode 100644
index 8d132223f6a0..000000000000
--- a/wpa_supplicant/eap_testing.txt
+++ /dev/null
@@ -1,392 +0,0 @@
-Automatic regression and interoperability testing of wpa_supplicant's
-IEEE 802.1X/EAPOL authentication
-
-Test program:
-- Linked some parts of IEEE 802.1X Authenticator implementation from
- hostapd (RADIUS client and RADIUS processing, EAP<->RADIUS
- encapsulation/decapsulation) into wpa_supplicant.
-- Replaced wpa_supplicant.c and wpa.c with test code that trigger
- IEEE 802.1X authentication automatically without need for wireless
- client card or AP.
-- For EAP methods that generate keying material, the key derived by the
- Supplicant is verified to match with the one received by the (now
- integrated) Authenticator.
-
-The full automated test suite can now be run in couple of seconds, but
-I'm more than willing to add new RADIUS authentication servers to make
-this take a bit more time.. ;-) As an extra bonus, this can also be
-seen as automatic regression/interoperability testing for the RADIUS
-server, too.
-
-In order for me to be able to use a new authentication server, the
-server need to be available from Internet (at least from one static IP
-address) and I will need to get suitable user name/password pairs,
-certificates, and private keys for testing use. Other alternative
-would be to get an evaluation version of the server so that I can
-install it on my own test setup. If you are interested in providing
-either server access or evaluation version, please contact me
-(j@w1.fi).
-
-
-Test matrix
-
-+) tested successfully
-F) failed
--) server did not support
-?) not tested
-
-Cisco ACS ----------------------------------------------------------.
-hostapd --------------------------------------------------------. |
-Cisco Aironet 1200 AP (local RADIUS server) ----------------. | |
-Periodik Labs Elektron ---------------------------------. | | |
-Lucent NavisRadius ---------------------------------. | | | |
-Interlink RAD-Series ---------------------------. | | | | |
-Radiator -----------------------------------. | | | | | |
-Meetinghouse Aegis ---------------------. | | | | | | |
-Funk Steel-Belted ------------------. | | | | | | | |
-Funk Odyssey -------------------. | | | | | | | | |
-Microsoft IAS --------------. | | | | | | | | | |
-FreeRADIUS -------------. | | | | | | | | | | |
- | | | | | | | | | | | |
-
-EAP-MD5 + - - + + + + + - - + +
-EAP-GTC + - - ? + + + + - - + -
-EAP-OTP - - - - - + - - - - - -
-EAP-MSCHAPv2 + - - + + + + + - - + -
-EAP-TLS + + + + + + + + - - + +
-EAP-PEAPv0/MSCHAPv2 + + + + + + + + + - + +
-EAP-PEAPv0/GTC + - + - + + + + - - + +
-EAP-PEAPv0/OTP - - - - - + - - - - - -
-EAP-PEAPv0/MD5 + - - + + + + + - - + -
-EAP-PEAPv0/TLS + + - + + + F + - - + +
-EAP-PEAPv0/SIM - - - - - - - - - - + -
-EAP-PEAPv0/AKA - - - - - - - - - - + -
-EAP-PEAPv0/PSK - - - - - - - - - - + -
-EAP-PEAPv0/PAX - - - - - - - - - - + -
-EAP-PEAPv0/SAKE - - - - - - - - - - + -
-EAP-PEAPv0/GPSK - - - - - - - - - - + -
-EAP-PEAPv1/MSCHAPv2 - - + + + +1 + +5 +8 - + +
-EAP-PEAPv1/GTC - - + + + +1 + +5 +8 - + +
-EAP-PEAPv1/OTP - - - - - +1 - - - - - -
-EAP-PEAPv1/MD5 - - - + + +1 + +5 - - + -
-EAP-PEAPv1/TLS - - - + + +1 F +5 - - + +
-EAP-PEAPv1/SIM - - - - - - - - - - + -
-EAP-PEAPv1/AKA - - - - - - - - - - + -
-EAP-PEAPv1/PSK - - - - - - - - - - + -
-EAP-PEAPv1/PAX - - - - - - - - - - + -
-EAP-PEAPv1/SAKE - - - - - - - - - - + -
-EAP-PEAPv1/GPSK - - - - - - - - - - + -
-EAP-TTLS/CHAP + - +2 + + + + + + - + -
-EAP-TTLS/MSCHAP + - + + + + + + + - + -
-EAP-TTLS/MSCHAPv2 + - + + + + + + + - + -
-EAP-TTLS/PAP + - + + + + + + + - + -
-EAP-TTLS/EAP-MD5 + - +2 + + + + + + - + -
-EAP-TTLS/EAP-GTC + - +2 ? + + + + - - + -
-EAP-TTLS/EAP-OTP - - - - - + - - - - - -
-EAP-TTLS/EAP-MSCHAPv2 + - +2 + + + + + + - + -
-EAP-TTLS/EAP-TLS + - +2 + F + + + - - + -
-EAP-TTLS/EAP-SIM - - - - - - - - - - + -
-EAP-TTLS/EAP-AKA - - - - - - - - - - + -
-EAP-TTLS/EAP-PSK - - - - - - - - - - + -
-EAP-TTLS/EAP-PAX - - - - - - - - - - + -
-EAP-TTLS/EAP-SAKE - - - - - - - - - - + -
-EAP-TTLS/EAP-GPSK - - - - - - - - - - + -
-EAP-TTLS + TNC - - - - - + - - - - + -
-EAP-SIM + - - ? - + - ? - - + -
-EAP-AKA - - - - - + - - - - + -
-EAP-AKA' - - - - - - - - - - + -
-EAP-PSK +7 - - - - + - - - - + -
-EAP-PAX - - - - - + - - - - + -
-EAP-SAKE - - - - - - - - - - + -
-EAP-GPSK - - - - - - - - - - + -
-EAP-FAST/MSCHAPv2(prov) - - - + - + - - - + + +
-EAP-FAST/GTC(auth) - - - + - + - - - + + +
-EAP-FAST/MSCHAPv2(aprov)- - - - - + - - - - + +
-EAP-FAST/GTC(aprov) - - - - - + - - - - + +
-EAP-FAST/MD5(aprov) - - - - - + - - - - + -
-EAP-FAST/TLS(aprov) - - - - - - - - - - + +
-EAP-FAST/SIM(aprov) - - - - - - - - - - + -
-EAP-FAST/AKA(aprov) - - - - - - - - - - + -
-EAP-FAST/MSCHAPv2(auth) - - - - - + - - - - + +
-EAP-FAST/MD5(auth) - - - - - + - - - - + -
-EAP-FAST/TLS(auth) - - - - - - - - - - + +
-EAP-FAST/SIM(auth) - - - - - - - - - - + -
-EAP-FAST/AKA(auth) - - - - - - - - - - + -
-EAP-FAST + TNC - - - - - - - - - - + -
-LEAP + - + + + + F +6 - + - +
-EAP-TNC +9 - - - - + - - - - + -
-EAP-IKEv2 +10 - - - - - - - - - + -
-
-1) PEAPv1 required new label, "client PEAP encryption" instead of "client EAP
- encryption", during key derivation (requires phase1="peaplabel=1" in the
- network configuration in wpa_supplicant.conf)
-2) used FreeRADIUS as inner auth server
-5) PEAPv1 required termination of negotiation on tunneled EAP-Success and new
- label in key deriviation
- (phase1="peap_outer_success=0 peaplabel=1") (in "IETF Draft 5" mode)
-6) Authenticator simulator required patching for handling Access-Accept within
- negotiation (for the first EAP-Success of LEAP)
-7) tested only with an older (incompatible) draft of EAP-PSK; FreeRADIUS does
- not support the current EAP-PSK (RFC) specification
-8) PEAPv1 used non-standard version negotiation (client had to force v1 even
- though server reported v0 as the highest supported version)
-9) only EAP-TTLS/EAP-TNC tested, i.e., test did not include proper sequence of
- client authentication followed by TNC inside the tunnel
-10) worked only with special compatibility code to match the IKEv2 server
- implementation
-
-
-Automated tests:
-
-FreeRADIUS (2.0-beta/CVS snapshot)
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv0 / TLS
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / EAP-TLS
-- EAP-TTLS / CHAP
-- EAP-TTLS / PAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / EAP-TNC (partial support; no authentication sequence)
-- EAP-SIM
-- LEAP
-
-Microsoft Windows Server 2003 / IAS
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / TLS
-- EAP-MD5
-* IAS does not seem to support other EAP methods
-
-Funk Odyssey 2.01.00.653
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / GTC
- Note: PEAPv1 requires TLS key derivation to use label "client EAP encryption"
-- EAP-TTLS / CHAP (using FreeRADIUS as inner auth srv)
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge (using FreeRADIUS as inner auth srv)
-- EAP-TTLS / EAP-GTC (using FreeRADIUS as inner auth srv)
-- EAP-TTLS / EAP-MSCHAPv2 (using FreeRADIUS as inner auth srv)
-- EAP-TTLS / EAP-TLS (using FreeRADIUS as inner auth srv)
-* not supported in Odyssey:
- - EAP-MD5-Challenge
- - EAP-GTC
- - EAP-MSCHAPv2
- - EAP-PEAP / MD5-Challenge
- - EAP-PEAP / TLS
-
-Funk Steel-Belted Radius Enterprise Edition v4.71.739
-- EAP-MD5-Challenge
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / MD5
-- EAP-PEAPv0 / TLS
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / MD5
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / TLS
- Note: PEAPv1 requires TLS key derivation to use label "client EAP encryption"
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / EAP-TLS
-
-Meetinghouse Aegis 1.1.4
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / TLS
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / TLS
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / MD5-Challenge
- Note: PEAPv1 requires TLS key derivation to use label "client EAP encryption"
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-MSCHAPv2
-* did not work
- - EAP-TTLS / EAP-TLS
- (Server rejects authentication without any reason in debug log. It
- looks like the inner TLS negotiation starts properly and the last
- packet from Supplicant looks like the one sent in the Phase 1. The
- server generates a valid looking reply in the same way as in Phase
- 1, but then ends up sending Access-Reject. Maybe an issue with TTLS
- fragmentation in the Aegis server(?) The packet seems to include
- 1328 bytes of EAP-Message and this may go beyond the fragmentation
- limit with AVP encapsulation and TLS tunneling. Note: EAP-PEAP/TLS
- did work, so this issue seems to be with something TTLS specific.)
-
-Radiator 3.17.1 (eval, with all patches up to and including 2007-05-25)
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-OTP
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / OTP
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv0 / TLS
- Note: Needed to use unknown identity in outer auth and some times the server
- seems to get confused and fails to send proper Phase 2 data.
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / OTP
-- EAP-PEAPv1 / MD5-Challenge
-- EAP-PEAPv1 / TLS
- Note: This has some additional requirements for EAPTLS_MaxFragmentSize.
- Using 1300 for outer auth and 500 for inner auth seemed to work.
- Note: Needed to use unknown identity in outer auth and some times the server
- seems to get confused and fails to send proper Phase 2 data.
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-OTP
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / EAP-TLS
- Note: This has some additional requirements for EAPTLS_MaxFragmentSize.
- Using 1300 for outer auth and 500 for inner auth seemed to work.
-- EAP-SIM
-- EAP-AKA
-- EAP-PSK
-- EAP-PAX
-- EAP-TNC
-
-Interlink Networks RAD-Series 6.1.2.7
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / MD5-Challenge
- Note: PEAPv1 requires TLS key derivation to use label "client EAP encryption"
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / EAP-TLS
-* did not work
- - EAP-PEAPv0 / TLS
- - EAP-PEAPv1 / TLS
- (Failed to decrypt Phase 2 data)
-
-Lucent NavisRadius 4.4.0
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / TLS
-- EAP-PEAPv1 / MD5-Challenge
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / TLS
- "IETF Draft 5" mode requires phase1="peap_outer_success=0 peaplabel=1"
- 'Cisco ACU 5.05' mode works without phase1 configuration
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-TLS
-
-Note: user certificate from NavisRadius had private key in a format
-that wpa_supplicant could not use. Converting this to PKCS#12 and then
-back to PEM allowed wpa_supplicant to use the key.
-
-
-hostapd v0.3.3
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-PEAPv1 / MSCHAPv2
-- EAP-PEAPv1 / GTC
-- EAP-PEAPv1 / MD5-Challenge
-- EAP-TTLS / CHAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
-- EAP-TTLS / PAP
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-SIM
-- EAP-PAX
-
-PEAPv1:
-
-Funk Odyssey 2.01.00.653:
-- uses tunneled EAP-Success, expects reply in tunnel or TLS ACK, sends MPPE
- keys with outer EAP-Success message after this
-- uses label "client EAP encryption"
-- (peap_outer_success 1 and 2 work)
-
-Funk Steel-Belted Radius Enterprise Edition v4.71.739
-- uses tunneled EAP-Success, expects reply in tunnel or TLS ACK, sends MPPE
- keys with outer EAP-Success message after this
-- uses label "client EAP encryption"
-- (peap_outer_success 1 and 2 work)
-
-Radiator 3.9:
-- uses TLV Success and Reply, sends MPPE keys with outer EAP-Success message
- after this
-- uses label "client PEAP encryption"
-
-Lucent NavisRadius 4.4.0 (in "IETF Draft 5" mode):
-- sends tunneled EAP-Success with MPPE keys and expects the authentication to
- terminate at this point (gets somewhat confused with reply to this)
-- uses label "client PEAP encryption"
-- phase1="peap_outer_success=0 peaplabel=1"
-
-Lucent NavisRadius 4.4.0 (in "Cisco ACU 5.05" mode):
-- sends tunneled EAP-Success with MPPE keys and expects to receive TLS ACK
- as a reply
-- uses label "client EAP encryption"
-
-Meetinghouse Aegis 1.1.4
-- uses tunneled EAP-Success, expects reply in tunnel or TLS ACK, sends MPPE
- keys with outer EAP-Success message after this
-- uses label "client EAP encryption"
-- peap_outer_success 1 and 2 work
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
deleted file mode 100644
index e256ac50eec4..000000000000
--- a/wpa_supplicant/eapol_test.c
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * WPA Supplicant - test code
- * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c.
- * Not used in production version.
- */
-
-#include "includes.h"
-#include <assert.h>
-
-#include "common.h"
-#include "utils/ext_password.h"
-#include "common/version.h"
-#include "crypto/tls.h"
-#include "config.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "eap_peer/eap.h"
-#include "eap_server/eap_methods.h"
-#include "eloop.h"
-#include "utils/base64.h"
-#include "rsn_supp/wpa.h"
-#include "wpa_supplicant_i.h"
-#include "radius/radius.h"
-#include "radius/radius_client.h"
-#include "common/wpa_ctrl.h"
-#include "ctrl_iface.h"
-#include "pcsc_funcs.h"
-#include "wpas_glue.h"
-
-
-const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
-
-
-struct extra_radius_attr {
- u8 type;
- char syntax;
- char *data;
- struct extra_radius_attr *next;
-};
-
-struct eapol_test_data {
- struct wpa_supplicant *wpa_s;
-
- int eapol_test_num_reauths;
- int no_mppe_keys;
- int num_mppe_ok, num_mppe_mismatch;
- int req_eap_key_name;
-
- u8 radius_identifier;
- struct radius_msg *last_recv_radius;
- struct in_addr own_ip_addr;
- struct radius_client_data *radius;
- struct hostapd_radius_servers *radius_conf;
-
- /* last received EAP Response from Authentication Server */
- struct wpabuf *last_eap_radius;
-
- u8 authenticator_pmk[PMK_LEN];
- size_t authenticator_pmk_len;
- u8 authenticator_eap_key_name[256];
- size_t authenticator_eap_key_name_len;
- int radius_access_accept_received;
- int radius_access_reject_received;
- int auth_timed_out;
-
- u8 *eap_identity;
- size_t eap_identity_len;
-
- char *connect_info;
- u8 own_addr[ETH_ALEN];
- struct extra_radius_attr *extra_attrs;
-
- FILE *server_cert_file;
-
- const char *pcsc_reader;
- const char *pcsc_pin;
-
- unsigned int ctrl_iface:1;
- unsigned int id_req_sent:1;
-};
-
-static struct eapol_test_data eapol_test;
-
-
-static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx);
-
-
-static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
- int level, const char *txt, size_t len)
-{
- if (addr)
- wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n",
- MAC2STR(addr), txt);
- else
- wpa_printf(MSG_DEBUG, "%s", txt);
-}
-
-
-static int add_extra_attr(struct radius_msg *msg,
- struct extra_radius_attr *attr)
-{
- size_t len;
- char *pos;
- u32 val;
- char buf[RADIUS_MAX_ATTR_LEN + 1];
-
- switch (attr->syntax) {
- case 's':
- os_snprintf(buf, sizeof(buf), "%s", attr->data);
- len = os_strlen(buf);
- break;
- case 'n':
- buf[0] = '\0';
- len = 1;
- break;
- case 'x':
- pos = attr->data;
- if (pos[0] == '0' && pos[1] == 'x')
- pos += 2;
- len = os_strlen(pos);
- if ((len & 1) || (len / 2) > RADIUS_MAX_ATTR_LEN) {
- printf("Invalid extra attribute hexstring\n");
- return -1;
- }
- len /= 2;
- if (hexstr2bin(pos, (u8 *) buf, len) < 0) {
- printf("Invalid extra attribute hexstring\n");
- return -1;
- }
- break;
- case 'd':
- val = htonl(atoi(attr->data));
- os_memcpy(buf, &val, 4);
- len = 4;
- break;
- default:
- printf("Incorrect extra attribute syntax specification\n");
- return -1;
- }
-
- if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) {
- printf("Could not add attribute %d\n", attr->type);
- return -1;
- }
-
- return 0;
-}
-
-
-static int add_extra_attrs(struct radius_msg *msg,
- struct extra_radius_attr *attrs)
-{
- struct extra_radius_attr *p;
- for (p = attrs; p; p = p->next) {
- if (add_extra_attr(msg, p) < 0)
- return -1;
- }
- return 0;
-}
-
-
-static struct extra_radius_attr *
-find_extra_attr(struct extra_radius_attr *attrs, u8 type)
-{
- struct extra_radius_attr *p;
- for (p = attrs; p; p = p->next) {
- if (p->type == type)
- return p;
- }
- return NULL;
-}
-
-
-static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
- const u8 *eap, size_t len)
-{
- struct radius_msg *msg;
- char buf[RADIUS_MAX_ATTR_LEN + 1];
- const struct eap_hdr *hdr;
- const u8 *pos;
-
- wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
- "packet");
-
- e->radius_identifier = radius_client_get_id(e->radius);
- msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
- e->radius_identifier);
- if (msg == NULL) {
- printf("Could not create net RADIUS packet\n");
- return;
- }
-
- radius_msg_make_authenticator(msg);
-
- hdr = (const struct eap_hdr *) eap;
- pos = (const u8 *) (hdr + 1);
- if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE &&
- pos[0] == EAP_TYPE_IDENTITY) {
- pos++;
- os_free(e->eap_identity);
- e->eap_identity_len = len - sizeof(*hdr) - 1;
- e->eap_identity = os_malloc(e->eap_identity_len);
- if (e->eap_identity) {
- os_memcpy(e->eap_identity, pos, e->eap_identity_len);
- wpa_hexdump(MSG_DEBUG, "Learned identity from "
- "EAP-Response-Identity",
- e->eap_identity, e->eap_identity_len);
- }
- }
-
- if (e->eap_identity &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
- e->eap_identity, e->eap_identity_len)) {
- printf("Could not add User-Name\n");
- goto fail;
- }
-
- if (e->req_eap_key_name &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, (u8 *) "\0",
- 1)) {
- printf("Could not add EAP-Key-Name\n");
- goto fail;
- }
-
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
- (u8 *) &e->own_ip_addr, 4)) {
- printf("Could not add NAS-IP-Address\n");
- goto fail;
- }
-
- os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
- MAC2STR(e->wpa_s->own_addr));
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID)
- &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
- (u8 *) buf, os_strlen(buf))) {
- printf("Could not add Calling-Station-Id\n");
- goto fail;
- }
-
- /* TODO: should probably check MTU from driver config; 2304 is max for
- * IEEE 802.11, but use 1400 to avoid problems with too large packets
- */
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) &&
- !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
- printf("Could not add Framed-MTU\n");
- goto fail;
- }
-
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) &&
- !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
- RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
- printf("Could not add NAS-Port-Type\n");
- goto fail;
- }
-
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_SERVICE_TYPE) &&
- !radius_msg_add_attr_int32(msg, RADIUS_ATTR_SERVICE_TYPE,
- RADIUS_SERVICE_TYPE_FRAMED)) {
- printf("Could not add Service-Type\n");
- goto fail;
- }
-
- os_snprintf(buf, sizeof(buf), "%s", e->connect_info);
- if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
- (u8 *) buf, os_strlen(buf))) {
- printf("Could not add Connect-Info\n");
- goto fail;
- }
-
- if (add_extra_attrs(msg, e->extra_attrs) < 0)
- goto fail;
-
- if (eap && !radius_msg_add_eap(msg, eap, len)) {
- printf("Could not add EAP-Message\n");
- goto fail;
- }
-
- /* State attribute must be copied if and only if this packet is
- * Access-Request reply to the previous Access-Challenge */
- if (e->last_recv_radius &&
- radius_msg_get_hdr(e->last_recv_radius)->code ==
- RADIUS_CODE_ACCESS_CHALLENGE) {
- int res = radius_msg_copy_attr(msg, e->last_recv_radius,
- RADIUS_ATTR_STATE);
- if (res < 0) {
- printf("Could not copy State attribute from previous "
- "Access-Challenge\n");
- goto fail;
- }
- if (res > 0) {
- wpa_printf(MSG_DEBUG, " Copied RADIUS State "
- "Attribute");
- }
- }
-
- if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr)
- < 0)
- goto fail;
- return;
-
- fail:
- radius_msg_free(msg);
-}
-
-
-static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
- size_t len)
-{
- printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n",
- type, (unsigned long) len);
- if (type == IEEE802_1X_TYPE_EAP_PACKET) {
- wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len);
- ieee802_1x_encapsulate_radius(&eapol_test, buf, len);
- }
- return 0;
-}
-
-
-static void eapol_test_set_config_blob(void *ctx,
- struct wpa_config_blob *blob)
-{
- struct eapol_test_data *e = ctx;
- wpa_config_set_blob(e->wpa_s->conf, blob);
-}
-
-
-static const struct wpa_config_blob *
-eapol_test_get_config_blob(void *ctx, const char *name)
-{
- struct eapol_test_data *e = ctx;
- return wpa_config_get_blob(e->wpa_s->conf, name);
-}
-
-
-static void eapol_test_eapol_done_cb(void *ctx)
-{
- struct eapol_test_data *e = ctx;
-
- printf("WPA: EAPOL processing complete\n");
- wpa_supplicant_cancel_auth_timeout(e->wpa_s);
- wpa_supplicant_set_state(e->wpa_s, WPA_COMPLETED);
-}
-
-
-static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx)
-{
- struct eapol_test_data *e = eloop_ctx;
- printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n");
- e->radius_access_accept_received = 0;
- send_eap_request_identity(e->wpa_s, NULL);
-}
-
-
-static int eapol_test_compare_pmk(struct eapol_test_data *e)
-{
- u8 pmk[PMK_LEN];
- int ret = 1;
- const u8 *sess_id;
- size_t sess_id_len;
-
- if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) {
- wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
- if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) {
- printf("WARNING: PMK mismatch\n");
- wpa_hexdump(MSG_DEBUG, "PMK from AS",
- e->authenticator_pmk, PMK_LEN);
- } else if (e->radius_access_accept_received)
- ret = 0;
- } else if (e->authenticator_pmk_len == 16 &&
- eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) {
- wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
- if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) {
- printf("WARNING: PMK mismatch\n");
- wpa_hexdump(MSG_DEBUG, "PMK from AS",
- e->authenticator_pmk, 16);
- } else if (e->radius_access_accept_received)
- ret = 0;
- } else if (e->radius_access_accept_received && e->no_mppe_keys) {
- /* No keying material expected */
- ret = 0;
- }
-
- if (ret && !e->no_mppe_keys)
- e->num_mppe_mismatch++;
- else if (!e->no_mppe_keys)
- e->num_mppe_ok++;
-
- sess_id = eapol_sm_get_session_id(e->wpa_s->eapol, &sess_id_len);
- if (!sess_id)
- return ret;
- if (e->authenticator_eap_key_name_len == 0) {
- wpa_printf(MSG_INFO, "No EAP-Key-Name received from server");
- return ret;
- }
-
- if (e->authenticator_eap_key_name_len != sess_id_len ||
- os_memcmp(e->authenticator_eap_key_name, sess_id, sess_id_len) != 0)
- {
- wpa_printf(MSG_INFO,
- "Locally derived EAP Session-Id does not match EAP-Key-Name from server");
- wpa_hexdump(MSG_DEBUG, "EAP Session-Id", sess_id, sess_id_len);
- wpa_hexdump(MSG_DEBUG, "EAP-Key-Name from server",
- e->authenticator_eap_key_name,
- e->authenticator_eap_key_name_len);
- } else {
- wpa_printf(MSG_INFO,
- "Locally derived EAP Session-Id matches EAP-Key-Name from server");
- }
-
- return ret;
-}
-
-
-static void eapol_sm_cb(struct eapol_sm *eapol, enum eapol_supp_result result,
- void *ctx)
-{
- struct eapol_test_data *e = ctx;
- printf("eapol_sm_cb: result=%d\n", result);
- e->id_req_sent = 0;
- if (e->ctrl_iface)
- return;
- e->eapol_test_num_reauths--;
- if (e->eapol_test_num_reauths < 0)
- eloop_terminate();
- else {
- eapol_test_compare_pmk(e);
- eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL);
- }
-}
-
-
-static void eapol_test_write_cert(FILE *f, const char *subject,
- const struct wpabuf *cert)
-{
- char *encoded;
-
- encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL);
- if (encoded == NULL)
- return;
- fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s"
- "-----END CERTIFICATE-----\n\n", subject, encoded);
- os_free(encoded);
-}
-
-
-#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
-static void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
- const char *default_txt)
-{
- struct eapol_test_data *e = ctx;
- struct wpa_supplicant *wpa_s = e->wpa_s;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- const char *field_name, *txt = NULL;
- char *buf;
- size_t buflen;
- int len;
-
- if (ssid == NULL)
- return;
-
- field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
- &txt);
- if (field_name == NULL) {
- wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
- field);
- return;
- }
-
- buflen = 100 + os_strlen(txt) + ssid->ssid_len;
- buf = os_malloc(buflen);
- if (buf == NULL)
- return;
- len = os_snprintf(buf, buflen,
- WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
- field_name, ssid->id, txt);
- if (os_snprintf_error(buflen, len)) {
- os_free(buf);
- return;
- }
- if (ssid->ssid && buflen > len + ssid->ssid_len) {
- os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
- len += ssid->ssid_len;
- buf[len] = '\0';
- }
- buf[buflen - 1] = '\0';
- wpa_msg(wpa_s, MSG_INFO, "%s", buf);
- os_free(buf);
-}
-#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
-#define eapol_test_eap_param_needed NULL
-#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
-
-
-static void eapol_test_cert_cb(void *ctx, struct tls_cert_data *cert,
- const char *cert_hash)
-{
- struct eapol_test_data *e = ctx;
- int i;
-
- wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
- "depth=%d subject='%s'%s%s",
- cert->depth, cert->subject,
- cert_hash ? " hash=" : "",
- cert_hash ? cert_hash : "");
-
- if (cert->cert) {
- char *cert_hex;
- size_t len = wpabuf_len(cert->cert) * 2 + 1;
- cert_hex = os_malloc(len);
- if (cert_hex) {
- wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert),
- wpabuf_len(cert->cert));
- wpa_msg_ctrl(e->wpa_s, MSG_INFO,
- WPA_EVENT_EAP_PEER_CERT
- "depth=%d subject='%s' cert=%s",
- cert->depth, cert->subject, cert_hex);
- os_free(cert_hex);
- }
-
- if (e->server_cert_file)
- eapol_test_write_cert(e->server_cert_file,
- cert->subject, cert->cert);
- }
-
- for (i = 0; i < cert->num_altsubject; i++)
- wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
- "depth=%d %s", cert->depth, cert->altsubject[i]);
-}
-
-
-static void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len)
-{
- struct eapol_test_data *e = ctx;
- struct wpa_supplicant *wpa_s = e->wpa_s;
- char *str;
- int res;
-
- wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity",
- id, len);
-
- if (wpa_s->current_ssid == NULL)
- return;
-
- if (id == NULL) {
- if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
- "NULL", 0) < 0)
- return;
- } else {
- str = os_malloc(len * 2 + 1);
- if (str == NULL)
- return;
- wpa_snprintf_hex(str, len * 2 + 1, id, len);
- res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
- str, 0);
- os_free(str);
- if (res < 0)
- return;
- }
-}
-
-
-static enum wpa_states eapol_test_get_state(void *ctx)
-{
- struct eapol_test_data *e = ctx;
- struct wpa_supplicant *wpa_s = e->wpa_s;
-
- return wpa_s->wpa_state;
-}
-
-
-static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct eapol_config eapol_conf;
- struct eapol_ctx *ctx;
- struct wpa_sm_ctx *wctx;
-
- ctx = os_zalloc(sizeof(*ctx));
- if (ctx == NULL) {
- printf("Failed to allocate EAPOL context.\n");
- return -1;
- }
- ctx->ctx = e;
- ctx->msg_ctx = wpa_s;
- ctx->scard_ctx = wpa_s->scard;
- ctx->cb = eapol_sm_cb;
- ctx->cb_ctx = e;
- ctx->eapol_send_ctx = wpa_s;
- ctx->preauth = 0;
- ctx->eapol_done_cb = eapol_test_eapol_done_cb;
- ctx->eapol_send = eapol_test_eapol_send;
- ctx->set_config_blob = eapol_test_set_config_blob;
- ctx->get_config_blob = eapol_test_get_config_blob;
- ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
- ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
- ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
- ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers;
- ctx->eap_param_needed = eapol_test_eap_param_needed;
- ctx->cert_cb = eapol_test_cert_cb;
- ctx->cert_in_cb = 1;
- ctx->set_anon_id = eapol_test_set_anon_id;
-
- wpa_s->eapol = eapol_sm_init(ctx);
- if (wpa_s->eapol == NULL) {
- os_free(ctx);
- printf("Failed to initialize EAPOL state machines.\n");
- return -1;
- }
-
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
- wctx = os_zalloc(sizeof(*wctx));
- if (wctx == NULL) {
- os_free(ctx);
- return -1;
- }
- wctx->ctx = e;
- wctx->msg_ctx = wpa_s;
- wctx->get_state = eapol_test_get_state;
- wpa_s->wpa = wpa_sm_init(wctx);
- if (!wpa_s->wpa) {
- os_free(ctx);
- os_free(wctx);
- return -1;
- }
-
- if (!ssid)
- return 0;
-
- wpa_s->current_ssid = ssid;
- os_memset(&eapol_conf, 0, sizeof(eapol_conf));
- eapol_conf.accept_802_1x_keys = 1;
- eapol_conf.required_keys = 0;
- eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
- eapol_conf.workaround = ssid->eap_workaround;
- eapol_conf.external_sim = wpa_s->conf->external_sim;
- eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
- eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
-
-
- eapol_sm_notify_portValid(wpa_s->eapol, false);
- /* 802.1X::portControl = Auto */
- eapol_sm_notify_portEnabled(wpa_s->eapol, true);
-
- return 0;
-}
-
-
-static void test_eapol_clean(struct eapol_test_data *e,
- struct wpa_supplicant *wpa_s)
-{
- struct extra_radius_attr *p, *prev;
-
- wpa_sm_deinit(wpa_s->wpa);
- wpa_s->wpa = NULL;
- radius_client_deinit(e->radius);
- wpabuf_free(e->last_eap_radius);
- radius_msg_free(e->last_recv_radius);
- e->last_recv_radius = NULL;
- os_free(e->eap_identity);
- e->eap_identity = NULL;
- eapol_sm_deinit(wpa_s->eapol);
- wpa_s->eapol = NULL;
- if (e->radius_conf && e->radius_conf->auth_server) {
- os_free(e->radius_conf->auth_server->shared_secret);
- os_free(e->radius_conf->auth_server);
- }
- os_free(e->radius_conf);
- e->radius_conf = NULL;
- scard_deinit(wpa_s->scard);
- wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
- wpa_s->ctrl_iface = NULL;
-
- ext_password_deinit(wpa_s->ext_pw);
- wpa_s->ext_pw = NULL;
-
- wpa_config_free(wpa_s->conf);
-
- p = e->extra_attrs;
- while (p) {
- prev = p;
- p = p->next;
- os_free(prev);
- }
-}
-
-
-static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- u8 buf[100], *pos;
- struct ieee802_1x_hdr *hdr;
- struct eap_hdr *eap;
-
- hdr = (struct ieee802_1x_hdr *) buf;
- hdr->version = EAPOL_VERSION;
- hdr->type = IEEE802_1X_TYPE_EAP_PACKET;
- hdr->length = htons(5);
-
- eap = (struct eap_hdr *) (hdr + 1);
- eap->code = EAP_CODE_REQUEST;
- if (os_get_random((u8 *) &eap->identifier, sizeof(eap->identifier)) < 0)
- eap->identifier = os_random() & 0xff;
- eap->length = htons(5);
- pos = (u8 *) (eap + 1);
- *pos = EAP_TYPE_IDENTITY;
-
- printf("Sending fake EAP-Request-Identity\n");
- eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf,
- sizeof(*hdr) + 5);
-}
-
-
-static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct eapol_test_data *e = eloop_ctx;
- printf("EAPOL test timed out\n");
- e->auth_timed_out = 1;
- eloop_terminate();
-}
-
-
-static char *eap_type_text(u8 type)
-{
- switch (type) {
- case EAP_TYPE_IDENTITY: return "Identity";
- case EAP_TYPE_NOTIFICATION: return "Notification";
- case EAP_TYPE_NAK: return "Nak";
- case EAP_TYPE_TLS: return "TLS";
- case EAP_TYPE_TTLS: return "TTLS";
- case EAP_TYPE_PEAP: return "PEAP";
- case EAP_TYPE_SIM: return "SIM";
- case EAP_TYPE_GTC: return "GTC";
- case EAP_TYPE_MD5: return "MD5";
- case EAP_TYPE_OTP: return "OTP";
- case EAP_TYPE_FAST: return "FAST";
- case EAP_TYPE_SAKE: return "SAKE";
- case EAP_TYPE_PSK: return "PSK";
- default: return "Unknown";
- }
-}
-
-
-static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
-{
- struct wpabuf *eap;
- const struct eap_hdr *hdr;
- int eap_type = -1;
- char buf[64];
- struct radius_msg *msg;
-
- if (e->last_recv_radius == NULL)
- return;
-
- msg = e->last_recv_radius;
-
- eap = radius_msg_get_eap(msg);
- if (eap == NULL) {
- /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
- * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
- * attribute */
- wpa_printf(MSG_DEBUG, "could not extract "
- "EAP-Message from RADIUS message");
- wpabuf_free(e->last_eap_radius);
- e->last_eap_radius = NULL;
- return;
- }
-
- if (wpabuf_len(eap) < sizeof(*hdr)) {
- wpa_printf(MSG_DEBUG, "too short EAP packet "
- "received from authentication server");
- wpabuf_free(eap);
- return;
- }
-
- if (wpabuf_len(eap) > sizeof(*hdr))
- eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
-
- hdr = wpabuf_head(eap);
- switch (hdr->code) {
- case EAP_CODE_REQUEST:
- os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
- eap_type >= 0 ? eap_type_text(eap_type) : "??",
- eap_type);
- break;
- case EAP_CODE_RESPONSE:
- os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
- eap_type >= 0 ? eap_type_text(eap_type) : "??",
- eap_type);
- break;
- case EAP_CODE_SUCCESS:
- os_strlcpy(buf, "EAP Success", sizeof(buf));
- /* LEAP uses EAP Success within an authentication, so must not
- * stop here with eloop_terminate(); */
- break;
- case EAP_CODE_FAILURE:
- os_strlcpy(buf, "EAP Failure", sizeof(buf));
- if (e->ctrl_iface)
- break;
- eloop_terminate();
- break;
- default:
- os_strlcpy(buf, "unknown EAP code", sizeof(buf));
- wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap);
- break;
- }
- wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
- "id=%d len=%d) from RADIUS server: %s",
- hdr->code, hdr->identifier, ntohs(hdr->length), buf);
-
- /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */
-
- wpabuf_free(e->last_eap_radius);
- e->last_eap_radius = eap;
-
- {
- struct ieee802_1x_hdr *dot1x;
- dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap));
- assert(dot1x != NULL);
- dot1x->version = EAPOL_VERSION;
- dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
- dot1x->length = htons(wpabuf_len(eap));
- os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap),
- wpabuf_len(eap));
- eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
- (u8 *) dot1x,
- sizeof(*dot1x) + wpabuf_len(eap));
- os_free(dot1x);
- }
-}
-
-
-static void ieee802_1x_get_keys(struct eapol_test_data *e,
- struct radius_msg *msg, struct radius_msg *req,
- const u8 *shared_secret,
- size_t shared_secret_len)
-{
- struct radius_ms_mppe_keys *keys;
- u8 *buf;
- size_t len;
-
- keys = radius_msg_get_ms_keys(msg, req, shared_secret,
- shared_secret_len);
- if (keys && keys->send == NULL && keys->recv == NULL) {
- os_free(keys);
- keys = radius_msg_get_cisco_keys(msg, req, shared_secret,
- shared_secret_len);
- }
-
- if (keys) {
- if (keys->send) {
- wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)",
- keys->send, keys->send_len);
- }
- if (keys->recv) {
- wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)",
- keys->recv, keys->recv_len);
- e->authenticator_pmk_len =
- keys->recv_len > PMK_LEN ? PMK_LEN :
- keys->recv_len;
- os_memcpy(e->authenticator_pmk, keys->recv,
- e->authenticator_pmk_len);
- if (e->authenticator_pmk_len == 16 && keys->send &&
- keys->send_len == 16) {
- /* MS-CHAP-v2 derives 16 octet keys */
- wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key "
- "to extend PMK to 32 octets");
- os_memcpy(e->authenticator_pmk +
- e->authenticator_pmk_len,
- keys->send, keys->send_len);
- e->authenticator_pmk_len += keys->send_len;
- }
- }
-
- os_free(keys->send);
- os_free(keys->recv);
- os_free(keys);
- }
-
- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_EAP_KEY_NAME, &buf, &len,
- NULL) == 0) {
- os_memcpy(e->authenticator_eap_key_name, buf, len);
- e->authenticator_eap_key_name_len = len;
- } else {
- e->authenticator_eap_key_name_len = 0;
- }
-}
-
-
-/* Process the RADIUS frames from Authentication Server */
-static RadiusRxResult
-ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
- const u8 *shared_secret, size_t shared_secret_len,
- void *data)
-{
- struct eapol_test_data *e = data;
- struct radius_hdr *hdr = radius_msg_get_hdr(msg);
-
- /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
- * present when packet contains an EAP-Message attribute */
- if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
- radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
- 0) < 0 &&
- radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
- wpa_printf(MSG_DEBUG, "Allowing RADIUS "
- "Access-Reject without Message-Authenticator "
- "since it does not include EAP-Message\n");
- } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
- req, 1)) {
- printf("Incoming RADIUS packet did not have correct "
- "Message-Authenticator - dropped\n");
- return RADIUS_RX_UNKNOWN;
- }
-
- if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
- hdr->code != RADIUS_CODE_ACCESS_REJECT &&
- hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
- printf("Unknown RADIUS message code\n");
- return RADIUS_RX_UNKNOWN;
- }
-
- e->radius_identifier = -1;
- wpa_printf(MSG_DEBUG, "RADIUS packet matching with station");
-
- radius_msg_free(e->last_recv_radius);
- e->last_recv_radius = msg;
-
- switch (hdr->code) {
- case RADIUS_CODE_ACCESS_ACCEPT:
- e->radius_access_accept_received = 1;
- ieee802_1x_get_keys(e, msg, req, shared_secret,
- shared_secret_len);
- break;
- case RADIUS_CODE_ACCESS_REJECT:
- e->radius_access_reject_received = 1;
- break;
- }
-
- ieee802_1x_decapsulate_radius(e);
-
- if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
- e->eapol_test_num_reauths < 0) ||
- hdr->code == RADIUS_CODE_ACCESS_REJECT) {
- if (!e->ctrl_iface)
- eloop_terminate();
- }
-
- return RADIUS_RX_QUEUED;
-}
-
-
-static int driver_get_ssid(void *priv, u8 *ssid)
-{
- ssid[0] = 0;
- return 0;
-}
-
-
-static int driver_get_bssid(void *priv, u8 *bssid)
-{
- struct eapol_test_data *e = priv;
-
- if (e->ctrl_iface && !e->id_req_sent) {
- eloop_register_timeout(0, 0, send_eap_request_identity,
- e->wpa_s, NULL);
- e->id_req_sent = 1;
- }
-
- os_memset(bssid, 0, ETH_ALEN);
- bssid[5] = 1;
- return 0;
-}
-
-
-static int driver_get_capa(void *priv, struct wpa_driver_capa *capa)
-{
- os_memset(capa, 0, sizeof(*capa));
- capa->flags = WPA_DRIVER_FLAGS_WIRED;
- return 0;
-}
-
-
-struct wpa_driver_ops eapol_test_drv_ops = {
- .name = "test",
- .get_ssid = driver_get_ssid,
- .get_bssid = driver_get_bssid,
- .get_capa = driver_get_capa,
-};
-
-static void wpa_init_conf(struct eapol_test_data *e,
- struct wpa_supplicant *wpa_s, const char *authsrv,
- int port, const char *secret,
- const char *cli_addr, const char *ifname)
-{
- struct hostapd_radius_server *as;
- int res;
-
- wpa_s->driver = &eapol_test_drv_ops;
- wpa_s->drv_priv = e;
- wpa_s->bssid[5] = 1;
- os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN);
- e->own_ip_addr.s_addr = htonl((127 << 24) | 1);
- os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
-
- e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers));
- assert(e->radius_conf != NULL);
- e->radius_conf->num_auth_servers = 1;
- as = os_zalloc(sizeof(struct hostapd_radius_server));
- assert(as != NULL);
-#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
- {
- int a[4];
- u8 *pos;
- sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
- pos = (u8 *) &as->addr.u.v4;
- *pos++ = a[0];
- *pos++ = a[1];
- *pos++ = a[2];
- *pos++ = a[3];
- as->addr.af = AF_INET;
- }
-#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
- if (hostapd_parse_ip_addr(authsrv, &as->addr) < 0) {
- wpa_printf(MSG_ERROR, "Invalid IP address '%s'",
- authsrv);
- assert(0);
- }
-#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
- as->port = port;
- as->shared_secret = (u8 *) os_strdup(secret);
- as->shared_secret_len = os_strlen(secret);
- e->radius_conf->auth_server = as;
- e->radius_conf->auth_servers = as;
- e->radius_conf->msg_dumps = 1;
- if (cli_addr) {
- if (hostapd_parse_ip_addr(cli_addr,
- &e->radius_conf->client_addr) == 0)
- e->radius_conf->force_client_addr = 1;
- else {
- wpa_printf(MSG_ERROR, "Invalid IP address '%s'",
- cli_addr);
- assert(0);
- }
- }
-
- e->radius = radius_client_init(wpa_s, e->radius_conf);
- assert(e->radius != NULL);
-
- res = radius_client_register(e->radius, RADIUS_AUTH,
- ieee802_1x_receive_auth, e);
- assert(res == 0);
-}
-
-
-static int scard_test(struct eapol_test_data *e)
-{
- struct scard_data *scard;
- size_t len;
- char imsi[20];
- unsigned char _rand[16];
-#ifdef PCSC_FUNCS
- unsigned char sres[4];
- unsigned char kc[8];
-#endif /* PCSC_FUNCS */
-#define num_triplets 5
- unsigned char rand_[num_triplets][16];
- unsigned char sres_[num_triplets][4];
- unsigned char kc_[num_triplets][8];
- int i, res;
- size_t j;
-
-#define AKA_RAND_LEN 16
-#define AKA_AUTN_LEN 16
-#define AKA_AUTS_LEN 14
-#define RES_MAX_LEN 16
-#define IK_LEN 16
-#define CK_LEN 16
- unsigned char aka_rand[AKA_RAND_LEN];
- unsigned char aka_autn[AKA_AUTN_LEN];
- unsigned char aka_auts[AKA_AUTS_LEN];
- unsigned char aka_res[RES_MAX_LEN];
- size_t aka_res_len;
- unsigned char aka_ik[IK_LEN];
- unsigned char aka_ck[CK_LEN];
-
- scard = scard_init(e->pcsc_reader);
- if (scard == NULL)
- return -1;
- if (scard_set_pin(scard, e->pcsc_pin)) {
- wpa_printf(MSG_WARNING, "PIN validation failed");
- scard_deinit(scard);
- return -1;
- }
-
- len = sizeof(imsi);
- if (scard_get_imsi(scard, imsi, &len))
- goto failed;
- wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len);
- /* NOTE: Permanent Username: 1 | IMSI */
-
- wpa_printf(MSG_DEBUG, "SCARD: MNC length %d",
- scard_get_mnc_len(scard));
-
- os_memset(_rand, 0, sizeof(_rand));
- if (scard_gsm_auth(scard, _rand, sres, kc))
- goto failed;
-
- os_memset(_rand, 0xff, sizeof(_rand));
- if (scard_gsm_auth(scard, _rand, sres, kc))
- goto failed;
-
- for (i = 0; i < num_triplets; i++) {
- os_memset(rand_[i], i, sizeof(rand_[i]));
- if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i]))
- goto failed;
- }
-
- for (i = 0; i < num_triplets; i++) {
- printf("1");
- for (j = 0; j < len; j++)
- printf("%c", imsi[j]);
- printf(",");
- for (j = 0; j < 16; j++)
- printf("%02X", rand_[i][j]);
- printf(",");
- for (j = 0; j < 4; j++)
- printf("%02X", sres_[i][j]);
- printf(",");
- for (j = 0; j < 8; j++)
- printf("%02X", kc_[i][j]);
- printf("\n");
- }
-
- wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication");
-
- /* seq 39 (0x28) */
- os_memset(aka_rand, 0xaa, 16);
- os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf"
- "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16);
-
- res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len,
- aka_ik, aka_ck, aka_auts);
- if (res == 0) {
- wpa_printf(MSG_DEBUG, "UMTS auth completed successfully");
- wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len);
- wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN);
- wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN);
- } else if (res == -2) {
- wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization "
- "failure");
- wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "UMTS auth failed");
- }
-
-failed:
- scard_deinit(scard);
-
- return 0;
-#undef num_triplets
-}
-
-
-static int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[])
-{
- struct scard_data *scard;
- size_t len;
- char imsi[20];
- unsigned char _rand[16];
- unsigned char sres[4];
- unsigned char kc[8];
- int num_triplets;
- int i;
- size_t j;
-
- if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) {
- printf("invalid parameters for sim command\n");
- return -1;
- }
-
- if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) {
- /* disable debug output */
- wpa_debug_level = 99;
- }
-
- scard = scard_init(e->pcsc_reader);
- if (scard == NULL) {
- printf("Failed to open smartcard connection\n");
- return -1;
- }
- if (scard_set_pin(scard, argv[0])) {
- wpa_printf(MSG_WARNING, "PIN validation failed");
- scard_deinit(scard);
- return -1;
- }
-
- len = sizeof(imsi);
- if (scard_get_imsi(scard, imsi, &len)) {
- scard_deinit(scard);
- return -1;
- }
-
- for (i = 0; i < num_triplets; i++) {
- os_memset(_rand, i, sizeof(_rand));
- if (scard_gsm_auth(scard, _rand, sres, kc))
- break;
-
- /* IMSI:Kc:SRES:RAND */
- for (j = 0; j < len; j++)
- printf("%c", imsi[j]);
- printf(":");
- for (j = 0; j < 8; j++)
- printf("%02X", kc[j]);
- printf(":");
- for (j = 0; j < 4; j++)
- printf("%02X", sres[j]);
- printf(":");
- for (j = 0; j < 16; j++)
- printf("%02X", _rand[j]);
- printf("\n");
- }
-
- scard_deinit(scard);
-
- return 0;
-}
-
-
-static void eapol_test_terminate(int sig, void *signal_ctx)
-{
- struct wpa_supplicant *wpa_s = signal_ctx;
- wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig);
- eloop_terminate();
-}
-
-
-static void usage(void)
-{
- printf("usage:\n"
- "eapol_test [-enWSv] -c<conf> [-a<AS IP>] [-p<AS port>] "
- "[-s<AS secret>]\\\n"
- " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
- " [-M<client MAC address>] [-o<server cert file] \\\n"
- " [-N<attr spec>] [-R<PC/SC reader>] "
- "[-P<PC/SC PIN>] \\\n"
- " [-A<client IP>] [-i<ifname>] [-T<ctrl_iface>]\n"
- "eapol_test scard\n"
- "eapol_test sim <PIN> <num triplets> [debug]\n"
- "\n");
- printf("options:\n"
- " -c<conf> = configuration file\n"
- " -a<AS IP> = IP address of the authentication server, "
- "default 127.0.0.1\n"
- " -p<AS port> = UDP port of the authentication server, "
- "default 1812\n"
- " -s<AS secret> = shared secret with the authentication "
- "server, default 'radius'\n"
- " -A<client IP> = IP address of the client, default: select "
- "automatically\n"
- " -r<count> = number of re-authentications\n"
- " -e = Request EAP-Key-Name\n"
- " -W = wait for a control interface monitor before starting\n"
- " -S = save configuration after authentication\n"
- " -n = no MPPE keys expected\n"
- " -v = show version\n"
- " -t<timeout> = sets timeout in seconds (default: 30 s)\n"
- " -C<Connect-Info> = RADIUS Connect-Info (default: "
- "CONNECT 11Mbps 802.11b)\n"
- " -M<client MAC address> = Set own MAC address "
- "(Calling-Station-Id,\n"
- " default: 02:00:00:00:00:01)\n"
- " -o<server cert file> = Write received server certificate\n"
- " chain to the specified file\n"
- " -N<attr spec> = send arbitrary attribute specified by:\n"
- " attr_id:syntax:value or attr_id\n"
- " attr_id - number id of the attribute\n"
- " syntax - one of: s, d, x\n"
- " s = string\n"
- " d = integer\n"
- " x = octet string\n"
- " value - attribute value.\n"
- " When only attr_id is specified, NULL will be used as "
- "value.\n"
- " Multiple attributes can be specified by using the "
- "option several times.\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- struct wpa_global global;
- struct wpa_supplicant wpa_s;
- int c, ret = 1, wait_for_monitor = 0, save_config = 0;
- char *as_addr = "127.0.0.1";
- int as_port = 1812;
- char *as_secret = "radius";
- char *cli_addr = NULL;
- char *conf = NULL;
- int timeout = 30;
- char *pos;
- struct extra_radius_attr *p = NULL, *p1;
- const char *ifname = "test";
- const char *ctrl_iface = NULL;
-
- if (os_program_init())
- return -1;
-
- hostapd_logger_register_cb(hostapd_logger_cb);
-
- os_memset(&eapol_test, 0, sizeof(eapol_test));
- eapol_test.connect_info = "CONNECT 11Mbps 802.11b";
- os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN);
- eapol_test.pcsc_pin = "1234";
-
- wpa_debug_level = 0;
- wpa_debug_show_keys = 1;
-
- for (;;) {
- c = getopt(argc, argv, "a:A:c:C:ei:M:nN:o:p:P:r:R:s:St:T:vW");
- if (c < 0)
- break;
- switch (c) {
- case 'a':
- as_addr = optarg;
- break;
- case 'A':
- cli_addr = optarg;
- break;
- case 'c':
- conf = optarg;
- break;
- case 'C':
- eapol_test.connect_info = optarg;
- break;
- case 'e':
- eapol_test.req_eap_key_name = 1;
- break;
- case 'i':
- ifname = optarg;
- break;
- case 'M':
- if (hwaddr_aton(optarg, eapol_test.own_addr)) {
- usage();
- return -1;
- }
- break;
- case 'n':
- eapol_test.no_mppe_keys++;
- break;
- case 'o':
- if (eapol_test.server_cert_file)
- fclose(eapol_test.server_cert_file);
- eapol_test.server_cert_file = fopen(optarg, "w");
- if (eapol_test.server_cert_file == NULL) {
- printf("Could not open '%s' for writing\n",
- optarg);
- return -1;
- }
- break;
- case 'p':
- as_port = atoi(optarg);
- break;
- case 'P':
- eapol_test.pcsc_pin = optarg;
- break;
- case 'r':
- eapol_test.eapol_test_num_reauths = atoi(optarg);
- break;
- case 'R':
- eapol_test.pcsc_reader = optarg;
- break;
- case 's':
- as_secret = optarg;
- break;
- case 'S':
- save_config++;
- break;
- case 't':
- timeout = atoi(optarg);
- break;
- case 'T':
- ctrl_iface = optarg;
- eapol_test.ctrl_iface = 1;
- break;
- case 'v':
- printf("eapol_test v%s\n", VERSION_STR);
- return 0;
- case 'W':
- wait_for_monitor++;
- break;
- case 'N':
- p1 = os_zalloc(sizeof(*p1));
- if (p1 == NULL)
- break;
- if (!p)
- eapol_test.extra_attrs = p1;
- else
- p->next = p1;
- p = p1;
-
- p->type = atoi(optarg);
- pos = os_strchr(optarg, ':');
- if (pos == NULL) {
- p->syntax = 'n';
- p->data = NULL;
- break;
- }
-
- pos++;
- if (pos[0] == '\0' || pos[1] != ':') {
- printf("Incorrect format of attribute "
- "specification\n");
- break;
- }
-
- p->syntax = pos[0];
- p->data = pos + 2;
- break;
- default:
- usage();
- return -1;
- }
- }
-
- if (argc > optind && os_strcmp(argv[optind], "scard") == 0) {
- return scard_test(&eapol_test);
- }
-
- if (argc > optind && os_strcmp(argv[optind], "sim") == 0) {
- return scard_get_triplets(&eapol_test, argc - optind - 1,
- &argv[optind + 1]);
- }
-
- if (conf == NULL && !ctrl_iface) {
- usage();
- printf("Configuration file is required.\n");
- return -1;
- }
-
- if (eap_register_methods()) {
- wpa_printf(MSG_ERROR, "Failed to register EAP methods");
- return -1;
- }
-
- if (eloop_init()) {
- wpa_printf(MSG_ERROR, "Failed to initialize event loop");
- return -1;
- }
-
- os_memset(&global, 0, sizeof(global));
- os_memset(&wpa_s, 0, sizeof(wpa_s));
- wpa_s.global = &global;
- eapol_test.wpa_s = &wpa_s;
- dl_list_init(&wpa_s.bss);
- dl_list_init(&wpa_s.bss_id);
- if (conf)
- wpa_s.conf = wpa_config_read(conf, NULL);
- else
- wpa_s.conf = wpa_config_alloc_empty(ctrl_iface, NULL);
- if (wpa_s.conf == NULL) {
- printf("Failed to parse configuration file '%s'.\n", conf);
- return -1;
- }
- if (!ctrl_iface && wpa_s.conf->ssid == NULL) {
- printf("No networks defined.\n");
- return -1;
- }
-
- if (eapol_test.pcsc_reader) {
- os_free(wpa_s.conf->pcsc_reader);
- wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader);
- }
-
- wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret,
- cli_addr, ifname);
- wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
- if (wpa_s.ctrl_iface == NULL) {
- printf("Failed to initialize control interface '%s'.\n"
- "You may have another eapol_test process already "
- "running or the file was\n"
- "left by an unclean termination of eapol_test in "
- "which case you will need\n"
- "to manually remove this file before starting "
- "eapol_test again.\n",
- wpa_s.conf->ctrl_interface);
- return -1;
- }
- if (wpa_s.conf->ssid &&
- wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid))
- return -1;
-
- if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
- return -1;
-
- if (wpas_init_ext_pw(&wpa_s) < 0)
- return -1;
-
- if (wait_for_monitor)
- wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface);
-
- if (!ctrl_iface) {
- eloop_register_timeout(timeout, 0, eapol_test_timeout,
- &eapol_test, NULL);
- eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s,
- NULL);
- }
- eloop_register_signal_terminate(eapol_test_terminate, &wpa_s);
- eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s);
- eloop_run();
-
- eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL);
- eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL);
-
- if (eapol_test_compare_pmk(&eapol_test) == 0 ||
- eapol_test.no_mppe_keys)
- ret = 0;
- if (eapol_test.auth_timed_out)
- ret = -2;
- if (eapol_test.radius_access_reject_received)
- ret = -3;
-
- if (save_config)
- wpa_config_write(conf, wpa_s.conf);
-
- test_eapol_clean(&eapol_test, &wpa_s);
-
- eap_peer_unregister_methods();
-#ifdef CONFIG_AP
- eap_server_unregister_methods();
-#endif /* CONFIG_AP */
-
- eloop_destroy();
-
- if (eapol_test.server_cert_file)
- fclose(eapol_test.server_cert_file);
-
- printf("MPPE keys OK: %d mismatch: %d\n",
- eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
- if (eapol_test.num_mppe_mismatch)
- ret = -4;
- if (ret)
- printf("FAILURE\n");
- else
- printf("SUCCESS\n");
-
- os_program_deinit();
-
- return ret;
-}
diff --git a/wpa_supplicant/eapol_test.py b/wpa_supplicant/eapol_test.py
deleted file mode 100755
index 88c83f343597..000000000000
--- a/wpa_supplicant/eapol_test.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env python2
-#
-# eapol_test controller
-# Copyright (c) 2015, Jouni Malinen <j@w1.fi>
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import argparse
-import logging
-import os
-import Queue
-import sys
-import threading
-
-logger = logging.getLogger()
-dir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__))
-sys.path.append(os.path.join(dir, '..', 'wpaspy'))
-import wpaspy
-wpas_ctrl = '/tmp/eapol_test'
-
-class eapol_test:
- def __init__(self, ifname):
- self.ifname = ifname
- self.ctrl = wpaspy.Ctrl(os.path.join(wpas_ctrl, ifname))
- if "PONG" not in self.ctrl.request("PING"):
- raise Exception("Failed to connect to eapol_test (%s)" % ifname)
- self.mon = wpaspy.Ctrl(os.path.join(wpas_ctrl, ifname))
- self.mon.attach()
-
- def add_network(self):
- id = self.request("ADD_NETWORK")
- if "FAIL" in id:
- raise Exception("ADD_NETWORK failed")
- return int(id)
-
- def remove_network(self, id):
- id = self.request("REMOVE_NETWORK " + str(id))
- if "FAIL" in id:
- raise Exception("REMOVE_NETWORK failed")
- return None
-
- def set_network(self, id, field, value):
- res = self.request("SET_NETWORK " + str(id) + " " + field + " " + value)
- if "FAIL" in res:
- raise Exception("SET_NETWORK failed")
- return None
-
- def set_network_quoted(self, id, field, value):
- res = self.request("SET_NETWORK " + str(id) + " " + field + ' "' + value + '"')
- if "FAIL" in res:
- raise Exception("SET_NETWORK failed")
- return None
-
- def request(self, cmd, timeout=10):
- return self.ctrl.request(cmd, timeout=timeout)
-
- def wait_event(self, events, timeout=10):
- start = os.times()[4]
- while True:
- while self.mon.pending():
- ev = self.mon.recv()
- logger.debug(self.ifname + ": " + ev)
- for event in events:
- if event in ev:
- return ev
- now = os.times()[4]
- remaining = start + timeout - now
- if remaining <= 0:
- break
- if not self.mon.pending(timeout=remaining):
- break
- return None
-
-def run(ifname, count, no_fast_reauth, res, conf):
- et = eapol_test(ifname)
-
- et.request("AP_SCAN 0")
- if no_fast_reauth:
- et.request("SET fast_reauth 0")
- else:
- et.request("SET fast_reauth 1")
- id = et.add_network()
-
- if len(conf):
- for item in conf:
- et.set_network(id, item, conf[item])
- else:
- et.set_network(id, "key_mgmt", "IEEE8021X")
- et.set_network(id, "eapol_flags", "0")
- et.set_network(id, "eap", "TLS")
- et.set_network_quoted(id, "identity", "user")
- et.set_network_quoted(id, "ca_cert", 'ca.pem')
- et.set_network_quoted(id, "client_cert", 'client.pem')
- et.set_network_quoted(id, "private_key", 'client.key')
- et.set_network_quoted(id, "private_key_passwd", 'whatever')
-
- et.set_network(id, "disabled", "0")
-
- fail = False
- for i in range(count):
- et.request("REASSOCIATE")
- ev = et.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-EAP-FAILURE"])
- if ev is None or "CTRL-EVENT-CONNECTED" not in ev:
- fail = True
- break
-
- et.remove_network(id)
-
- if fail:
- res.put("FAIL (%d OK)" % i)
- else:
- res.put("PASS %d" % (i + 1))
-
-def main():
- parser = argparse.ArgumentParser(description='eapol_test controller')
- parser.add_argument('--ctrl', help='control interface directory')
- parser.add_argument('--num', help='number of processes')
- parser.add_argument('--iter', help='number of iterations')
- parser.add_argument('--no-fast-reauth', action='store_true',
- dest='no_fast_reauth',
- help='disable TLS session resumption')
- parser.add_argument('--conf', help='file of network conf items')
- args = parser.parse_args()
-
- num = int(args.num)
- iter = int(args.iter)
- if args.ctrl:
- global wpas_ctrl
- wpas_ctrl = args.ctrl
-
- conf = {}
- if args.conf:
- f = open(args.conf, "r")
- for line in f:
- confitem = line.split("=")
- if len(confitem) == 2:
- conf[confitem[0].strip()] = confitem[1].strip()
- f.close()
-
- t = {}
- res = {}
- for i in range(num):
- res[i] = Queue.Queue()
- t[i] = threading.Thread(target=run, args=(str(i), iter,
- args.no_fast_reauth, res[i],
- conf))
- for i in range(num):
- t[i].start()
- for i in range(num):
- t[i].join()
- try:
- results = res[i].get(False)
- except:
- results = "N/A"
- print("%d: %s" % (i, results))
-
-if __name__ == "__main__":
- main()
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
deleted file mode 100644
index f55e1846e205..000000000000
--- a/wpa_supplicant/events.c
+++ /dev/null
@@ -1,5783 +0,0 @@
-/*
- * WPA Supplicant - Driver event processing
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "eloop.h"
-#include "config.h"
-#include "l2_packet/l2_packet.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "pcsc_funcs.h"
-#include "rsn_supp/preauth.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "common/wpa_ctrl.h"
-#include "eap_peer/eap.h"
-#include "ap/hostapd.h"
-#include "p2p/p2p.h"
-#include "fst/fst.h"
-#include "wnm_sta.h"
-#include "notify.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/gas_server.h"
-#include "common/dpp.h"
-#include "common/ptksa_cache.h"
-#include "crypto/random.h"
-#include "bssid_ignore.h"
-#include "wpas_glue.h"
-#include "wps_supplicant.h"
-#include "ibss_rsn.h"
-#include "sme.h"
-#include "gas_query.h"
-#include "p2p_supplicant.h"
-#include "bgscan.h"
-#include "autoscan.h"
-#include "ap.h"
-#include "bss.h"
-#include "scan.h"
-#include "offchannel.h"
-#include "interworking.h"
-#include "mesh.h"
-#include "mesh_mpm.h"
-#include "wmm_ac.h"
-#include "dpp_supplicant.h"
-
-
-#define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5
-
-
-#ifndef CONFIG_NO_SCAN_PROCESSING
-static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
- int new_scan, int own_request);
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-
-
-int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- struct os_reltime now;
-
- if (ssid == NULL || ssid->disabled_until.sec == 0)
- return 0;
-
- os_get_reltime(&now);
- if (ssid->disabled_until.sec > now.sec)
- return ssid->disabled_until.sec - now.sec;
-
- wpas_clear_temp_disabled(wpa_s, ssid, 0);
-
- return 0;
-}
-
-
-#ifndef CONFIG_NO_SCAN_PROCESSING
-/**
- * wpas_reenabled_network_time - Time until first network is re-enabled
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: If all enabled networks are temporarily disabled, returns the time
- * (in sec) until the first network is re-enabled. Otherwise returns 0.
- *
- * This function is used in case all enabled networks are temporarily disabled,
- * in which case it returns the time (in sec) that the first network will be
- * re-enabled. The function assumes that at least one network is enabled.
- */
-static int wpas_reenabled_network_time(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
- int disabled_for, res = 0;
-
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->conf->auto_interworking && wpa_s->conf->interworking &&
- wpa_s->conf->cred)
- return 0;
-#endif /* CONFIG_INTERWORKING */
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid->disabled)
- continue;
-
- disabled_for = wpas_temp_disabled(wpa_s, ssid);
- if (!disabled_for)
- return 0;
-
- if (!res || disabled_for < res)
- res = disabled_for;
- }
-
- return res;
-}
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-
-
-void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (wpa_s->disconnected || wpa_s->wpa_state != WPA_SCANNING)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Try to associate due to network getting re-enabled");
- if (wpa_supplicant_fast_associate(wpa_s) != 1) {
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-}
-
-
-static struct wpa_bss * wpa_supplicant_get_new_bss(
- struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wpa_bss *bss = NULL;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid->ssid_len > 0)
- bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
- if (!bss)
- bss = wpa_bss_get_bssid(wpa_s, bssid);
-
- return bss;
-}
-
-
-static void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
-
- if (!bss) {
- wpa_supplicant_update_scan_results(wpa_s);
-
- /* Get the BSS from the new scan results */
- bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
- }
-
- if (bss)
- wpa_s->current_bss = bss;
-}
-
-
-static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid, *old_ssid;
- u8 drv_ssid[SSID_MAX_LEN];
- size_t drv_ssid_len;
- int res;
-
- if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
- wpa_supplicant_update_current_bss(wpa_s);
-
- if (wpa_s->current_ssid->ssid_len == 0)
- return 0; /* current profile still in use */
- res = wpa_drv_get_ssid(wpa_s, drv_ssid);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to read SSID from driver");
- return 0; /* try to use current profile */
- }
- drv_ssid_len = res;
-
- if (drv_ssid_len == wpa_s->current_ssid->ssid_len &&
- os_memcmp(drv_ssid, wpa_s->current_ssid->ssid,
- drv_ssid_len) == 0)
- return 0; /* current profile still in use */
-
-#ifdef CONFIG_OWE
- if ((wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- wpa_s->current_bss &&
- (wpa_s->current_bss->flags & WPA_BSS_OWE_TRANSITION) &&
- drv_ssid_len == wpa_s->current_bss->ssid_len &&
- os_memcmp(drv_ssid, wpa_s->current_bss->ssid,
- drv_ssid_len) == 0)
- return 0; /* current profile still in use */
-#endif /* CONFIG_OWE */
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "Driver-initiated BSS selection changed the SSID to %s",
- wpa_ssid_txt(drv_ssid, drv_ssid_len));
- /* continue selecting a new network profile */
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "
- "information");
- ssid = wpa_supplicant_get_ssid(wpa_s);
- if (ssid == NULL) {
- wpa_msg(wpa_s, MSG_INFO,
- "No network configuration found for the current AP");
- return -1;
- }
-
- if (wpas_network_disabled(wpa_s, ssid)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled");
- return -1;
- }
-
- if (disallowed_bssid(wpa_s, wpa_s->bssid) ||
- disallowed_ssid(wpa_s, ssid->ssid, ssid->ssid_len)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS is disallowed");
- return -1;
- }
-
- res = wpas_temp_disabled(wpa_s, ssid);
- if (res > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is temporarily "
- "disabled for %d second(s)", res);
- return -1;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
- "current AP");
- if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
- u8 wpa_ie[80];
- size_t wpa_ie_len = sizeof(wpa_ie);
- if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
- wpa_ie, &wpa_ie_len) < 0)
- wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites");
- } else {
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- }
-
- if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- old_ssid = wpa_s->current_ssid;
- wpa_s->current_ssid = ssid;
-
- wpa_supplicant_update_current_bss(wpa_s);
-
- wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
- wpa_supplicant_initiate_eapol(wpa_s);
- if (old_ssid != wpa_s->current_ssid)
- wpas_notify_network_changed(wpa_s);
-
- return 0;
-}
-
-
-void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (wpa_s->countermeasures) {
- wpa_s->countermeasures = 0;
- wpa_drv_set_countermeasures(wpa_s, 0);
- wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
-
- /*
- * It is possible that the device is sched scanning, which means
- * that a connection attempt will be done only when we receive
- * scan results. However, in this case, it would be preferable
- * to scan and connect immediately, so cancel the sched_scan and
- * issue a regular scan flow.
- */
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-}
-
-
-void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
-{
- int bssid_changed;
-
- wnm_bss_keep_alive_deinit(wpa_s);
-
-#ifdef CONFIG_IBSS_RSN
- ibss_rsn_deinit(wpa_s->ibss_rsn);
- wpa_s->ibss_rsn = NULL;
-#endif /* CONFIG_IBSS_RSN */
-
-#ifdef CONFIG_AP
- wpa_supplicant_ap_deinit(wpa_s);
-#endif /* CONFIG_AP */
-
-#ifdef CONFIG_HS20
- /* Clear possibly configured frame filters */
- wpa_drv_configure_frame_filters(wpa_s, 0);
-#endif /* CONFIG_HS20 */
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- return;
-
- if (os_reltime_initialized(&wpa_s->session_start)) {
- os_reltime_age(&wpa_s->session_start, &wpa_s->session_length);
- wpa_s->session_start.sec = 0;
- wpa_s->session_start.usec = 0;
- wpas_notify_session_length(wpa_s);
- }
-
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
- os_memset(wpa_s->bssid, 0, ETH_ALEN);
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- sme_clear_on_disassoc(wpa_s);
- wpa_s->current_bss = NULL;
- wpa_s->assoc_freq = 0;
-
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-
- eapol_sm_notify_portEnabled(wpa_s->eapol, false);
- eapol_sm_notify_portValid(wpa_s->eapol, false);
- if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP || wpa_s->drv_authorized_port)
- eapol_sm_notify_eap_success(wpa_s->eapol, false);
- wpa_s->drv_authorized_port = 0;
- wpa_s->ap_ies_from_associnfo = 0;
- wpa_s->current_ssid = NULL;
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_s->key_mgmt = 0;
-
- wpas_rrm_reset(wpa_s);
- wpa_s->wnmsleep_used = 0;
- wnm_clear_coloc_intf_reporting(wpa_s);
- wpa_s->disable_mbo_oce = 0;
-
-#ifdef CONFIG_TESTING_OPTIONS
- wpa_s->last_tk_alg = WPA_ALG_NONE;
- os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
-#endif /* CONFIG_TESTING_OPTIONS */
- wpa_s->ieee80211ac = 0;
-
- if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
- wpa_s->enabled_4addr_mode = 0;
-}
-
-
-static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ie_data ie;
- int pmksa_set = -1;
- size_t i;
- struct rsn_pmksa_cache_entry *cur_pmksa;
-
- /* Start with assumption of no PMKSA cache entry match for cases other
- * than SAE. In particular, this is needed to generate the PMKSA cache
- * entries for Suite B cases with driver-based roaming indication. */
- cur_pmksa = pmksa_cache_get_current(wpa_s->wpa);
- if (cur_pmksa && !wpa_key_mgmt_sae(cur_pmksa->akmp))
- pmksa_cache_clear_current(wpa_s->wpa);
-
- if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
- ie.pmkid == NULL)
- return;
-
- for (i = 0; i < ie.num_pmkid; i++) {
- pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
- ie.pmkid + i * PMKID_LEN,
- NULL, NULL, 0, NULL, 0);
- if (pmksa_set == 0) {
- eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
- break;
- }
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from "
- "PMKSA cache", pmksa_set == 0 ? "" : "not ");
-}
-
-
-static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (data == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: No data in PMKID candidate "
- "event");
- return;
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
- " index=%d preauth=%d",
- MAC2STR(data->pmkid_candidate.bssid),
- data->pmkid_candidate.index,
- data->pmkid_candidate.preauth);
-
- pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
- data->pmkid_candidate.index,
- data->pmkid_candidate.preauth);
-}
-
-
-static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
- return 0;
-
-#ifdef IEEE8021X_EAPOL
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
- wpa_s->current_ssid &&
- !(wpa_s->current_ssid->eapol_flags &
- (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
- EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
- /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
- * plaintext or static WEP keys). */
- return 0;
- }
-#endif /* IEEE8021X_EAPOL */
-
- return 1;
-}
-
-
-/**
- * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
- * @wpa_s: pointer to wpa_supplicant data
- * @ssid: Configuration data for the network
- * Returns: 0 on success, -1 on failure
- *
- * This function is called when starting authentication with a network that is
- * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
- */
-int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-#ifdef IEEE8021X_EAPOL
-#ifdef PCSC_FUNCS
- int aka = 0, sim = 0;
-
- if ((ssid != NULL && ssid->eap.pcsc == NULL) ||
- wpa_s->scard != NULL || wpa_s->conf->external_sim)
- return 0;
-
- if (ssid == NULL || ssid->eap.eap_methods == NULL) {
- sim = 1;
- aka = 1;
- } else {
- struct eap_method_type *eap = ssid->eap.eap_methods;
- while (eap->vendor != EAP_VENDOR_IETF ||
- eap->method != EAP_TYPE_NONE) {
- if (eap->vendor == EAP_VENDOR_IETF) {
- if (eap->method == EAP_TYPE_SIM)
- sim = 1;
- else if (eap->method == EAP_TYPE_AKA ||
- eap->method == EAP_TYPE_AKA_PRIME)
- aka = 1;
- }
- eap++;
- }
- }
-
- if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
- sim = 0;
- if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL &&
- eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME) ==
- NULL)
- aka = 0;
-
- if (!sim && !aka) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to "
- "use SIM, but neither EAP-SIM nor EAP-AKA are "
- "enabled");
- return 0;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to use SIM "
- "(sim=%d aka=%d) - initialize PCSC", sim, aka);
-
- wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
- if (wpa_s->scard == NULL) {
- wpa_msg(wpa_s, MSG_WARNING, "Failed to initialize SIM "
- "(pcsc-lite)");
- return -1;
- }
- wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
- eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
-#endif /* PCSC_FUNCS */
-#endif /* IEEE8021X_EAPOL */
-
- return 0;
-}
-
-
-#ifndef CONFIG_NO_SCAN_PROCESSING
-
-#ifdef CONFIG_WEP
-static int has_wep_key(struct wpa_ssid *ssid)
-{
- int i;
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i])
- return 1;
- }
-
- return 0;
-}
-#endif /* CONFIG_WEP */
-
-
-static int wpa_supplicant_match_privacy(struct wpa_bss *bss,
- struct wpa_ssid *ssid)
-{
- int privacy = 0;
-
- if (ssid->mixed_cell)
- return 1;
-
-#ifdef CONFIG_WPS
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
- return 1;
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_OWE
- if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only)
- return 1;
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_WEP
- if (has_wep_key(ssid))
- privacy = 1;
-#endif /* CONFIG_WEP */
-
-#ifdef IEEE8021X_EAPOL
- if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
- ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
- EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
- privacy = 1;
-#endif /* IEEE8021X_EAPOL */
-
- if (wpa_key_mgmt_wpa(ssid->key_mgmt))
- privacy = 1;
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)
- privacy = 1;
-
- if (bss->caps & IEEE80211_CAP_PRIVACY)
- return privacy;
- return !privacy;
-}
-
-
-static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss, int debug_print)
-{
- struct wpa_ie_data ie;
- int proto_match = 0;
- const u8 *rsn_ie, *wpa_ie;
- int ret;
-#ifdef CONFIG_WEP
- int wep_ok;
-#endif /* CONFIG_WEP */
-
- ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
- if (ret >= 0)
- return ret;
-
-#ifdef CONFIG_WEP
- /* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */
- wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
- (((ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
- ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) ||
- (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
-#endif /* CONFIG_WEP */
-
- rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- while ((ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) && rsn_ie) {
- proto_match++;
-
- if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - parse failed");
- break;
- }
- if (!ie.has_pairwise)
- ie.pairwise_cipher = wpa_default_rsn_cipher(bss->freq);
- if (!ie.has_group)
- ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
-
-#ifdef CONFIG_WEP
- if (wep_ok &&
- (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
- {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " selected based on TSN in RSN IE");
- return 1;
- }
-#endif /* CONFIG_WEP */
-
- if (!(ie.proto & ssid->proto) &&
- !(ssid->proto & WPA_PROTO_OSEN)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - proto mismatch");
- break;
- }
-
- if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - PTK cipher mismatch");
- break;
- }
-
- if (!(ie.group_cipher & ssid->group_cipher)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - GTK cipher mismatch");
- break;
- }
-
- if (ssid->group_mgmt_cipher &&
- !(ie.mgmt_group_cipher & ssid->group_mgmt_cipher)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - group mgmt cipher mismatch");
- break;
- }
-
- if (!(ie.key_mgmt & ssid->key_mgmt)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - key mgmt mismatch");
- break;
- }
-
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
- wpas_get_ssid_pmf(wpa_s, ssid) ==
- MGMT_FRAME_PROTECTION_REQUIRED) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - no mgmt frame protection");
- break;
- }
- if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
- wpas_get_ssid_pmf(wpa_s, ssid) ==
- NO_MGMT_FRAME_PROTECTION) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip RSN IE - no mgmt frame protection enabled but AP requires it");
- break;
- }
-
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " selected based on RSN IE");
- return 1;
- }
-
- if (wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED &&
- (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE) || ssid->owe_only)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - MFP Required but network not MFP Capable");
- return 0;
- }
-
- wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
- proto_match++;
-
- if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip WPA IE - parse failed");
- break;
- }
-
-#ifdef CONFIG_WEP
- if (wep_ok &&
- (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
- {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " selected based on TSN in WPA IE");
- return 1;
- }
-#endif /* CONFIG_WEP */
-
- if (!(ie.proto & ssid->proto)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip WPA IE - proto mismatch");
- break;
- }
-
- if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip WPA IE - PTK cipher mismatch");
- break;
- }
-
- if (!(ie.group_cipher & ssid->group_cipher)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip WPA IE - GTK cipher mismatch");
- break;
- }
-
- if (!(ie.key_mgmt & ssid->key_mgmt)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip WPA IE - key mgmt mismatch");
- break;
- }
-
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " selected based on WPA IE");
- return 1;
- }
-
- if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && !wpa_ie &&
- !rsn_ie) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " allow for non-WPA IEEE 802.1X");
- return 1;
- }
-
-#ifdef CONFIG_OWE
- if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only &&
- !wpa_ie && !rsn_ie) {
- if (wpa_s->owe_transition_select &&
- wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE) &&
- ssid->owe_transition_bss_select_count + 1 <=
- MAX_OWE_TRANSITION_BSS_SELECT_COUNT) {
- ssid->owe_transition_bss_select_count++;
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip OWE transition BSS (selection count %d does not exceed %d)",
- ssid->owe_transition_bss_select_count,
- MAX_OWE_TRANSITION_BSS_SELECT_COUNT);
- wpa_s->owe_transition_search = 1;
- return 0;
- }
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " allow in OWE transition mode");
- return 1;
- }
-#endif /* CONFIG_OWE */
-
- if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) &&
- wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - no WPA/RSN proto match");
- return 0;
- }
-
- if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) &&
- wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " allow in OSEN");
- return 1;
- }
-
- if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " allow in non-WPA/WPA2");
- return 1;
- }
-
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " reject due to mismatch with WPA/WPA2");
-
- return 0;
-}
-
-
-static int freq_allowed(int *freqs, int freq)
-{
- int i;
-
- if (freqs == NULL)
- return 1;
-
- for (i = 0; freqs[i]; i++)
- if (freqs[i] == freq)
- return 1;
- return 0;
-}
-
-
-static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_bss *bss, int debug_print)
-{
- const struct hostapd_hw_modes *mode = NULL, *modes;
- const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
- const u8 *rate_ie;
- int i, j, k;
-
- if (bss->freq == 0)
- return 1; /* Cannot do matching without knowing band */
-
- modes = wpa_s->hw.modes;
- if (modes == NULL) {
- /*
- * The driver does not provide any additional information
- * about the utilized hardware, so allow the connection attempt
- * to continue.
- */
- return 1;
- }
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- for (j = 0; j < modes[i].num_channels; j++) {
- int freq = modes[i].channels[j].freq;
- if (freq == bss->freq) {
- if (mode &&
- mode->mode == HOSTAPD_MODE_IEEE80211G)
- break; /* do not allow 802.11b replace
- * 802.11g */
- mode = &modes[i];
- break;
- }
- }
- }
-
- if (mode == NULL)
- return 0;
-
- for (i = 0; i < (int) sizeof(scan_ie); i++) {
- rate_ie = wpa_bss_get_ie(bss, scan_ie[i]);
- if (rate_ie == NULL)
- continue;
-
- for (j = 2; j < rate_ie[1] + 2; j++) {
- int flagged = !!(rate_ie[j] & 0x80);
- int r = (rate_ie[j] & 0x7f) * 5;
-
- /*
- * IEEE Std 802.11n-2009 7.3.2.2:
- * The new BSS Membership selector value is encoded
- * like a legacy basic rate, but it is not a rate and
- * only indicates if the BSS members are required to
- * support the mandatory features of Clause 20 [HT PHY]
- * in order to join the BSS.
- */
- if (flagged && ((rate_ie[j] & 0x7f) ==
- BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
- if (!ht_supported(mode)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " hardware does not support HT PHY");
- return 0;
- }
- continue;
- }
-
- /* There's also a VHT selector for 802.11ac */
- if (flagged && ((rate_ie[j] & 0x7f) ==
- BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) {
- if (!vht_supported(mode)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " hardware does not support VHT PHY");
- return 0;
- }
- continue;
- }
-
-#ifdef CONFIG_SAE
- if (flagged && ((rate_ie[j] & 0x7f) ==
- BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) {
- if (wpa_s->conf->sae_pwe == 0 &&
- !ssid->sae_password_id &&
- wpa_key_mgmt_sae(ssid->key_mgmt)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " SAE H2E disabled");
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ignore_sae_h2e_only) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "TESTING: Ignore SAE H2E requirement mismatch");
- continue;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- return 0;
- }
- continue;
- }
-#endif /* CONFIG_SAE */
-
- if (!flagged)
- continue;
-
- /* check for legacy basic rates */
- for (k = 0; k < mode->num_rates; k++) {
- if (mode->rates[k] == r)
- break;
- }
- if (k == mode->num_rates) {
- /*
- * IEEE Std 802.11-2007 7.3.2.2 demands that in
- * order to join a BSS all required rates
- * have to be supported by the hardware.
- */
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " hardware does not support required rate %d.%d Mbps (freq=%d mode==%d num_rates=%d)",
- r / 10, r % 10,
- bss->freq, mode->mode, mode->num_rates);
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-
-/*
- * Test whether BSS is in an ESS.
- * This is done differently in DMG (60 GHz) and non-DMG bands
- */
-static int bss_is_ess(struct wpa_bss *bss)
-{
- if (bss_is_dmg(bss)) {
- return (bss->caps & IEEE80211_CAP_DMG_MASK) ==
- IEEE80211_CAP_DMG_AP;
- }
-
- return ((bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
- IEEE80211_CAP_ESS);
-}
-
-
-static int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
-{
- size_t i;
-
- for (i = 0; i < ETH_ALEN; i++) {
- if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
- return 0;
- }
- return 1;
-}
-
-
-static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
-{
- size_t i;
-
- for (i = 0; i < num; i++) {
- const u8 *a = list + i * ETH_ALEN * 2;
- const u8 *m = a + ETH_ALEN;
-
- if (match_mac_mask(a, addr, m))
- return 1;
- }
- return 0;
-}
-
-
-static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- const u8 **ret_ssid, size_t *ret_ssid_len)
-{
-#ifdef CONFIG_OWE
- const u8 *owe, *pos, *end, *bssid;
- u8 ssid_len;
- struct wpa_bss *open_bss;
-
- owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (!owe || !wpa_bss_get_ie(bss, WLAN_EID_RSN))
- return;
-
- pos = owe + 6;
- end = owe + 2 + owe[1];
-
- if (end - pos < ETH_ALEN + 1)
- return;
- bssid = pos;
- pos += ETH_ALEN;
- ssid_len = *pos++;
- if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
- return;
-
- /* Match the profile SSID against the OWE transition mode SSID on the
- * open network. */
- wpa_dbg(wpa_s, MSG_DEBUG, "OWE: transition mode BSSID: " MACSTR
- " SSID: %s", MAC2STR(bssid), wpa_ssid_txt(pos, ssid_len));
- *ret_ssid = pos;
- *ret_ssid_len = ssid_len;
-
- if (!(bss->flags & WPA_BSS_OWE_TRANSITION)) {
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (wpas_network_disabled(wpa_s, ssid))
- continue;
- if (ssid->ssid_len == ssid_len &&
- os_memcmp(ssid->ssid, pos, ssid_len) == 0) {
- /* OWE BSS in transition mode for a currently
- * enabled OWE network. */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "OWE: transition mode OWE SSID for active OWE profile");
- bss->flags |= WPA_BSS_OWE_TRANSITION;
- break;
- }
- }
- }
-
- if (bss->ssid_len > 0)
- return;
-
- open_bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- if (!open_bss)
- return;
- if (ssid_len != open_bss->ssid_len ||
- os_memcmp(pos, open_bss->ssid, ssid_len) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "OWE: transition mode SSID mismatch: %s",
- wpa_ssid_txt(open_bss->ssid, open_bss->ssid_len));
- return;
- }
-
- owe = wpa_bss_get_vendor_ie(open_bss, OWE_IE_VENDOR_TYPE);
- if (!owe || wpa_bss_get_ie(open_bss, WLAN_EID_RSN)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "OWE: transition mode open BSS unexpected info");
- return;
- }
-
- pos = owe + 6;
- end = owe + 2 + owe[1];
-
- if (end - pos < ETH_ALEN + 1)
- return;
- if (os_memcmp(pos, bss->bssid, ETH_ALEN) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "OWE: transition mode BSSID mismatch: " MACSTR,
- MAC2STR(pos));
- return;
- }
- pos += ETH_ALEN;
- ssid_len = *pos++;
- if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
- return;
- wpa_dbg(wpa_s, MSG_DEBUG, "OWE: learned transition mode OWE SSID: %s",
- wpa_ssid_txt(pos, ssid_len));
- os_memcpy(bss->ssid, pos, ssid_len);
- bss->ssid_len = ssid_len;
- bss->flags |= WPA_BSS_OWE_TRANSITION;
-#endif /* CONFIG_OWE */
-}
-
-
-static int disabled_freq(struct wpa_supplicant *wpa_s, int freq)
-{
- int i, j;
-
- if (!wpa_s->hw.modes || !wpa_s->hw.num_modes)
- return 0;
-
- for (j = 0; j < wpa_s->hw.num_modes; j++) {
- struct hostapd_hw_modes *mode = &wpa_s->hw.modes[j];
-
- for (i = 0; i < mode->num_channels; i++) {
- struct hostapd_channel_data *chan = &mode->channels[i];
-
- if (chan->freq == freq)
- return !!(chan->flag & HOSTAPD_CHAN_DISABLED);
- }
- }
-
- return 1;
-}
-
-
-static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const u8 *match_ssid, size_t match_ssid_len,
- struct wpa_bss *bss, int bssid_ignore_count,
- bool debug_print);
-
-
-#ifdef CONFIG_SAE_PK
-static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s,
- struct wpa_bss *orig_bss,
- struct wpa_ssid *ssid,
- const u8 *match_ssid,
- size_t match_ssid_len)
-{
- struct wpa_bss *bss;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- int count;
- const u8 *ie;
-
- if (bss == orig_bss)
- continue;
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
- continue;
-
- /* TODO: Could be more thorough in checking what kind of
- * signal strength or throughput estimate would be acceptable
- * compared to the originally selected BSS. */
- if (bss->est_throughput < 2000)
- return false;
-
- count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid);
- if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len,
- bss, count, 0))
- return true;
- }
-
- return false;
-}
-#endif /* CONFIG_SAE_PK */
-
-
-static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const u8 *match_ssid, size_t match_ssid_len,
- struct wpa_bss *bss, int bssid_ignore_count,
- bool debug_print)
-{
- int res;
- bool wpa, check_ssid, osen, rsn_osen = false;
- struct wpa_ie_data data;
-#ifdef CONFIG_MBO
- const u8 *assoc_disallow;
-#endif /* CONFIG_MBO */
-#ifdef CONFIG_SAE
- u8 rsnxe_capa = 0;
-#endif /* CONFIG_SAE */
- const u8 *ie;
-
- ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- wpa = ie && ie[1];
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- wpa |= ie && ie[1];
- if (ie && wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) == 0 &&
- (data.key_mgmt & WPA_KEY_MGMT_OSEN))
- rsn_osen = true;
- ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- osen = ie != NULL;
-
-#ifdef CONFIG_SAE
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (ie && ie[1] >= 1)
- rsnxe_capa = ie[2];
-#endif /* CONFIG_SAE */
-
- check_ssid = wpa || ssid->ssid_len > 0;
-
- if (wpas_network_disabled(wpa_s, ssid)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - disabled");
- return false;
- }
-
- res = wpas_temp_disabled(wpa_s, ssid);
- if (res > 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - disabled temporarily for %d second(s)",
- res);
- return false;
- }
-
-#ifdef CONFIG_WPS
- if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && bssid_ignore_count) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - BSSID ignored (WPS)");
- return false;
- }
-
- if (wpa && ssid->ssid_len == 0 &&
- wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
- check_ssid = false;
-
- if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
- /* Only allow wildcard SSID match if an AP advertises active
- * WPS operation that matches our mode. */
- check_ssid = ssid->ssid_len > 0 ||
- !wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss);
- }
-#endif /* CONFIG_WPS */
-
- if (ssid->bssid_set && ssid->ssid_len == 0 &&
- os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
- check_ssid = false;
-
- if (check_ssid &&
- (match_ssid_len != ssid->ssid_len ||
- os_memcmp(match_ssid, ssid->ssid, match_ssid_len) != 0)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID mismatch");
- return false;
- }
-
- if (ssid->bssid_set &&
- os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - BSSID mismatch");
- return false;
- }
-
- /* check the list of BSSIDs to ignore */
- if (ssid->num_bssid_ignore &&
- addr_in_list(bss->bssid, ssid->bssid_ignore,
- ssid->num_bssid_ignore)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - BSSID configured to be ignored");
- return false;
- }
-
- /* if there is a list of accepted BSSIDs, only accept those APs */
- if (ssid->num_bssid_accept &&
- !addr_in_list(bss->bssid, ssid->bssid_accept,
- ssid->num_bssid_accept)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - BSSID not in list of accepted values");
- return false;
- }
-
- if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss, debug_print))
- return false;
-
- if (!osen && !wpa &&
- !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
- !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
- !(ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - non-WPA network not allowed");
- return false;
- }
-
-#ifdef CONFIG_WEP
- if (wpa && !wpa_key_mgmt_wpa(ssid->key_mgmt) && has_wep_key(ssid)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - ignore WPA/WPA2 AP for WEP network block");
- return false;
- }
-#endif /* CONFIG_WEP */
-
- if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen && !rsn_osen) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - non-OSEN network not allowed");
- return false;
- }
-
- if (!wpa_supplicant_match_privacy(bss, ssid)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - privacy mismatch");
- return false;
- }
-
- if (ssid->mode != WPAS_MODE_MESH && !bss_is_ess(bss) &&
- !bss_is_pbss(bss)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - not ESS, PBSS, or MBSS");
- return false;
- }
-
- if (ssid->pbss != 2 && ssid->pbss != bss_is_pbss(bss)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - PBSS mismatch (ssid %d bss %d)",
- ssid->pbss, bss_is_pbss(bss));
- return false;
- }
-
- if (!freq_allowed(ssid->freq_list, bss->freq)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - frequency not allowed");
- return false;
- }
-
-#ifdef CONFIG_MESH
- if (ssid->mode == WPAS_MODE_MESH && ssid->frequency > 0 &&
- ssid->frequency != bss->freq) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - frequency not allowed (mesh)");
- return false;
- }
-#endif /* CONFIG_MESH */
-
- if (!rate_match(wpa_s, ssid, bss, debug_print)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - rate sets do not match");
- return false;
- }
-
-#ifdef CONFIG_SAE
- if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
- wpa_s->conf->sae_pwe != 3 && wpa_key_mgmt_sae(ssid->key_mgmt) &&
- !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - SAE H2E required, but not supported by the AP");
- return false;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_SAE_PK
- if (ssid->sae_pk == SAE_PK_MODE_ONLY &&
- !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK))) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - SAE-PK required, but not supported by the AP");
- return false;
- }
-#endif /* CONFIG_SAE_PK */
-
-#ifndef CONFIG_IBSS_RSN
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPA_NONE))) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - IBSS RSN not supported in the build");
- return false;
- }
-#endif /* !CONFIG_IBSS_RSN */
-
-#ifdef CONFIG_P2P
- if (ssid->p2p_group &&
- !wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
- !wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - no P2P IE seen");
- return false;
- }
-
- if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) {
- struct wpabuf *p2p_ie;
- u8 dev_addr[ETH_ALEN];
-
- ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
- if (!ie) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - no P2P element");
- return false;
- }
- p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
- if (!p2p_ie) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - could not fetch P2P element");
- return false;
- }
-
- if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0 ||
- os_memcmp(dev_addr, ssid->go_p2p_dev_addr, ETH_ALEN) != 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - no matching GO P2P Device Address in P2P element");
- wpabuf_free(p2p_ie);
- return false;
- }
- wpabuf_free(p2p_ie);
- }
-
- /*
- * TODO: skip the AP if its P2P IE has Group Formation bit set in the
- * P2P Group Capability Bitmap and we are not in Group Formation with
- * that device.
- */
-#endif /* CONFIG_P2P */
-
- if (os_reltime_before(&bss->last_update, &wpa_s->scan_min_time)) {
- struct os_reltime diff;
-
- os_reltime_sub(&wpa_s->scan_min_time, &bss->last_update, &diff);
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - scan result not recent enough (%u.%06u seconds too old)",
- (unsigned int) diff.sec,
- (unsigned int) diff.usec);
- return false;
- }
-#ifdef CONFIG_MBO
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ignore_assoc_disallow)
- goto skip_assoc_disallow;
-#endif /* CONFIG_TESTING_OPTIONS */
- assoc_disallow = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_ASSOC_DISALLOW);
- if (assoc_disallow && assoc_disallow[1] >= 1) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - MBO association disallowed (reason %u)",
- assoc_disallow[2]);
- return false;
- }
-
- if (wpa_is_bss_tmp_disallowed(wpa_s, bss)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - AP temporarily disallowed");
- return false;
- }
-#ifdef CONFIG_TESTING_OPTIONS
-skip_assoc_disallow:
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_MBO */
-
-#ifdef CONFIG_DPP
- if ((ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
- !wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid) &&
- (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
- !ssid->dpp_csign)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - no PMKSA entry for DPP");
- return false;
- }
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_SAE_PK
- if (ssid->sae_pk == SAE_PK_MODE_AUTOMATIC &&
- wpa_key_mgmt_sae(ssid->key_mgmt) &&
- ((ssid->sae_password &&
- sae_pk_valid_password(ssid->sae_password)) ||
- (!ssid->sae_password && ssid->passphrase &&
- sae_pk_valid_password(ssid->passphrase))) &&
- !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
- sae_pk_acceptable_bss_with_pk(wpa_s, bss, ssid, match_ssid,
- match_ssid_len)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - another acceptable BSS with SAE-PK in the same ESS");
- return false;
- }
-#endif /* CONFIG_SAE_PK */
-
- if (bss->ssid_len == 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - no SSID known for the BSS");
- return false;
- }
-
- /* Matching configuration found */
- return true;
-}
-
-
-struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
- int i, struct wpa_bss *bss,
- struct wpa_ssid *group,
- int only_first_ssid, int debug_print)
-{
- u8 wpa_ie_len, rsn_ie_len;
- const u8 *ie;
- struct wpa_ssid *ssid;
- int osen;
- const u8 *match_ssid;
- size_t match_ssid_len;
- int bssid_ignore_count;
-
- ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- wpa_ie_len = ie ? ie[1] : 0;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- rsn_ie_len = ie ? ie[1] : 0;
-
- ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- osen = ie != NULL;
-
- if (debug_print) {
- wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR
- " ssid='%s' wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d freq=%d %s%s%s",
- i, MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len),
- wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
- bss->freq,
- wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ?
- " wps" : "",
- (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
- wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE))
- ? " p2p" : "",
- osen ? " osen=1" : "");
- }
-
- bssid_ignore_count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid);
- if (bssid_ignore_count) {
- int limit = 1;
- if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
- /*
- * When only a single network is enabled, we can
- * trigger BSSID ignoring on the first failure. This
- * should not be done with multiple enabled networks to
- * avoid getting forced to move into a worse ESS on
- * single error if there are no other BSSes of the
- * current ESS.
- */
- limit = 0;
- }
- if (bssid_ignore_count > limit) {
- if (debug_print) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- " skip - BSSID ignored (count=%d limit=%d)",
- bssid_ignore_count, limit);
- }
- return NULL;
- }
- }
-
- match_ssid = bss->ssid;
- match_ssid_len = bss->ssid_len;
- owe_trans_ssid(wpa_s, bss, &match_ssid, &match_ssid_len);
-
- if (match_ssid_len == 0) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID not known");
- return NULL;
- }
-
- if (disallowed_bssid(wpa_s, bss->bssid)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - BSSID disallowed");
- return NULL;
- }
-
- if (disallowed_ssid(wpa_s, match_ssid, match_ssid_len)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID disallowed");
- return NULL;
- }
-
- if (disabled_freq(wpa_s, bss->freq)) {
- if (debug_print)
- wpa_dbg(wpa_s, MSG_DEBUG, " skip - channel disabled");
- return NULL;
- }
-
- for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
- if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len,
- bss, bssid_ignore_count, debug_print))
- return ssid;
- }
-
- /* No matching configuration found */
- return NULL;
-}
-
-
-static struct wpa_bss *
-wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *group,
- struct wpa_ssid **selected_ssid,
- int only_first_ssid)
-{
- unsigned int i;
-
- if (wpa_s->current_ssid) {
- struct wpa_ssid *ssid;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Scan results matching the currently selected network");
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- struct wpa_bss *bss = wpa_s->last_scan_res[i];
-
- ssid = wpa_scan_res_match(wpa_s, i, bss, group,
- only_first_ssid, 0);
- if (ssid != wpa_s->current_ssid)
- continue;
- wpa_dbg(wpa_s, MSG_DEBUG, "%u: " MACSTR
- " freq=%d level=%d snr=%d est_throughput=%u",
- i, MAC2STR(bss->bssid), bss->freq, bss->level,
- bss->snr, bss->est_throughput);
- }
- }
-
- if (only_first_ssid)
- wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d",
- group->id);
- else
- wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
- group->priority);
-
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- struct wpa_bss *bss = wpa_s->last_scan_res[i];
-
- wpa_s->owe_transition_select = 1;
- *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group,
- only_first_ssid, 1);
- wpa_s->owe_transition_select = 0;
- if (!*selected_ssid)
- continue;
- wpa_dbg(wpa_s, MSG_DEBUG, " selected %sBSS " MACSTR
- " ssid='%s'",
- bss == wpa_s->current_bss ? "current ": "",
- MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- return bss;
- }
-
- return NULL;
-}
-
-
-struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid **selected_ssid)
-{
- struct wpa_bss *selected = NULL;
- size_t prio;
- struct wpa_ssid *next_ssid = NULL;
- struct wpa_ssid *ssid;
-
- if (wpa_s->last_scan_res == NULL ||
- wpa_s->last_scan_res_used == 0)
- return NULL; /* no scan results from last update */
-
- if (wpa_s->next_ssid) {
- /* check that next_ssid is still valid */
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid == wpa_s->next_ssid)
- break;
- }
- next_ssid = ssid;
- wpa_s->next_ssid = NULL;
- }
-
- while (selected == NULL) {
- for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
- if (next_ssid && next_ssid->priority ==
- wpa_s->conf->pssid[prio]->priority) {
- selected = wpa_supplicant_select_bss(
- wpa_s, next_ssid, selected_ssid, 1);
- if (selected)
- break;
- }
- selected = wpa_supplicant_select_bss(
- wpa_s, wpa_s->conf->pssid[prio],
- selected_ssid, 0);
- if (selected)
- break;
- }
-
- if (selected == NULL && wpa_s->bssid_ignore &&
- !wpa_s->countermeasures) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "No APs found - clear BSSID ignore list and try again");
- wpa_bssid_ignore_clear(wpa_s);
- wpa_s->bssid_ignore_cleared = true;
- } else if (selected == NULL)
- break;
- }
-
- ssid = *selected_ssid;
- if (selected && ssid && ssid->mem_only_psk && !ssid->psk_set &&
- !ssid->passphrase && !ssid->ext_psk) {
- const char *field_name, *txt = NULL;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "PSK/passphrase not yet available for the selected network");
-
- wpas_notify_network_request(wpa_s, ssid,
- WPA_CTRL_REQ_PSK_PASSPHRASE, NULL);
-
- field_name = wpa_supplicant_ctrl_req_to_string(
- WPA_CTRL_REQ_PSK_PASSPHRASE, NULL, &txt);
- if (field_name == NULL)
- return NULL;
-
- wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
-
- selected = NULL;
- }
-
- return selected;
-}
-
-
-static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
- int timeout_sec, int timeout_usec)
-{
- if (!wpa_supplicant_enabled_networks(wpa_s)) {
- /*
- * No networks are enabled; short-circuit request so
- * we don't wait timeout seconds before transitioning
- * to INACTIVE state.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request "
- "since there are no enabled networks");
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
- return;
- }
-
- wpa_s->scan_for_connection = 1;
- wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
-}
-
-
-int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected,
- struct wpa_ssid *ssid)
-{
- if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
- "PBC session overlap");
- wpas_notify_wps_event_pbc_overlap(wpa_s);
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
- wpa_s->p2p_in_provisioning) {
- eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb,
- wpa_s, NULL);
- return -1;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WPS
- wpas_wps_pbc_overlap(wpa_s);
- wpas_wps_cancel(wpa_s);
-#endif /* CONFIG_WPS */
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "Considering connect request: reassociate: %d selected: "
- MACSTR " bssid: " MACSTR " pending: " MACSTR
- " wpa_state: %s ssid=%p current_ssid=%p",
- wpa_s->reassociate, MAC2STR(selected->bssid),
- MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
- wpa_supplicant_state_txt(wpa_s->wpa_state),
- ssid, wpa_s->current_ssid);
-
- /*
- * Do not trigger new association unless the BSSID has changed or if
- * reassociation is requested. If we are in process of associating with
- * the selected BSSID, do not trigger new attempt.
- */
- if (wpa_s->reassociate ||
- (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
- ((wpa_s->wpa_state != WPA_ASSOCIATING &&
- wpa_s->wpa_state != WPA_AUTHENTICATING) ||
- (!is_zero_ether_addr(wpa_s->pending_bssid) &&
- os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
- 0) ||
- (is_zero_ether_addr(wpa_s->pending_bssid) &&
- ssid != wpa_s->current_ssid)))) {
- if (wpa_supplicant_scard_init(wpa_s, ssid)) {
- wpa_supplicant_req_new_scan(wpa_s, 10, 0);
- return 0;
- }
- wpa_msg(wpa_s, MSG_DEBUG, "Request association with " MACSTR,
- MAC2STR(selected->bssid));
- wpa_supplicant_associate(wpa_s, selected, ssid);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "Already associated or trying to "
- "connect with the selected AP");
- }
-
- return 0;
-}
-
-
-static struct wpa_ssid *
-wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
-{
- size_t prio;
- struct wpa_ssid *ssid;
-
- for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
- for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
- {
- if (wpas_network_disabled(wpa_s, ssid))
- continue;
-#ifndef CONFIG_IBSS_RSN
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE |
- WPA_KEY_MGMT_WPA_NONE))) {
- wpa_msg(wpa_s, MSG_INFO,
- "IBSS RSN not supported in the build - cannot use the profile for SSID '%s'",
- wpa_ssid_txt(ssid->ssid,
- ssid->ssid_len));
- continue;
- }
-#endif /* !CONFIG_IBSS_RSN */
- if (ssid->mode == WPAS_MODE_IBSS ||
- ssid->mode == WPAS_MODE_AP ||
- ssid->mode == WPAS_MODE_MESH)
- return ssid;
- }
- }
- return NULL;
-}
-
-
-/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
- * on BSS added and BSS changed events */
-static void wpa_supplicant_rsn_preauth_scan_results(
- struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
-
- if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
- return;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- const u8 *ssid, *rsn;
-
- ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
- if (ssid == NULL)
- continue;
-
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (rsn == NULL)
- continue;
-
- rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
- }
-
-}
-
-
-#ifndef CONFIG_NO_ROAMING
-
-static int wpas_get_snr_signal_info(u32 frequency, int avg_signal, int noise)
-{
- if (noise == WPA_INVALID_NOISE)
- noise = IS_5GHZ(frequency) ? DEFAULT_NOISE_FLOOR_5GHZ :
- DEFAULT_NOISE_FLOOR_2GHZ;
- return avg_signal - noise;
-}
-
-
-static unsigned int
-wpas_get_est_throughput_from_bss_snr(const struct wpa_supplicant *wpa_s,
- const struct wpa_bss *bss, int snr)
-{
- int rate = wpa_bss_get_max_rate(bss);
- const u8 *ies = wpa_bss_ie_ptr(bss);
- size_t ie_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
-
- return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, bss->freq);
-}
-
-
-int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
- struct wpa_bss *current_bss,
- struct wpa_bss *selected)
-{
- int min_diff, diff;
- int to_5ghz;
- int cur_level;
- unsigned int cur_est, sel_est;
- struct wpa_signal_info si;
- int cur_snr = 0;
- int ret = 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation");
- wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
- " freq=%d level=%d snr=%d est_throughput=%u",
- MAC2STR(current_bss->bssid),
- current_bss->freq, current_bss->level,
- current_bss->snr, current_bss->est_throughput);
- wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR
- " freq=%d level=%d snr=%d est_throughput=%u",
- MAC2STR(selected->bssid), selected->freq, selected->level,
- selected->snr, selected->est_throughput);
-
- if (wpa_s->current_ssid->bssid_set &&
- os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
- 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS "
- "has preferred BSSID");
- return 1;
- }
-
- cur_level = current_bss->level;
- cur_est = current_bss->est_throughput;
- sel_est = selected->est_throughput;
-
- /*
- * Try to poll the signal from the driver since this will allow to get
- * more accurate values. In some cases, there can be big differences
- * between the RSSI of the Probe Response frames of the AP we are
- * associated with and the Beacon frames we hear from the same AP after
- * association. This can happen, e.g., when there are two antennas that
- * hear the AP very differently. If the driver chooses to hear the
- * Probe Response frames during the scan on the "bad" antenna because
- * it wants to save power, but knows to choose the other antenna after
- * association, we will hear our AP with a low RSSI as part of the
- * scan even when we can hear it decently on the other antenna. To cope
- * with this, ask the driver to teach us how it hears the AP. Also, the
- * scan results may be a bit old, since we can very quickly get fresh
- * information about our currently associated AP.
- */
- if (wpa_drv_signal_poll(wpa_s, &si) == 0 &&
- (si.avg_beacon_signal || si.avg_signal)) {
- cur_level = si.avg_beacon_signal ? si.avg_beacon_signal :
- si.avg_signal;
- cur_snr = wpas_get_snr_signal_info(si.frequency, cur_level,
- si.current_noise);
-
- cur_est = wpas_get_est_throughput_from_bss_snr(wpa_s,
- current_bss,
- cur_snr);
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Using signal poll values for the current BSS: level=%d snr=%d est_throughput=%u",
- cur_level, cur_snr, cur_est);
- }
-
- if (sel_est > cur_est + 5000) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Allow reassociation - selected BSS has better estimated throughput");
- return 1;
- }
-
- to_5ghz = selected->freq > 4000 && current_bss->freq < 4000;
-
- if (cur_level < 0 && cur_level > selected->level + to_5ghz * 2 &&
- sel_est < cur_est * 1.2) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
- "signal level");
- return 0;
- }
-
- if (cur_est > sel_est + 5000) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Skip roam - Current BSS has better estimated throughput");
- return 0;
- }
-
- if (cur_snr > GREAT_SNR) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Skip roam - Current BSS has good SNR (%u > %u)",
- cur_snr, GREAT_SNR);
- return 0;
- }
-
- if (cur_level < -85) /* ..-86 dBm */
- min_diff = 1;
- else if (cur_level < -80) /* -85..-81 dBm */
- min_diff = 2;
- else if (cur_level < -75) /* -80..-76 dBm */
- min_diff = 3;
- else if (cur_level < -70) /* -75..-71 dBm */
- min_diff = 4;
- else if (cur_level < 0) /* -70..-1 dBm */
- min_diff = 5;
- else /* unspecified units (not in dBm) */
- min_diff = 2;
-
- if (cur_est > sel_est * 1.5)
- min_diff += 10;
- else if (cur_est > sel_est * 1.2)
- min_diff += 5;
- else if (cur_est > sel_est * 1.1)
- min_diff += 2;
- else if (cur_est > sel_est)
- min_diff++;
- else if (sel_est > cur_est * 1.5)
- min_diff -= 10;
- else if (sel_est > cur_est * 1.2)
- min_diff -= 5;
- else if (sel_est > cur_est * 1.1)
- min_diff -= 2;
- else if (sel_est > cur_est)
- min_diff--;
-
- if (to_5ghz)
- min_diff -= 2;
- diff = selected->level - cur_level;
- if (diff < min_diff) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Skip roam - too small difference in signal level (%d < %d)",
- diff, min_diff);
- ret = 0;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Allow reassociation due to difference in signal level (%d >= %d)",
- diff, min_diff);
- ret = 1;
- }
- wpa_msg_ctrl(wpa_s, MSG_INFO, "%scur_bssid=" MACSTR
- " cur_freq=%d cur_level=%d cur_est=%d sel_bssid=" MACSTR
- " sel_freq=%d sel_level=%d sel_est=%d",
- ret ? WPA_EVENT_DO_ROAM : WPA_EVENT_SKIP_ROAM,
- MAC2STR(current_bss->bssid),
- current_bss->freq, cur_level, cur_est,
- MAC2STR(selected->bssid),
- selected->freq, selected->level, sel_est);
- return ret;
-}
-
-#endif /* CONFIG_NO_ROAMING */
-
-
-static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected,
- struct wpa_ssid *ssid)
-{
- struct wpa_bss *current_bss = NULL;
-
- if (wpa_s->reassociate)
- return 1; /* explicit request to reassociate */
- if (wpa_s->wpa_state < WPA_ASSOCIATED)
- return 1; /* we are not associated; continue */
- if (wpa_s->current_ssid == NULL)
- return 1; /* unknown current SSID */
- if (wpa_s->current_ssid != ssid)
- return 1; /* different network block */
-
- if (wpas_driver_bss_selection(wpa_s))
- return 0; /* Driver-based roaming */
-
- if (wpa_s->current_ssid->ssid)
- current_bss = wpa_bss_get(wpa_s, wpa_s->bssid,
- wpa_s->current_ssid->ssid,
- wpa_s->current_ssid->ssid_len);
- if (!current_bss)
- current_bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
-
- if (!current_bss)
- return 1; /* current BSS not seen in scan results */
-
- if (current_bss == selected)
- return 0;
-
- if (selected->last_update_idx > current_bss->last_update_idx)
- return 1; /* current BSS not seen in the last scan */
-
-#ifndef CONFIG_NO_ROAMING
- return wpa_supplicant_need_to_roam_within_ess(wpa_s, current_bss,
- selected);
-#else /* CONFIG_NO_ROAMING */
- return 0;
-#endif /* CONFIG_NO_ROAMING */
-}
-
-
-/*
- * Return a negative value if no scan results could be fetched or if scan
- * results should not be shared with other virtual interfaces.
- * Return 0 if scan results were fetched and may be shared with other
- * interfaces.
- * Return 1 if scan results may be shared with other virtual interfaces but may
- * not trigger any operations.
- * Return 2 if the interface was removed and cannot be used.
- */
-static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data,
- int own_request, int update_only)
-{
- struct wpa_scan_results *scan_res = NULL;
- int ret = 0;
- int ap = 0;
-#ifndef CONFIG_NO_RANDOM_POOL
- size_t i, num;
-#endif /* CONFIG_NO_RANDOM_POOL */
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface)
- ap = 1;
-#endif /* CONFIG_AP */
-
- wpa_supplicant_notify_scanning(wpa_s, 0);
-
- scan_res = wpa_supplicant_get_scan_results(wpa_s,
- data ? &data->scan_info :
- NULL, 1);
- if (scan_res == NULL) {
- if (wpa_s->conf->ap_scan == 2 || ap ||
- wpa_s->scan_res_handler == scan_only_handler)
- return -1;
- if (!own_request)
- return -1;
- if (data && data->scan_info.external_scan)
- return -1;
- if (wpa_s->scan_res_fail_handler) {
- void (*handler)(struct wpa_supplicant *wpa_s);
-
- handler = wpa_s->scan_res_fail_handler;
- wpa_s->scan_res_fail_handler = NULL;
- handler(wpa_s);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Failed to get scan results - try scanning again");
- wpa_supplicant_req_new_scan(wpa_s, 1, 0);
- }
-
- ret = -1;
- goto scan_work_done;
- }
-
-#ifndef CONFIG_NO_RANDOM_POOL
- num = scan_res->num;
- if (num > 10)
- num = 10;
- for (i = 0; i < num; i++) {
- u8 buf[5];
- struct wpa_scan_res *res = scan_res->res[i];
- buf[0] = res->bssid[5];
- buf[1] = res->qual & 0xff;
- buf[2] = res->noise & 0xff;
- buf[3] = res->level & 0xff;
- buf[4] = res->tsf & 0xff;
- random_add_randomness(buf, sizeof(buf));
- }
-#endif /* CONFIG_NO_RANDOM_POOL */
-
- if (update_only) {
- ret = 1;
- goto scan_work_done;
- }
-
- if (own_request && wpa_s->scan_res_handler &&
- !(data && data->scan_info.external_scan)) {
- void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
-
- scan_res_handler = wpa_s->scan_res_handler;
- wpa_s->scan_res_handler = NULL;
- scan_res_handler(wpa_s, scan_res);
- ret = 1;
- goto scan_work_done;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available (own=%u ext=%u)",
- wpa_s->own_scan_running,
- data ? data->scan_info.external_scan : 0);
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_s->manual_scan_use_id && wpa_s->own_scan_running &&
- own_request && !(data && data->scan_info.external_scan)) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
- wpa_s->manual_scan_id);
- wpa_s->manual_scan_use_id = 0;
- } else {
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
- }
- wpas_notify_scan_results(wpa_s);
-
- wpas_notify_scan_done(wpa_s, 1);
-
- if (ap) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore scan results in AP mode");
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface->scan_cb)
- wpa_s->ap_iface->scan_cb(wpa_s->ap_iface);
-#endif /* CONFIG_AP */
- goto scan_work_done;
- }
-
- if (data && data->scan_info.external_scan) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Do not use results from externally requested scan operation for network selection");
- wpa_scan_results_free(scan_res);
- return 0;
- }
-
- if (wnm_scan_process(wpa_s, 1) > 0)
- goto scan_work_done;
-
- if (sme_proc_obss_scan(wpa_s) > 0)
- goto scan_work_done;
-
- if (own_request && data &&
- wpas_beacon_rep_scan_process(wpa_s, scan_res, &data->scan_info) > 0)
- goto scan_work_done;
-
- if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
- goto scan_work_done;
-
- if (autoscan_notify_scan(wpa_s, scan_res))
- goto scan_work_done;
-
- if (wpa_s->disconnected) {
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- goto scan_work_done;
- }
-
- if (!wpas_driver_bss_selection(wpa_s) &&
- bgscan_notify_scan(wpa_s, scan_res) == 1)
- goto scan_work_done;
-
- wpas_wps_update_ap_info(wpa_s, scan_res);
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING &&
- wpa_s->wpa_state < WPA_COMPLETED)
- goto scan_work_done;
-
- wpa_scan_results_free(scan_res);
-
- if (own_request && wpa_s->scan_work) {
- struct wpa_radio_work *work = wpa_s->scan_work;
- wpa_s->scan_work = NULL;
- radio_work_done(work);
- }
-
- os_free(wpa_s->last_scan_freqs);
- wpa_s->last_scan_freqs = NULL;
- wpa_s->num_last_scan_freqs = 0;
- if (own_request && data &&
- data->scan_info.freqs && data->scan_info.num_freqs) {
- wpa_s->last_scan_freqs = os_malloc(sizeof(int) *
- data->scan_info.num_freqs);
- if (wpa_s->last_scan_freqs) {
- os_memcpy(wpa_s->last_scan_freqs,
- data->scan_info.freqs,
- sizeof(int) * data->scan_info.num_freqs);
- wpa_s->num_last_scan_freqs = data->scan_info.num_freqs;
- }
- }
-
- return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
-
-scan_work_done:
- wpa_scan_results_free(scan_res);
- if (own_request && wpa_s->scan_work) {
- struct wpa_radio_work *work = wpa_s->scan_work;
- wpa_s->scan_work = NULL;
- radio_work_done(work);
- }
- return ret;
-}
-
-
-static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
- int new_scan, int own_request)
-{
- struct wpa_bss *selected;
- struct wpa_ssid *ssid = NULL;
- int time_to_reenable = wpas_reenabled_network_time(wpa_s);
-
- if (time_to_reenable > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Postpone network selection by %d seconds since all networks are disabled",
- time_to_reenable);
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
- eloop_register_timeout(time_to_reenable, 0,
- wpas_network_reenabled, wpa_s, NULL);
- return 0;
- }
-
- if (wpa_s->p2p_mgmt)
- return 0; /* no normal connection on p2p_mgmt interface */
-
- wpa_s->owe_transition_search = 0;
- selected = wpa_supplicant_pick_network(wpa_s, &ssid);
-
-#ifdef CONFIG_MESH
- if (wpa_s->ifmsh) {
- wpa_msg(wpa_s, MSG_INFO,
- "Avoiding join because we already joined a mesh group");
- return 0;
- }
-#endif /* CONFIG_MESH */
-
- if (selected) {
- int skip;
- skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid);
- if (skip) {
- if (new_scan)
- wpa_supplicant_rsn_preauth_scan_results(wpa_s);
- return 0;
- }
-
- wpa_s->suitable_network++;
-
- if (ssid != wpa_s->current_ssid &&
- wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
-
- if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed");
- return -1;
- }
- if (new_scan)
- wpa_supplicant_rsn_preauth_scan_results(wpa_s);
- /*
- * Do not allow other virtual radios to trigger operations based
- * on these scan results since we do not want them to start
- * other associations at the same time.
- */
- return 1;
- } else {
- wpa_s->no_suitable_network++;
- wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
- ssid = wpa_supplicant_pick_new_network(wpa_s);
- if (ssid) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
- wpa_supplicant_associate(wpa_s, NULL, ssid);
- if (new_scan)
- wpa_supplicant_rsn_preauth_scan_results(wpa_s);
- } else if (own_request) {
- /*
- * No SSID found. If SCAN results are as a result of
- * own scan request and not due to a scan request on
- * another shared interface, try another scan.
- */
- int timeout_sec = wpa_s->scan_interval;
- int timeout_usec = 0;
-#ifdef CONFIG_P2P
- int res;
-
- res = wpas_p2p_scan_no_go_seen(wpa_s);
- if (res == 2)
- return 2;
- if (res == 1)
- return 0;
-
- if (wpa_s->p2p_in_provisioning ||
- wpa_s->show_group_started ||
- wpa_s->p2p_in_invitation) {
- /*
- * Use shorter wait during P2P Provisioning
- * state and during P2P join-a-group operation
- * to speed up group formation.
- */
- timeout_sec = 0;
- timeout_usec = 250000;
- wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
- timeout_usec);
- return 0;
- }
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->conf->auto_interworking &&
- wpa_s->conf->interworking &&
- wpa_s->conf->cred) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: "
- "start ANQP fetch since no matching "
- "networks found");
- wpa_s->network_select = 1;
- wpa_s->auto_network_select = 1;
- interworking_start_fetch_anqp(wpa_s);
- return 1;
- }
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_WPS
- if (wpa_s->after_wps > 0 || wpas_wps_searching(wpa_s)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Use shorter wait during WPS processing");
- timeout_sec = 0;
- timeout_usec = 500000;
- wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
- timeout_usec);
- return 0;
- }
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_OWE
- if (wpa_s->owe_transition_search) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "OWE: Use shorter wait during transition mode search");
- timeout_sec = 0;
- timeout_usec = 500000;
- wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
- timeout_usec);
- return 0;
- }
-#endif /* CONFIG_OWE */
- if (wpa_supplicant_req_sched_scan(wpa_s))
- wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
- timeout_usec);
-
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- WPA_EVENT_NETWORK_NOT_FOUND);
- }
- }
- return 0;
-}
-
-
-static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- struct wpa_supplicant *ifs;
- int res;
-
- res = _wpa_supplicant_event_scan_results(wpa_s, data, 1, 0);
- if (res == 2) {
- /*
- * Interface may have been removed, so must not dereference
- * wpa_s after this.
- */
- return 1;
- }
-
- if (res < 0) {
- /*
- * If no scan results could be fetched, then no need to
- * notify those interfaces that did not actually request
- * this scan. Similarly, if scan results started a new operation on this
- * interface, do not notify other interfaces to avoid concurrent
- * operations during a connection attempt.
- */
- return 0;
- }
-
- /*
- * Check other interfaces to see if they share the same radio. If
- * so, they get updated with this same scan info.
- */
- dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
- radio_list) {
- if (ifs != wpa_s) {
- wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
- "sibling", ifs->ifname);
- res = _wpa_supplicant_event_scan_results(ifs, data, 0,
- res > 0);
- if (res < 0)
- return 0;
- }
- }
-
- return 0;
-}
-
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-
-
-int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_NO_SCAN_PROCESSING
- return -1;
-#else /* CONFIG_NO_SCAN_PROCESSING */
- struct os_reltime now;
-
- wpa_s->ignore_post_flush_scan_res = 0;
-
- if (wpa_s->last_scan_res_used == 0)
- return -1;
-
- os_get_reltime(&now);
- if (os_reltime_expired(&now, &wpa_s->last_scan,
- wpa_s->conf->scan_res_valid_for_connect)) {
- wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
- return -1;
- }
-
- return wpas_select_network_from_last_scan(wpa_s, 0, 1);
-#endif /* CONFIG_NO_SCAN_PROCESSING */
-}
-
-#ifdef CONFIG_WNM
-
-static void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (wpa_s->wpa_state < WPA_ASSOCIATED)
- return;
-
- if (!wpa_s->no_keep_alive) {
- wpa_printf(MSG_DEBUG, "WNM: Send keep-alive to AP " MACSTR,
- MAC2STR(wpa_s->bssid));
- /* TODO: could skip this if normal data traffic has been sent */
- /* TODO: Consider using some more appropriate data frame for
- * this */
- if (wpa_s->l2)
- l2_packet_send(wpa_s->l2, wpa_s->bssid, 0x0800,
- (u8 *) "", 0);
- }
-
-#ifdef CONFIG_SME
- if (wpa_s->sme.bss_max_idle_period) {
- unsigned int msec;
- msec = wpa_s->sme.bss_max_idle_period * 1024; /* times 1000 */
- if (msec > 100)
- msec -= 100;
- eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
- wnm_bss_keep_alive, wpa_s, NULL);
- }
-#endif /* CONFIG_SME */
-}
-
-
-static void wnm_process_assoc_resp(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len)
-{
- struct ieee802_11_elems elems;
-
- if (ies == NULL)
- return;
-
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
- return;
-
-#ifdef CONFIG_SME
- if (elems.bss_max_idle_period) {
- unsigned int msec;
- wpa_s->sme.bss_max_idle_period =
- WPA_GET_LE16(elems.bss_max_idle_period);
- wpa_printf(MSG_DEBUG, "WNM: BSS Max Idle Period: %u (* 1000 "
- "TU)%s", wpa_s->sme.bss_max_idle_period,
- (elems.bss_max_idle_period[2] & 0x01) ?
- " (protected keep-live required)" : "");
- if (wpa_s->sme.bss_max_idle_period == 0)
- wpa_s->sme.bss_max_idle_period = 1;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
- eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
- /* msec times 1000 */
- msec = wpa_s->sme.bss_max_idle_period * 1024;
- if (msec > 100)
- msec -= 100;
- eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
- wnm_bss_keep_alive, wpa_s,
- NULL);
- }
- }
-#endif /* CONFIG_SME */
-}
-
-#endif /* CONFIG_WNM */
-
-
-void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WNM
- eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
-#endif /* CONFIG_WNM */
-}
-
-
-#ifdef CONFIG_INTERWORKING
-
-static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
- size_t len)
-{
- int res;
-
- wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len);
- res = wpa_drv_set_qos_map(wpa_s, qos_map, len);
- if (res) {
- wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver");
- }
-
- return res;
-}
-
-
-static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len)
-{
- struct ieee802_11_elems elems;
-
- if (ies == NULL)
- return;
-
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
- return;
-
- if (elems.qos_map_set) {
- wpas_qos_map_set(wpa_s, elems.qos_map_set,
- elems.qos_map_set_len);
- }
-}
-
-#endif /* CONFIG_INTERWORKING */
-
-
-static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len)
-{
- struct ieee802_11_elems elems;
- const u8 *map_sub_elem, *pos;
- size_t len;
-
- wpa_s->multi_ap_ie = 0;
-
- if (!ies ||
- ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
- !elems.multi_ap || elems.multi_ap_len < 7)
- return;
-
- pos = elems.multi_ap + 4;
- len = elems.multi_ap_len - 4;
-
- map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
- if (!map_sub_elem || map_sub_elem[1] < 1)
- return;
-
- wpa_s->multi_ap_backhaul = !!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS);
- wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
- MULTI_AP_FRONTHAUL_BSS);
- wpa_s->multi_ap_ie = 1;
-}
-
-
-static void multi_ap_set_4addr_mode(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->current_ssid ||
- !wpa_s->current_ssid->multi_ap_backhaul_sta)
- return;
-
- if (!wpa_s->multi_ap_ie) {
- wpa_printf(MSG_INFO,
- "AP does not include valid Multi-AP element");
- goto fail;
- }
-
- if (!wpa_s->multi_ap_backhaul) {
- if (wpa_s->multi_ap_fronthaul &&
- wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- wpa_printf(MSG_INFO,
- "WPS active, accepting fronthaul-only BSS");
- /* Don't set 4addr mode in this case, so just return */
- return;
- }
- wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
- goto fail;
- }
-
- if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
- wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
- goto fail;
- }
- wpa_s->enabled_4addr_mode = 1;
- return;
-
-fail:
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-}
-
-
-#ifdef CONFIG_FST
-static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
- const u8 *ie, size_t ie_len)
-{
- struct mb_ies_info mb_ies;
-
- if (!ie || !ie_len || !wpa_s->fst)
- return -ENOENT;
-
- os_memset(&mb_ies, 0, sizeof(mb_ies));
-
- while (ie_len >= 2 && mb_ies.nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
- size_t len;
-
- len = 2 + ie[1];
- if (len > ie_len) {
- wpa_hexdump(MSG_DEBUG, "FST: Truncated IE found",
- ie, ie_len);
- break;
- }
-
- if (ie[0] == WLAN_EID_MULTI_BAND) {
- wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
- (unsigned int) len);
- mb_ies.ies[mb_ies.nof_ies].ie = ie + 2;
- mb_ies.ies[mb_ies.nof_ies].ie_len = len - 2;
- mb_ies.nof_ies++;
- }
-
- ie_len -= len;
- ie += len;
- }
-
- if (mb_ies.nof_ies > 0) {
- wpabuf_free(wpa_s->received_mb_ies);
- wpa_s->received_mb_ies = mb_ies_by_info(&mb_ies);
- return 0;
- }
-
- return -ENOENT;
-}
-#endif /* CONFIG_FST */
-
-
-static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- int sel;
- const u8 *p;
- int l, len;
- bool found = false;
- struct wpa_ie_data ie;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpa_bss *bss = wpa_s->current_bss;
- int pmf;
-
- if (!ssid)
- return 0;
-
- p = data->assoc_info.req_ies;
- l = data->assoc_info.req_ies_len;
-
- while (p && l >= 2) {
- len = p[1] + 2;
- if (len > l) {
- wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
- p, l);
- break;
- }
- if (((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
- (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
- (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
- (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
- (p[0] == WLAN_EID_RSN && p[1] >= 2))) {
- found = true;
- break;
- }
- l -= len;
- p += len;
- }
-
- if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
- return 0;
-
- wpa_hexdump(MSG_DEBUG,
- "WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq",
- p, l);
-
- /* Update proto from (Re)Association Request frame info */
- wpa_s->wpa_proto = ie.proto;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
- !!(wpa_s->wpa_proto &
- (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
-
- /* Update AKMP suite from (Re)Association Request frame info */
- sel = ie.key_mgmt;
- if (ssid->key_mgmt)
- sel &= ssid->key_mgmt;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP key_mgmt 0x%x network key_mgmt 0x%x; available key_mgmt 0x%x",
- ie.key_mgmt, ssid->key_mgmt, sel);
- if (ie.key_mgmt && !sel) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_AKMP_NOT_VALID);
- return -1;
- }
-
- wpa_s->key_mgmt = ie.key_mgmt;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d",
- wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto),
- wpa_s->wpa_proto);
-
- /* Update pairwise cipher from (Re)Association Request frame info */
- sel = ie.pairwise_cipher;
- if (ssid->pairwise_cipher)
- sel &= ssid->pairwise_cipher;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x",
- ie.pairwise_cipher, ssid->pairwise_cipher, sel);
- if (ie.pairwise_cipher && !sel) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID);
- return -1;
- }
-
- wpa_s->pairwise_cipher = ie.pairwise_cipher;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
- wpa_s->pairwise_cipher);
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
- wpa_cipher_txt(wpa_s->pairwise_cipher));
-
- /* Update other parameters based on AP's WPA IE/RSNE, if available */
- if (!bss) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: current_bss == NULL - skip AP IE check");
- return 0;
- }
-
- /* Update GTK and IGTK from AP's RSNE */
- found = false;
-
- if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
- const u8 *bss_rsn;
-
- bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (bss_rsn) {
- p = bss_rsn;
- len = 2 + bss_rsn[1];
- found = true;
- }
- } else if (wpa_s->wpa_proto & WPA_PROTO_WPA) {
- const u8 *bss_wpa;
-
- bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- if (bss_wpa) {
- p = bss_wpa;
- len = 2 + bss_wpa[1];
- found = true;
- }
- }
-
- if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
- return 0;
-
- pmf = wpas_get_ssid_pmf(wpa_s, ssid);
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
- pmf == MGMT_FRAME_PROTECTION_REQUIRED) {
- /* AP does not support MFP, local configuration requires it */
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
- return -1;
- }
- if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
- pmf == NO_MGMT_FRAME_PROTECTION) {
- /* AP requires MFP, local configuration disables it */
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
- return -1;
- }
-
- /* Update PMF from local configuration now that MFP validation was done
- * above */
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf);
-
- /* Update GTK from AP's RSNE */
- sel = ie.group_cipher;
- if (ssid->group_cipher)
- sel &= ssid->group_cipher;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x",
- ie.group_cipher, ssid->group_cipher, sel);
- if (ie.group_cipher && !sel) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID);
- return -1;
- }
-
- wpa_s->group_cipher = ie.group_cipher;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
- wpa_cipher_txt(wpa_s->group_cipher));
-
- /* Update IGTK from AP RSN IE */
- sel = ie.mgmt_group_cipher;
- if (ssid->group_mgmt_cipher)
- sel &= ssid->group_mgmt_cipher;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
- ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
-
- if (pmf == NO_MGMT_FRAME_PROTECTION ||
- !(ie.capabilities & WPA_CAPABILITY_MFPC)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x",
- ie.capabilities);
- ie.mgmt_group_cipher = 0;
- }
-
- if (ie.mgmt_group_cipher && !sel) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED);
- return -1;
- }
-
- wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
- wpa_s->mgmt_group_cipher);
- if (wpa_s->mgmt_group_cipher)
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s",
- wpa_cipher_txt(wpa_s->mgmt_group_cipher));
- else
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
-
- return 0;
-}
-
-
-static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- int l, len, found = 0, found_x = 0, wpa_found, rsn_found;
- const u8 *p;
- u8 bssid[ETH_ALEN];
- bool bssid_known;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
- bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
- if (data->assoc_info.req_ies)
- wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
- data->assoc_info.req_ies_len);
- if (data->assoc_info.resp_ies) {
- wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-#ifdef CONFIG_TDLS
- wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-#endif /* CONFIG_TDLS */
-#ifdef CONFIG_WNM
- wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-#endif /* CONFIG_WNM */
-#ifdef CONFIG_INTERWORKING
- interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-#endif /* CONFIG_INTERWORKING */
- if (wpa_s->hw_capab == CAPAB_VHT &&
- get_ie(data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
- wpa_s->ieee80211ac = 1;
-
- multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
- }
- if (data->assoc_info.beacon_ies)
- wpa_hexdump(MSG_DEBUG, "beacon_ies",
- data->assoc_info.beacon_ies,
- data->assoc_info.beacon_ies_len);
- if (data->assoc_info.freq)
- wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
- data->assoc_info.freq);
-
- wpa_s->connection_set = 0;
- if (data->assoc_info.req_ies && data->assoc_info.resp_ies) {
- struct ieee802_11_elems req_elems, resp_elems;
-
- if (ieee802_11_parse_elems(data->assoc_info.req_ies,
- data->assoc_info.req_ies_len,
- &req_elems, 0) != ParseFailed &&
- ieee802_11_parse_elems(data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len,
- &resp_elems, 0) != ParseFailed) {
- wpa_s->connection_set = 1;
- wpa_s->connection_ht = req_elems.ht_capabilities &&
- resp_elems.ht_capabilities;
- /* Do not include subset of VHT on 2.4 GHz vendor
- * extension in consideration for reporting VHT
- * association. */
- wpa_s->connection_vht = req_elems.vht_capabilities &&
- resp_elems.vht_capabilities &&
- (!data->assoc_info.freq ||
- wpas_freq_to_band(data->assoc_info.freq) !=
- BAND_2_4_GHZ);
- wpa_s->connection_he = req_elems.he_capabilities &&
- resp_elems.he_capabilities;
- }
- }
-
- p = data->assoc_info.req_ies;
- l = data->assoc_info.req_ies_len;
-
- /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
- while (p && l >= 2) {
- len = p[1] + 2;
- if (len > l) {
- wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
- p, l);
- break;
- }
- if (!found &&
- ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
- (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
- (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
- (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
- (p[0] == WLAN_EID_RSN && p[1] >= 2))) {
- if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
- break;
- found = 1;
- wpa_find_assoc_pmkid(wpa_s);
- }
- if (!found_x && p[0] == WLAN_EID_RSNX) {
- if (wpa_sm_set_assoc_rsnxe(wpa_s->wpa, p, len))
- break;
- found_x = 1;
- }
- l -= len;
- p += len;
- }
- if (!found && data->assoc_info.req_ies)
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- if (!found_x && data->assoc_info.req_ies)
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
-
-#ifdef CONFIG_FILS
-#ifdef CONFIG_SME
- if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
- wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) &&
- (!data->assoc_info.resp_frame ||
- fils_process_assoc_resp(wpa_s->wpa,
- data->assoc_info.resp_frame,
- data->assoc_info.resp_frame_len) < 0)) {
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
- return -1;
- }
-#endif /* CONFIG_SME */
-
- /* Additional processing for FILS when SME is in driver */
- if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
- wpa_sm_set_reset_fils_completed(wpa_s->wpa, 1);
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_OWE
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
- (!bssid_known ||
- owe_process_assoc_resp(wpa_s->wpa, bssid,
- data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len) < 0)) {
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
- return -1;
- }
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_DPP2
- wpa_sm_set_dpp_z(wpa_s->wpa, NULL);
- if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP &&
- wpa_s->dpp_pfs) {
- struct ieee802_11_elems elems;
-
- if (ieee802_11_parse_elems(data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len,
- &elems, 0) == ParseFailed ||
- !elems.owe_dh)
- goto no_pfs;
- if (dpp_pfs_process(wpa_s->dpp_pfs, elems.owe_dh,
- elems.owe_dh_len) < 0) {
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_UNSPECIFIED);
- return -1;
- }
-
- wpa_sm_set_dpp_z(wpa_s->wpa, wpa_s->dpp_pfs->secret);
- }
-no_pfs:
-#endif /* CONFIG_DPP2 */
-
-#ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SME
- if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
- if (!bssid_known ||
- wpa_ft_validate_reassoc_resp(wpa_s->wpa,
- data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len,
- bssid) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
- "Reassociation Response failed");
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_INVALID_IE);
- return -1;
- }
- }
-
- p = data->assoc_info.resp_ies;
- l = data->assoc_info.resp_ies_len;
-
-#ifdef CONFIG_WPS_STRICT
- if (p && wpa_s->current_ssid &&
- wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
- struct wpabuf *wps;
- wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
- if (wps == NULL) {
- wpa_msg(wpa_s, MSG_INFO, "WPS-STRICT: AP did not "
- "include WPS IE in (Re)Association Response");
- return -1;
- }
-
- if (wps_validate_assoc_resp(wps) < 0) {
- wpabuf_free(wps);
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_INVALID_IE);
- return -1;
- }
- wpabuf_free(wps);
- }
-#endif /* CONFIG_WPS_STRICT */
-
- /* Go through the IEs and make a copy of the MDIE, if present. */
- while (p && l >= 2) {
- len = p[1] + 2;
- if (len > l) {
- wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
- p, l);
- break;
- }
- if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
- p[1] >= MOBILITY_DOMAIN_ID_LEN) {
- wpa_s->sme.ft_used = 1;
- os_memcpy(wpa_s->sme.mobility_domain, p + 2,
- MOBILITY_DOMAIN_ID_LEN);
- break;
- }
- l -= len;
- p += len;
- }
-#endif /* CONFIG_SME */
-
- /* Process FT when SME is in the driver */
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- wpa_ft_is_completed(wpa_s->wpa)) {
- if (!bssid_known ||
- wpa_ft_validate_reassoc_resp(wpa_s->wpa,
- data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len,
- bssid) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
- "Reassociation Response failed");
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_INVALID_IE);
- return -1;
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
- }
-
- wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-#endif /* CONFIG_IEEE80211R */
-
- if (bssid_known)
- wpas_handle_assoc_resp_mscs(wpa_s, bssid,
- data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-
- /* WPA/RSN IE from Beacon/ProbeResp */
- p = data->assoc_info.beacon_ies;
- l = data->assoc_info.beacon_ies_len;
-
- /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
- */
- wpa_found = rsn_found = 0;
- while (p && l >= 2) {
- len = p[1] + 2;
- if (len > l) {
- wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
- p, l);
- break;
- }
- if (!wpa_found &&
- p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
- os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
- wpa_found = 1;
- wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
- }
-
- if (!rsn_found &&
- p[0] == WLAN_EID_RSN && p[1] >= 2) {
- rsn_found = 1;
- wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
- }
-
- if (p[0] == WLAN_EID_RSNX && p[1] >= 1)
- wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
-
- l -= len;
- p += len;
- }
-
- if (!wpa_found && data->assoc_info.beacon_ies)
- wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
- if (!rsn_found && data->assoc_info.beacon_ies) {
- wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
- }
- if (wpa_found || rsn_found)
- wpa_s->ap_ies_from_associnfo = 1;
-
- if (wpa_s->assoc_freq && data->assoc_info.freq &&
- wpa_s->assoc_freq != data->assoc_info.freq) {
- wpa_printf(MSG_DEBUG, "Operating frequency changed from "
- "%u to %u MHz",
- wpa_s->assoc_freq, data->assoc_info.freq);
- wpa_supplicant_update_scan_results(wpa_s);
- }
-
- wpa_s->assoc_freq = data->assoc_info.freq;
-
- wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len);
-
- return 0;
-}
-
-
-static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
-{
- const u8 *bss_wpa = NULL, *bss_rsn = NULL, *bss_rsnx = NULL;
-
- if (!wpa_s->current_bss || !wpa_s->current_ssid)
- return -1;
-
- if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt))
- return 0;
-
- bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
- WPA_IE_VENDOR_TYPE);
- bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
- bss_rsnx = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSNX);
-
- if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
- bss_wpa ? 2 + bss_wpa[1] : 0) ||
- wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
- bss_rsn ? 2 + bss_rsn[1] : 0) ||
- wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
- bss_rsnx ? 2 + bss_rsnx[1] : 0))
- return -1;
-
- return 0;
-}
-
-
-static void wpas_fst_update_mb_assoc(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-#ifdef CONFIG_FST
- struct assoc_info *ai = data ? &data->assoc_info : NULL;
- struct wpa_bss *bss = wpa_s->current_bss;
- const u8 *ieprb, *iebcn;
-
- wpabuf_free(wpa_s->received_mb_ies);
- wpa_s->received_mb_ies = NULL;
-
- if (ai &&
- !wpas_fst_update_mbie(wpa_s, ai->resp_ies, ai->resp_ies_len)) {
- wpa_printf(MSG_DEBUG,
- "FST: MB IEs updated from Association Response frame");
- return;
- }
-
- if (ai &&
- !wpas_fst_update_mbie(wpa_s, ai->beacon_ies, ai->beacon_ies_len)) {
- wpa_printf(MSG_DEBUG,
- "FST: MB IEs updated from association event Beacon IEs");
- return;
- }
-
- if (!bss)
- return;
-
- ieprb = wpa_bss_ie_ptr(bss);
- iebcn = ieprb + bss->ie_len;
-
- if (!wpas_fst_update_mbie(wpa_s, ieprb, bss->ie_len))
- wpa_printf(MSG_DEBUG, "FST: MB IEs updated from bss IE");
- else if (!wpas_fst_update_mbie(wpa_s, iebcn, bss->beacon_ie_len))
- wpa_printf(MSG_DEBUG, "FST: MB IEs updated from bss beacon IE");
-#endif /* CONFIG_FST */
-}
-
-
-static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- u8 bssid[ETH_ALEN];
- int ft_completed, already_authorized;
- int new_bss = 0;
-#if defined(CONFIG_FILS) || defined(CONFIG_MBO)
- struct wpa_bss *bss;
-#endif /* CONFIG_FILS || CONFIG_MBO */
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- if (!data)
- return;
- hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
- data->assoc_info.addr,
- data->assoc_info.req_ies,
- data->assoc_info.req_ies_len,
- data->assoc_info.reassoc);
- return;
- }
-#endif /* CONFIG_AP */
-
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
- wpa_s->own_reconnect_req = 0;
-
- ft_completed = wpa_ft_is_completed(wpa_s->wpa);
- if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
- return;
- /*
- * FILS authentication can share the same mechanism to mark the
- * connection fully authenticated, so set ft_completed also based on
- * FILS result.
- */
- if (!ft_completed)
- ft_completed = wpa_fils_is_completed(wpa_s->wpa);
-
- if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
- wpa_dbg(wpa_s, MSG_ERROR, "Failed to get BSSID");
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- return;
- }
-
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
- if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
- if (os_reltime_initialized(&wpa_s->session_start)) {
- os_reltime_age(&wpa_s->session_start,
- &wpa_s->session_length);
- wpa_s->session_start.sec = 0;
- wpa_s->session_start.usec = 0;
- wpas_notify_session_length(wpa_s);
- } else {
- wpas_notify_auth_changed(wpa_s);
- os_get_reltime(&wpa_s->session_start);
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
- MACSTR, MAC2STR(bssid));
- new_bss = 1;
- random_add_randomness(bssid, ETH_ALEN);
- os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- wpas_notify_bssid_changed(wpa_s);
-
- if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
- wpa_clear_keys(wpa_s, bssid);
- }
- if (wpa_supplicant_select_config(wpa_s) < 0) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- return;
- }
- }
-
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- data && wpa_supplicant_use_own_rsne_params(wpa_s, data) < 0)
- return;
-
- multi_ap_set_4addr_mode(wpa_s);
-
- if (wpa_s->conf->ap_scan == 1 &&
- wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) {
- if (wpa_supplicant_assoc_update_ie(wpa_s) < 0 && new_bss)
- wpa_msg(wpa_s, MSG_WARNING,
- "WPA/RSN IEs not updated");
- }
-
- wpas_fst_update_mb_assoc(wpa_s, data);
-
-#ifdef CONFIG_SME
- os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
- wpa_s->sme.prev_bssid_set = 1;
- wpa_s->sme.last_unprot_disconnect.sec = 0;
-#endif /* CONFIG_SME */
-
- wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
- if (wpa_s->current_ssid) {
- /* When using scanning (ap_scan=1), SIM PC/SC interface can be
- * initialized before association, but for other modes,
- * initialize PC/SC here, if the current configuration needs
- * smartcard or SIM/USIM. */
- wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
- }
- wpa_sm_notify_assoc(wpa_s->wpa, bssid);
- if (wpa_s->l2)
- l2_packet_notify_auth_start(wpa_s->l2);
-
- already_authorized = data && data->assoc_info.authorized;
-
- /*
- * Set portEnabled first to false in order to get EAP state machine out
- * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
- * state machine may transit to AUTHENTICATING state based on obsolete
- * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
- * AUTHENTICATED without ever giving chance to EAP state machine to
- * reset the state.
- */
- if (!ft_completed && !already_authorized) {
- eapol_sm_notify_portEnabled(wpa_s->eapol, false);
- eapol_sm_notify_portValid(wpa_s->eapol, false);
- }
- if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || ft_completed ||
- already_authorized || wpa_s->drv_authorized_port)
- eapol_sm_notify_eap_success(wpa_s->eapol, false);
- /* 802.1X::portControl = Auto */
- eapol_sm_notify_portEnabled(wpa_s->eapol, true);
- wpa_s->eapol_received = 0;
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
- (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_IBSS)) {
- if (wpa_s->current_ssid &&
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE &&
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
- /*
- * Set the key after having received joined-IBSS event
- * from the driver.
- */
- wpa_supplicant_set_wpa_none_key(wpa_s,
- wpa_s->current_ssid);
- }
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- } else if (!ft_completed) {
- /* Timeout for receiving the first EAPOL packet */
- wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
- }
- wpa_supplicant_cancel_scan(wpa_s);
-
- if (ft_completed) {
- /*
- * FT protocol completed - make sure EAPOL state machine ends
- * up in authenticated.
- */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- eapol_sm_notify_portValid(wpa_s->eapol, true);
- eapol_sm_notify_eap_success(wpa_s->eapol, true);
- } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
- wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
- /*
- * We are done; the driver will take care of RSN 4-way
- * handshake.
- */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- eapol_sm_notify_portValid(wpa_s->eapol, true);
- eapol_sm_notify_eap_success(wpa_s->eapol, true);
- } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
- wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
- /*
- * The driver will take care of RSN 4-way handshake, so we need
- * to allow EAPOL supplicant to complete its work without
- * waiting for WPA supplicant.
- */
- eapol_sm_notify_portValid(wpa_s->eapol, true);
- }
-
- wpa_s->last_eapol_matches_bssid = 0;
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->rsne_override_eapol) {
- wpa_printf(MSG_DEBUG,
- "TESTING: RSNE EAPOL-Key msg 2/4 override");
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa,
- wpabuf_head(wpa_s->rsne_override_eapol),
- wpabuf_len(wpa_s->rsne_override_eapol));
- }
- if (wpa_s->rsnxe_override_eapol) {
- wpa_printf(MSG_DEBUG,
- "TESTING: RSNXE EAPOL-Key msg 2/4 override");
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa,
- wpabuf_head(wpa_s->rsnxe_override_eapol),
- wpabuf_len(wpa_s->rsnxe_override_eapol));
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->pending_eapol_rx) {
- struct os_reltime now, age;
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
- if (age.sec == 0 && age.usec < 200000 &&
- os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
- 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Process pending EAPOL "
- "frame that was received just before "
- "association notification");
- wpa_supplicant_rx_eapol(
- wpa_s, wpa_s->pending_eapol_rx_src,
- wpabuf_head(wpa_s->pending_eapol_rx),
- wpabuf_len(wpa_s->pending_eapol_rx));
- }
- wpabuf_free(wpa_s->pending_eapol_rx);
- wpa_s->pending_eapol_rx = NULL;
- }
-
-#ifdef CONFIG_WEP
- if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
- wpa_s->current_ssid &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
- /* Set static WEP keys again */
- wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
- }
-#endif /* CONFIG_WEP */
-
-#ifdef CONFIG_IBSS_RSN
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
- wpa_s->ibss_rsn == NULL) {
- wpa_s->ibss_rsn = ibss_rsn_init(wpa_s, wpa_s->current_ssid);
- if (!wpa_s->ibss_rsn) {
- wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- return;
- }
-
- ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
- }
-#endif /* CONFIG_IBSS_RSN */
-
- wpas_wps_notify_assoc(wpa_s, bssid);
-
- if (data) {
- wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len,
- &data->assoc_info.wmm_params);
-
- if (wpa_s->reassoc_same_bss)
- wmm_ac_restore_tspecs(wpa_s);
- }
-
-#if defined(CONFIG_FILS) || defined(CONFIG_MBO)
- bss = wpa_bss_get_bssid(wpa_s, bssid);
-#endif /* CONFIG_FILS || CONFIG_MBO */
-#ifdef CONFIG_FILS
- if (wpa_key_mgmt_fils(wpa_s->key_mgmt)) {
- const u8 *fils_cache_id = wpa_bss_get_fils_cache_id(bss);
-
- if (fils_cache_id)
- wpa_sm_set_fils_cache_id(wpa_s->wpa, fils_cache_id);
- }
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_MBO
- wpas_mbo_check_pmf(wpa_s, bss, wpa_s->current_ssid);
-#endif /* CONFIG_MBO */
-
-#ifdef CONFIG_DPP2
- wpa_s->dpp_pfs_fallback = 0;
-#endif /* CONFIG_DPP2 */
-}
-
-
-static int disconnect_reason_recoverable(u16 reason_code)
-{
- return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
- reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
- reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
-}
-
-
-static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
- u16 reason_code,
- int locally_generated)
-{
- const u8 *bssid;
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
- /*
- * At least Host AP driver and a Prism3 card seemed to be
- * generating streams of disconnected events when configuring
- * IBSS for WPA-None. Ignore them for now.
- */
- return;
- }
-
- bssid = wpa_s->bssid;
- if (is_zero_ether_addr(bssid))
- bssid = wpa_s->pending_bssid;
-
- if (!is_zero_ether_addr(bssid) ||
- wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
- " reason=%d%s",
- MAC2STR(bssid), reason_code,
- locally_generated ? " locally_generated=1" : "");
- }
-}
-
-
-static int could_be_psk_mismatch(struct wpa_supplicant *wpa_s, u16 reason_code,
- int locally_generated)
-{
- if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE ||
- !wpa_s->new_connection ||
- !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_key_mgmt_sae(wpa_s->key_mgmt))
- return 0; /* Not in initial 4-way handshake with PSK */
-
- /*
- * It looks like connection was lost while trying to go through PSK
- * 4-way handshake. Filter out known disconnection cases that are caused
- * by something else than PSK mismatch to avoid confusing reports.
- */
-
- if (locally_generated) {
- if (reason_code == WLAN_REASON_IE_IN_4WAY_DIFFERS)
- return 0;
- }
-
- return 1;
-}
-
-
-static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
- u16 reason_code,
- int locally_generated)
-{
- const u8 *bssid;
- int authenticating;
- u8 prev_pending_bssid[ETH_ALEN];
- struct wpa_bss *fast_reconnect = NULL;
- struct wpa_ssid *fast_reconnect_ssid = NULL;
- struct wpa_ssid *last_ssid;
- struct wpa_bss *curr = NULL;
-
- authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
- os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
- /*
- * At least Host AP driver and a Prism3 card seemed to be
- * generating streams of disconnected events when configuring
- * IBSS for WPA-None. Ignore them for now.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - ignore in "
- "IBSS/WPA-None mode");
- return;
- }
-
- if (!wpa_s->disconnected && wpa_s->wpa_state >= WPA_AUTHENTICATING &&
- reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY &&
- locally_generated)
- /*
- * Remove the inactive AP (which is probably out of range) from
- * the BSS list after marking disassociation. In particular
- * mac80211-based drivers use the
- * WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY reason code in
- * locally generated disconnection events for cases where the
- * AP does not reply anymore.
- */
- curr = wpa_s->current_bss;
-
- if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
- "pre-shared key may be incorrect");
- if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
- return; /* P2P group removed */
- wpas_auth_failed(wpa_s, "WRONG_KEY");
-#ifdef CONFIG_DPP2
- wpas_dpp_send_conn_status_result(wpa_s,
- DPP_STATUS_AUTH_FAILURE);
-#endif /* CONFIG_DPP2 */
- }
- if (!wpa_s->disconnected &&
- (!wpa_s->auto_reconnect_disabled ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS ||
- wpas_wps_searching(wpa_s) ||
- wpas_wps_reenable_networks_pending(wpa_s))) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to "
- "reconnect (wps=%d/%d wpa_state=%d)",
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS,
- wpas_wps_searching(wpa_s),
- wpa_s->wpa_state);
- if (wpa_s->wpa_state == WPA_COMPLETED &&
- wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
- (wpa_s->own_reconnect_req ||
- (!locally_generated &&
- disconnect_reason_recoverable(reason_code)))) {
- /*
- * It looks like the AP has dropped association with
- * us, but could allow us to get back in. This is also
- * triggered for cases where local reconnection request
- * is used to force reassociation with the same BSS.
- * Try to reconnect to the same BSS without a full scan
- * to save time for some common cases.
- */
- fast_reconnect = wpa_s->current_bss;
- fast_reconnect_ssid = wpa_s->current_ssid;
- } else if (wpa_s->wpa_state >= WPA_ASSOCIATING) {
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new "
- "immediate scan");
- }
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not "
- "try to re-connect");
- wpa_s->reassociate = 0;
- wpa_s->disconnected = 1;
- if (!wpa_s->pno)
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
- bssid = wpa_s->bssid;
- if (is_zero_ether_addr(bssid))
- bssid = wpa_s->pending_bssid;
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpas_connection_failed(wpa_s, bssid);
- wpa_sm_notify_disassoc(wpa_s->wpa);
- ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE);
-
- if (locally_generated)
- wpa_s->disconnect_reason = -reason_code;
- else
- wpa_s->disconnect_reason = reason_code;
- wpas_notify_disconnect_reason(wpa_s);
- if (wpa_supplicant_dynamic_keys(wpa_s)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys");
- wpa_clear_keys(wpa_s, wpa_s->bssid);
- }
- last_ssid = wpa_s->current_ssid;
- wpa_supplicant_mark_disassoc(wpa_s);
-
- if (curr)
- wpa_bss_remove(wpa_s, curr, "Connection to AP lost");
-
- if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
- sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
- wpa_s->current_ssid = last_ssid;
- }
-
- if (fast_reconnect &&
- !wpas_network_disabled(wpa_s, fast_reconnect_ssid) &&
- !disallowed_bssid(wpa_s, fast_reconnect->bssid) &&
- !disallowed_ssid(wpa_s, fast_reconnect->ssid,
- fast_reconnect->ssid_len) &&
- !wpas_temp_disabled(wpa_s, fast_reconnect_ssid) &&
- !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect)) {
-#ifndef CONFIG_NO_SCAN_PROCESSING
- wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
- if (wpa_supplicant_connect(wpa_s, fast_reconnect,
- fast_reconnect_ssid) < 0) {
- /* Recover through full scan */
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- }
-#endif /* CONFIG_NO_SCAN_PROCESSING */
- } else if (fast_reconnect) {
- /*
- * Could not reconnect to the same BSS due to network being
- * disabled. Use a new scan to match the alternative behavior
- * above, i.e., to continue automatic reconnection attempt in a
- * way that enforces disabled network rules.
- */
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- }
-}
-
-
-#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
-void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (!wpa_s->pending_mic_error_report)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Sending pending MIC error report");
- wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
- wpa_s->pending_mic_error_report = 0;
-}
-#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
-
-
-static void
-wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- int pairwise;
- struct os_reltime t;
-
- wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
- pairwise = (data && data->michael_mic_failure.unicast);
- os_get_reltime(&t);
- if ((wpa_s->last_michael_mic_error.sec &&
- !os_reltime_expired(&t, &wpa_s->last_michael_mic_error, 60)) ||
- wpa_s->pending_mic_error_report) {
- if (wpa_s->pending_mic_error_report) {
- /*
- * Send the pending MIC error report immediately since
- * we are going to start countermeasures and AP better
- * do the same.
- */
- wpa_sm_key_request(wpa_s->wpa, 1,
- wpa_s->pending_mic_error_pairwise);
- }
-
- /* Send the new MIC error report immediately since we are going
- * to start countermeasures and AP better do the same.
- */
- wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
-
- /* initialize countermeasures */
- wpa_s->countermeasures = 1;
-
- wpa_bssid_ignore_add(wpa_s, wpa_s->bssid);
-
- wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
-
- /*
- * Need to wait for completion of request frame. We do not get
- * any callback for the message completion, so just wait a
- * short while and hope for the best. */
- os_sleep(0, 10000);
-
- wpa_drv_set_countermeasures(wpa_s, 1);
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_MICHAEL_MIC_FAILURE);
- eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
- wpa_s, NULL);
- eloop_register_timeout(60, 0,
- wpa_supplicant_stop_countermeasures,
- wpa_s, NULL);
- /* TODO: mark the AP rejected for 60 second. STA is
- * allowed to associate with another AP.. */
- } else {
-#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
- if (wpa_s->mic_errors_seen) {
- /*
- * Reduce the effectiveness of Michael MIC error
- * reports as a means for attacking against TKIP if
- * more than one MIC failure is noticed with the same
- * PTK. We delay the transmission of the reports by a
- * random time between 0 and 60 seconds in order to
- * force the attacker wait 60 seconds before getting
- * the information on whether a frame resulted in a MIC
- * failure.
- */
- u8 rval[4];
- int sec;
-
- if (os_get_random(rval, sizeof(rval)) < 0)
- sec = os_random() % 60;
- else
- sec = WPA_GET_BE32(rval) % 60;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error "
- "report %d seconds", sec);
- wpa_s->pending_mic_error_report = 1;
- wpa_s->pending_mic_error_pairwise = pairwise;
- eloop_cancel_timeout(
- wpa_supplicant_delayed_mic_error_report,
- wpa_s, NULL);
- eloop_register_timeout(
- sec, os_random() % 1000000,
- wpa_supplicant_delayed_mic_error_report,
- wpa_s, NULL);
- } else {
- wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
- }
-#else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
- wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
-#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
- }
- wpa_s->last_michael_mic_error = t;
- wpa_s->mic_errors_seen++;
-}
-
-
-#ifdef CONFIG_TERMINATE_ONLASTIF
-static int any_interfaces(struct wpa_supplicant *head)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
- if (!wpa_s->interface_removed)
- return 1;
- return 0;
-}
-#endif /* CONFIG_TERMINATE_ONLASTIF */
-
-
-static void
-wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
- return;
-
- switch (data->interface_status.ievent) {
- case EVENT_INTERFACE_ADDED:
- if (!wpa_s->interface_removed)
- break;
- wpa_s->interface_removed = 0;
- wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was added");
- if (wpa_supplicant_driver_init(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the "
- "driver after interface was added");
- }
-
-#ifdef CONFIG_P2P
- if (!wpa_s->global->p2p &&
- !wpa_s->global->p2p_disabled &&
- !wpa_s->conf->p2p_disabled &&
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
- wpas_p2p_add_p2pdev_interface(
- wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
- wpa_printf(MSG_INFO,
- "P2P: Failed to enable P2P Device interface");
- /* Try to continue without. P2P will be disabled. */
- }
-#endif /* CONFIG_P2P */
-
- break;
- case EVENT_INTERFACE_REMOVED:
- wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
- wpa_s->interface_removed = 1;
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
- l2_packet_deinit(wpa_s->l2);
- wpa_s->l2 = NULL;
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p &&
- wpa_s->global->p2p_init_wpa_s->parent == wpa_s &&
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Removing P2P Device interface");
- wpa_supplicant_remove_iface(
- wpa_s->global, wpa_s->global->p2p_init_wpa_s,
- 0);
- wpa_s->global->p2p_init_wpa_s = NULL;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_MATCH_IFACE
- if (wpa_s->matched) {
- wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
- break;
- }
-#endif /* CONFIG_MATCH_IFACE */
-
-#ifdef CONFIG_TERMINATE_ONLASTIF
- /* check if last interface */
- if (!any_interfaces(wpa_s->global->ifaces))
- eloop_terminate();
-#endif /* CONFIG_TERMINATE_ONLASTIF */
- break;
- }
-}
-
-
-#ifdef CONFIG_TDLS
-static void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (data == NULL)
- return;
- switch (data->tdls.oper) {
- case TDLS_REQUEST_SETUP:
- wpa_tdls_remove(wpa_s->wpa, data->tdls.peer);
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
- else
- wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
- break;
- case TDLS_REQUEST_TEARDOWN:
- if (wpa_tdls_is_external_setup(wpa_s->wpa))
- wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
- data->tdls.reason_code);
- else
- wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN,
- data->tdls.peer);
- break;
- case TDLS_REQUEST_DISCOVER:
- wpa_tdls_send_discovery_request(wpa_s->wpa,
- data->tdls.peer);
- break;
- }
-}
-#endif /* CONFIG_TDLS */
-
-
-#ifdef CONFIG_WNM
-static void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (data == NULL)
- return;
- switch (data->wnm.oper) {
- case WNM_OPER_SLEEP:
- wpa_printf(MSG_DEBUG, "Start sending WNM-Sleep Request "
- "(action=%d, intval=%d)",
- data->wnm.sleep_action, data->wnm.sleep_intval);
- ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
- data->wnm.sleep_intval, NULL);
- break;
- }
-}
-#endif /* CONFIG_WNM */
-
-
-#ifdef CONFIG_IEEE80211R
-static void
-wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (data == NULL)
- return;
-
- if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
- data->ft_ies.ies_len,
- data->ft_ies.ft_action,
- data->ft_ies.target_ap,
- data->ft_ies.ric_ies,
- data->ft_ies.ric_ies_len) < 0) {
- /* TODO: prevent MLME/driver from trying to associate? */
- }
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-#ifdef CONFIG_IBSS_RSN
-static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- struct wpa_ssid *ssid;
- if (wpa_s->wpa_state < WPA_ASSOCIATED)
- return;
- if (data == NULL)
- return;
- ssid = wpa_s->current_ssid;
- if (ssid == NULL)
- return;
- if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
- return;
-
- ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
-}
-
-
-static void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL)
- return;
-
- /* check if the ssid is correctly configured as IBSS/RSN */
- if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
- return;
-
- ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame,
- data->rx_mgmt.frame_len);
-}
-#endif /* CONFIG_IBSS_RSN */
-
-
-#ifdef CONFIG_IEEE80211R
-static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
- size_t len)
-{
- const u8 *sta_addr, *target_ap_addr;
- u16 status;
-
- wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
- return; /* only SME case supported for now */
- if (len < 1 + 2 * ETH_ALEN + 2)
- return;
- if (data[0] != 2)
- return; /* Only FT Action Response is supported for now */
- sta_addr = data + 1;
- target_ap_addr = data + 1 + ETH_ALEN;
- status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: Received FT Action Response: STA "
- MACSTR " TargetAP " MACSTR " status %u",
- MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
-
- if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: Foreign STA Address " MACSTR
- " in FT Action Response", MAC2STR(sta_addr));
- return;
- }
-
- if (status) {
- wpa_dbg(wpa_s, MSG_DEBUG, "FT: FT Action Response indicates "
- "failure (status code %d)", status);
- /* TODO: report error to FT code(?) */
- return;
- }
-
- if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
- len - (1 + 2 * ETH_ALEN + 2), 1,
- target_ap_addr, NULL, 0) < 0)
- return;
-
-#ifdef CONFIG_SME
- {
- struct wpa_bss *bss;
- bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
- if (bss)
- wpa_s->sme.freq = bss->freq;
- wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
- sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
- WLAN_AUTH_FT);
- }
-#endif /* CONFIG_SME */
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-static void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s,
- struct unprot_deauth *e)
-{
- wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame "
- "dropped: " MACSTR " -> " MACSTR
- " (reason code %u)",
- MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
- sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
-}
-
-
-static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
- struct unprot_disassoc *e)
-{
- wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame "
- "dropped: " MACSTR " -> " MACSTR
- " (reason code %u)",
- MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
- sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
-}
-
-
-static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr,
- u16 reason_code, int locally_generated,
- const u8 *ie, size_t ie_len, int deauth)
-{
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface && addr) {
- hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], addr);
- return;
- }
-
- if (wpa_s->ap_iface) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in AP mode");
- return;
- }
-#endif /* CONFIG_AP */
-
- if (!locally_generated)
- wpa_s->own_disconnect_req = 0;
-
- wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated);
-
- if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED ||
- ((wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
- (wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) &&
- eapol_sm_failed(wpa_s->eapol))) &&
- !wpa_s->eap_expected_failure))
- wpas_auth_failed(wpa_s, "AUTH_FAILED");
-
-#ifdef CONFIG_P2P
- if (deauth && reason_code > 0) {
- if (wpas_p2p_deauth_notif(wpa_s, addr, reason_code, ie, ie_len,
- locally_generated) > 0) {
- /*
- * The interface was removed, so cannot continue
- * processing any additional operations after this.
- */
- return;
- }
- }
-#endif /* CONFIG_P2P */
-
- wpa_supplicant_event_disassoc_finish(wpa_s, reason_code,
- locally_generated);
-}
-
-
-static void wpas_event_disassoc(struct wpa_supplicant *wpa_s,
- struct disassoc_info *info)
-{
- u16 reason_code = 0;
- int locally_generated = 0;
- const u8 *addr = NULL;
- const u8 *ie = NULL;
- size_t ie_len = 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
-
- if (info) {
- addr = info->addr;
- ie = info->ie;
- ie_len = info->ie_len;
- reason_code = info->reason_code;
- locally_generated = info->locally_generated;
- wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u (%s)%s", reason_code,
- reason2str(reason_code),
- locally_generated ? " locally_generated=1" : "");
- if (addr)
- wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
- MAC2STR(addr));
- wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
- ie, ie_len);
- }
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface && info && info->addr) {
- hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], info->addr);
- return;
- }
-
- if (wpa_s->ap_iface) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in AP mode");
- return;
- }
-#endif /* CONFIG_AP */
-
-#ifdef CONFIG_P2P
- if (info) {
- wpas_p2p_disassoc_notif(
- wpa_s, info->addr, reason_code, info->ie, info->ie_len,
- locally_generated);
- }
-#endif /* CONFIG_P2P */
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- sme_event_disassoc(wpa_s, info);
-
- wpas_event_disconnect(wpa_s, addr, reason_code, locally_generated,
- ie, ie_len, 0);
-}
-
-
-static void wpas_event_deauth(struct wpa_supplicant *wpa_s,
- struct deauth_info *info)
-{
- u16 reason_code = 0;
- int locally_generated = 0;
- const u8 *addr = NULL;
- const u8 *ie = NULL;
- size_t ie_len = 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Deauthentication notification");
-
- if (info) {
- addr = info->addr;
- ie = info->ie;
- ie_len = info->ie_len;
- reason_code = info->reason_code;
- locally_generated = info->locally_generated;
- wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u (%s)%s",
- reason_code, reason2str(reason_code),
- locally_generated ? " locally_generated=1" : "");
- if (addr) {
- wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
- MAC2STR(addr));
- }
- wpa_hexdump(MSG_DEBUG, "Deauthentication frame IE(s)",
- ie, ie_len);
- }
-
- wpa_reset_ft_completed(wpa_s->wpa);
-
- wpas_event_disconnect(wpa_s, addr, reason_code,
- locally_generated, ie, ie_len, 1);
-}
-
-
-static const char * reg_init_str(enum reg_change_initiator init)
-{
- switch (init) {
- case REGDOM_SET_BY_CORE:
- return "CORE";
- case REGDOM_SET_BY_USER:
- return "USER";
- case REGDOM_SET_BY_DRIVER:
- return "DRIVER";
- case REGDOM_SET_BY_COUNTRY_IE:
- return "COUNTRY_IE";
- case REGDOM_BEACON_HINT:
- return "BEACON_HINT";
- }
- return "?";
-}
-
-
-static const char * reg_type_str(enum reg_type type)
-{
- switch (type) {
- case REGDOM_TYPE_UNKNOWN:
- return "UNKNOWN";
- case REGDOM_TYPE_COUNTRY:
- return "COUNTRY";
- case REGDOM_TYPE_WORLD:
- return "WORLD";
- case REGDOM_TYPE_CUSTOM_WORLD:
- return "CUSTOM_WORLD";
- case REGDOM_TYPE_INTERSECTION:
- return "INTERSECTION";
- }
- return "?";
-}
-
-
-void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
- struct channel_list_changed *info)
-{
- struct wpa_supplicant *ifs;
- u8 dfs_domain;
-
- /*
- * To allow backwards compatibility with higher level layers that
- * assumed the REGDOM_CHANGE event is sent over the initially added
- * interface. Find the highest parent of this interface and use it to
- * send the event.
- */
- for (ifs = wpa_s; ifs->parent && ifs != ifs->parent; ifs = ifs->parent)
- ;
-
- if (info) {
- wpa_msg(ifs, MSG_INFO,
- WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
- reg_init_str(info->initiator), reg_type_str(info->type),
- info->alpha2[0] ? " alpha2=" : "",
- info->alpha2[0] ? info->alpha2 : "");
- }
-
- if (wpa_s->drv_priv == NULL)
- return; /* Ignore event during drv initialization */
-
- dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
- radio_list) {
- wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
- ifs->ifname);
- free_hw_features(ifs);
- ifs->hw.modes = wpa_drv_get_hw_feature_data(
- ifs, &ifs->hw.num_modes, &ifs->hw.flags, &dfs_domain);
-
- /* Restart PNO/sched_scan with updated channel list */
- if (ifs->pno) {
- wpas_stop_pno(ifs);
- wpas_start_pno(ifs);
- } else if (ifs->sched_scanning && !ifs->pno_sched_pending) {
- wpa_dbg(ifs, MSG_DEBUG,
- "Channel list changed - restart sched_scan");
- wpas_scan_restart_sched_scan(ifs);
- }
- }
-
- wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DRIVER);
-}
-
-
-static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
- const u8 *frame, size_t len, int freq,
- int rssi)
-{
- const struct ieee80211_mgmt *mgmt;
- const u8 *payload;
- size_t plen;
- u8 category;
-
- if (len < IEEE80211_HDRLEN + 2)
- return;
-
- mgmt = (const struct ieee80211_mgmt *) frame;
- payload = frame + IEEE80211_HDRLEN;
- category = *payload++;
- plen = len - IEEE80211_HDRLEN - 1;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
- " Category=%u DataLen=%d freq=%d MHz",
- MAC2STR(mgmt->sa), category, (int) plen, freq);
-
- if (category == WLAN_ACTION_WMM) {
- wmm_ac_rx_action(wpa_s, mgmt->da, mgmt->sa, payload, plen);
- return;
- }
-
-#ifdef CONFIG_IEEE80211R
- if (category == WLAN_ACTION_FT) {
- ft_rx_action(wpa_s, payload, plen);
- return;
- }
-#endif /* CONFIG_IEEE80211R */
-
-#ifdef CONFIG_SME
- if (category == WLAN_ACTION_SA_QUERY) {
- sme_sa_query_rx(wpa_s, mgmt->da, mgmt->sa, payload, plen);
- return;
- }
-#endif /* CONFIG_SME */
-
-#ifdef CONFIG_WNM
- if (mgmt->u.action.category == WLAN_ACTION_WNM) {
- ieee802_11_rx_wnm_action(wpa_s, mgmt, len);
- return;
- }
-#endif /* CONFIG_WNM */
-
-#ifdef CONFIG_GAS
- if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
- mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
- gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- payload, plen, freq) == 0)
- return;
-#endif /* CONFIG_GAS */
-
-#ifdef CONFIG_GAS_SERVER
- if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
- mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
- gas_server_rx(wpa_s->gas_server, mgmt->da, mgmt->sa, mgmt->bssid,
- mgmt->u.action.category,
- payload, plen, freq) == 0)
- return;
-#endif /* CONFIG_GAS_SERVER */
-
-#ifdef CONFIG_TDLS
- if (category == WLAN_ACTION_PUBLIC && plen >= 4 &&
- payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "TDLS: Received Discovery Response from " MACSTR,
- MAC2STR(mgmt->sa));
- return;
- }
-#endif /* CONFIG_TDLS */
-
-#ifdef CONFIG_INTERWORKING
- if (category == WLAN_ACTION_QOS && plen >= 1 &&
- payload[0] == QOS_QOS_MAP_CONFIG) {
- const u8 *pos = payload + 1;
- size_t qlen = plen - 1;
- wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
- MACSTR, MAC2STR(mgmt->sa));
- if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) == 0 &&
- qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
- pos[1] <= qlen - 2 && pos[1] >= 16)
- wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
- return;
- }
-#endif /* CONFIG_INTERWORKING */
-
- if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
- payload[0] == WLAN_RRM_RADIO_MEASUREMENT_REQUEST) {
- wpas_rrm_handle_radio_measurement_request(wpa_s, mgmt->sa,
- mgmt->da,
- payload + 1,
- plen - 1);
- return;
- }
-
- if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
- payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
- wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1);
- return;
- }
-
- if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
- payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
- wpas_rrm_handle_link_measurement_request(wpa_s, mgmt->sa,
- payload + 1, plen - 1,
- rssi);
- return;
- }
-
-#ifdef CONFIG_FST
- if (mgmt->u.action.category == WLAN_ACTION_FST && wpa_s->fst) {
- fst_rx_action(wpa_s->fst, mgmt, len);
- return;
- }
-#endif /* CONFIG_FST */
-
-#ifdef CONFIG_DPP
- if (category == WLAN_ACTION_PUBLIC && plen >= 5 &&
- payload[0] == WLAN_PA_VENDOR_SPECIFIC &&
- WPA_GET_BE24(&payload[1]) == OUI_WFA &&
- payload[4] == DPP_OUI_TYPE) {
- payload++;
- plen--;
- wpas_dpp_rx_action(wpa_s, mgmt->sa, payload, plen, freq);
- return;
- }
-#endif /* CONFIG_DPP */
-
- if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
- payload[0] == ROBUST_AV_SCS_RESP) {
- wpas_handle_robust_av_scs_recv_action(wpa_s, mgmt->sa,
- payload + 1, plen - 1);
- return;
- }
-
- if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
- payload[0] == ROBUST_AV_MSCS_RESP) {
- wpas_handle_robust_av_recv_action(wpa_s, mgmt->sa,
- payload + 1, plen - 1);
- return;
- }
-
- if (category == WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED && plen > 4 &&
- WPA_GET_BE32(payload) == QM_ACTION_VENDOR_TYPE) {
- wpas_handle_qos_mgmt_recv_action(wpa_s, mgmt->sa,
- payload + 4, plen - 4);
- return;
- }
-
- wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
- category, payload, plen, freq);
- if (wpa_s->ifmsh)
- mesh_mpm_action_rx(wpa_s, mgmt, len);
-}
-
-
-static void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s,
- union wpa_event_data *event)
-{
- struct wpa_freq_range_list *list;
- char *str = NULL;
-
- list = &event->freq_range;
-
- if (list->num)
- str = freq_range_list_str(list);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s",
- str ? str : "");
-
-#ifdef CONFIG_P2P
- if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) {
- wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range",
- __func__);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event");
-
- /*
- * The update channel flow will also take care of moving a GO
- * from the unsafe frequency if needed.
- */
- wpas_p2p_update_channel_list(wpa_s,
- WPAS_P2P_CHANNEL_UPDATE_AVOID);
- }
-#endif /* CONFIG_P2P */
-
- os_free(str);
-}
-
-
-static void wpa_supplicant_event_port_authorized(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->wpa_state == WPA_ASSOCIATED) {
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- eapol_sm_notify_portValid(wpa_s->eapol, true);
- eapol_sm_notify_eap_success(wpa_s->eapol, true);
- wpa_s->drv_authorized_port = 1;
- }
-}
-
-
-static unsigned int wpas_event_cac_ms(const struct wpa_supplicant *wpa_s,
- int freq)
-{
- size_t i;
- int j;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- const struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
-
- for (j = 0; j < mode->num_channels; j++) {
- const struct hostapd_channel_data *chan;
-
- chan = &mode->channels[j];
- if (chan->freq == freq)
- return chan->dfs_cac_ms;
- }
- }
-
- return 0;
-}
-
-
-static void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
-#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
- if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_started(wpa_s, radar);
- } else
-#endif /* NEED_AP_MLME && CONFIG_AP */
- {
- unsigned int cac_time = wpas_event_cac_ms(wpa_s, radar->freq);
-
- cac_time /= 1000; /* convert from ms to sec */
- if (!cac_time)
- cac_time = 10 * 60; /* max timeout: 10 minutes */
-
- /* Restart auth timeout: CAC time added to initial timeout */
- wpas_auth_timeout_restart(wpa_s, cac_time);
- }
-}
-
-
-static void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
-#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
- if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_finished(wpa_s, radar);
- } else
-#endif /* NEED_AP_MLME && CONFIG_AP */
- {
- /* Restart auth timeout with original value after CAC is
- * finished */
- wpas_auth_timeout_restart(wpa_s, 0);
- }
-}
-
-
-static void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
-{
-#if defined(NEED_AP_MLME) && defined(CONFIG_AP)
- if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_aborted(wpa_s, radar);
- } else
-#endif /* NEED_AP_MLME && CONFIG_AP */
- {
- /* Restart auth timeout with original value after CAC is
- * aborted */
- wpas_auth_timeout_restart(wpa_s, 0);
- }
-}
-
-
-static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Connection authorized by device, previous state %d",
- wpa_s->wpa_state);
-
- wpa_supplicant_event_port_authorized(wpa_s);
-
- wpa_s->last_eapol_matches_bssid = 1;
-
- wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr);
- wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck,
- data->assoc_info.ptk_kck_len,
- data->assoc_info.ptk_kek,
- data->assoc_info.ptk_kek_len);
-#ifdef CONFIG_FILS
- if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
- struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
- const u8 *fils_cache_id = wpa_bss_get_fils_cache_id(bss);
-
- /* Update ERP next sequence number */
- eapol_sm_update_erp_next_seq_num(
- wpa_s->eapol, data->assoc_info.fils_erp_next_seq_num);
-
- if (data->assoc_info.fils_pmk && data->assoc_info.fils_pmkid) {
- /* Add the new PMK and PMKID to the PMKSA cache */
- wpa_sm_pmksa_cache_add(wpa_s->wpa,
- data->assoc_info.fils_pmk,
- data->assoc_info.fils_pmk_len,
- data->assoc_info.fils_pmkid,
- wpa_s->bssid, fils_cache_id);
- } else if (data->assoc_info.fils_pmkid) {
- /* Update the current PMKSA used for this connection */
- pmksa_cache_set_current(wpa_s->wpa,
- data->assoc_info.fils_pmkid,
- NULL, NULL, 0, NULL, 0);
- }
- }
-#endif /* CONFIG_FILS */
-}
-
-
-static const char * connect_fail_reason(enum sta_connect_fail_reason_codes code)
-{
- switch (code) {
- case STA_CONNECT_FAIL_REASON_UNSPECIFIED:
- return "";
- case STA_CONNECT_FAIL_REASON_NO_BSS_FOUND:
- return "no_bss_found";
- case STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL:
- return "auth_tx_fail";
- case STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED:
- return "auth_no_ack_received";
- case STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED:
- return "auth_no_resp_received";
- case STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL:
- return "assoc_req_tx_fail";
- case STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED:
- return "assoc_no_ack_received";
- case STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED:
- return "assoc_no_resp_received";
- default:
- return "unknown_reason";
- }
-}
-
-
-static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- const u8 *bssid = data->assoc_reject.bssid;
-#ifdef CONFIG_MBO
- struct wpa_bss *reject_bss;
-#endif /* CONFIG_MBO */
-
- if (!bssid || is_zero_ether_addr(bssid))
- bssid = wpa_s->pending_bssid;
-#ifdef CONFIG_MBO
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- reject_bss = wpa_s->current_bss;
- else
- reject_bss = wpa_bss_get_bssid(wpa_s, bssid);
-#endif /* CONFIG_MBO */
-
- if (data->assoc_reject.bssid)
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
- "bssid=" MACSTR " status_code=%u%s%s%s%s%s",
- MAC2STR(data->assoc_reject.bssid),
- data->assoc_reject.status_code,
- data->assoc_reject.timed_out ? " timeout" : "",
- data->assoc_reject.timeout_reason ? "=" : "",
- data->assoc_reject.timeout_reason ?
- data->assoc_reject.timeout_reason : "",
- data->assoc_reject.reason_code !=
- STA_CONNECT_FAIL_REASON_UNSPECIFIED ?
- " qca_driver_reason=" : "",
- connect_fail_reason(data->assoc_reject.reason_code));
- else
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
- "status_code=%u%s%s%s%s%s",
- data->assoc_reject.status_code,
- data->assoc_reject.timed_out ? " timeout" : "",
- data->assoc_reject.timeout_reason ? "=" : "",
- data->assoc_reject.timeout_reason ?
- data->assoc_reject.timeout_reason : "",
- data->assoc_reject.reason_code !=
- STA_CONNECT_FAIL_REASON_UNSPECIFIED ?
- " qca_driver_reason=" : "",
- connect_fail_reason(data->assoc_reject.reason_code));
- wpa_s->assoc_status_code = data->assoc_reject.status_code;
- wpas_notify_assoc_status_code(wpa_s);
-
-#ifdef CONFIG_OWE
- if (data->assoc_reject.status_code ==
- WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
- wpa_s->current_ssid &&
- wpa_s->current_ssid->owe_group == 0 &&
- wpa_s->last_owe_group != 21) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpa_bss *bss = wpa_s->current_bss;
-
- if (!bss) {
- bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- if (!bss) {
- wpas_connection_failed(wpa_s, bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- return;
- }
- }
- wpa_printf(MSG_DEBUG, "OWE: Try next supported DH group");
- wpas_connect_work_done(wpa_s);
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_supplicant_connect(wpa_s, bss, ssid);
- return;
- }
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_DPP2
- /* Try to follow AP's PFS policy. WLAN_STATUS_ASSOC_DENIED_UNSPEC is
- * the status code defined in the DPP R2 tech spec.
- * WLAN_STATUS_AKMP_NOT_VALID is addressed in the same manner as an
- * interoperability workaround with older hostapd implementation. */
- if (DPP_VERSION > 1 && wpa_s->current_ssid &&
- (wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP ||
- ((wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP)) &&
- wpa_s->current_ssid->dpp_pfs == 0 &&
- (data->assoc_reject.status_code ==
- WLAN_STATUS_ASSOC_DENIED_UNSPEC ||
- data->assoc_reject.status_code == WLAN_STATUS_AKMP_NOT_VALID)) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpa_bss *bss = wpa_s->current_bss;
-
- wpa_s->current_ssid->dpp_pfs_fallback ^= 1;
- if (!bss)
- bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- if (!bss || wpa_s->dpp_pfs_fallback) {
- wpa_printf(MSG_DEBUG,
- "DPP: Updated PFS policy for next try");
- wpas_connection_failed(wpa_s, bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- return;
- }
- wpa_printf(MSG_DEBUG, "DPP: Try again with updated PFS policy");
- wpa_s->dpp_pfs_fallback = 1;
- wpas_connect_work_done(wpa_s);
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_supplicant_connect(wpa_s, bss, ssid);
- return;
- }
-#endif /* CONFIG_DPP2 */
-
-#ifdef CONFIG_MBO
- if (data->assoc_reject.status_code ==
- WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
- reject_bss && data->assoc_reject.resp_ies) {
- const u8 *rssi_rej;
-
- rssi_rej = mbo_get_attr_from_ies(
- data->assoc_reject.resp_ies,
- data->assoc_reject.resp_ies_len,
- OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
- if (rssi_rej && rssi_rej[1] == 2) {
- wpa_printf(MSG_DEBUG,
- "OCE: RSSI-based association rejection from "
- MACSTR " (Delta RSSI: %u, Retry Delay: %u)",
- MAC2STR(reject_bss->bssid),
- rssi_rej[2], rssi_rej[3]);
- wpa_bss_tmp_disallow(wpa_s,
- reject_bss->bssid,
- rssi_rej[3],
- rssi_rej[2] + reject_bss->level);
- }
- }
-#endif /* CONFIG_MBO */
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
- sme_event_assoc_reject(wpa_s, data);
- return;
- }
-
- /* Driver-based SME cases */
-
-#ifdef CONFIG_SAE
- if (wpa_s->current_ssid &&
- wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt) &&
- !data->assoc_reject.timed_out) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SAE: Drop PMKSA cache entry");
- wpa_sm_aborted_cached(wpa_s->wpa);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_DPP
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP &&
- !data->assoc_reject.timed_out) {
- wpa_dbg(wpa_s, MSG_DEBUG, "DPP: Drop PMKSA cache entry");
- wpa_sm_aborted_cached(wpa_s->wpa);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
- }
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_FILS
- /* Update ERP next sequence number */
- if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
- fils_pmksa_cache_flush(wpa_s);
- eapol_sm_update_erp_next_seq_num(
- wpa_s->eapol,
- data->assoc_reject.fils_erp_next_seq_num);
- fils_connection_failure(wpa_s);
- }
-#endif /* CONFIG_FILS */
-
- wpas_connection_failed(wpa_s, bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
-}
-
-
-static void wpas_event_unprot_beacon(struct wpa_supplicant *wpa_s,
- struct unprot_beacon *data)
-{
- struct wpabuf *buf;
- int res;
-
- if (!data || wpa_s->wpa_state != WPA_COMPLETED ||
- os_memcmp(data->sa, wpa_s->bssid, ETH_ALEN) != 0)
- return;
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_UNPROT_BEACON MACSTR,
- MAC2STR(data->sa));
-
- buf = wpabuf_alloc(4);
- if (!buf)
- return;
-
- wpabuf_put_u8(buf, WLAN_ACTION_WNM);
- wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
- wpabuf_put_u8(buf, 1); /* Dialog Token */
- wpabuf_put_u8(buf, WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE);
-
- res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (res < 0)
- wpa_printf(MSG_DEBUG,
- "Failed to send WNM-Notification Request frame");
-
- wpabuf_free(buf);
-}
-
-
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
- union wpa_event_data *data)
-{
- struct wpa_supplicant *wpa_s = ctx;
- int resched;
- struct os_reltime age, clear_at;
-#ifndef CONFIG_NO_STDOUT_DEBUG
- int level = MSG_DEBUG;
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
- event != EVENT_INTERFACE_ENABLED &&
- event != EVENT_INTERFACE_STATUS &&
- event != EVENT_SCAN_RESULTS &&
- event != EVENT_SCHED_SCAN_STOPPED) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Ignore event %s (%d) while interface is disabled",
- event_to_string(event), event);
- return;
- }
-
-#ifndef CONFIG_NO_STDOUT_DEBUG
- if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) {
- const struct ieee80211_hdr *hdr;
- u16 fc;
- hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
- fc = le_to_host16(hdr->frame_control);
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
- level = MSG_EXCESSIVE;
- }
-
- wpa_dbg(wpa_s, level, "Event %s (%d) received",
- event_to_string(event), event);
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
- switch (event) {
- case EVENT_AUTH:
-#ifdef CONFIG_FST
- if (!wpas_fst_update_mbie(wpa_s, data->auth.ies,
- data->auth.ies_len))
- wpa_printf(MSG_DEBUG,
- "FST: MB IEs updated from auth IE");
-#endif /* CONFIG_FST */
- sme_event_auth(wpa_s, data);
- wpa_s->auth_status_code = data->auth.status_code;
- wpas_notify_auth_status_code(wpa_s);
- break;
- case EVENT_ASSOC:
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ignore_auth_resp) {
- wpa_printf(MSG_INFO,
- "EVENT_ASSOC - ignore_auth_resp active!");
- break;
- }
- if (wpa_s->testing_resend_assoc) {
- wpa_printf(MSG_INFO,
- "EVENT_DEAUTH - testing_resend_assoc");
- break;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_s->disconnected) {
- wpa_printf(MSG_INFO,
- "Ignore unexpected EVENT_ASSOC in disconnected state");
- break;
- }
- wpa_supplicant_event_assoc(wpa_s, data);
- wpa_s->assoc_status_code = WLAN_STATUS_SUCCESS;
- if (data &&
- (data->assoc_info.authorized ||
- (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- wpa_fils_is_completed(wpa_s->wpa))))
- wpa_supplicant_event_assoc_auth(wpa_s, data);
- if (data) {
- wpa_msg(wpa_s, MSG_INFO,
- WPA_EVENT_SUBNET_STATUS_UPDATE "status=%u",
- data->assoc_info.subnet_status);
- }
- break;
- case EVENT_DISASSOC:
- wpas_event_disassoc(wpa_s,
- data ? &data->disassoc_info : NULL);
- break;
- case EVENT_DEAUTH:
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ignore_auth_resp) {
- wpa_printf(MSG_INFO,
- "EVENT_DEAUTH - ignore_auth_resp active!");
- break;
- }
- if (wpa_s->testing_resend_assoc) {
- wpa_printf(MSG_INFO,
- "EVENT_DEAUTH - testing_resend_assoc");
- break;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- wpas_event_deauth(wpa_s,
- data ? &data->deauth_info : NULL);
- break;
- case EVENT_MICHAEL_MIC_FAILURE:
- wpa_supplicant_event_michael_mic_failure(wpa_s, data);
- break;
-#ifndef CONFIG_NO_SCAN_PROCESSING
- case EVENT_SCAN_STARTED:
- if (wpa_s->own_scan_requested ||
- (data && !data->scan_info.external_scan)) {
- struct os_reltime diff;
-
- os_get_reltime(&wpa_s->scan_start_time);
- os_reltime_sub(&wpa_s->scan_start_time,
- &wpa_s->scan_trigger_time, &diff);
- wpa_dbg(wpa_s, MSG_DEBUG, "Own scan request started a scan in %ld.%06ld seconds",
- diff.sec, diff.usec);
- wpa_s->own_scan_requested = 0;
- wpa_s->own_scan_running = 1;
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_s->manual_scan_use_id) {
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- WPA_EVENT_SCAN_STARTED "id=%u",
- wpa_s->manual_scan_id);
- } else {
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- WPA_EVENT_SCAN_STARTED);
- }
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
- wpa_s->radio->external_scan_req_interface = wpa_s;
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
- }
- break;
- case EVENT_SCAN_RESULTS:
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_s->scan_res_handler = NULL;
- wpa_s->own_scan_running = 0;
- wpa_s->radio->external_scan_req_interface = NULL;
- wpa_s->last_scan_req = NORMAL_SCAN_REQ;
- break;
- }
-
- if (!(data && data->scan_info.external_scan) &&
- os_reltime_initialized(&wpa_s->scan_start_time)) {
- struct os_reltime now, diff;
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->scan_start_time, &diff);
- wpa_s->scan_start_time.sec = 0;
- wpa_s->scan_start_time.usec = 0;
- wpa_dbg(wpa_s, MSG_DEBUG, "Scan completed in %ld.%06ld seconds",
- diff.sec, diff.usec);
- }
- if (wpa_supplicant_event_scan_results(wpa_s, data))
- break; /* interface may have been removed */
- if (!(data && data->scan_info.external_scan))
- wpa_s->own_scan_running = 0;
- if (data && data->scan_info.nl_scan_event)
- wpa_s->radio->external_scan_req_interface = NULL;
- radio_work_check_next(wpa_s);
- break;
-#endif /* CONFIG_NO_SCAN_PROCESSING */
- case EVENT_ASSOCINFO:
- wpa_supplicant_event_associnfo(wpa_s, data);
- break;
- case EVENT_INTERFACE_STATUS:
- wpa_supplicant_event_interface_status(wpa_s, data);
- break;
- case EVENT_PMKID_CANDIDATE:
- wpa_supplicant_event_pmkid_candidate(wpa_s, data);
- break;
-#ifdef CONFIG_TDLS
- case EVENT_TDLS:
- wpa_supplicant_event_tdls(wpa_s, data);
- break;
-#endif /* CONFIG_TDLS */
-#ifdef CONFIG_WNM
- case EVENT_WNM:
- wpa_supplicant_event_wnm(wpa_s, data);
- break;
-#endif /* CONFIG_WNM */
-#ifdef CONFIG_IEEE80211R
- case EVENT_FT_RESPONSE:
- wpa_supplicant_event_ft_response(wpa_s, data);
- break;
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IBSS_RSN
- case EVENT_IBSS_RSN_START:
- wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
- break;
-#endif /* CONFIG_IBSS_RSN */
- case EVENT_ASSOC_REJECT:
- wpas_event_assoc_reject(wpa_s, data);
- break;
- case EVENT_AUTH_TIMED_OUT:
- /* It is possible to get this event from earlier connection */
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Ignore AUTH_TIMED_OUT in mesh configuration");
- break;
- }
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- sme_event_auth_timed_out(wpa_s, data);
- break;
- case EVENT_ASSOC_TIMED_OUT:
- /* It is possible to get this event from earlier connection */
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Ignore ASSOC_TIMED_OUT in mesh configuration");
- break;
- }
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- sme_event_assoc_timed_out(wpa_s, data);
- break;
- case EVENT_TX_STATUS:
- wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR
- " type=%d stype=%d",
- MAC2STR(data->tx_status.dst),
- data->tx_status.type, data->tx_status.stype);
-#ifdef CONFIG_PASN
- if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
- data->tx_status.stype == WLAN_FC_STYPE_AUTH &&
- wpas_pasn_auth_tx_status(wpa_s, data->tx_status.data,
- data->tx_status.data_len,
- data->tx_status.ack) == 0)
- break;
-#endif /* CONFIG_PASN */
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface == NULL) {
-#ifdef CONFIG_OFFCHANNEL
- if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
- data->tx_status.stype == WLAN_FC_STYPE_ACTION)
- offchannel_send_action_tx_status(
- wpa_s, data->tx_status.dst,
- data->tx_status.data,
- data->tx_status.data_len,
- data->tx_status.ack ?
- OFFCHANNEL_SEND_ACTION_SUCCESS :
- OFFCHANNEL_SEND_ACTION_NO_ACK);
-#endif /* CONFIG_OFFCHANNEL */
- break;
- }
-#endif /* CONFIG_AP */
-#ifdef CONFIG_OFFCHANNEL
- wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
- MACSTR, MAC2STR(wpa_s->p2pdev->pending_action_dst));
- /*
- * Catch TX status events for Action frames we sent via group
- * interface in GO mode, or via standalone AP interface.
- * Note, wpa_s->p2pdev will be the same as wpa_s->parent,
- * except when the primary interface is used as a GO interface
- * (for drivers which do not have group interface concurrency)
- */
- if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
- data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
- os_memcmp(wpa_s->p2pdev->pending_action_dst,
- data->tx_status.dst, ETH_ALEN) == 0) {
- offchannel_send_action_tx_status(
- wpa_s->p2pdev, data->tx_status.dst,
- data->tx_status.data,
- data->tx_status.data_len,
- data->tx_status.ack ?
- OFFCHANNEL_SEND_ACTION_SUCCESS :
- OFFCHANNEL_SEND_ACTION_NO_ACK);
- break;
- }
-#endif /* CONFIG_OFFCHANNEL */
-#ifdef CONFIG_AP
- switch (data->tx_status.type) {
- case WLAN_FC_TYPE_MGMT:
- ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
- data->tx_status.data_len,
- data->tx_status.stype,
- data->tx_status.ack);
- break;
- case WLAN_FC_TYPE_DATA:
- ap_tx_status(wpa_s, data->tx_status.dst,
- data->tx_status.data,
- data->tx_status.data_len,
- data->tx_status.ack);
- break;
- }
-#endif /* CONFIG_AP */
- break;
-#ifdef CONFIG_AP
- case EVENT_EAPOL_TX_STATUS:
- ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
- data->eapol_tx_status.data,
- data->eapol_tx_status.data_len,
- data->eapol_tx_status.ack);
- break;
- case EVENT_DRIVER_CLIENT_POLL_OK:
- ap_client_poll_ok(wpa_s, data->client_poll.addr);
- break;
- case EVENT_RX_FROM_UNKNOWN:
- if (wpa_s->ap_iface == NULL)
- break;
- ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr,
- data->rx_from_unknown.wds);
- break;
-#endif /* CONFIG_AP */
-
- case EVENT_CH_SWITCH_STARTED:
- case EVENT_CH_SWITCH:
- if (!data || !wpa_s->current_ssid)
- break;
-
- wpa_msg(wpa_s, MSG_INFO,
- "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d",
- event == EVENT_CH_SWITCH ? WPA_EVENT_CHANNEL_SWITCH :
- WPA_EVENT_CHANNEL_SWITCH_STARTED,
- data->ch_switch.freq,
- data->ch_switch.ht_enabled,
- data->ch_switch.ch_offset,
- channel_width_to_string(data->ch_switch.ch_width),
- data->ch_switch.cf1,
- data->ch_switch.cf2);
- if (event == EVENT_CH_SWITCH_STARTED)
- break;
-
- wpa_s->assoc_freq = data->ch_switch.freq;
- wpa_s->current_ssid->frequency = data->ch_switch.freq;
- if (wpa_s->current_bss &&
- wpa_s->current_bss->freq != data->ch_switch.freq) {
- wpa_s->current_bss->freq = data->ch_switch.freq;
- notify_bss_changes(wpa_s, WPA_BSS_FREQ_CHANGED_FLAG,
- wpa_s->current_bss);
- }
-
-#ifdef CONFIG_SME
- switch (data->ch_switch.ch_offset) {
- case 1:
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE;
- break;
- case -1:
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW;
- break;
- default:
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN;
- break;
- }
-#endif /* CONFIG_SME */
-
-#ifdef CONFIG_AP
- if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
- wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO ||
- wpa_s->current_ssid->mode == WPAS_MODE_MESH ||
- wpa_s->current_ssid->mode ==
- WPAS_MODE_P2P_GROUP_FORMATION) {
- wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
- data->ch_switch.ht_enabled,
- data->ch_switch.ch_offset,
- data->ch_switch.ch_width,
- data->ch_switch.cf1,
- data->ch_switch.cf2,
- 1);
- }
-#endif /* CONFIG_AP */
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- sme_event_ch_switch(wpa_s);
-
- wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS);
- wnm_clear_coloc_intf_reporting(wpa_s);
- break;
-#ifdef CONFIG_AP
-#ifdef NEED_AP_MLME
- case EVENT_DFS_RADAR_DETECTED:
- if (data)
- wpas_ap_event_dfs_radar_detected(wpa_s,
- &data->dfs_event);
- break;
- case EVENT_DFS_NOP_FINISHED:
- if (data)
- wpas_ap_event_dfs_cac_nop_finished(wpa_s,
- &data->dfs_event);
- break;
-#endif /* NEED_AP_MLME */
-#endif /* CONFIG_AP */
- case EVENT_DFS_CAC_STARTED:
- if (data)
- wpas_event_dfs_cac_started(wpa_s, &data->dfs_event);
- break;
- case EVENT_DFS_CAC_FINISHED:
- if (data)
- wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event);
- break;
- case EVENT_DFS_CAC_ABORTED:
- if (data)
- wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event);
- break;
- case EVENT_RX_MGMT: {
- u16 fc, stype;
- const struct ieee80211_mgmt *mgmt;
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ext_mgmt_frame_handling) {
- struct rx_mgmt *rx = &data->rx_mgmt;
- size_t hex_len = 2 * rx->frame_len + 1;
- char *hex = os_malloc(hex_len);
- if (hex) {
- wpa_snprintf_hex(hex, hex_len,
- rx->frame, rx->frame_len);
- wpa_msg(wpa_s, MSG_INFO, "MGMT-RX freq=%d datarate=%u ssi_signal=%d %s",
- rx->freq, rx->datarate, rx->ssi_signal,
- hex);
- os_free(hex);
- }
- break;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- mgmt = (const struct ieee80211_mgmt *)
- data->rx_mgmt.frame;
- fc = le_to_host16(mgmt->frame_control);
- stype = WLAN_FC_GET_STYPE(fc);
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface == NULL) {
-#endif /* CONFIG_AP */
-#ifdef CONFIG_P2P
- if (stype == WLAN_FC_STYPE_PROBE_REQ &&
- data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
- const u8 *src = mgmt->sa;
- const u8 *ie;
- size_t ie_len;
-
- ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
- ie_len = data->rx_mgmt.frame_len -
- IEEE80211_HDRLEN;
- wpas_p2p_probe_req_rx(
- wpa_s, src, mgmt->da,
- mgmt->bssid, ie, ie_len,
- data->rx_mgmt.freq,
- data->rx_mgmt.ssi_signal);
- break;
- }
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_IBSS_RSN
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
- stype == WLAN_FC_STYPE_AUTH &&
- data->rx_mgmt.frame_len >= 30) {
- wpa_supplicant_event_ibss_auth(wpa_s, data);
- break;
- }
-#endif /* CONFIG_IBSS_RSN */
-
- if (stype == WLAN_FC_STYPE_ACTION) {
- wpas_event_rx_mgmt_action(
- wpa_s, data->rx_mgmt.frame,
- data->rx_mgmt.frame_len,
- data->rx_mgmt.freq,
- data->rx_mgmt.ssi_signal);
- break;
- }
-
- if (wpa_s->ifmsh) {
- mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt);
- break;
- }
-#ifdef CONFIG_PASN
- if (stype == WLAN_FC_STYPE_AUTH &&
- wpas_pasn_auth_rx(wpa_s, mgmt,
- data->rx_mgmt.frame_len) != -2)
- break;
-#endif /* CONFIG_PASN */
-
-#ifdef CONFIG_SAE
- if (stype == WLAN_FC_STYPE_AUTH &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
- sme_external_auth_mgmt_rx(
- wpa_s, data->rx_mgmt.frame,
- data->rx_mgmt.frame_len);
- break;
- }
-#endif /* CONFIG_SAE */
- wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
- "management frame in non-AP mode");
- break;
-#ifdef CONFIG_AP
- }
-
- if (stype == WLAN_FC_STYPE_PROBE_REQ &&
- data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
- const u8 *ie;
- size_t ie_len;
-
- ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
- ie_len = data->rx_mgmt.frame_len - IEEE80211_HDRLEN;
-
- wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
- mgmt->bssid, ie, ie_len,
- data->rx_mgmt.ssi_signal);
- }
-
- ap_mgmt_rx(wpa_s, &data->rx_mgmt);
-#endif /* CONFIG_AP */
- break;
- }
- case EVENT_RX_PROBE_REQ:
- if (data->rx_probe_req.sa == NULL ||
- data->rx_probe_req.ie == NULL)
- break;
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
- data->rx_probe_req.sa,
- data->rx_probe_req.da,
- data->rx_probe_req.bssid,
- data->rx_probe_req.ie,
- data->rx_probe_req.ie_len,
- data->rx_probe_req.ssi_signal);
- break;
- }
-#endif /* CONFIG_AP */
- wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
- data->rx_probe_req.da,
- data->rx_probe_req.bssid,
- data->rx_probe_req.ie,
- data->rx_probe_req.ie_len,
- 0,
- data->rx_probe_req.ssi_signal);
- break;
- case EVENT_REMAIN_ON_CHANNEL:
-#ifdef CONFIG_OFFCHANNEL
- offchannel_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq,
- data->remain_on_channel.duration);
-#endif /* CONFIG_OFFCHANNEL */
- wpas_p2p_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq,
- data->remain_on_channel.duration);
-#ifdef CONFIG_DPP
- wpas_dpp_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq,
- data->remain_on_channel.duration);
-#endif /* CONFIG_DPP */
- break;
- case EVENT_CANCEL_REMAIN_ON_CHANNEL:
-#ifdef CONFIG_OFFCHANNEL
- offchannel_cancel_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq);
-#endif /* CONFIG_OFFCHANNEL */
- wpas_p2p_cancel_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq);
-#ifdef CONFIG_DPP
- wpas_dpp_cancel_remain_on_channel_cb(
- wpa_s, data->remain_on_channel.freq);
-#endif /* CONFIG_DPP */
- break;
- case EVENT_EAPOL_RX:
- wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
- data->eapol_rx.data,
- data->eapol_rx.data_len);
- break;
- case EVENT_SIGNAL_CHANGE:
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
- "above=%d signal=%d noise=%d txrate=%d",
- data->signal_change.above_threshold,
- data->signal_change.current_signal,
- data->signal_change.current_noise,
- data->signal_change.current_txrate);
- wpa_bss_update_level(wpa_s->current_bss,
- data->signal_change.current_signal);
- bgscan_notify_signal_change(
- wpa_s, data->signal_change.above_threshold,
- data->signal_change.current_signal,
- data->signal_change.current_noise,
- data->signal_change.current_txrate);
- break;
- case EVENT_INTERFACE_MAC_CHANGED:
- wpa_supplicant_update_mac_addr(wpa_s);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
- break;
- case EVENT_INTERFACE_ENABLED:
- wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- u8 addr[ETH_ALEN];
-
- eloop_cancel_timeout(wpas_clear_disabled_interface,
- wpa_s, NULL);
- os_memcpy(addr, wpa_s->own_addr, ETH_ALEN);
- wpa_supplicant_update_mac_addr(wpa_s);
- if (os_memcmp(addr, wpa_s->own_addr, ETH_ALEN) != 0)
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
- else
- wpa_sm_pmksa_cache_reconfig(wpa_s->wpa);
- wpa_supplicant_set_default_scan_ies(wpa_s);
- if (wpa_s->p2p_mgmt) {
- wpa_supplicant_set_state(wpa_s,
- WPA_DISCONNECTED);
- break;
- }
-
-#ifdef CONFIG_AP
- if (!wpa_s->ap_iface) {
- wpa_supplicant_set_state(wpa_s,
- WPA_DISCONNECTED);
- wpa_s->scan_req = NORMAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- } else
- wpa_supplicant_set_state(wpa_s,
- WPA_COMPLETED);
-#else /* CONFIG_AP */
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-#endif /* CONFIG_AP */
- }
- break;
- case EVENT_INTERFACE_DISABLED:
- wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
- (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
- wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
- /*
- * Mark interface disabled if this happens to end up not
- * being removed as a separate P2P group interface.
- */
- wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
- /*
- * The interface was externally disabled. Remove
- * it assuming an external entity will start a
- * new session if needed.
- */
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->p2p_group)
- wpas_p2p_interface_unavailable(wpa_s);
- else
- wpas_p2p_disconnect(wpa_s);
- /*
- * wpa_s instance may have been freed, so must not use
- * it here anymore.
- */
- break;
- }
- if (wpa_s->p2p_scan_work && wpa_s->global->p2p &&
- p2p_in_progress(wpa_s->global->p2p) > 1) {
- /* This radio work will be cancelled, so clear P2P
- * state as well.
- */
- p2p_stop_find(wpa_s->global->p2p);
- }
-#endif /* CONFIG_P2P */
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- /*
- * Indicate disconnection to keep ctrl_iface events
- * consistent.
- */
- wpa_supplicant_event_disassoc(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
- }
- wpa_supplicant_mark_disassoc(wpa_s);
- os_reltime_age(&wpa_s->last_scan, &age);
- if (age.sec >= wpa_s->conf->scan_res_valid_for_connect) {
- clear_at.sec = wpa_s->conf->scan_res_valid_for_connect;
- clear_at.usec = 0;
- } else {
- struct os_reltime tmp;
-
- tmp.sec = wpa_s->conf->scan_res_valid_for_connect;
- tmp.usec = 0;
- os_reltime_sub(&tmp, &age, &clear_at);
- }
- eloop_register_timeout(clear_at.sec, clear_at.usec,
- wpas_clear_disabled_interface,
- wpa_s, NULL);
- radio_remove_works(wpa_s, NULL, 0);
-
- wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
- break;
- case EVENT_CHANNEL_LIST_CHANGED:
- wpa_supplicant_update_channel_list(
- wpa_s, &data->channel_list_changed);
- break;
- case EVENT_INTERFACE_UNAVAILABLE:
- wpas_p2p_interface_unavailable(wpa_s);
- break;
- case EVENT_BEST_CHANNEL:
- wpa_dbg(wpa_s, MSG_DEBUG, "Best channel event received "
- "(%d %d %d)",
- data->best_chan.freq_24, data->best_chan.freq_5,
- data->best_chan.freq_overall);
- wpa_s->best_24_freq = data->best_chan.freq_24;
- wpa_s->best_5_freq = data->best_chan.freq_5;
- wpa_s->best_overall_freq = data->best_chan.freq_overall;
- wpas_p2p_update_best_channels(wpa_s, data->best_chan.freq_24,
- data->best_chan.freq_5,
- data->best_chan.freq_overall);
- break;
- case EVENT_UNPROT_DEAUTH:
- wpa_supplicant_event_unprot_deauth(wpa_s,
- &data->unprot_deauth);
- break;
- case EVENT_UNPROT_DISASSOC:
- wpa_supplicant_event_unprot_disassoc(wpa_s,
- &data->unprot_disassoc);
- break;
- case EVENT_STATION_LOW_ACK:
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface && data)
- hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0],
- data->low_ack.addr);
-#endif /* CONFIG_AP */
-#ifdef CONFIG_TDLS
- if (data)
- wpa_tdls_disable_unreachable_link(wpa_s->wpa,
- data->low_ack.addr);
-#endif /* CONFIG_TDLS */
- break;
- case EVENT_IBSS_PEER_LOST:
-#ifdef CONFIG_IBSS_RSN
- ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
-#endif /* CONFIG_IBSS_RSN */
- break;
- case EVENT_DRIVER_GTK_REKEY:
- if (os_memcmp(data->driver_gtk_rekey.bssid,
- wpa_s->bssid, ETH_ALEN))
- break;
- if (!wpa_s->wpa)
- break;
- wpa_sm_update_replay_ctr(wpa_s->wpa,
- data->driver_gtk_rekey.replay_ctr);
- break;
- case EVENT_SCHED_SCAN_STOPPED:
- wpa_s->sched_scanning = 0;
- resched = wpa_s->scanning && wpas_scan_scheduled(wpa_s);
- wpa_supplicant_notify_scanning(wpa_s, 0);
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- break;
-
- /*
- * If the driver stopped scanning without being requested to,
- * request a new scan to continue scanning for networks.
- */
- if (!wpa_s->sched_scan_stop_req &&
- wpa_s->wpa_state == WPA_SCANNING) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Restart scanning after unexpected sched_scan stop event");
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- break;
- }
-
- wpa_s->sched_scan_stop_req = 0;
-
- /*
- * Start a new sched scan to continue searching for more SSIDs
- * either if timed out or PNO schedule scan is pending.
- */
- if (wpa_s->sched_scan_timed_out) {
- wpa_supplicant_req_sched_scan(wpa_s);
- } else if (wpa_s->pno_sched_pending) {
- wpa_s->pno_sched_pending = 0;
- wpas_start_pno(wpa_s);
- } else if (resched) {
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-
- break;
- case EVENT_WPS_BUTTON_PUSHED:
-#ifdef CONFIG_WPS
- wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
-#endif /* CONFIG_WPS */
- break;
- case EVENT_AVOID_FREQUENCIES:
- wpa_supplicant_notify_avoid_freq(wpa_s, data);
- break;
- case EVENT_CONNECT_FAILED_REASON:
-#ifdef CONFIG_AP
- if (!wpa_s->ap_iface || !data)
- break;
- hostapd_event_connect_failed_reason(
- wpa_s->ap_iface->bss[0],
- data->connect_failed_reason.addr,
- data->connect_failed_reason.code);
-#endif /* CONFIG_AP */
- break;
- case EVENT_NEW_PEER_CANDIDATE:
-#ifdef CONFIG_MESH
- if (!wpa_s->ifmsh || !data)
- break;
- wpa_mesh_notify_peer(wpa_s, data->mesh_peer.peer,
- data->mesh_peer.ies,
- data->mesh_peer.ie_len);
-#endif /* CONFIG_MESH */
- break;
- case EVENT_SURVEY:
-#ifdef CONFIG_AP
- if (!wpa_s->ap_iface)
- break;
- hostapd_event_get_survey(wpa_s->ap_iface,
- &data->survey_results);
-#endif /* CONFIG_AP */
- break;
- case EVENT_ACS_CHANNEL_SELECTED:
-#ifdef CONFIG_AP
-#ifdef CONFIG_ACS
- if (!wpa_s->ap_iface)
- break;
- hostapd_acs_channel_selected(wpa_s->ap_iface->bss[0],
- &data->acs_selected_channels);
-#endif /* CONFIG_ACS */
-#endif /* CONFIG_AP */
- break;
- case EVENT_P2P_LO_STOP:
-#ifdef CONFIG_P2P
- wpa_s->p2p_lo_started = 0;
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_LISTEN_OFFLOAD_STOP
- P2P_LISTEN_OFFLOAD_STOP_REASON "reason=%d",
- data->p2p_lo_stop.reason_code);
-#endif /* CONFIG_P2P */
- break;
- case EVENT_BEACON_LOSS:
- if (!wpa_s->current_bss || !wpa_s->current_ssid)
- break;
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_BEACON_LOSS);
- bgscan_notify_beacon_loss(wpa_s);
- break;
- case EVENT_EXTERNAL_AUTH:
-#ifdef CONFIG_SAE
- if (!wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG, "SAE: current_ssid is NULL");
- break;
- }
- sme_external_auth_trigger(wpa_s, data);
-#endif /* CONFIG_SAE */
- break;
- case EVENT_PORT_AUTHORIZED:
- wpa_supplicant_event_port_authorized(wpa_s);
- break;
- case EVENT_STATION_OPMODE_CHANGED:
-#ifdef CONFIG_AP
- if (!wpa_s->ap_iface || !data)
- break;
-
- hostapd_event_sta_opmode_changed(wpa_s->ap_iface->bss[0],
- data->sta_opmode.addr,
- data->sta_opmode.smps_mode,
- data->sta_opmode.chan_width,
- data->sta_opmode.rx_nss);
-#endif /* CONFIG_AP */
- break;
- case EVENT_UNPROT_BEACON:
- wpas_event_unprot_beacon(wpa_s, &data->unprot_beacon);
- break;
- default:
- wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
- break;
- }
-}
-
-
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
- union wpa_event_data *data)
-{
- struct wpa_supplicant *wpa_s;
-
- if (event != EVENT_INTERFACE_STATUS)
- return;
-
- wpa_s = wpa_supplicant_get_iface(ctx, data->interface_status.ifname);
- if (wpa_s && wpa_s->driver->get_ifindex) {
- unsigned int ifindex;
-
- ifindex = wpa_s->driver->get_ifindex(wpa_s->drv_priv);
- if (ifindex != data->interface_status.ifindex) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "interface status ifindex %d mismatch (%d)",
- ifindex, data->interface_status.ifindex);
- return;
- }
- }
-#ifdef CONFIG_MATCH_IFACE
- else if (data->interface_status.ievent == EVENT_INTERFACE_ADDED) {
- struct wpa_interface *wpa_i;
-
- wpa_i = wpa_supplicant_match_iface(
- ctx, data->interface_status.ifname);
- if (!wpa_i)
- return;
- wpa_s = wpa_supplicant_add_iface(ctx, wpa_i, NULL);
- os_free(wpa_i);
- }
-#endif /* CONFIG_MATCH_IFACE */
-
- if (wpa_s)
- wpa_supplicant_event(wpa_s, event, data);
-}
diff --git a/wpa_supplicant/examples/60_wpa_supplicant b/wpa_supplicant/examples/60_wpa_supplicant
deleted file mode 100755
index 39bd8e09b589..000000000000
--- a/wpa_supplicant/examples/60_wpa_supplicant
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-# /etc/pm/sleep.d/60_wpa_supplicant
-# Action script to notify wpa_supplicant of pm-action events.
-
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-
-WPACLI=wpa_cli
-
-case "$1" in
- suspend|hibernate)
- $WPACLI suspend
- ;;
- resume|thaw)
- $WPACLI resume
- ;;
-esac
-
-exit 0
diff --git a/wpa_supplicant/examples/dbus-listen-preq.py b/wpa_supplicant/examples/dbus-listen-preq.py
deleted file mode 100755
index 337519f4e927..000000000000
--- a/wpa_supplicant/examples/dbus-listen-preq.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/python
-
-from __future__ import print_function
-import dbus
-import sys
-import time
-import gobject
-from dbus.mainloop.glib import DBusGMainLoop
-
-WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1"
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface"
-
-def usage():
- print("Usage: %s <ifname>" % sys.argv[0])
- print("Press Ctrl-C to stop")
-
-def ProbeRequest(args):
- if 'addr' in args:
- print('%.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['addr']),
- end=' ')
- if 'dst' in args:
- print('-> %.2x:%.2x:%.2x:%.2x:%.2x:%.2x' % tuple(args['dst']),
- end=' ')
- if 'bssid' in args:
- print('(bssid %.2x:%.2x:%.2x:%.2x:%.2x:%.2x)' % tuple(args['dst']),
- end=' ')
- if 'signal' in args:
- print('signal:%d' % args['signal'], end=' ')
- if 'ies' in args:
- print('have IEs (%d bytes)' % len(args['ies']), end=' ')
- print('')
-
-if __name__ == "__main__":
- global bus
- global wpas_obj
- global if_obj
- global p2p_iface
-
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
-
- # Print list of i/f if no one is specified
- if (len(sys.argv) < 2) :
- usage()
- sys.exit(0)
-
- wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
-
- ifname = sys.argv[1]
-
- path = wpas.GetInterface(ifname)
-
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
-
- bus.add_signal_receiver(ProbeRequest,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="ProbeRequest")
-
- iface.SubscribeProbeReq()
-
- gobject.MainLoop().run()
diff --git a/wpa_supplicant/examples/dpp-nfc.py b/wpa_supplicant/examples/dpp-nfc.py
deleted file mode 100755
index 8e865f3fcd33..000000000000
--- a/wpa_supplicant/examples/dpp-nfc.py
+++ /dev/null
@@ -1,1186 +0,0 @@
-#!/usr/bin/python3
-#
-# Example nfcpy to wpa_supplicant wrapper for DPP NFC operations
-# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
-# Copyright (c) 2019-2020, The Linux Foundation
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import binascii
-import errno
-import os
-import struct
-import sys
-import time
-import threading
-import argparse
-
-import nfc
-import ndef
-
-import logging
-
-scriptsdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__))
-sys.path.append(os.path.join(scriptsdir, '..', '..', 'wpaspy'))
-import wpaspy
-
-wpas_ctrl = '/var/run/wpa_supplicant'
-ifname = None
-init_on_touch = False
-in_raw_mode = False
-prev_tcgetattr = 0
-no_input = False
-continue_loop = True
-terminate_now = False
-summary_file = None
-success_file = None
-netrole = None
-operation_success = False
-mutex = threading.Lock()
-
-C_NORMAL = '\033[0m'
-C_RED = '\033[91m'
-C_GREEN = '\033[92m'
-C_YELLOW = '\033[93m'
-C_BLUE = '\033[94m'
-C_MAGENTA = '\033[95m'
-C_CYAN = '\033[96m'
-
-def summary(txt, color=None):
- with mutex:
- if color:
- print(color + txt + C_NORMAL)
- else:
- print(txt)
- if summary_file:
- with open(summary_file, 'a') as f:
- f.write(txt + "\n")
-
-def success_report(txt):
- summary(txt)
- if success_file:
- with open(success_file, 'a') as f:
- f.write(txt + "\n")
-
-def wpas_connect():
- ifaces = []
- if os.path.isdir(wpas_ctrl):
- try:
- ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
- except OSError as error:
- summary("Could not find wpa_supplicant: %s", str(error))
- return None
-
- if len(ifaces) < 1:
- summary("No wpa_supplicant control interface found")
- return None
-
- for ctrl in ifaces:
- if ifname and ifname not in ctrl:
- continue
- if os.path.basename(ctrl).startswith("p2p-dev-"):
- # skip P2P management interface
- continue
- try:
- summary("Trying to use control interface " + ctrl)
- wpas = wpaspy.Ctrl(ctrl)
- return wpas
- except Exception as e:
- pass
- summary("Could not connect to wpa_supplicant")
- return None
-
-def dpp_nfc_uri_process(uri):
- wpas = wpas_connect()
- if wpas is None:
- return False
- peer_id = wpas.request("DPP_NFC_URI " + uri)
- if "FAIL" in peer_id:
- summary("Could not parse DPP URI from NFC URI record", color=C_RED)
- return False
- peer_id = int(peer_id)
- summary("peer_id=%d for URI from NFC Tag: %s" % (peer_id, uri))
- cmd = "DPP_AUTH_INIT peer=%d" % peer_id
- global enrollee_only, configurator_only, config_params
- if enrollee_only:
- cmd += " role=enrollee"
- elif configurator_only:
- cmd += " role=configurator"
- if config_params:
- cmd += " " + config_params
- summary("Initiate DPP authentication: " + cmd)
- res = wpas.request(cmd)
- if "OK" not in res:
- summary("Failed to initiate DPP Authentication", color=C_RED)
- return False
- summary("DPP Authentication initiated")
- return True
-
-def dpp_hs_tag_read(record):
- wpas = wpas_connect()
- if wpas is None:
- return False
- summary(record)
- if len(record.data) < 5:
- summary("Too short DPP HS", color=C_RED)
- return False
- if record.data[0] != 0:
- summary("Unexpected URI Identifier Code", color=C_RED)
- return False
- uribuf = record.data[1:]
- try:
- uri = uribuf.decode()
- except:
- summary("Invalid URI payload", color=C_RED)
- return False
- summary("URI: " + uri)
- if not uri.startswith("DPP:"):
- summary("Not a DPP URI", color=C_RED)
- return False
- return dpp_nfc_uri_process(uri)
-
-def get_status(wpas, extra=None):
- if extra:
- extra = "-" + extra
- else:
- extra = ""
- res = wpas.request("STATUS" + extra)
- lines = res.splitlines()
- vals = dict()
- for l in lines:
- try:
- [name, value] = l.split('=', 1)
- except ValueError:
- summary("Ignore unexpected status line: %s" % l)
- continue
- vals[name] = value
- return vals
-
-def get_status_field(wpas, field, extra=None):
- vals = get_status(wpas, extra)
- if field in vals:
- return vals[field]
- return None
-
-def own_addr(wpas):
- addr = get_status_field(wpas, "address")
- if addr is None:
- addr = get_status_field(wpas, "bssid[0]")
- return addr
-
-def dpp_bootstrap_gen(wpas, type="qrcode", chan=None, mac=None, info=None,
- curve=None, key=None):
- cmd = "DPP_BOOTSTRAP_GEN type=" + type
- if chan:
- cmd += " chan=" + chan
- if mac:
- if mac is True:
- mac = own_addr(wpas)
- if mac is None:
- summary("Could not determine local MAC address for bootstrap info")
- else:
- cmd += " mac=" + mac.replace(':', '')
- if info:
- cmd += " info=" + info
- if curve:
- cmd += " curve=" + curve
- if key:
- cmd += " key=" + key
- res = wpas.request(cmd)
- if "FAIL" in res:
- raise Exception("Failed to generate bootstrapping info")
- return int(res)
-
-def dpp_start_listen(wpas, freq):
- if get_status_field(wpas, "bssid[0]"):
- summary("Own AP freq: %s MHz" % str(get_status_field(wpas, "freq")))
- if get_status_field(wpas, "beacon_set", extra="DRIVER") is None:
- summary("Enable beaconing to have radio ready for RX")
- wpas.request("DISABLE")
- wpas.request("SET start_disabled 0")
- wpas.request("ENABLE")
- cmd = "DPP_LISTEN %d" % freq
- global enrollee_only
- global configurator_only
- if enrollee_only:
- cmd += " role=enrollee"
- elif configurator_only:
- cmd += " role=configurator"
- global netrole
- if netrole:
- cmd += " netrole=" + netrole
- summary(cmd)
- res = wpas.request(cmd)
- if "OK" not in res:
- summary("Failed to start DPP listen", color=C_RED)
- return False
- return True
-
-def wpas_get_nfc_uri(start_listen=True, pick_channel=False, chan_override=None):
- listen_freq = 2412
- wpas = wpas_connect()
- if wpas is None:
- return None
- global own_id, chanlist
- if chan_override:
- chan = chan_override
- else:
- chan = chanlist
- if chan and chan.startswith("81/"):
- listen_freq = int(chan[3:].split(',')[0]) * 5 + 2407
- if chan is None and get_status_field(wpas, "bssid[0]"):
- freq = get_status_field(wpas, "freq")
- if freq:
- freq = int(freq)
- if freq >= 2412 and freq <= 2462:
- chan = "81/%d" % ((freq - 2407) / 5)
- summary("Use current AP operating channel (%d MHz) as the URI channel list (%s)" % (freq, chan))
- listen_freq = freq
- if chan is None and pick_channel:
- chan = "81/6"
- summary("Use channel 2437 MHz since no other preference provided")
- listen_freq = 2437
- own_id = dpp_bootstrap_gen(wpas, type="nfc-uri", chan=chan, mac=True)
- res = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % own_id).rstrip()
- if "FAIL" in res:
- return None
- if start_listen:
- if not dpp_start_listen(wpas, listen_freq):
- raise Exception("Failed to start listen operation on %d MHz" % listen_freq)
- return res
-
-def wpas_report_handover_req(uri):
- wpas = wpas_connect()
- if wpas is None:
- return None
- global own_id
- cmd = "DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (own_id, uri)
- return wpas.request(cmd)
-
-def wpas_report_handover_sel(uri):
- wpas = wpas_connect()
- if wpas is None:
- return None
- global own_id
- cmd = "DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (own_id, uri)
- return wpas.request(cmd)
-
-def dpp_handover_client(handover, alt=False):
- summary("About to start run_dpp_handover_client (alt=%s)" % str(alt))
- if alt:
- handover.i_m_selector = False
- run_dpp_handover_client(handover, alt)
- summary("Done run_dpp_handover_client (alt=%s)" % str(alt))
-
-def run_client_alt(handover, alt):
- if handover.start_client_alt and not alt:
- handover.start_client_alt = False
- summary("Try to send alternative handover request")
- dpp_handover_client(handover, alt=True)
-
-class HandoverClient(nfc.handover.HandoverClient):
- def __init__(self, handover, llc):
- super(HandoverClient, self).__init__(llc)
- self.handover = handover
-
- def recv_records(self, timeout=None):
- msg = self.recv_octets(timeout)
- if msg is None:
- return None
- records = list(ndef.message_decoder(msg, 'relax'))
- if records and records[0].type == 'urn:nfc:wkt:Hs':
- summary("Handover client received message '{0}'".format(records[0].type))
- return list(ndef.message_decoder(msg, 'relax'))
- summary("Handover client received invalid message: %s" + binascii.hexlify(msg))
- return None
-
- def recv_octets(self, timeout=None):
- start = time.time()
- msg = bytearray()
- while True:
- poll_timeout = 0.1 if timeout is None or timeout > 0.1 else timeout
- if not self.socket.poll('recv', poll_timeout):
- if timeout:
- timeout -= time.time() - start
- if timeout <= 0:
- return None
- start = time.time()
- continue
- try:
- r = self.socket.recv()
- if r is None:
- return None
- msg += r
- except TypeError:
- return b''
- try:
- list(ndef.message_decoder(msg, 'strict', {}))
- return bytes(msg)
- except ndef.DecodeError:
- if timeout:
- timeout -= time.time() - start
- if timeout <= 0:
- return None
- start = time.time()
- continue
- return None
-
-def run_dpp_handover_client(handover, alt=False):
- chan_override = None
- if alt:
- chan_override = handover.altchanlist
- handover.alt_proposal_used = True
- global test_uri, test_alt_uri
- if test_uri:
- summary("TEST MODE: Using specified URI (alt=%s)" % str(alt))
- uri = test_alt_uri if alt else test_uri
- else:
- uri = wpas_get_nfc_uri(start_listen=False, chan_override=chan_override)
- if uri is None:
- summary("Cannot start handover client - no bootstrap URI available",
- color=C_RED)
- return
- handover.my_uri = uri
- uri = ndef.UriRecord(uri)
- summary("NFC URI record for DPP: " + str(uri))
- carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data)
- global test_crn
- if test_crn:
- prev, = struct.unpack('>H', test_crn)
- summary("TEST MODE: Use specified crn %d" % prev)
- crn = test_crn
- test_crn = struct.pack('>H', prev + 0x10)
- else:
- crn = os.urandom(2)
- hr = ndef.HandoverRequestRecord(version="1.4", crn=crn)
- hr.add_alternative_carrier('active', carrier.name)
- message = [hr, carrier]
- summary("NFC Handover Request message for DPP: " + str(message))
-
- if handover.peer_crn is not None and not alt:
- summary("NFC handover request from peer was already received - do not send own")
- return
- if handover.client:
- summary("Use already started handover client")
- client = handover.client
- else:
- summary("Start handover client")
- client = HandoverClient(handover, handover.llc)
- try:
- summary("Trying to initiate NFC connection handover")
- client.connect()
- summary("Connected for handover")
- except nfc.llcp.ConnectRefused:
- summary("Handover connection refused")
- client.close()
- return
- except Exception as e:
- summary("Other exception: " + str(e))
- client.close()
- return
- handover.client = client
-
- if handover.peer_crn is not None and not alt:
- summary("NFC handover request from peer was already received - do not send own")
- return
-
- summary("Sending handover request")
-
- handover.my_crn_ready = True
-
- if not client.send_records(message):
- handover.my_crn_ready = False
- summary("Failed to send handover request", color=C_RED)
- run_client_alt(handover, alt)
- return
-
- handover.my_crn, = struct.unpack('>H', crn)
-
- summary("Receiving handover response")
- try:
- start = time.time()
- message = client.recv_records(timeout=3.0)
- end = time.time()
- summary("Received {} record(s) in {} seconds".format(len(message) if message is not None else -1, end - start))
- except Exception as e:
- # This is fine if we are the handover selector
- if handover.hs_sent:
- summary("Client receive failed as expected since I'm the handover server: %s" % str(e))
- elif handover.alt_proposal_used and not alt:
- summary("Client received failed for initial proposal as expected since alternative proposal was also used: %s" % str(e))
- else:
- summary("Client receive failed: %s" % str(e), color=C_RED)
- message = None
- if message is None:
- if handover.hs_sent:
- summary("No response received as expected since I'm the handover server")
- elif handover.alt_proposal_used and not alt:
- summary("No response received for initial proposal as expected since alternative proposal was also used")
- elif handover.try_own and not alt:
- summary("No response received for initial proposal as expected since alternative proposal will also be sent")
- else:
- summary("No response received", color=C_RED)
- run_client_alt(handover, alt)
- return
- summary("Received message: " + str(message))
- if len(message) < 1 or \
- not isinstance(message[0], ndef.HandoverSelectRecord):
- summary("Response was not Hs - received: " + message.type)
- return
-
- summary("Received handover select message")
- summary("alternative carriers: " + str(message[0].alternative_carriers))
- if handover.i_m_selector:
- summary("Ignore the received select since I'm the handover selector")
- run_client_alt(handover, alt)
- return
-
- if handover.alt_proposal_used and not alt:
- summary("Ignore received handover select for the initial proposal since alternative proposal was sent")
- client.close()
- return
-
- dpp_found = False
- for carrier in message:
- if isinstance(carrier, ndef.HandoverSelectRecord):
- continue
- summary("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.dpp":
- if len(carrier.data) == 0 or carrier.data[0] != 0:
- summary("URI Identifier Code 'None' not seen", color=C_RED)
- continue
- summary("DPP carrier type match - send to wpa_supplicant")
- dpp_found = True
- uri = carrier.data[1:].decode("utf-8")
- summary("DPP URI: " + uri)
- handover.peer_uri = uri
- if test_uri:
- summary("TEST MODE: Fake processing")
- break
- res = wpas_report_handover_sel(uri)
- if res is None or "FAIL" in res:
- summary("DPP handover report rejected", color=C_RED)
- break
-
- success_report("DPP handover reported successfully (initiator)")
- summary("peer_id=" + res)
- peer_id = int(res)
- wpas = wpas_connect()
- if wpas is None:
- break
-
- global enrollee_only
- global config_params
- if enrollee_only:
- extra = " role=enrollee"
- elif config_params:
- extra = " role=configurator " + config_params
- else:
- # TODO: Single Configurator instance
- res = wpas.request("DPP_CONFIGURATOR_ADD")
- if "FAIL" in res:
- summary("Failed to initiate Configurator", color=C_RED)
- break
- conf_id = int(res)
- extra = " conf=sta-dpp configurator=%d" % conf_id
- global own_id
- summary("Initiate DPP authentication")
- cmd = "DPP_AUTH_INIT peer=%d own=%d" % (peer_id, own_id)
- cmd += extra
- res = wpas.request(cmd)
- if "FAIL" in res:
- summary("Failed to initiate DPP authentication", color=C_RED)
- break
-
- if not dpp_found and handover.no_alt_proposal:
- summary("DPP carrier not seen in response - do not allow alternative proposal anymore")
- elif not dpp_found:
- summary("DPP carrier not seen in response - allow peer to initiate a new handover with different parameters")
- handover.alt_proposal = True
- handover.my_crn_ready = False
- handover.my_crn = None
- handover.peer_crn = None
- handover.hs_sent = False
- summary("Returning from dpp_handover_client")
- return
-
- summary("Remove peer")
- handover.close()
- summary("Done with handover")
- global only_one
- if only_one:
- print("only_one -> stop loop")
- global continue_loop
- continue_loop = False
-
- global no_wait
- if no_wait or only_one:
- summary("Trying to exit..")
- global terminate_now
- terminate_now = True
-
- summary("Returning from dpp_handover_client")
-
-class HandoverServer(nfc.handover.HandoverServer):
- def __init__(self, handover, llc):
- super(HandoverServer, self).__init__(llc)
- self.sent_carrier = None
- self.ho_server_processing = False
- self.success = False
- self.llc = llc
- self.handover = handover
-
- def serve(self, socket):
- peer_sap = socket.getpeername()
- summary("Serving handover client on remote sap {0}".format(peer_sap))
- send_miu = socket.getsockopt(nfc.llcp.SO_SNDMIU)
- try:
- while socket.poll("recv"):
- req = bytearray()
- while socket.poll("recv"):
- r = socket.recv()
- if r is None:
- return None
- summary("Received %d octets" % len(r))
- req += r
- if len(req) == 0:
- continue
- try:
- list(ndef.message_decoder(req, 'strict', {}))
- except ndef.DecodeError:
- continue
- summary("Full message received")
- resp = self._process_request_data(req)
- if resp is None or len(resp) == 0:
- summary("No handover select to send out - wait for a possible alternative handover request")
- handover.alt_proposal = True
- req = bytearray()
- continue
-
- for offset in range(0, len(resp), send_miu):
- if not socket.send(resp[offset:offset + send_miu]):
- summary("Failed to send handover select - connection closed")
- return
- summary("Sent out full handover select")
- if handover.terminate_on_hs_send_completion:
- handover.delayed_exit()
-
- except nfc.llcp.Error as e:
- global terminate_now
- summary("HandoverServer exception: %s" % e,
- color=None if e.errno == errno.EPIPE or terminate_now else C_RED)
- finally:
- socket.close()
- summary("Handover serve thread exiting")
-
- def process_handover_request_message(self, records):
- handover = self.handover
- self.ho_server_processing = True
- global in_raw_mode
- was_in_raw_mode = in_raw_mode
- clear_raw_mode()
- if was_in_raw_mode:
- print("\n")
- summary("HandoverServer - request received: " + str(records))
-
- for carrier in records:
- if not isinstance(carrier, ndef.HandoverRequestRecord):
- continue
- if carrier.collision_resolution_number:
- handover.peer_crn = carrier.collision_resolution_number
- summary("peer_crn: %d" % handover.peer_crn)
-
- if handover.my_crn is None and handover.my_crn_ready:
- summary("Still trying to send own handover request - wait a moment to see if that succeeds before checking crn values")
- for i in range(10):
- if handover.my_crn is not None:
- break
- time.sleep(0.01)
- if handover.my_crn is not None:
- summary("my_crn: %d" % handover.my_crn)
-
- if handover.my_crn is not None and handover.peer_crn is not None:
- if handover.my_crn == handover.peer_crn:
- summary("Same crn used - automatic collision resolution failed")
- # TODO: Should generate a new Handover Request message
- return ''
- if ((handover.my_crn & 1) == (handover.peer_crn & 1) and \
- handover.my_crn > handover.peer_crn) or \
- ((handover.my_crn & 1) != (handover.peer_crn & 1) and \
- handover.my_crn < handover.peer_crn):
- summary("I'm the Handover Selector Device")
- handover.i_m_selector = True
- else:
- summary("Peer is the Handover Selector device")
- summary("Ignore the received request.")
- return ''
-
- hs = ndef.HandoverSelectRecord('1.4')
- sel = [hs]
-
- found = False
-
- for carrier in records:
- if isinstance(carrier, ndef.HandoverRequestRecord):
- continue
- summary("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.dpp":
- summary("DPP carrier type match - add DPP carrier record")
- if len(carrier.data) == 0 or carrier.data[0] != 0:
- summary("URI Identifier Code 'None' not seen", color=C_RED)
- continue
- uri = carrier.data[1:].decode("utf-8")
- summary("Received DPP URI: " + uri)
-
- global test_uri, test_alt_uri
- if test_uri:
- summary("TEST MODE: Using specified URI")
- data = test_sel_uri if test_sel_uri else test_uri
- elif handover.alt_proposal and handover.altchanlist:
- summary("Use alternative channel list while processing alternative proposal from peer")
- data = wpas_get_nfc_uri(start_listen=False,
- chan_override=handover.altchanlist,
- pick_channel=True)
- else:
- data = wpas_get_nfc_uri(start_listen=False,
- pick_channel=True)
- summary("Own URI (pre-processing): %s" % data)
-
- if test_uri:
- summary("TEST MODE: Fake processing")
- res = "OK"
- data += " [%s]" % uri
- else:
- res = wpas_report_handover_req(uri)
- if res is None or "FAIL" in res:
- summary("DPP handover request processing failed",
- color=C_RED)
- if handover.altchanlist:
- data = wpas_get_nfc_uri(start_listen=False,
- chan_override=handover.altchanlist)
- summary("Own URI (try another channel list): %s" % data)
- continue
-
- if test_alt_uri:
- summary("TEST MODE: Reject initial proposal")
- continue
-
- found = True
-
- if not test_uri:
- wpas = wpas_connect()
- if wpas is None:
- continue
- global own_id
- data = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % own_id).rstrip()
- if "FAIL" in data:
- continue
- summary("Own URI (post-processing): %s" % data)
- handover.my_uri = data
- handover.peer_uri = uri
- uri = ndef.UriRecord(data)
- summary("Own bootstrapping NFC URI record: " + str(uri))
-
- if not test_uri:
- info = wpas.request("DPP_BOOTSTRAP_INFO %d" % own_id)
- freq = None
- for line in info.splitlines():
- if line.startswith("use_freq="):
- freq = int(line.split('=')[1])
- if freq is None or freq == 0:
- summary("No channel negotiated over NFC - use channel 6")
- freq = 2437
- else:
- summary("Negotiated channel: %d MHz" % freq)
- if not dpp_start_listen(wpas, freq):
- break
-
- carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data)
- summary("Own DPP carrier record: " + str(carrier))
- hs.add_alternative_carrier('active', carrier.name)
- sel = [hs, carrier]
- break
-
- summary("Sending handover select: " + str(sel))
- if found:
- summary("Handover completed successfully")
- handover.terminate_on_hs_send_completion = True
- self.success = True
- handover.hs_sent = True
- handover.i_m_selector = True
- elif handover.no_alt_proposal:
- summary("Do not try alternative proposal anymore - handover failed",
- color=C_RED)
- handover.hs_sent = True
- else:
- summary("Try to initiate with alternative parameters")
- handover.try_own = True
- handover.hs_sent = False
- handover.no_alt_proposal = True
- if handover.client_thread:
- handover.start_client_alt = True
- else:
- handover.client_thread = threading.Thread(target=llcp_worker,
- args=(self.llc, True))
- handover.client_thread.start()
- return sel
-
-def clear_raw_mode():
- import sys, tty, termios
- global prev_tcgetattr, in_raw_mode
- if not in_raw_mode:
- return
- fd = sys.stdin.fileno()
- termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
- in_raw_mode = False
-
-def getch():
- import sys, tty, termios, select
- global prev_tcgetattr, in_raw_mode
- fd = sys.stdin.fileno()
- prev_tcgetattr = termios.tcgetattr(fd)
- ch = None
- try:
- tty.setraw(fd)
- in_raw_mode = True
- [i, o, e] = select.select([fd], [], [], 0.05)
- if i:
- ch = sys.stdin.read(1)
- finally:
- termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
- in_raw_mode = False
- return ch
-
-def dpp_tag_read(tag):
- success = False
- for record in tag.ndef.records:
- summary(record)
- summary("record type " + record.type)
- if record.type == "application/vnd.wfa.dpp":
- summary("DPP HS tag - send to wpa_supplicant")
- success = dpp_hs_tag_read(record)
- break
- if isinstance(record, ndef.UriRecord):
- summary("URI record: uri=" + record.uri)
- summary("URI record: iri=" + record.iri)
- if record.iri.startswith("DPP:"):
- summary("DPP URI")
- if not dpp_nfc_uri_process(record.iri):
- break
- success = True
- else:
- summary("Ignore unknown URI")
- break
-
- if success:
- success_report("Tag read succeeded")
-
- return success
-
-def rdwr_connected_write_tag(tag):
- summary("Tag found - writing - " + str(tag))
- if not tag.ndef:
- summary("Not a formatted NDEF tag", color=C_RED)
- return
- if not tag.ndef.is_writeable:
- summary("Not a writable tag", color=C_RED)
- return
- global dpp_tag_data
- if tag.ndef.capacity < len(dpp_tag_data):
- summary("Not enough room for the message")
- return
- try:
- tag.ndef.records = dpp_tag_data
- except ValueError as e:
- summary("Writing the tag failed: %s" % str(e), color=C_RED)
- return
- success_report("Tag write succeeded")
- summary("Tag writing completed - remove tag", color=C_GREEN)
- global only_one, operation_success
- operation_success = True
- if only_one:
- global continue_loop
- continue_loop = False
- global dpp_sel_wait_remove
- return dpp_sel_wait_remove
-
-def write_nfc_uri(clf, wait_remove=True):
- summary("Write NFC URI record")
- data = wpas_get_nfc_uri()
- if data is None:
- summary("Could not get NFC URI from wpa_supplicant", color=C_RED)
- return
-
- global dpp_sel_wait_remove
- dpp_sel_wait_remove = wait_remove
- summary("URI: %s" % data)
- uri = ndef.UriRecord(data)
- summary(uri)
-
- summary("Touch an NFC tag to write URI record", color=C_CYAN)
- global dpp_tag_data
- dpp_tag_data = [uri]
- clf.connect(rdwr={'on-connect': rdwr_connected_write_tag})
-
-def write_nfc_hs(clf, wait_remove=True):
- summary("Write NFC Handover Select record on a tag")
- data = wpas_get_nfc_uri()
- if data is None:
- summary("Could not get NFC URI from wpa_supplicant", color=C_RED)
- return
-
- global dpp_sel_wait_remove
- dpp_sel_wait_remove = wait_remove
- summary("URI: %s" % data)
- uri = ndef.UriRecord(data)
- summary(uri)
- carrier = ndef.Record('application/vnd.wfa.dpp', 'A', uri.data)
- hs = ndef.HandoverSelectRecord('1.4')
- hs.add_alternative_carrier('active', carrier.name)
- summary(hs)
- summary(carrier)
-
- summary("Touch an NFC tag to write HS record", color=C_CYAN)
- global dpp_tag_data
- dpp_tag_data = [hs, carrier]
- summary(dpp_tag_data)
- clf.connect(rdwr={'on-connect': rdwr_connected_write_tag})
-
-def rdwr_connected(tag):
- global only_one, no_wait
- summary("Tag connected: " + str(tag))
-
- if tag.ndef:
- summary("NDEF tag: " + tag.type)
- summary(tag.ndef.records)
- success = dpp_tag_read(tag)
- if only_one and success:
- global continue_loop
- continue_loop = False
- else:
- summary("Not an NDEF tag - remove tag", color=C_RED)
- return True
-
- return not no_wait
-
-def llcp_worker(llc, try_alt):
- global handover
- print("Start of llcp_worker()")
- if try_alt:
- summary("Starting handover client (try_alt)")
- dpp_handover_client(handover, alt=True)
- summary("Exiting llcp_worker thread (try_alt)")
- return
- global init_on_touch
- if init_on_touch:
- summary("Starting handover client (init_on_touch)")
- dpp_handover_client(handover)
- summary("Exiting llcp_worker thread (init_on_touch)")
- return
-
- global no_input
- if no_input:
- summary("Wait for handover to complete")
- else:
- print("Wait for handover to complete - press 'i' to initiate")
- while not handover.wait_connection and handover.srv.sent_carrier is None:
- if handover.try_own:
- handover.try_own = False
- summary("Try to initiate another handover with own parameters")
- handover.my_crn_ready = False
- handover.my_crn = None
- handover.peer_crn = None
- handover.hs_sent = False
- dpp_handover_client(handover, alt=True)
- summary("Exiting llcp_worker thread (retry with own parameters)")
- return
- if handover.srv.ho_server_processing:
- time.sleep(0.025)
- elif no_input:
- time.sleep(0.5)
- else:
- res = getch()
- if res != 'i':
- continue
- clear_raw_mode()
- summary("Starting handover client")
- dpp_handover_client(handover)
- summary("Exiting llcp_worker thread (manual init)")
- return
-
- global in_raw_mode
- was_in_raw_mode = in_raw_mode
- clear_raw_mode()
- if was_in_raw_mode:
- print("\r")
- summary("Exiting llcp_worker thread")
-
-class ConnectionHandover():
- def __init__(self):
- self.client = None
- self.client_thread = None
- self.reset()
- self.exit_thread = None
-
- def reset(self):
- self.wait_connection = False
- self.my_crn_ready = False
- self.my_crn = None
- self.peer_crn = None
- self.hs_sent = False
- self.no_alt_proposal = False
- self.alt_proposal_used = False
- self.i_m_selector = False
- self.start_client_alt = False
- self.terminate_on_hs_send_completion = False
- self.try_own = False
- self.my_uri = None
- self.peer_uri = None
- self.connected = False
- self.alt_proposal = False
-
- def start_handover_server(self, llc):
- summary("Start handover server")
- self.llc = llc
- self.srv = HandoverServer(self, llc)
-
- def close(self):
- if self.client:
- self.client.close()
- self.client = None
-
- def run_delayed_exit(self):
- summary("Trying to exit (delayed)..")
- time.sleep(0.25)
- summary("Trying to exit (after wait)..")
- global terminate_now
- terminate_now = True
-
- def delayed_exit(self):
- global only_one
- if only_one:
- self.exit_thread = threading.Thread(target=self.run_delayed_exit)
- self.exit_thread.start()
-
-def llcp_startup(llc):
- global handover
- handover.start_handover_server(llc)
- return llc
-
-def llcp_connected(llc):
- summary("P2P LLCP connected")
- global handover
- handover.connected = True
- handover.srv.start()
- if init_on_touch or not no_input:
- handover.client_thread = threading.Thread(target=llcp_worker,
- args=(llc, False))
- handover.client_thread.start()
- return True
-
-def llcp_release(llc):
- summary("LLCP release")
- global handover
- handover.close()
- return True
-
-def terminate_loop():
- global terminate_now
- return terminate_now
-
-def main():
- clf = nfc.ContactlessFrontend()
-
- parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for DPP NFC operations')
- parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
- action='store_const', dest='loglevel',
- help='verbose debug output')
- parser.add_argument('-q', const=logging.WARNING, action='store_const',
- dest='loglevel', help='be quiet')
- parser.add_argument('--only-one', '-1', action='store_true',
- help='run only one operation and exit')
- parser.add_argument('--init-on-touch', '-I', action='store_true',
- help='initiate handover on touch')
- parser.add_argument('--no-wait', action='store_true',
- help='do not wait for tag to be removed before exiting')
- parser.add_argument('--ifname', '-i',
- help='network interface name')
- parser.add_argument('--no-input', '-a', action='store_true',
- help='do not use stdout input to initiate handover')
- parser.add_argument('--tag-read-only', '-t', action='store_true',
- help='tag read only (do not allow connection handover)')
- parser.add_argument('--handover-only', action='store_true',
- help='connection handover only (do not allow tag read)')
- parser.add_argument('--enrollee', action='store_true',
- help='run as Enrollee-only')
- parser.add_argument('--configurator', action='store_true',
- help='run as Configurator-only')
- parser.add_argument('--config-params', default='',
- help='configurator parameters')
- parser.add_argument('--ctrl', default='/var/run/wpa_supplicant',
- help='wpa_supplicant/hostapd control interface')
- parser.add_argument('--summary',
- help='summary file for writing status updates')
- parser.add_argument('--success',
- help='success file for writing success update')
- parser.add_argument('--device', default='usb', help='NFC device to open')
- parser.add_argument('--chan', default=None, help='channel list')
- parser.add_argument('--altchan', default=None, help='alternative channel list')
- parser.add_argument('--netrole', default=None, help='netrole for Enrollee')
- parser.add_argument('--test-uri', default=None,
- help='test mode: initial URI')
- parser.add_argument('--test-alt-uri', default=None,
- help='test mode: alternative URI')
- parser.add_argument('--test-sel-uri', default=None,
- help='test mode: handover select URI')
- parser.add_argument('--test-crn', default=None,
- help='test mode: hardcoded crn')
- parser.add_argument('command', choices=['write-nfc-uri',
- 'write-nfc-hs'],
- nargs='?')
- args = parser.parse_args()
- summary(args)
-
- global handover
- handover = ConnectionHandover()
-
- global only_one
- only_one = args.only_one
-
- global no_wait
- no_wait = args.no_wait
-
- global chanlist, netrole, test_uri, test_alt_uri, test_sel_uri
- global test_crn
- chanlist = args.chan
- handover.altchanlist = args.altchan
- netrole = args.netrole
- test_uri = args.test_uri
- test_alt_uri = args.test_alt_uri
- test_sel_uri = args.test_sel_uri
- if args.test_crn:
- test_crn = struct.pack('>H', int(args.test_crn))
- else:
- test_crn = None
-
- logging.basicConfig(level=args.loglevel)
- for l in ['nfc.clf.rcs380',
- 'nfc.clf.transport',
- 'nfc.clf.device',
- 'nfc.clf.__init__',
- 'nfc.llcp',
- 'nfc.handover']:
- log = logging.getLogger(l)
- log.setLevel(args.loglevel)
-
- global init_on_touch
- init_on_touch = args.init_on_touch
-
- global enrollee_only
- enrollee_only = args.enrollee
-
- global configurator_only
- configurator_only = args.configurator
-
- global config_params
- config_params = args.config_params
-
- if args.ifname:
- global ifname
- ifname = args.ifname
- summary("Selected ifname " + ifname)
-
- if args.ctrl:
- global wpas_ctrl
- wpas_ctrl = args.ctrl
-
- if args.summary:
- global summary_file
- summary_file = args.summary
-
- if args.success:
- global success_file
- success_file = args.success
-
- if args.no_input:
- global no_input
- no_input = True
-
- clf = nfc.ContactlessFrontend()
-
- try:
- if not clf.open(args.device):
- summary("Could not open connection with an NFC device", color=C_RED)
- raise SystemExit(1)
-
- if args.command == "write-nfc-uri":
- write_nfc_uri(clf, wait_remove=not args.no_wait)
- if not operation_success:
- raise SystemExit(1)
- raise SystemExit
-
- if args.command == "write-nfc-hs":
- write_nfc_hs(clf, wait_remove=not args.no_wait)
- if not operation_success:
- raise SystemExit(1)
- raise SystemExit
-
- global continue_loop
- while continue_loop:
- global in_raw_mode
- was_in_raw_mode = in_raw_mode
- clear_raw_mode()
- if was_in_raw_mode:
- print("\r")
- if args.handover_only:
- summary("Waiting a peer to be touched", color=C_MAGENTA)
- elif args.tag_read_only:
- summary("Waiting for a tag to be touched", color=C_BLUE)
- else:
- summary("Waiting for a tag or peer to be touched",
- color=C_GREEN)
- handover.wait_connection = True
- try:
- if args.tag_read_only:
- if not clf.connect(rdwr={'on-connect': rdwr_connected}):
- break
- elif args.handover_only:
- if not clf.connect(llcp={'on-startup': llcp_startup,
- 'on-connect': llcp_connected,
- 'on-release': llcp_release},
- terminate=terminate_loop):
- break
- else:
- if not clf.connect(rdwr={'on-connect': rdwr_connected},
- llcp={'on-startup': llcp_startup,
- 'on-connect': llcp_connected,
- 'on-release': llcp_release},
- terminate=terminate_loop):
- break
- except Exception as e:
- summary("clf.connect failed: " + str(e))
- break
-
- if only_one and handover.connected:
- role = "selector" if handover.i_m_selector else "requestor"
- summary("Connection handover result: I'm the %s" % role,
- color=C_YELLOW)
- if handover.peer_uri:
- summary("Peer URI: " + handover.peer_uri, color=C_YELLOW)
- if handover.my_uri:
- summary("My URI: " + handover.my_uri, color=C_YELLOW)
- if not (handover.peer_uri and handover.my_uri):
- summary("Negotiated connection handover failed",
- color=C_YELLOW)
- break
-
- except KeyboardInterrupt:
- raise SystemExit
- finally:
- clf.close()
-
- raise SystemExit
-
-if __name__ == '__main__':
- main()
diff --git a/wpa_supplicant/examples/dpp-qrcode.py b/wpa_supplicant/examples/dpp-qrcode.py
deleted file mode 100755
index b468d15cf9cd..000000000000
--- a/wpa_supplicant/examples/dpp-qrcode.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/python
-#
-# Example Android logcat to wpa_supplicant wrapper for QR Code scans
-# Copyright (c) 2017, Qualcomm Atheros, Inc.
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import os
-import sys
-import argparse
-import logging
-import qrcode
-
-scriptsdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__))
-sys.path.append(os.path.join(scriptsdir, '..', '..', 'wpaspy'))
-
-import wpaspy
-
-wpas_ctrl = '/var/run/wpa_supplicant'
-
-def wpas_connect():
- ifaces = []
- if os.path.isdir(wpas_ctrl):
- try:
- ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
- except OSError as error:
- print("Could not find wpa_supplicant: ", error)
- return None
-
- if len(ifaces) < 1:
- print("No wpa_supplicant control interface found")
- return None
-
- for ctrl in ifaces:
- try:
- wpas = wpaspy.Ctrl(ctrl)
- return wpas
- except Exception as e:
- pass
- return None
-
-def dpp_logcat():
- for line in iter(sys.stdin.readline, ''):
- if "ResultHandler: Launching intent: Intent" not in line:
- continue
- if "act=android.intent.action.VIEW" not in line:
- continue
- uri = None
- for val in line.split(' '):
- if val.startswith('dat='):
- uri = val.split('=', 1)[1]
- break
- if not uri:
- continue
- if not uri.startswith('DPP:'):
- continue
- print("Found DPP bootstrap info URI:")
- print(uri)
- wpas = wpas_connect()
- if not wpas:
- print("Could not connect to wpa_supplicant")
- print('')
- continue
- res = wpas.request("DPP_QR_CODE " + uri);
- try:
- id = int(res)
- except ValueError:
- print("QR Code URI rejected")
- continue
- print("QR Code URI accepted - ID=%d" % id)
- print(wpas.request("DPP_BOOTSTRAP_INFO %d" % id))
- del wpas
-
-def dpp_display(curve):
- wpas = wpas_connect()
- if not wpas:
- print("Could not connect to wpa_supplicant")
- return
- res = wpas.request("STATUS")
- addr = None
- for line in res.splitlines():
- if line.startswith("address="):
- addr = line.split('=')[1]
- break
- cmd = "DPP_BOOTSTRAP_GEN type=qrcode"
- cmd += " chan=81/1"
- if addr:
- cmd += " mac=" + addr.replace(':','')
- if curve:
- cmd += " curve=" + curve
- res = wpas.request(cmd)
- try:
- id = int(res)
- except ValueError:
- print("Failed to generate bootstrap info URI")
- return
- print("Bootstrap information - ID=%d" % id)
- print(wpas.request("DPP_BOOTSTRAP_INFO %d" % id))
- uri = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id)
- print(uri)
- print("ID=%d" % id)
- qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M,
- border=3)
- qr.add_data(uri, optimize=5)
- qr.print_ascii(tty=True)
- print("ID=%d" % id)
- del wpas
-
-def main():
- parser = argparse.ArgumentParser(description='Android logcat to wpa_supplicant integration for DPP QR Code operations')
- parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
- action='store_const', dest='loglevel',
- help='verbose debug output')
- parser.add_argument('--curve', '-c',
- help='set a specific curve (P-256, P-384, P-521, BP-256R1, BP-384R1, BP-512R1) for key generation')
- parser.add_argument('command', choices=['logcat',
- 'display'],
- nargs='?')
- args = parser.parse_args()
-
- logging.basicConfig(level=args.loglevel)
-
- if args.command == "logcat":
- dpp_logcat()
- elif args.command == "display":
- dpp_display(args.curve)
-
-if __name__ == '__main__':
- main()
diff --git a/wpa_supplicant/examples/ieee8021x.conf b/wpa_supplicant/examples/ieee8021x.conf
deleted file mode 100644
index e8a5503d8359..000000000000
--- a/wpa_supplicant/examples/ieee8021x.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-# IEEE 802.1X with dynamic WEP keys using EAP-PEAP/MSCHAPv2
-
-ctrl_interface=/var/run/wpa_supplicant
-
-network={
- ssid="example 802.1x network"
- key_mgmt=IEEE8021X
- eap=PEAP
- phase2="auth=MSCHAPV2"
- identity="user name"
- password="password"
- ca_cert="/etc/cert/ca.pem"
-}
diff --git a/wpa_supplicant/examples/openCryptoki.conf b/wpa_supplicant/examples/openCryptoki.conf
deleted file mode 100644
index e2301a61cabf..000000000000
--- a/wpa_supplicant/examples/openCryptoki.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-# EAP-TLS using private key and certificates via OpenSSL PKCS#11 engine and
-# openCryptoki (e.g., with TPM token)
-
-# This example uses following PKCS#11 objects:
-# $ pkcs11-tool --module /usr/lib/opencryptoki/libopencryptoki.so -O -l
-# Please enter User PIN:
-# Private Key Object; RSA
-# label: rsakey
-# ID: 04
-# Usage: decrypt, sign, unwrap
-# Certificate Object, type = X.509 cert
-# label: ca
-# ID: 01
-# Certificate Object, type = X.509 cert
-# label: cert
-# ID: 04
-
-# Configure OpenSSL to load the PKCS#11 engine and openCryptoki module
-pkcs11_engine_path=/usr/lib/engines/engine_pkcs11.so
-pkcs11_module_path=/usr/lib/opencryptoki/libopencryptoki.so
-
-network={
- ssid="test network"
- key_mgmt=WPA-EAP
- eap=TLS
- identity="User"
-
- # use OpenSSL PKCS#11 engine for this network
- engine=1
- engine_id="pkcs11"
-
- # select the private key and certificates based on ID (see pkcs11-tool
- # output above)
- key_id="4"
- cert_id="4"
- ca_cert_id="1"
-
- # set the PIN code; leave this out to configure the PIN to be requested
- # interactively when needed (e.g., via wpa_gui or wpa_cli)
- pin="123456"
-}
diff --git a/wpa_supplicant/examples/p2p-action-udhcp.sh b/wpa_supplicant/examples/p2p-action-udhcp.sh
deleted file mode 100755
index 53d8b777cd51..000000000000
--- a/wpa_supplicant/examples/p2p-action-udhcp.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/sh
-
-IFNAME=$1
-CMD=$2
-
-kill_daemon() {
- NAME=$1
- PF=$2
-
- if [ ! -r $PF ]; then
- return
- fi
-
- PID=`cat $PF`
- if [ $PID -gt 0 ]; then
- if ps $PID | grep -q $NAME; then
- kill $PID
- fi
- fi
- rm $PF
-}
-
-if [ "$CMD" = "P2P-GROUP-STARTED" ]; then
- GIFNAME=$3
- if [ "$4" = "GO" ]; then
- kill_daemon udhcpc /var/run/udhcpc-$GIFNAME.pid
- ifconfig $GIFNAME 192.168.42.1 up
- udhcpd /etc/udhcpd-p2p.conf
- fi
- if [ "$4" = "client" ]; then
- kill_daemon udhcpc /var/run/udhcpc-$GIFNAME.pid
- kill_daemon udhcpd /var/run/udhcpd-$GIFNAME.pid
- udhcpc -i $GIFNAME -p /var/run/udhcpc-$GIFNAME.pid \
- -s /etc/udhcpc.script
- fi
-fi
-
-if [ "$CMD" = "P2P-GROUP-REMOVED" ]; then
- GIFNAME=$3
- if [ "$4" = "GO" ]; then
- kill_daemon udhcpd /var/run/udhcpd-$GIFNAME.pid
- ifconfig $GIFNAME 0.0.0.0
- fi
- if [ "$4" = "client" ]; then
- kill_daemon udhcpc /var/run/udhcpc-$GIFNAME.pid
- ifconfig $GIFNAME 0.0.0.0
- fi
-fi
-
-if [ "$CMD" = "P2P-CROSS-CONNECT-ENABLE" ]; then
- GIFNAME=$3
- UPLINK=$4
- # enable NAT/masquerade $GIFNAME -> $UPLINK
- iptables -P FORWARD DROP
- iptables -t nat -A POSTROUTING -o $UPLINK -j MASQUERADE
- iptables -A FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
- iptables -A FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
- sysctl net.ipv4.ip_forward=1
-fi
-
-if [ "$CMD" = "P2P-CROSS-CONNECT-DISABLE" ]; then
- GIFNAME=$3
- UPLINK=$4
- # disable NAT/masquerade $GIFNAME -> $UPLINK
- sysctl net.ipv4.ip_forward=0
- iptables -t nat -D POSTROUTING -o $UPLINK -j MASQUERADE
- iptables -D FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
- iptables -D FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
-fi
diff --git a/wpa_supplicant/examples/p2p-action.sh b/wpa_supplicant/examples/p2p-action.sh
deleted file mode 100755
index 6c27b27b787e..000000000000
--- a/wpa_supplicant/examples/p2p-action.sh
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/sh
-
-IFNAME=$1
-CMD=$2
-
-kill_daemon() {
- NAME=$1
- PF=$2
-
- if [ ! -r $PF ]; then
- return
- fi
-
- PID=`cat $PF`
- if [ $PID -gt 0 ]; then
- if ps $PID | grep -q $NAME; then
- kill $PID
- fi
- fi
- rm $PF
-}
-
-if [ "$CMD" = "P2P-GROUP-STARTED" ]; then
- GIFNAME=$3
- if [ "$4" = "GO" ]; then
- kill_daemon dhclient /var/run/dhclient-$GIFNAME.pid
- rm /var/run/dhclient.leases-$GIFNAME
- kill_daemon dnsmasq /var/run/dnsmasq.pid-$GIFNAME
- ifconfig $GIFNAME 192.168.42.1 up
- if ! dnsmasq -x /var/run/dnsmasq.pid-$GIFNAME \
- -i $GIFNAME \
- -F192.168.42.11,192.168.42.99; then
- # another dnsmasq instance may be running and blocking us; try to
- # start with -z to avoid that
- dnsmasq -x /var/run/dnsmasq.pid-$GIFNAME \
- -i $GIFNAME \
- -F192.168.42.11,192.168.42.99 --listen-address 192.168.42.1 -z -p 0
- fi
- fi
- if [ "$4" = "client" ]; then
- kill_daemon dhclient /var/run/dhclient-$GIFNAME.pid
- rm /var/run/dhclient.leases-$GIFNAME
- kill_daemon dnsmasq /var/run/dnsmasq.pid-$GIFNAME
- ipaddr=`echo "$*" | sed 's/.* ip_addr=\([^ ]*\).*/\1/'`
- ipmask=`echo "$*" | sed 's/.* ip_mask=\([^ ]*\).*/\1/'`
- goipaddr=`echo "$*" | sed 's/.* go_ip_addr=\([^ ]*\).*/\1/'`
- if echo "$ipaddr$ipmask$goipaddr" | grep -q ' '; then
- ipaddr=""
- ipmask=""
- goipaddr=""
- fi
- if [ -n "$ipaddr" ]; then
- sudo ifconfig $GIFNAME "$ipaddr" netmask "$ipmask"
- sudo ip ro re default via "$goipaddr"
- exit 0
- fi
- dhclient -pf /var/run/dhclient-$GIFNAME.pid \
- -lf /var/run/dhclient.leases-$GIFNAME \
- -nw \
- $GIFNAME
- fi
-fi
-
-if [ "$CMD" = "P2P-GROUP-REMOVED" ]; then
- GIFNAME=$3
- if [ "$4" = "GO" ]; then
- kill_daemon dnsmasq /var/run/dnsmasq.pid-$GIFNAME
- ifconfig $GIFNAME 0.0.0.0
- fi
- if [ "$4" = "client" ]; then
- kill_daemon dhclient /var/run/dhclient-$GIFNAME.pid
- rm /var/run/dhclient.leases-$GIFNAME
- ifconfig $GIFNAME 0.0.0.0
- fi
-fi
-
-if [ "$CMD" = "P2P-CROSS-CONNECT-ENABLE" ]; then
- GIFNAME=$3
- UPLINK=$4
- # enable NAT/masquerade $GIFNAME -> $UPLINK
- iptables -P FORWARD DROP
- iptables -t nat -A POSTROUTING -o $UPLINK -j MASQUERADE
- iptables -A FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
- iptables -A FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
- sysctl net.ipv4.ip_forward=1
-fi
-
-if [ "$CMD" = "P2P-CROSS-CONNECT-DISABLE" ]; then
- GIFNAME=$3
- UPLINK=$4
- # disable NAT/masquerade $GIFNAME -> $UPLINK
- sysctl net.ipv4.ip_forward=0
- iptables -t nat -D POSTROUTING -o $UPLINK -j MASQUERADE
- iptables -D FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
- iptables -D FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
-fi
diff --git a/wpa_supplicant/examples/p2p-nfc.py b/wpa_supplicant/examples/p2p-nfc.py
deleted file mode 100755
index 889ac8bff155..000000000000
--- a/wpa_supplicant/examples/p2p-nfc.py
+++ /dev/null
@@ -1,654 +0,0 @@
-#!/usr/bin/python
-#
-# Example nfcpy to wpa_supplicant wrapper for P2P NFC operations
-# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import os
-import sys
-import time
-import random
-import threading
-import argparse
-
-import nfc
-import nfc.ndef
-import nfc.llcp
-import nfc.handover
-
-import logging
-
-import wpaspy
-
-wpas_ctrl = '/var/run/wpa_supplicant'
-ifname = None
-init_on_touch = False
-in_raw_mode = False
-prev_tcgetattr = 0
-include_wps_req = True
-include_p2p_req = True
-no_input = False
-srv = None
-continue_loop = True
-terminate_now = False
-summary_file = None
-success_file = None
-
-def summary(txt):
- print(txt)
- if summary_file:
- with open(summary_file, 'a') as f:
- f.write(txt + "\n")
-
-def success_report(txt):
- summary(txt)
- if success_file:
- with open(success_file, 'a') as f:
- f.write(txt + "\n")
-
-def wpas_connect():
- ifaces = []
- if os.path.isdir(wpas_ctrl):
- try:
- ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
- except OSError as error:
- print("Could not find wpa_supplicant: ", error)
- return None
-
- if len(ifaces) < 1:
- print("No wpa_supplicant control interface found")
- return None
-
- for ctrl in ifaces:
- if ifname:
- if ifname not in ctrl:
- continue
- try:
- print("Trying to use control interface " + ctrl)
- wpas = wpaspy.Ctrl(ctrl)
- return wpas
- except Exception as e:
- pass
- return None
-
-
-def wpas_tag_read(message):
- wpas = wpas_connect()
- if (wpas == None):
- return False
- cmd = "WPS_NFC_TAG_READ " + str(message).encode("hex")
- global force_freq
- if force_freq:
- cmd = cmd + " freq=" + force_freq
- if "FAIL" in wpas.request(cmd):
- return False
- return True
-
-
-def wpas_get_handover_req():
- wpas = wpas_connect()
- if (wpas == None):
- return None
- res = wpas.request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip()
- if "FAIL" in res:
- return None
- return res.decode("hex")
-
-def wpas_get_handover_req_wps():
- wpas = wpas_connect()
- if (wpas == None):
- return None
- res = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip()
- if "FAIL" in res:
- return None
- return res.decode("hex")
-
-
-def wpas_get_handover_sel(tag=False):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- if tag:
- res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG").rstrip()
- else:
- res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip()
- if "FAIL" in res:
- return None
- return res.decode("hex")
-
-
-def wpas_get_handover_sel_wps():
- wpas = wpas_connect()
- if (wpas == None):
- return None
- res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR");
- if "FAIL" in res:
- return None
- return res.rstrip().decode("hex")
-
-
-def wpas_report_handover(req, sel, type):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- cmd = "NFC_REPORT_HANDOVER " + type + " P2P " + str(req).encode("hex") + " " + str(sel).encode("hex")
- global force_freq
- if force_freq:
- cmd = cmd + " freq=" + force_freq
- return wpas.request(cmd)
-
-
-def wpas_report_handover_wsc(req, sel, type):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- cmd = "NFC_REPORT_HANDOVER " + type + " WPS " + str(req).encode("hex") + " " + str(sel).encode("hex")
- if force_freq:
- cmd = cmd + " freq=" + force_freq
- return wpas.request(cmd)
-
-
-def p2p_handover_client(llc):
- message = nfc.ndef.HandoverRequestMessage(version="1.2")
- message.nonce = random.randint(0, 0xffff)
-
- global include_p2p_req
- if include_p2p_req:
- data = wpas_get_handover_req()
- if (data == None):
- summary("Could not get handover request carrier record from wpa_supplicant")
- return
- print("Handover request carrier record from wpa_supplicant: " + data.encode("hex"))
- datamsg = nfc.ndef.Message(data)
- message.add_carrier(datamsg[0], "active", datamsg[1:])
-
- global include_wps_req
- if include_wps_req:
- print("Handover request (pre-WPS):")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
-
- data = wpas_get_handover_req_wps()
- if data:
- print("Add WPS request in addition to P2P")
- datamsg = nfc.ndef.Message(data)
- message.add_carrier(datamsg[0], "active", datamsg[1:])
-
- print("Handover request:")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
- print(str(message).encode("hex"))
-
- client = nfc.handover.HandoverClient(llc)
- try:
- summary("Trying to initiate NFC connection handover")
- client.connect()
- summary("Connected for handover")
- except nfc.llcp.ConnectRefused:
- summary("Handover connection refused")
- client.close()
- return
- except Exception as e:
- summary("Other exception: " + str(e))
- client.close()
- return
-
- summary("Sending handover request")
-
- if not client.send(message):
- summary("Failed to send handover request")
- client.close()
- return
-
- summary("Receiving handover response")
- message = client._recv()
- if message is None:
- summary("No response received")
- client.close()
- return
- if message.type != "urn:nfc:wkt:Hs":
- summary("Response was not Hs - received: " + message.type)
- client.close()
- return
-
- print("Received message")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
- print(str(message).encode("hex"))
- message = nfc.ndef.HandoverSelectMessage(message)
- summary("Handover select received")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
-
- for carrier in message.carriers:
- print("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.p2p":
- print("P2P carrier type match - send to wpa_supplicant")
- if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
- success_report("P2P handover reported successfully (initiator)")
- else:
- summary("P2P handover report rejected")
- break
-
- print("Remove peer")
- client.close()
- print("Done with handover")
- global only_one
- if only_one:
- print("only_one -> stop loop")
- global continue_loop
- continue_loop = False
-
- global no_wait
- if no_wait:
- print("Trying to exit..")
- global terminate_now
- terminate_now = True
-
-
-class HandoverServer(nfc.handover.HandoverServer):
- def __init__(self, llc):
- super(HandoverServer, self).__init__(llc)
- self.sent_carrier = None
- self.ho_server_processing = False
- self.success = False
-
- # override to avoid parser error in request/response.pretty() in nfcpy
- # due to new WSC handover format
- def _process_request(self, request):
- summary("received handover request {}".format(request.type))
- response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
- if not request.type == 'urn:nfc:wkt:Hr':
- summary("not a handover request")
- else:
- try:
- request = nfc.ndef.HandoverRequestMessage(request)
- except nfc.ndef.DecodeError as e:
- summary("error decoding 'Hr' message: {}".format(e))
- else:
- response = self.process_request(request)
- summary("send handover response {}".format(response.type))
- return response
-
- def process_request(self, request):
- self.ho_server_processing = True
- clear_raw_mode()
- print("HandoverServer - request received")
- try:
- print("Parsed handover request: " + request.pretty())
- except Exception as e:
- print(e)
-
- sel = nfc.ndef.HandoverSelectMessage(version="1.2")
-
- found = False
-
- for carrier in request.carriers:
- print("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.p2p":
- print("P2P carrier type match - add P2P carrier record")
- found = True
- self.received_carrier = carrier.record
- print("Carrier record:")
- try:
- print(carrier.record.pretty())
- except Exception as e:
- print(e)
- data = wpas_get_handover_sel()
- if data is None:
- print("Could not get handover select carrier record from wpa_supplicant")
- continue
- print("Handover select carrier record from wpa_supplicant:")
- print(data.encode("hex"))
- self.sent_carrier = data
- if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"):
- success_report("P2P handover reported successfully (responder)")
- else:
- summary("P2P handover report rejected")
- break
-
- message = nfc.ndef.Message(data);
- sel.add_carrier(message[0], "active", message[1:])
- break
-
- for carrier in request.carriers:
- if found:
- break
- print("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.wsc":
- print("WSC carrier type match - add WSC carrier record")
- found = True
- self.received_carrier = carrier.record
- print("Carrier record:")
- try:
- print(carrier.record.pretty())
- except Exception as e:
- print(e)
- data = wpas_get_handover_sel_wps()
- if data is None:
- print("Could not get handover select carrier record from wpa_supplicant")
- continue
- print("Handover select carrier record from wpa_supplicant:")
- print(data.encode("hex"))
- self.sent_carrier = data
- if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"):
- success_report("WSC handover reported successfully")
- else:
- summary("WSC handover report rejected")
- break
-
- message = nfc.ndef.Message(data);
- sel.add_carrier(message[0], "active", message[1:])
- found = True
- break
-
- print("Handover select:")
- try:
- print(sel.pretty())
- except Exception as e:
- print(e)
- print(str(sel).encode("hex"))
-
- summary("Sending handover select")
- self.success = True
- return sel
-
-
-def clear_raw_mode():
- import sys, tty, termios
- global prev_tcgetattr, in_raw_mode
- if not in_raw_mode:
- return
- fd = sys.stdin.fileno()
- termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
- in_raw_mode = False
-
-
-def getch():
- import sys, tty, termios, select
- global prev_tcgetattr, in_raw_mode
- fd = sys.stdin.fileno()
- prev_tcgetattr = termios.tcgetattr(fd)
- ch = None
- try:
- tty.setraw(fd)
- in_raw_mode = True
- [i, o, e] = select.select([fd], [], [], 0.05)
- if i:
- ch = sys.stdin.read(1)
- finally:
- termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr)
- in_raw_mode = False
- return ch
-
-
-def p2p_tag_read(tag):
- success = False
- if len(tag.ndef.message):
- for record in tag.ndef.message:
- print("record type " + record.type)
- if record.type == "application/vnd.wfa.wsc":
- summary("WPS tag - send to wpa_supplicant")
- success = wpas_tag_read(tag.ndef.message)
- break
- if record.type == "application/vnd.wfa.p2p":
- summary("P2P tag - send to wpa_supplicant")
- success = wpas_tag_read(tag.ndef.message)
- break
- else:
- summary("Empty tag")
-
- if success:
- success_report("Tag read succeeded")
-
- return success
-
-
-def rdwr_connected_p2p_write(tag):
- summary("Tag found - writing - " + str(tag))
- global p2p_sel_data
- tag.ndef.message = str(p2p_sel_data)
- success_report("Tag write succeeded")
- print("Done - remove tag")
- global only_one
- if only_one:
- global continue_loop
- continue_loop = False
- global p2p_sel_wait_remove
- return p2p_sel_wait_remove
-
-def wps_write_p2p_handover_sel(clf, wait_remove=True):
- print("Write P2P handover select")
- data = wpas_get_handover_sel(tag=True)
- if (data == None):
- summary("Could not get P2P handover select from wpa_supplicant")
- return
-
- global p2p_sel_wait_remove
- p2p_sel_wait_remove = wait_remove
- global p2p_sel_data
- p2p_sel_data = nfc.ndef.HandoverSelectMessage(version="1.2")
- message = nfc.ndef.Message(data);
- p2p_sel_data.add_carrier(message[0], "active", message[1:])
- print("Handover select:")
- try:
- print(p2p_sel_data.pretty())
- except Exception as e:
- print(e)
- print(str(p2p_sel_data).encode("hex"))
-
- print("Touch an NFC tag")
- clf.connect(rdwr={'on-connect': rdwr_connected_p2p_write})
-
-
-def rdwr_connected(tag):
- global only_one, no_wait
- summary("Tag connected: " + str(tag))
-
- if tag.ndef:
- print("NDEF tag: " + tag.type)
- try:
- print(tag.ndef.message.pretty())
- except Exception as e:
- print(e)
- success = p2p_tag_read(tag)
- if only_one and success:
- global continue_loop
- continue_loop = False
- else:
- summary("Not an NDEF tag - remove tag")
- return True
-
- return not no_wait
-
-
-def llcp_worker(llc):
- global init_on_touch
- if init_on_touch:
- print("Starting handover client")
- p2p_handover_client(llc)
- return
-
- global no_input
- if no_input:
- print("Wait for handover to complete")
- else:
- print("Wait for handover to complete - press 'i' to initiate ('w' for WPS only, 'p' for P2P only)")
- global srv
- global wait_connection
- while not wait_connection and srv.sent_carrier is None:
- if srv.ho_server_processing:
- time.sleep(0.025)
- elif no_input:
- time.sleep(0.5)
- else:
- global include_wps_req, include_p2p_req
- res = getch()
- if res == 'i':
- include_wps_req = True
- include_p2p_req = True
- elif res == 'p':
- include_wps_req = False
- include_p2p_req = True
- elif res == 'w':
- include_wps_req = True
- include_p2p_req = False
- else:
- continue
- clear_raw_mode()
- print("Starting handover client")
- p2p_handover_client(llc)
- return
-
- clear_raw_mode()
- print("Exiting llcp_worker thread")
-
-def llcp_startup(clf, llc):
- print("Start LLCP server")
- global srv
- srv = HandoverServer(llc)
- return llc
-
-def llcp_connected(llc):
- print("P2P LLCP connected")
- global wait_connection
- wait_connection = False
- global init_on_touch
- if not init_on_touch:
- global srv
- srv.start()
- if init_on_touch or not no_input:
- threading.Thread(target=llcp_worker, args=(llc,)).start()
- return True
-
-def terminate_loop():
- global terminate_now
- return terminate_now
-
-def main():
- clf = nfc.ContactlessFrontend()
-
- parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for P2P and WPS NFC operations')
- parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
- action='store_const', dest='loglevel',
- help='verbose debug output')
- parser.add_argument('-q', const=logging.WARNING, action='store_const',
- dest='loglevel', help='be quiet')
- parser.add_argument('--only-one', '-1', action='store_true',
- help='run only one operation and exit')
- parser.add_argument('--init-on-touch', '-I', action='store_true',
- help='initiate handover on touch')
- parser.add_argument('--no-wait', action='store_true',
- help='do not wait for tag to be removed before exiting')
- parser.add_argument('--ifname', '-i',
- help='network interface name')
- parser.add_argument('--no-wps-req', '-N', action='store_true',
- help='do not include WPS carrier record in request')
- parser.add_argument('--no-input', '-a', action='store_true',
- help='do not use stdout input to initiate handover')
- parser.add_argument('--tag-read-only', '-t', action='store_true',
- help='tag read only (do not allow connection handover)')
- parser.add_argument('--handover-only', action='store_true',
- help='connection handover only (do not allow tag read)')
- parser.add_argument('--freq', '-f',
- help='forced frequency of operating channel in MHz')
- parser.add_argument('--summary',
- help='summary file for writing status updates')
- parser.add_argument('--success',
- help='success file for writing success update')
- parser.add_argument('command', choices=['write-p2p-sel'],
- nargs='?')
- args = parser.parse_args()
-
- global only_one
- only_one = args.only_one
-
- global no_wait
- no_wait = args.no_wait
-
- global force_freq
- force_freq = args.freq
-
- logging.basicConfig(level=args.loglevel)
-
- global init_on_touch
- init_on_touch = args.init_on_touch
-
- if args.ifname:
- global ifname
- ifname = args.ifname
- print("Selected ifname " + ifname)
-
- if args.no_wps_req:
- global include_wps_req
- include_wps_req = False
-
- if args.summary:
- global summary_file
- summary_file = args.summary
-
- if args.success:
- global success_file
- success_file = args.success
-
- if args.no_input:
- global no_input
- no_input = True
-
- clf = nfc.ContactlessFrontend()
- global wait_connection
-
- try:
- if not clf.open("usb"):
- print("Could not open connection with an NFC device")
- raise SystemExit
-
- if args.command == "write-p2p-sel":
- wps_write_p2p_handover_sel(clf, wait_remove=not args.no_wait)
- raise SystemExit
-
- global continue_loop
- while continue_loop:
- print("Waiting for a tag or peer to be touched")
- wait_connection = True
- try:
- if args.tag_read_only:
- if not clf.connect(rdwr={'on-connect': rdwr_connected}):
- break
- elif args.handover_only:
- if not clf.connect(llcp={'on-startup': llcp_startup,
- 'on-connect': llcp_connected},
- terminate=terminate_loop):
- break
- else:
- if not clf.connect(rdwr={'on-connect': rdwr_connected},
- llcp={'on-startup': llcp_startup,
- 'on-connect': llcp_connected},
- terminate=terminate_loop):
- break
- except Exception as e:
- print("clf.connect failed")
-
- global srv
- if only_one and srv and srv.success:
- raise SystemExit
-
- except KeyboardInterrupt:
- raise SystemExit
- finally:
- clf.close()
-
- raise SystemExit
-
-if __name__ == '__main__':
- main()
diff --git a/wpa_supplicant/examples/p2p/p2p_connect.py b/wpa_supplicant/examples/p2p/p2p_connect.py
deleted file mode 100644
index bfb553341ad6..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_connect.py
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/python
-# Tests p2p_connect
-# Will try to connect to another peer
-# and form a group
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> -m <wps_method> \ " \
- % sys.argv[0])
- print(" -a <addr> [-p <pin>] [-g <go_intent>] \ ")
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -m = wps method")
- print(" -a = peer address")
- print(" -p = pin number (8 digits)")
- print(" -g = group owner intent")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0 -a 0015008352c0 -m display -p 12345670" % sys.argv[0])
-
-
-# Required Signals
-def GONegotiationSuccess(status):
- print("Go Negotiation Success")
-
-def GONegotiationFailure(status):
- print('Go Negotiation Failed. Status:')
- print(format(status))
- os._exit(0)
-
-def GroupStarted(properties):
- if properties.has_key("group_object"):
- print('Group Formation Complete %s' \
- % properties["group_object"])
- os._exit(0)
-
-def WpsFailure(status, etc):
- print("WPS Authentication Failure".format(status))
- print(etc)
- os._exit(0)
-
-class P2P_Connect():
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global ifname
- global wpas
- global wpas_dbus_interface
- global timeout
- global path
- global wps_method
- global go_intent
- global addr
- global pin
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Dictionary of Arguments
- global p2p_connect_arguements
-
- # Constructor
- def __init__(self,ifname,wpas_dbus_interface,addr,
- pin,wps_method,go_intent):
- # Initializes variables and threads
- self.ifname = ifname
- self.wpas_dbus_interface = wpas_dbus_interface
- self.wps_method = wps_method
- self.go_intent = go_intent
- self.addr = addr
- self.pin = pin
-
- # Generating interface/object paths
- self.wpas_dbus_opath = \
- "/" + self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = \
- self.wpas_dbus_opath + "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(
- self.wpas_object, self.wpas_dbus_interface)
-
- # See if wpa_supplicant already knows about this interface
- self.path = None
- try:
- self.path = self.wpas.GetInterface(ifname)
- except dbus.DBusException as exc:
- if not str(exc).startswith(
- self.wpas_dbus_interface + \
- ".InterfaceUnknown:"):
- raise exc
- try:
- path = self.wpas.CreateInterface(
- {'Ifname': ifname, 'Driver': 'test'})
- time.sleep(1)
-
- except dbus.DBusException as exc:
- if not str(exc).startswith(
- self.wpas_dbus_interface + \
- ".InterfaceExists:"):
- raise exc
-
- # Get Interface and objects
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface,self.path)
- self.p2p_interface = dbus.Interface(
- self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- # Add signals
- self.bus.add_signal_receiver(GONegotiationSuccess,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="GONegotiationSuccess")
- self.bus.add_signal_receiver(GONegotiationFailure,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="GONegotiationFailure")
- self.bus.add_signal_receiver(GroupStarted,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="GroupStarted")
- self.bus.add_signal_receiver(WpsFailure,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="WpsFailed")
-
-
- #Constructing all the arguments needed to connect
- def constructArguements(self):
- # Adding required arguments
- self.p2p_connect_arguements = {'wps_method':self.wps_method,
- 'peer':dbus.ObjectPath(self.path+'/Peers/'+self.addr)}
-
- # Display requires a pin, and a go intent of 15
- if (self.wps_method == 'display'):
- if (self.pin != None):
- self.p2p_connect_arguements.update({'pin':self.pin})
- else:
- print("Error:\n Pin required for wps_method=display")
- usage()
- quit()
-
- if (self.go_intent != None and int(self.go_intent) != 15):
- print("go_intent overwritten to 15")
-
- self.go_intent = '15'
-
- # Keypad requires a pin, and a go intent of less than 15
- elif (self.wps_method == 'keypad'):
- if (self.pin != None):
- self.p2p_connect_arguements.update({'pin':self.pin})
- else:
- print("Error:\n Pin required for wps_method=keypad")
- usage()
- quit()
-
- if (self.go_intent != None and int(self.go_intent) == 15):
- error = "Error :\n Group Owner intent cannot be" + \
- " 15 for wps_method=keypad"
- print(error)
- usage()
- quit()
-
- # Doesn't require pin
- # for ./wpa_cli, p2p_connect [mac] [pin#], wps_method=keypad
- elif (self.wps_method == 'pin'):
- if (self.pin != None):
- print("pin ignored")
-
- # No pin is required for pbc so it is ignored
- elif (self.wps_method == 'pbc'):
- if (self.pin != None):
- print("pin ignored")
-
- else:
- print("Error:\n wps_method not supported or does not exist")
- usage()
- quit()
-
- # Go_intent is optional for all arguments
- if (self.go_intent != None):
- self.p2p_connect_arguements.update(
- {'go_intent':dbus.Int32(self.go_intent)})
-
- # Running p2p_connect
- def run(self):
- try:
- result_pin = self.p2p_interface.Connect(
- self.p2p_connect_arguements)
-
- except dbus.DBusException as exc:
- raise exc
-
- if (self.wps_method == 'pin' and \
- not self.p2p_connect_arguements.has_key('pin') ):
- print("Connect return with pin value of %d " % int(result_pin))
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
-
- # Required
- interface_name = None
- wps_method = None
- addr = None
-
- # Conditionally optional
- pin = None
-
- # Optional
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
- go_intent = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:m:a:p:g:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # WPS Method
- elif (key == "-m"):
- wps_method = value
- # Address
- elif (key == "-a"):
- addr = value
- # Pin
- elif (key == "-p"):
- pin = value
- # Group Owner Intent
- elif (key == "-g"):
- go_intent = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Required Arguments check
- if (interface_name == None or wps_method == None or addr == None):
- print("Error:\n Required arguments not specified")
- usage()
- quit()
-
- # Group Owner Intent Check
- if (go_intent != None and (int(go_intent) > 15 or int(go_intent) < 0) ):
- print("Error:\n Group Owner Intent must be between 0 and 15 inclusive")
- usage()
- quit()
-
- # Pin Check
- if (pin != None and len(pin) != 8):
- print("Error:\n Pin is not 8 digits")
- usage()
- quit()
-
- try:
- p2p_connect_test = P2P_Connect(interface_name,wpas_dbus_interface,
- addr,pin,wps_method,go_intent)
-
- except:
- print("Error:\n Invalid Arguments")
- usage()
- quit()
-
- p2p_connect_test.constructArguements()
- p2p_connect_test.run()
-
- os._exit(0)
diff --git a/wpa_supplicant/examples/p2p/p2p_disconnect.py b/wpa_supplicant/examples/p2p/p2p_disconnect.py
deleted file mode 100644
index f04b98e667ce..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_disconnect.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/python
-# Tests P2P_Disconnect
-# Will perform disconnect on interface_name
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import threading
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> \ " \
- % sys.argv[0])
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i p2p-wlan0-0" % sys.argv[0])
-
-# Required Signals
-def GroupFinished(status, etc):
- print("Disconnected")
- os._exit(0)
-
-class P2P_Disconnect (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global timeout
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,timeout):
- # Initializes variables and threads
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
- self.timeout = timeout
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- # Signals
- self.bus.add_signal_receiver(GroupFinished,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="GroupFinished")
-
- # Runs p2p_disconnect
- def run(self):
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- self.p2p_interface.Disconnect()
- gobject.MainLoop().run()
-
-
-if __name__ == "__main__":
-
- timeout = 5
- # Defaults for optional inputs
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- # Constructor
- try:
- p2p_disconnect_test = P2P_Disconnect(interface_name,
- wpas_dbus_interface,timeout)
-
- except:
- print("Error:\n Invalid wpas_dbus_interface")
- usage()
- quit()
-
- # Start P2P_Disconnect
- p2p_disconnect_test.start()
-
- try:
- time.sleep(int(p2p_disconnect_test.timeout))
-
- except:
- pass
-
- print("Disconnect timed out")
- quit()
diff --git a/wpa_supplicant/examples/p2p/p2p_find.py b/wpa_supplicant/examples/p2p/p2p_find.py
deleted file mode 100644
index 412d8120031a..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_find.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/python
-# Tests p2p_find
-# Will list all devices found/lost within a time frame (timeout)
-# Then Program will exit
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import threading
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> [-t <timeout>] \ " \
- % sys.argv[0])
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -t = timeout = 0s (infinite)")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0 -t 10" % sys.argv[0])
-
-# Required Signals
-def deviceFound(devicepath):
- print("Device found: %s" % (devicepath))
-
-def deviceLost(devicepath):
- print("Device lost: %s" % (devicepath))
-
-class P2P_Find (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global timeout
- global path
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,timeout):
- # Initializes variables and threads
- self.timeout = int(timeout)
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- #Adds listeners for find and lost
- self.bus.add_signal_receiver(deviceFound,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="DeviceFound")
- self.bus.add_signal_receiver(deviceLost,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="DeviceLost")
-
-
- # Sets up p2p_find
- P2PFindDict = dbus.Dictionary(
- {'Timeout':int(self.timeout)})
- self.p2p_interface.Find(P2PFindDict)
-
- # Run p2p_find
- def run(self):
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
-
- # Defaults for optional inputs
- timeout = 0
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:t:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Timeout
- elif (key == "-t"):
- if ( int(value) >= 0):
- timeout = value
- else:
- print("Error:\n Timeout cannot be negative")
- usage()
- quit()
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- # Constructor
- try:
- p2p_find_test = P2P_Find(interface_name, wpas_dbus_interface, timeout)
-
- except:
- print("Error:\n Invalid wpas_dbus_interface")
- usage()
- quit()
-
- # Start P2P_Find
- p2p_find_test.start()
-
- try:
- # If timeout is 0, then run forever
- if (timeout == 0):
- while(True):
- pass
- # Else sleep for (timeout)
- else:
- time.sleep(p2p_find_test.timeout)
-
- except:
- pass
-
- quit()
diff --git a/wpa_supplicant/examples/p2p/p2p_flush.py b/wpa_supplicant/examples/p2p/p2p_flush.py
deleted file mode 100644
index 5cc3a0e18b23..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_flush.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/python
-# Tests P2P_Flush
-# Will flush the p2p interface
-# Then Program will exit
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import threading
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> \ " \
- % sys.argv[0])
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0" % sys.argv[0])
-
-# Required Signals\
-def deviceLost(devicepath):
- print("Device lost: %s" % (devicepath))
-
-class P2P_Flush (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global timeout
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,timeout):
- # Initializes variables and threads
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
- self.timeout = timeout
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- # Signals
- self.bus.add_signal_receiver(deviceLost,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="DeviceLost")
-
- # Runs p2p_flush
- def run(self):
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- self.p2p_interface.Flush()
- gobject.MainLoop().run()
-
-
-if __name__ == "__main__":
- # Needed to show which devices were lost
- timeout = 5
- # Defaults for optional inputs
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- # Constructor
- try:
- p2p_flush_test = P2P_Flush(interface_name, wpas_dbus_interface,timeout)
-
- except:
- print("Error:\n Invalid wpas_dbus_interface")
- usage()
- quit()
-
- # Start P2P_Find
- p2p_flush_test.start()
-
- try:
- time.sleep(int(p2p_flush_test.timeout))
-
- except:
- pass
-
- print("p2p_flush complete")
- quit()
diff --git a/wpa_supplicant/examples/p2p/p2p_group_add.py b/wpa_supplicant/examples/p2p/p2p_group_add.py
deleted file mode 100644
index db6d60d80c1b..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_group_add.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/python
-# Tests p2p_group_add
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import getopt
-import threading
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> [-p <persistent>] \ " \
- % sys.argv[0])
- print(" [-f <frequency>] [-o <group_object_path>] \ ")
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -p = persistent group = 0 (0=false, 1=true)")
- print(" -f = frequency")
- print(" -o = persistent group object path")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0" % sys.argv[0])
-
-# Required Signals
-def GroupStarted(properties):
- if properties.has_key("group_object"):
- print('Group Formation Complete %s' \
- % properties["group_object"])
- os._exit(0)
-
-def WpsFailure(status, etc):
- print("WPS Authentication Failure".format(status))
- print(etc)
- os._exit(0)
-
-class P2P_Group_Add (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global persistent
- global frequency
- global persistent_group_object
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Arguments
- global P2PDictionary
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,persistent,frequency,
- persistent_group_object):
- # Initializes variables and threads
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
- self.persistent = persistent
- self.frequency = frequency
- self.persistent_group_object = persistent_group_object
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- #Adds listeners
- self.bus.add_signal_receiver(GroupStarted,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="GroupStarted")
- self.bus.add_signal_receiver(WpsFailure,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="WpsFailed")
-
- # Sets up p2p_group_add dictionary
- def constructArguments(self):
- self.P2PDictionary = {'persistent':self.persistent}
-
- if (self.frequency != None):
- if (int(self.frequency) > 0):
- self.P2PDictionary.update({'frequency':int(self.frequency)})
- else:
- print("Error:\n Frequency must be greater than 0")
- usage()
- os._exit(0)
-
- if (self.persistent_group_object != None):
- self.P2PDictionary.update({'persistent_group_object':
- self.persistent_group_object})
-
- # Run p2p_group_remove
- def run(self):
- try:
- self.p2p_interface.GroupAdd(self.P2PDictionary)
-
- except:
- print("Error:\n Could not perform group add")
- usage()
- os._exit(0)
-
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- gobject.MainLoop().run()
-
-
-if __name__ == "__main__":
-
- # Defaults for optional inputs
- # 0 = false, 1 = true
- persistent = False
- frequency = None
- persistent_group_object = None
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:p:f:o:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Timeout
- elif (key == "-p"):
- if (value == '0'):
- persistent = False
- elif (value == '1'):
- persistent = True
- else:
- print("Error:\n Persistent can only be 1 or 0")
- usage()
- os._exit(0)
- # Frequency
- elif (key == "-f"):
- frequency = value
- # Persistent group object path
- elif (key == "-o"):
- persistent_group_object = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- try:
- p2p_group_add_test = P2P_Group_Add(interface_name,wpas_dbus_interface,
- persistent,frequency,persistent_group_object)
- except:
- print("Error:\n Invalid Arguments")
-
- p2p_group_add_test.constructArguments()
- p2p_group_add_test.start()
- time.sleep(5)
- print("Error:\n Group formation timed out")
- os._exit(0)
diff --git a/wpa_supplicant/examples/p2p/p2p_invite.py b/wpa_supplicant/examples/p2p/p2p_invite.py
deleted file mode 100644
index 8944e11ed47c..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_invite.py
+++ /dev/null
@@ -1,201 +0,0 @@
-#!/usr/bin/python
-# Tests p2p_invite
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import getopt
-import threading
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> -a <addr> \ " \
- % sys.argv[0])
- print(" [-o <persistent_group_object>] [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -a = address of peer")
- print(" -o = persistent group object path")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i p2p-wlan0-0 -a 00150083523c" % sys.argv[0])
-
-# Required Signals
-def InvitationResult(invite_result):
- print("Invitation Result signal :")
- status = invite_result['status']
- print("status = ", status)
- if invite_result.has_key('BSSID'):
- bssid = invite_result['BSSID']
- print("BSSID = ", hex(bssid[0]) , ":" , \
- hex(bssid[1]) , ":" , hex(bssid[2]) , ":", \
- hex(bssid[3]) , ":" , hex(bssid[4]) , ":" , \
- hex(bssid[5]))
- os._exit(0)
-
-class P2P_Invite (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global addr
- global persistent_group_object
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Arguments
- global P2PDictionary
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,addr,
- persistent_group_object):
- # Initializes variables and threads
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
- self.addr = addr
- self.persistent_group_object = persistent_group_object
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- #Adds listeners
- self.bus.add_signal_receiver(InvitationResult,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="InvitationResult")
-
- # Sets up p2p_invite dictionary
- def constructArguements(self):
- self.P2PDictionary = \
- {'peer':dbus.ObjectPath(self.path+'/Peers/'+self.addr)}
- if (self.persistent_group_object != None):
- self.P2PDictionary.update({"persistent_group_object":
- self.persistent_group_object})
-
- # Run p2p_invite
- def run(self):
- try:
- self.p2p_interface.Invite(self.P2PDictionary)
-
- except:
- print("Error:\n Invalid Arguments")
- usage()
- os._exit(0)
-
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
- # Defaults for optional inputs
- addr = None
- persistent_group_object = None
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:o:w:a:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- elif (key == "-a"):
- addr = value
- # Persistent group object path
- elif (key == "-o"):
- persistent_group_object = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- if (addr == None):
- print("Error:\n peer address is required")
- usage()
- quit()
-
- try:
- p2p_invite_test = \
- P2P_Invite(interface_name,wpas_dbus_interface,
- addr,persistent_group_object)
- except:
- print("Error:\n Invalid Arguments")
- usage()
- os._exit(1)
-
- p2p_invite_test.constructArguements()
- p2p_invite_test.start()
- time.sleep(10)
- print("Error:\n p2p_invite timed out")
- os._exit(0)
diff --git a/wpa_supplicant/examples/p2p/p2p_listen.py b/wpa_supplicant/examples/p2p/p2p_listen.py
deleted file mode 100644
index cbeda9ff43ca..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_listen.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/python
-# Tests P2P_Find
-# Will listen
-# Then Program will exit
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import threading
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> [-t <timeout>] \ " \
- % sys.argv[0])
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -t = timeout = 0s (infinite)")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0 -t 5" % sys.argv[0])
-
-# Required Signals
-def p2pStateChange(status):
- print(status)
-
-class P2P_Listen(threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global timeout
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,timeout):
- # Initializes variables and threads
- self.timeout = int(timeout)
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- self.bus.add_signal_receiver(p2pStateChange,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="P2PStateChanged")
-
- # Run p2p_find
- def run(self):
- # Sets up p2p_listen
- self.p2p_interface.Listen(int(self.timeout))
-
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
-
- # Defaults for optional inputs
- timeout = 0
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"hi:t:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Timeout
- elif (key == "-t"):
- if ( int(value) >= 0):
- timeout = value
- else:
- print("Error:\n Timeout cannot be negative")
- usage()
- quit()
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- # Constructor
- try:
- p2p_listen_test = P2P_Listen(interface_name, wpas_dbus_interface, timeout)
-
- except:
- print("Error:\n Invalid wpas_dbus_interface")
- usage()
- quit()
-
- # Start P2P_Find
- p2p_listen_test.start()
-
- try:
- # If timeout is 0, then run forever
- if (int(p2p_listen_test.timeout) == 0):
- while(True):
- pass
- # Else sleep for (timeout)
- else:
- time.sleep(int(p2p_listen_test.timeout))
-
- except:
- pass
-
- quit()
diff --git a/wpa_supplicant/examples/p2p/p2p_stop_find.py b/wpa_supplicant/examples/p2p/p2p_stop_find.py
deleted file mode 100644
index f367196454d9..000000000000
--- a/wpa_supplicant/examples/p2p/p2p_stop_find.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/python
-# Tests p2p_stop_find
-######### MAY NEED TO RUN AS SUDO #############
-
-import dbus
-import sys, os
-import time
-import gobject
-import threading
-import getopt
-from dbus.mainloop.glib import DBusGMainLoop
-
-def usage():
- print("Usage:")
- print(" %s -i <interface_name> \ " \
- % sys.argv[0])
- print(" [-w <wpas_dbus_interface>]")
- print("Options:")
- print(" -i = interface name")
- print(" -w = wpas dbus interface = fi.w1.wpa_supplicant1")
- print("Example:")
- print(" %s -i wlan0" % sys.argv[0])
-
-# Required Signals
-def deviceLost(devicepath):
- print("Device lost: %s" % (devicepath))
-
-def p2pStateChange(status):
- print(status)
- os._exit(0)
-
-class P2P_Stop_Find (threading.Thread):
- # Needed Variables
- global bus
- global wpas_object
- global interface_object
- global p2p_interface
- global interface_name
- global wpas
- global wpas_dbus_interface
- global path
- global timeout
-
- # Dbus Paths
- global wpas_dbus_opath
- global wpas_dbus_interfaces_opath
- global wpas_dbus_interfaces_interface
- global wpas_dbus_interfaces_p2pdevice
-
- # Constructor
- def __init__(self,interface_name,wpas_dbus_interface,timeout):
- # Initializes variables and threads
- self.interface_name = interface_name
- self.wpas_dbus_interface = wpas_dbus_interface
- self.timeout = timeout
-
- # Initializes thread and daemon allows for ctrl-c kill
- threading.Thread.__init__(self)
- self.daemon = True
-
- # Generating interface/object paths
- self.wpas_dbus_opath = "/" + \
- self.wpas_dbus_interface.replace(".","/")
- self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
- "/Interfaces"
- self.wpas_dbus_interfaces_interface = \
- self.wpas_dbus_interface + ".Interface"
- self.wpas_dbus_interfaces_p2pdevice = \
- self.wpas_dbus_interfaces_interface \
- + ".P2PDevice"
-
- # Getting interfaces and objects
- DBusGMainLoop(set_as_default=True)
- self.bus = dbus.SystemBus()
- self.wpas_object = self.bus.get_object(
- self.wpas_dbus_interface,
- self.wpas_dbus_opath)
- self.wpas = dbus.Interface(self.wpas_object,
- self.wpas_dbus_interface)
-
- # Try to see if supplicant knows about interface
- # If not, throw an exception
- try:
- self.path = self.wpas.GetInterface(
- self.interface_name)
- except dbus.DBusException as exc:
- error = 'Error:\n Interface ' + self.interface_name \
- + ' was not found'
- print(error)
- usage()
- os._exit(0)
-
- self.interface_object = self.bus.get_object(
- self.wpas_dbus_interface, self.path)
- self.p2p_interface = dbus.Interface(self.interface_object,
- self.wpas_dbus_interfaces_p2pdevice)
-
- # Signals
- self.bus.add_signal_receiver(deviceLost,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="DeviceLost")
- self.bus.add_signal_receiver(p2pStateChange,
- dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
- signal_name="P2PStateChanged")
-
- # Runs p2p_stop_find
- def run(self):
- # Allows other threads to keep working while MainLoop runs
- # Required for timeout implementation
- gobject.MainLoop().get_context().iteration(True)
- gobject.threads_init()
- self.p2p_interface.StopFind()
- gobject.MainLoop().run()
-
-
-if __name__ == "__main__":
- # Needed because P2PStateChanged signal is not caught
- timeout = 5
- # Defaults for optional inputs
- wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
-
- # interface_name is required
- interface_name = None
-
- # Using getopts to handle options
- try:
- options, args = getopt.getopt(sys.argv[1:],"ht:i:w:")
-
- except getopt.GetoptError:
- usage()
- quit()
-
- # If there's a switch, override default option
- for key, value in options:
- # Help
- if (key == "-h"):
- usage()
- quit()
- # Interface Name
- elif (key == "-i"):
- interface_name = value
- # Dbus interface
- elif (key == "-w"):
- wpas_dbus_interface = value
- else:
- assert False, "unhandled option"
-
- # Interface name is required and was not given
- if (interface_name == None):
- print("Error:\n interface_name is required")
- usage()
- quit()
-
- # Constructor
- try:
- p2p_stop_find_test = P2P_Stop_Find(interface_name,
- wpas_dbus_interface,timeout)
-
- except:
- print("Error:\n Invalid wpas_dbus_interface")
- usage()
- quit()
-
- # Start P2P_Find
- p2p_stop_find_test.start()
-
- try:
- time.sleep(int(p2p_stop_find_test.timeout))
-
- except:
- pass
-
- print("p2p find stopped")
- quit()
diff --git a/wpa_supplicant/examples/plaintext.conf b/wpa_supplicant/examples/plaintext.conf
deleted file mode 100644
index 542ac1dd3b96..000000000000
--- a/wpa_supplicant/examples/plaintext.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-# Plaintext (no encryption) network
-
-ctrl_interface=/var/run/wpa_supplicant
-
-network={
- ssid="example open network"
- key_mgmt=NONE
-}
diff --git a/wpa_supplicant/examples/udhcpd-p2p.conf b/wpa_supplicant/examples/udhcpd-p2p.conf
deleted file mode 100644
index f92cc619e962..000000000000
--- a/wpa_supplicant/examples/udhcpd-p2p.conf
+++ /dev/null
@@ -1,118 +0,0 @@
-# Sample udhcpd configuration file (/etc/udhcpd.conf)
-
-# The start and end of the IP lease block
-
-start 192.168.42.20 #default: 192.168.0.20
-end 192.168.42.254 #default: 192.168.0.254
-
-
-# The interface that udhcpd will use
-
-interface wlan2 #default: eth0
-
-
-# The maximum number of leases (includes addresses reserved
-# by OFFER's, DECLINE's, and ARP conflicts)
-
-#max_leases 254 #default: 254
-
-
-# If remaining is true (default), udhcpd will store the time
-# remaining for each lease in the udhcpd leases file. This is
-# for embedded systems that cannot keep time between reboots.
-# If you set remaining to no, the absolute time that the lease
-# expires at will be stored in the dhcpd.leases file.
-
-#remaining yes #default: yes
-
-
-# The time period at which udhcpd will write out a dhcpd.leases
-# file. If this is 0, udhcpd will never automatically write a
-# lease file. (specified in seconds)
-
-#auto_time 7200 #default: 7200 (2 hours)
-
-
-# The amount of time that an IP will be reserved (leased) for if a
-# DHCP decline message is received (seconds).
-
-#decline_time 3600 #default: 3600 (1 hour)
-
-
-# The amount of time that an IP will be reserved (leased) for if an
-# ARP conflct occurs. (seconds
-
-#conflict_time 3600 #default: 3600 (1 hour)
-
-
-# How long an offered address is reserved (leased) in seconds
-
-#offer_time 60 #default: 60 (1 minute)
-
-# If a lease to be given is below this value, the full lease time is
-# instead used (seconds).
-
-#min_lease 60 #default: 60
-
-
-# The location of the leases file
-
-#lease_file /var/lib/misc/udhcpd.leases #default: /var/lib/misc/udhcpd.leases
-
-# The location of the pid file
-pidfile /var/run/udhcpd-wlan2.pid #default: /var/run/udhcpd.pid
-
-# Every time udhcpd writes a leases file, the below script will be called.
-# Useful for writing the lease file to flash every few hours.
-
-#notify_file #default: (no script)
-
-#notify_file dumpleases # <--- useful for debugging
-
-# The following are bootp specific options, setable by udhcpd.
-
-#siaddr 192.168.0.22 #default: 0.0.0.0
-
-#sname zorak #default: (none)
-
-#boot_file /var/nfs_root #default: (none)
-
-# The remainder of options are DHCP options and can be specified with the
-# keyword 'opt' or 'option'. If an option can take multiple items, such
-# as the dns option, they can be listed on the same line, or multiple
-# lines. The only option with a default is 'lease'.
-
-#Examles
-opt dns 192.168.2.1
-option subnet 255.255.255.0
-option domain atherosowl.com
-option lease 864000 # 10 days of seconds
-
-
-# Currently supported options, for more info, see options.c
-#opt subnet
-#opt timezone
-#opt router
-#opt timesvr
-#opt namesvr
-#opt dns
-#opt logsvr
-#opt cookiesvr
-#opt lprsvr
-#opt bootsize
-#opt domain
-#opt swapsvr
-#opt rootpath
-#opt ipttl
-#opt mtu
-#opt broadcast
-#opt wins
-#opt lease
-#opt ntpsrv
-#opt tftp
-#opt bootfile
-
-
-# Static leases map
-#static_lease 00:60:08:11:CE:4E 192.168.0.54
-#static_lease 00:60:08:11:CE:3E 192.168.0.44
diff --git a/wpa_supplicant/examples/wep.conf b/wpa_supplicant/examples/wep.conf
deleted file mode 100644
index 9c7b55f2722a..000000000000
--- a/wpa_supplicant/examples/wep.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-# Static WEP keys
-
-ctrl_interface=/var/run/wpa_supplicant
-
-network={
- ssid="example wep network"
- key_mgmt=NONE
- wep_key0="abcde"
- wep_key1=0102030405
- wep_tx_keyidx=0
-}
diff --git a/wpa_supplicant/examples/wpa-psk-tkip.conf b/wpa_supplicant/examples/wpa-psk-tkip.conf
deleted file mode 100644
index 93d7fc2444ea..000000000000
--- a/wpa_supplicant/examples/wpa-psk-tkip.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-# WPA-PSK/TKIP
-
-ctrl_interface=/var/run/wpa_supplicant
-
-network={
- ssid="example wpa-psk network"
- key_mgmt=WPA-PSK
- proto=WPA
- pairwise=TKIP
- group=TKIP
- psk="secret passphrase"
-}
diff --git a/wpa_supplicant/examples/wpa2-eap-ccmp.conf b/wpa_supplicant/examples/wpa2-eap-ccmp.conf
deleted file mode 100644
index d7a64d87b254..000000000000
--- a/wpa_supplicant/examples/wpa2-eap-ccmp.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-# WPA2-EAP/CCMP using EAP-TLS
-
-ctrl_interface=/var/run/wpa_supplicant
-
-network={
- ssid="example wpa2-eap network"
- key_mgmt=WPA-EAP
- proto=WPA2
- pairwise=CCMP
- group=CCMP
- eap=TLS
- ca_cert="/etc/cert/ca.pem"
- private_key="/etc/cert/user.p12"
- private_key_passwd="PKCS#12 passhrase"
-}
diff --git a/wpa_supplicant/examples/wpas-dbus-new-getall.py b/wpa_supplicant/examples/wpas-dbus-new-getall.py
deleted file mode 100755
index 732f54d20f8b..000000000000
--- a/wpa_supplicant/examples/wpas-dbus-new-getall.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-import gobject
-
-def main():
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object("fi.w1.wpa_supplicant1",
- "/fi/w1/wpa_supplicant1")
- props = wpas_obj.GetAll("fi.w1.wpa_supplicant1",
- dbus_interface=dbus.PROPERTIES_IFACE)
- print("GetAll(fi.w1.wpa_supplicant1, /fi/w1/wpa_supplicant1):")
- print(props)
-
- if len(sys.argv) != 2:
- os._exit(1)
-
- ifname = sys.argv[1]
-
- wpas = dbus.Interface(wpas_obj, "fi.w1.wpa_supplicant1")
- path = wpas.GetInterface(ifname)
- if_obj = bus.get_object("fi.w1.wpa_supplicant1", path)
- props = if_obj.GetAll("fi.w1.wpa_supplicant1.Interface",
- dbus_interface=dbus.PROPERTIES_IFACE)
- print('')
- print("GetAll(fi.w1.wpa_supplicant1.Interface, %s):" % (path))
- print(props)
-
- props = if_obj.GetAll("fi.w1.wpa_supplicant1.Interface.WPS",
- dbus_interface=dbus.PROPERTIES_IFACE)
- print('')
- print("GetAll(fi.w1.wpa_supplicant1.Interface.WPS, %s):" % (path))
- print(props)
-
- res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'BSSs',
- dbus_interface=dbus.PROPERTIES_IFACE)
- if len(res) > 0:
- bss_obj = bus.get_object("fi.w1.wpa_supplicant1", res[0])
- props = bss_obj.GetAll("fi.w1.wpa_supplicant1.BSS",
- dbus_interface=dbus.PROPERTIES_IFACE)
- print('')
- print("GetAll(fi.w1.wpa_supplicant1.BSS, %s):" % (res[0]))
- print(props)
-
- res = if_obj.Get("fi.w1.wpa_supplicant1.Interface", 'Networks',
- dbus_interface=dbus.PROPERTIES_IFACE)
- if len(res) > 0:
- net_obj = bus.get_object("fi.w1.wpa_supplicant1", res[0])
- props = net_obj.GetAll("fi.w1.wpa_supplicant1.Network",
- dbus_interface=dbus.PROPERTIES_IFACE)
- print('')
- print("GetAll(fi.w1.wpa_supplicant1.Network, %s):" % (res[0]))
- print(props)
-
-if __name__ == "__main__":
- main()
diff --git a/wpa_supplicant/examples/wpas-dbus-new-signals.py b/wpa_supplicant/examples/wpas-dbus-new-signals.py
deleted file mode 100755
index 366a65546af6..000000000000
--- a/wpa_supplicant/examples/wpas-dbus-new-signals.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-import gobject
-from dbus.mainloop.glib import DBusGMainLoop
-
-WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1"
-
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface"
-WPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces"
-WPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS"
-WPAS_DBUS_NETWORK_INTERFACE = "fi.w1.wpa_supplicant1.Network"
-
-def byte_array_to_string(s):
- import urllib
- r = ""
- for c in s:
- if c >= 32 and c < 127:
- r += "%c" % c
- else:
- r += urllib.quote(chr(c))
- return r
-
-def list_interfaces(wpas_obj):
- ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces',
- dbus_interface=dbus.PROPERTIES_IFACE)
- for path in ifaces:
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname',
- dbus_interface=dbus.PROPERTIES_IFACE)
- print(ifname)
-
-def interfaceAdded(interface, properties):
- print("InterfaceAdded(%s): Ifname=%s" % (interface, properties['Ifname']))
-
-def interfaceRemoved(interface):
- print("InterfaceRemoved(%s)" % (interface))
-
-def propertiesChanged(properties):
- for i in properties:
- print("PropertiesChanged: %s=%s" % (i, properties[i]))
-
-def showBss(bss):
- net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss)
- net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE)
-
- # Convert the byte-array for SSID and BSSID to printable strings
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID',
- dbus_interface=dbus.PROPERTIES_IFACE)
- bssid = ""
- for item in val:
- bssid = bssid + ":%02x" % item
- bssid = bssid[1:]
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID',
- dbus_interface=dbus.PROPERTIES_IFACE)
- ssid = byte_array_to_string(val)
-
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA',
- dbus_interface=dbus.PROPERTIES_IFACE)
- wpa = "no"
- if val != None:
- wpa = "yes"
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN',
- dbus_interface=dbus.PROPERTIES_IFACE)
- wpa2 = "no"
- if val != None:
- wpa2 = "yes"
- freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency',
- dbus_interface=dbus.PROPERTIES_IFACE)
- signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal',
- dbus_interface=dbus.PROPERTIES_IFACE)
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates',
- dbus_interface=dbus.PROPERTIES_IFACE)
- if len(val) > 0:
- maxrate = val[0] / 1000000
- else:
- maxrate = 0
-
- print(" %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq))
-
-def scanDone(success):
- gobject.MainLoop().quit()
- print("Scan done: success=%s" % success)
-
-def scanDone2(success, path=None):
- print("Scan done: success=%s [path=%s]" % (success, path))
-
-def bssAdded(bss, properties):
- print("BSS added: %s" % (bss))
- showBss(bss)
-
-def bssRemoved(bss):
- print("BSS removed: %s" % (bss))
-
-def blobAdded(blob):
- print("BlobAdded(%s)" % (blob))
-
-def blobRemoved(blob):
- print("BlobRemoved(%s)" % (blob))
-
-def networkAdded(network, properties):
- print("NetworkAdded(%s)" % (network))
-
-def networkRemoved(network):
- print("NetworkRemoved(%s)" % (network))
-
-def networkSelected(network):
- print("NetworkSelected(%s)" % (network))
-
-def propertiesChangedInterface(properties):
- for i in properties:
- print("PropertiesChanged(interface): %s=%s" % (i, properties[i]))
-
-def propertiesChangedBss(properties):
- for i in properties:
- print("PropertiesChanged(BSS): %s=%s" % (i, properties[i]))
-
-def propertiesChangedNetwork(properties):
- for i in properties:
- print("PropertiesChanged(Network): %s=%s" % (i, properties[i]))
-
-def main():
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- global bus
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
-
- if len(sys.argv) != 2:
- list_interfaces(wpas_obj)
- os._exit(1)
-
- wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
- bus.add_signal_receiver(interfaceAdded,
- dbus_interface=WPAS_DBUS_INTERFACE,
- signal_name="InterfaceAdded")
- bus.add_signal_receiver(interfaceRemoved,
- dbus_interface=WPAS_DBUS_INTERFACE,
- signal_name="InterfaceRemoved")
- bus.add_signal_receiver(propertiesChanged,
- dbus_interface=WPAS_DBUS_INTERFACE,
- signal_name="PropertiesChanged")
-
- ifname = sys.argv[1]
- path = wpas.GetInterface(ifname)
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
- iface.connect_to_signal("ScanDone", scanDone2,
- path_keyword='path')
-
- bus.add_signal_receiver(scanDone,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="ScanDone",
- path=path)
- bus.add_signal_receiver(bssAdded,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSAdded",
- path=path)
- bus.add_signal_receiver(bssRemoved,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSRemoved",
- path=path)
- bus.add_signal_receiver(blobAdded,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BlobAdded",
- path=path)
- bus.add_signal_receiver(blobRemoved,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BlobRemoved",
- path=path)
- bus.add_signal_receiver(networkAdded,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="NetworkAdded",
- path=path)
- bus.add_signal_receiver(networkRemoved,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="NetworkRemoved",
- path=path)
- bus.add_signal_receiver(networkSelected,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="NetworkSelected",
- path=path)
- bus.add_signal_receiver(propertiesChangedInterface,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="PropertiesChanged",
- path=path)
-
- bus.add_signal_receiver(propertiesChangedBss,
- dbus_interface=WPAS_DBUS_BSS_INTERFACE,
- signal_name="PropertiesChanged")
-
- bus.add_signal_receiver(propertiesChangedNetwork,
- dbus_interface=WPAS_DBUS_NETWORK_INTERFACE,
- signal_name="PropertiesChanged")
-
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
- main()
-
diff --git a/wpa_supplicant/examples/wpas-dbus-new-wps.py b/wpa_supplicant/examples/wpas-dbus-new-wps.py
deleted file mode 100755
index 7d87b1efd5dc..000000000000
--- a/wpa_supplicant/examples/wpas-dbus-new-wps.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-import gobject
-from dbus.mainloop.glib import DBusGMainLoop
-
-WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1"
-
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface"
-WPAS_DBUS_WPS_INTERFACE = "fi.w1.wpa_supplicant1.Interface.WPS"
-
-def propertiesChanged(properties):
- if properties.has_key("State"):
- print("PropertiesChanged: State: %s" % (properties["State"]))
-
-def scanDone(success):
- print("Scan done: success=%s" % success)
-
-def bssAdded(bss, properties):
- print("BSS added: %s" % (bss))
-
-def bssRemoved(bss):
- print("BSS removed: %s" % (bss))
-
-def wpsEvent(name, args):
- print("WPS event: %s" % (name))
- print(args)
-
-def credentials(cred):
- print("WPS credentials: %s" % (cred))
-
-def main():
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- global bus
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
-
- if len(sys.argv) != 2:
- print("Missing ifname argument")
- os._exit(1)
-
- wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
- bus.add_signal_receiver(scanDone,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="ScanDone")
- bus.add_signal_receiver(bssAdded,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSAdded")
- bus.add_signal_receiver(bssRemoved,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSRemoved")
- bus.add_signal_receiver(propertiesChanged,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="PropertiesChanged")
- bus.add_signal_receiver(wpsEvent,
- dbus_interface=WPAS_DBUS_WPS_INTERFACE,
- signal_name="Event")
- bus.add_signal_receiver(credentials,
- dbus_interface=WPAS_DBUS_WPS_INTERFACE,
- signal_name="Credentials")
-
- ifname = sys.argv[1]
-
- path = wpas.GetInterface(ifname)
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- if_obj.Set(WPAS_DBUS_WPS_INTERFACE, 'ProcessCredentials',
- dbus.Boolean(1),
- dbus_interface=dbus.PROPERTIES_IFACE)
- wps = dbus.Interface(if_obj, WPAS_DBUS_WPS_INTERFACE)
- wps.Start({'Role': 'enrollee', 'Type': 'pbc'})
-
- gobject.MainLoop().run()
-
-if __name__ == "__main__":
- main()
-
diff --git a/wpa_supplicant/examples/wpas-dbus-new.py b/wpa_supplicant/examples/wpas-dbus-new.py
deleted file mode 100755
index 6bf74ae44122..000000000000
--- a/wpa_supplicant/examples/wpas-dbus-new.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-import sys, os
-import time
-import gobject
-from dbus.mainloop.glib import DBusGMainLoop
-
-WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1"
-WPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1"
-
-WPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface"
-WPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces"
-WPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS"
-
-def byte_array_to_string(s):
- import urllib
- r = ""
- for c in s:
- if c >= 32 and c < 127:
- r += "%c" % c
- else:
- r += urllib.quote(chr(c))
- return r
-
-def list_interfaces(wpas_obj):
- ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces',
- dbus_interface=dbus.PROPERTIES_IFACE)
- for path in ifaces:
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname',
- dbus_interface=dbus.PROPERTIES_IFACE)
- print(ifname)
-
-def propertiesChanged(properties):
- if properties.has_key("State"):
- print("PropertiesChanged: State: %s" % (properties["State"]))
-
-def showBss(bss):
- net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss)
- net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE)
-
- # Convert the byte-array for SSID and BSSID to printable strings
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID',
- dbus_interface=dbus.PROPERTIES_IFACE)
- bssid = ""
- for item in val:
- bssid = bssid + ":%02x" % item
- bssid = bssid[1:]
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID',
- dbus_interface=dbus.PROPERTIES_IFACE)
- ssid = byte_array_to_string(val)
-
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA',
- dbus_interface=dbus.PROPERTIES_IFACE)
- wpa = "no"
- if len(val["KeyMgmt"]) > 0:
- wpa = "yes"
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN',
- dbus_interface=dbus.PROPERTIES_IFACE)
- wpa2 = "no"
- if len(val["KeyMgmt"]) > 0:
- wpa2 = "yes"
- freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency',
- dbus_interface=dbus.PROPERTIES_IFACE)
- signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal',
- dbus_interface=dbus.PROPERTIES_IFACE)
- val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates',
- dbus_interface=dbus.PROPERTIES_IFACE)
- if len(val) > 0:
- maxrate = val[0] / 1000000
- else:
- maxrate = 0
-
- print(" %s :: ssid='%s' wpa=%s wpa2=%s signal=%d rate=%d freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq))
-
-def scanDone(success):
- print("Scan done: success=%s" % success)
-
- res = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'BSSs',
- dbus_interface=dbus.PROPERTIES_IFACE)
-
- print("Scanned wireless networks:")
- for opath in res:
- print(opath)
- showBss(opath)
-
-def bssAdded(bss, properties):
- print("BSS added: %s" % (bss))
- showBss(bss)
-
-def bssRemoved(bss):
- print("BSS removed: %s" % (bss))
-
-def main():
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- global bus
- bus = dbus.SystemBus()
- wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
-
- if len(sys.argv) != 2:
- list_interfaces(wpas_obj)
- os._exit(1)
-
- wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
- bus.add_signal_receiver(scanDone,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="ScanDone")
- bus.add_signal_receiver(bssAdded,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSAdded")
- bus.add_signal_receiver(bssRemoved,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="BSSRemoved")
- bus.add_signal_receiver(propertiesChanged,
- dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
- signal_name="PropertiesChanged")
-
- ifname = sys.argv[1]
-
- # See if wpa_supplicant already knows about this interface
- path = None
- try:
- path = wpas.GetInterface(ifname)
- except dbus.DBusException as exc:
- if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceUnknown:"):
- raise exc
- try:
- path = wpas.CreateInterface({'Ifname': ifname, 'Driver': 'test'})
- time.sleep(1)
-
- except dbus.DBusException as exc:
- if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceExists:"):
- raise exc
-
- global if_obj
- if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
- global iface
- iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
- iface.Scan({'Type': 'active'})
-
- gobject.MainLoop().run()
-
- wpas.RemoveInterface(dbus.ObjectPath(path))
-
-if __name__ == "__main__":
- main()
-
diff --git a/wpa_supplicant/examples/wps-ap-cli b/wpa_supplicant/examples/wps-ap-cli
deleted file mode 100755
index 15d913ef1fae..000000000000
--- a/wpa_supplicant/examples/wps-ap-cli
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh
-
-CLI=wpa_cli
-
-pbc()
-{
- echo "Starting PBC mode"
- echo "Push button on the station within two minutes"
- if ! $CLI wps_pbc | grep -q OK; then
- echo "Failed to enable PBC mode"
- fi
-}
-
-enter_pin()
-{
- echo "Enter a PIN from a station to be enrolled to the network."
- printf "Enrollee PIN: "
- read pin
- cpin=`$CLI wps_check_pin "$pin" | tail -1`
- if [ "$cpin" = "FAIL-CHECKSUM" ]; then
- echo "Checksum digit is not valid"
- printf "Do you want to use this PIN (y/n)? "
- read resp
- case "$resp" in
- y*)
- cpin=`echo "$pin" | sed "s/[^1234567890]//g"`
- ;;
- *)
- return 1
- ;;
- esac
- fi
- if [ "$cpin" = "FAIL" ]; then
- echo "Invalid PIN: $pin"
- return 1
- fi
- echo "Enabling Enrollee PIN: $cpin"
- $CLI wps_pin any "$cpin"
-}
-
-show_config()
-{
- $CLI status wps
-}
-
-main_menu()
-{
- echo "WPS AP"
- echo "------"
- echo "1: Push button (activate PBC)"
- echo "2: Enter Enrollee PIN"
- echo "3: Show current configuration"
- echo "0: Exit wps-ap-cli"
-
- printf "Command: "
- read cmd
-
- case "$cmd" in
- 1)
- pbc
- ;;
- 2)
- enter_pin
- ;;
- 3)
- show_config
- ;;
- 0)
- exit 0
- ;;
- *)
- echo "Unknown command: $cmd"
- ;;
- esac
-
- echo
- main_menu
-}
-
-
-main_menu
diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py
deleted file mode 100755
index bb458fb37a84..000000000000
--- a/wpa_supplicant/examples/wps-nfc.py
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/usr/bin/python
-#
-# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations
-# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import os
-import sys
-import time
-import random
-import threading
-import argparse
-
-import nfc
-import nfc.ndef
-import nfc.llcp
-import nfc.handover
-
-import logging
-
-import wpaspy
-
-wpas_ctrl = '/var/run/wpa_supplicant'
-srv = None
-continue_loop = True
-terminate_now = False
-summary_file = None
-success_file = None
-
-def summary(txt):
- print(txt)
- if summary_file:
- with open(summary_file, 'a') as f:
- f.write(txt + "\n")
-
-def success_report(txt):
- summary(txt)
- if success_file:
- with open(success_file, 'a') as f:
- f.write(txt + "\n")
-
-def wpas_connect():
- ifaces = []
- if os.path.isdir(wpas_ctrl):
- try:
- ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
- except OSError as error:
- print("Could not find wpa_supplicant: ", error)
- return None
-
- if len(ifaces) < 1:
- print("No wpa_supplicant control interface found")
- return None
-
- for ctrl in ifaces:
- try:
- wpas = wpaspy.Ctrl(ctrl)
- return wpas
- except Exception as e:
- pass
- return None
-
-
-def wpas_tag_read(message):
- wpas = wpas_connect()
- if (wpas == None):
- return False
- if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")):
- return False
- return True
-
-def wpas_get_config_token(id=None):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- if id:
- ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id)
- else:
- ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF")
- if "FAIL" in ret:
- return None
- return ret.rstrip().decode("hex")
-
-
-def wpas_get_er_config_token(uuid):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- ret = wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid)
- if "FAIL" in ret:
- return None
- return ret.rstrip().decode("hex")
-
-
-def wpas_get_password_token():
- wpas = wpas_connect()
- if (wpas == None):
- return None
- ret = wpas.request("WPS_NFC_TOKEN NDEF")
- if "FAIL" in ret:
- return None
- return ret.rstrip().decode("hex")
-
-def wpas_get_handover_req():
- wpas = wpas_connect()
- if (wpas == None):
- return None
- ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR")
- if "FAIL" in ret:
- return None
- return ret.rstrip().decode("hex")
-
-
-def wpas_get_handover_sel(uuid):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- if uuid is None:
- res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip()
- else:
- res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip()
- if "FAIL" in res:
- return None
- return res.decode("hex")
-
-
-def wpas_report_handover(req, sel, type):
- wpas = wpas_connect()
- if (wpas == None):
- return None
- return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " +
- str(req).encode("hex") + " " +
- str(sel).encode("hex"))
-
-
-class HandoverServer(nfc.handover.HandoverServer):
- def __init__(self, llc):
- super(HandoverServer, self).__init__(llc)
- self.sent_carrier = None
- self.ho_server_processing = False
- self.success = False
-
- # override to avoid parser error in request/response.pretty() in nfcpy
- # due to new WSC handover format
- def _process_request(self, request):
- summary("received handover request {}".format(request.type))
- response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
- if not request.type == 'urn:nfc:wkt:Hr':
- summary("not a handover request")
- else:
- try:
- request = nfc.ndef.HandoverRequestMessage(request)
- except nfc.ndef.DecodeError as e:
- summary("error decoding 'Hr' message: {}".format(e))
- else:
- response = self.process_request(request)
- summary("send handover response {}".format(response.type))
- return response
-
- def process_request(self, request):
- self.ho_server_processing = True
- summary("HandoverServer - request received")
- try:
- print("Parsed handover request: " + request.pretty())
- except Exception as e:
- print(e)
-
- sel = nfc.ndef.HandoverSelectMessage(version="1.2")
-
- for carrier in request.carriers:
- print("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.wsc":
- summary("WPS carrier type match - add WPS carrier record")
- data = wpas_get_handover_sel(self.uuid)
- if data is None:
- summary("Could not get handover select carrier record from wpa_supplicant")
- continue
- print("Handover select carrier record from wpa_supplicant:")
- print(data.encode("hex"))
- self.sent_carrier = data
- if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"):
- success_report("Handover reported successfully (responder)")
- else:
- summary("Handover report rejected (responder)")
-
- message = nfc.ndef.Message(data);
- sel.add_carrier(message[0], "active", message[1:])
-
- print("Handover select:")
- try:
- print(sel.pretty())
- except Exception as e:
- print(e)
- print(str(sel).encode("hex"))
-
- summary("Sending handover select")
- self.success = True
- return sel
-
-
-def wps_handover_init(llc):
- summary("Trying to initiate WPS handover")
-
- data = wpas_get_handover_req()
- if (data == None):
- summary("Could not get handover request carrier record from wpa_supplicant")
- return
- print("Handover request carrier record from wpa_supplicant: " + data.encode("hex"))
-
- message = nfc.ndef.HandoverRequestMessage(version="1.2")
- message.nonce = random.randint(0, 0xffff)
- datamsg = nfc.ndef.Message(data)
- message.add_carrier(datamsg[0], "active", datamsg[1:])
-
- print("Handover request:")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
- print(str(message).encode("hex"))
-
- client = nfc.handover.HandoverClient(llc)
- try:
- summary("Trying to initiate NFC connection handover")
- client.connect()
- summary("Connected for handover")
- except nfc.llcp.ConnectRefused:
- summary("Handover connection refused")
- client.close()
- return
- except Exception as e:
- summary("Other exception: " + str(e))
- client.close()
- return
-
- summary("Sending handover request")
-
- if not client.send(message):
- summary("Failed to send handover request")
- client.close()
- return
-
- summary("Receiving handover response")
- message = client._recv()
- if message is None:
- summary("No response received")
- client.close()
- return
- if message.type != "urn:nfc:wkt:Hs":
- summary("Response was not Hs - received: " + message.type)
- client.close()
- return
-
- print("Received message")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
- print(str(message).encode("hex"))
- message = nfc.ndef.HandoverSelectMessage(message)
- summary("Handover select received")
- try:
- print(message.pretty())
- except Exception as e:
- print(e)
-
- for carrier in message.carriers:
- print("Remote carrier type: " + carrier.type)
- if carrier.type == "application/vnd.wfa.wsc":
- print("WPS carrier type match - send to wpa_supplicant")
- if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
- success_report("Handover reported successfully (initiator)")
- else:
- summary("Handover report rejected (initiator)")
- # nfcpy does not support the new format..
- #wifi = nfc.ndef.WifiConfigRecord(carrier.record)
- #print wifi.pretty()
-
- print("Remove peer")
- client.close()
- print("Done with handover")
- global only_one
- if only_one:
- global continue_loop
- continue_loop = False
-
- global no_wait
- if no_wait:
- print("Trying to exit..")
- global terminate_now
- terminate_now = True
-
-def wps_tag_read(tag, wait_remove=True):
- success = False
- if len(tag.ndef.message):
- for record in tag.ndef.message:
- print("record type " + record.type)
- if record.type == "application/vnd.wfa.wsc":
- summary("WPS tag - send to wpa_supplicant")
- success = wpas_tag_read(tag.ndef.message)
- break
- else:
- summary("Empty tag")
-
- if success:
- success_report("Tag read succeeded")
-
- if wait_remove:
- print("Remove tag")
- while tag.is_present:
- time.sleep(0.1)
-
- return success
-
-
-def rdwr_connected_write(tag):
- summary("Tag found - writing - " + str(tag))
- global write_data
- tag.ndef.message = str(write_data)
- success_report("Tag write succeeded")
- print("Done - remove tag")
- global only_one
- if only_one:
- global continue_loop
- continue_loop = False
- global write_wait_remove
- while write_wait_remove and tag.is_present:
- time.sleep(0.1)
-
-def wps_write_config_tag(clf, id=None, wait_remove=True):
- print("Write WPS config token")
- global write_data, write_wait_remove
- write_wait_remove = wait_remove
- write_data = wpas_get_config_token(id)
- if write_data == None:
- print("Could not get WPS config token from wpa_supplicant")
- sys.exit(1)
- return
- print("Touch an NFC tag")
- clf.connect(rdwr={'on-connect': rdwr_connected_write})
-
-
-def wps_write_er_config_tag(clf, uuid, wait_remove=True):
- print("Write WPS ER config token")
- global write_data, write_wait_remove
- write_wait_remove = wait_remove
- write_data = wpas_get_er_config_token(uuid)
- if write_data == None:
- print("Could not get WPS config token from wpa_supplicant")
- return
-
- print("Touch an NFC tag")
- clf.connect(rdwr={'on-connect': rdwr_connected_write})
-
-
-def wps_write_password_tag(clf, wait_remove=True):
- print("Write WPS password token")
- global write_data, write_wait_remove
- write_wait_remove = wait_remove
- write_data = wpas_get_password_token()
- if write_data == None:
- print("Could not get WPS password token from wpa_supplicant")
- return
-
- print("Touch an NFC tag")
- clf.connect(rdwr={'on-connect': rdwr_connected_write})
-
-
-def rdwr_connected(tag):
- global only_one, no_wait
- summary("Tag connected: " + str(tag))
-
- if tag.ndef:
- print("NDEF tag: " + tag.type)
- try:
- print(tag.ndef.message.pretty())
- except Exception as e:
- print(e)
- success = wps_tag_read(tag, not only_one)
- if only_one and success:
- global continue_loop
- continue_loop = False
- else:
- summary("Not an NDEF tag - remove tag")
- return True
-
- return not no_wait
-
-
-def llcp_worker(llc):
- global arg_uuid
- if arg_uuid is None:
- wps_handover_init(llc)
- print("Exiting llcp_worker thread")
- return
-
- global srv
- global wait_connection
- while not wait_connection and srv.sent_carrier is None:
- if srv.ho_server_processing:
- time.sleep(0.025)
-
-def llcp_startup(clf, llc):
- global arg_uuid
- if arg_uuid:
- print("Start LLCP server")
- global srv
- srv = HandoverServer(llc)
- if arg_uuid is "ap":
- print("Trying to handle WPS handover")
- srv.uuid = None
- else:
- print("Trying to handle WPS handover with AP " + arg_uuid)
- srv.uuid = arg_uuid
- return llc
-
-def llcp_connected(llc):
- print("P2P LLCP connected")
- global wait_connection
- wait_connection = False
- global arg_uuid
- if arg_uuid:
- global srv
- srv.start()
- else:
- threading.Thread(target=llcp_worker, args=(llc,)).start()
- print("llcp_connected returning")
- return True
-
-
-def terminate_loop():
- global terminate_now
- return terminate_now
-
-def main():
- clf = nfc.ContactlessFrontend()
-
- parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for WPS NFC operations')
- parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
- action='store_const', dest='loglevel',
- help='verbose debug output')
- parser.add_argument('-q', const=logging.WARNING, action='store_const',
- dest='loglevel', help='be quiet')
- parser.add_argument('--only-one', '-1', action='store_true',
- help='run only one operation and exit')
- parser.add_argument('--no-wait', action='store_true',
- help='do not wait for tag to be removed before exiting')
- parser.add_argument('--uuid',
- help='UUID of an AP (used for WPS ER operations)')
- parser.add_argument('--id',
- help='network id (used for WPS ER operations)')
- parser.add_argument('--summary',
- help='summary file for writing status updates')
- parser.add_argument('--success',
- help='success file for writing success update')
- parser.add_argument('command', choices=['write-config',
- 'write-er-config',
- 'write-password'],
- nargs='?')
- args = parser.parse_args()
-
- global arg_uuid
- arg_uuid = args.uuid
-
- global only_one
- only_one = args.only_one
-
- global no_wait
- no_wait = args.no_wait
-
- if args.summary:
- global summary_file
- summary_file = args.summary
-
- if args.success:
- global success_file
- success_file = args.success
-
- logging.basicConfig(level=args.loglevel)
-
- try:
- if not clf.open("usb"):
- print("Could not open connection with an NFC device")
- raise SystemExit
-
- if args.command == "write-config":
- wps_write_config_tag(clf, id=args.id, wait_remove=not args.no_wait)
- raise SystemExit
-
- if args.command == "write-er-config":
- wps_write_er_config_tag(clf, args.uuid, wait_remove=not args.no_wait)
- raise SystemExit
-
- if args.command == "write-password":
- wps_write_password_tag(clf, wait_remove=not args.no_wait)
- raise SystemExit
-
- global continue_loop
- while continue_loop:
- print("Waiting for a tag or peer to be touched")
- wait_connection = True
- try:
- if not clf.connect(rdwr={'on-connect': rdwr_connected},
- llcp={'on-startup': llcp_startup,
- 'on-connect': llcp_connected},
- terminate=terminate_loop):
- break
- except Exception as e:
- print("clf.connect failed")
-
- global srv
- if only_one and srv and srv.success:
- raise SystemExit
-
- except KeyboardInterrupt:
- raise SystemExit
- finally:
- clf.close()
-
- raise SystemExit
-
-if __name__ == '__main__':
- main()
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
deleted file mode 100644
index a6172d69233b..000000000000
--- a/wpa_supplicant/gas_query.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * Generic advertisement service (GAS) query
- * Copyright (c) 2009, Atheros Communications
- * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
- * Copyright (c) 2011-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_defs.h"
-#include "common/gas.h"
-#include "common/wpa_ctrl.h"
-#include "rsn_supp/wpa.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "driver_i.h"
-#include "offchannel.h"
-#include "gas_query.h"
-
-
-/** GAS query timeout in seconds */
-#define GAS_QUERY_TIMEOUT_PERIOD 2
-
-/* GAS query wait-time / duration in ms */
-#define GAS_QUERY_WAIT_TIME_INITIAL 1000
-#define GAS_QUERY_WAIT_TIME_COMEBACK 150
-
-/**
- * struct gas_query_pending - Pending GAS query
- */
-struct gas_query_pending {
- struct dl_list list;
- struct gas_query *gas;
- u8 addr[ETH_ALEN];
- u8 dialog_token;
- u8 next_frag_id;
- unsigned int wait_comeback:1;
- unsigned int offchannel_tx_started:1;
- unsigned int retry:1;
- unsigned int wildcard_bssid:1;
- unsigned int maintain_addr:1;
- int freq;
- u16 status_code;
- struct wpabuf *req;
- struct wpabuf *adv_proto;
- struct wpabuf *resp;
- struct os_reltime last_oper;
- void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code);
- void *ctx;
- u8 sa[ETH_ALEN];
-};
-
-/**
- * struct gas_query - Internal GAS query data
- */
-struct gas_query {
- struct wpa_supplicant *wpa_s;
- struct dl_list pending; /* struct gas_query_pending */
- struct gas_query_pending *current;
- struct wpa_radio_work *work;
- struct os_reltime last_mac_addr_rand;
- int last_rand_sa_type;
- u8 rand_addr[ETH_ALEN];
-};
-
-
-static void gas_query_tx_comeback_timeout(void *eloop_data, void *user_ctx);
-static void gas_query_timeout(void *eloop_data, void *user_ctx);
-static void gas_query_rx_comeback_timeout(void *eloop_data, void *user_ctx);
-static void gas_query_tx_initial_req(struct gas_query *gas,
- struct gas_query_pending *query);
-static int gas_query_new_dialog_token(struct gas_query *gas, const u8 *dst);
-
-
-static int ms_from_time(struct os_reltime *last)
-{
- struct os_reltime now, res;
-
- os_get_reltime(&now);
- os_reltime_sub(&now, last, &res);
- return res.sec * 1000 + res.usec / 1000;
-}
-
-
-/**
- * gas_query_init - Initialize GAS query component
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: Pointer to GAS query data or %NULL on failure
- */
-struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s)
-{
- struct gas_query *gas;
-
- gas = os_zalloc(sizeof(*gas));
- if (gas == NULL)
- return NULL;
-
- gas->wpa_s = wpa_s;
- dl_list_init(&gas->pending);
-
- return gas;
-}
-
-
-static const char * gas_result_txt(enum gas_query_result result)
-{
- switch (result) {
- case GAS_QUERY_SUCCESS:
- return "SUCCESS";
- case GAS_QUERY_FAILURE:
- return "FAILURE";
- case GAS_QUERY_TIMEOUT:
- return "TIMEOUT";
- case GAS_QUERY_PEER_ERROR:
- return "PEER_ERROR";
- case GAS_QUERY_INTERNAL_ERROR:
- return "INTERNAL_ERROR";
- case GAS_QUERY_STOPPED:
- return "STOPPED";
- case GAS_QUERY_DELETED_AT_DEINIT:
- return "DELETED_AT_DEINIT";
- }
-
- return "N/A";
-}
-
-
-static void gas_query_free(struct gas_query_pending *query, int del_list)
-{
- struct gas_query *gas = query->gas;
-
- if (del_list)
- dl_list_del(&query->list);
-
- if (gas->work && gas->work->ctx == query) {
- radio_work_done(gas->work);
- gas->work = NULL;
- }
-
- wpabuf_free(query->req);
- wpabuf_free(query->adv_proto);
- wpabuf_free(query->resp);
- os_free(query);
-}
-
-
-static void gas_query_done(struct gas_query *gas,
- struct gas_query_pending *query,
- enum gas_query_result result)
-{
- wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_DONE "addr=" MACSTR
- " dialog_token=%u freq=%d status_code=%u result=%s",
- MAC2STR(query->addr), query->dialog_token, query->freq,
- query->status_code, gas_result_txt(result));
- if (gas->current == query)
- gas->current = NULL;
- if (query->offchannel_tx_started)
- offchannel_send_action_done(gas->wpa_s);
- eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
- eloop_cancel_timeout(gas_query_timeout, gas, query);
- eloop_cancel_timeout(gas_query_rx_comeback_timeout, gas, query);
- dl_list_del(&query->list);
- query->cb(query->ctx, query->addr, query->dialog_token, result,
- query->adv_proto, query->resp, query->status_code);
- gas_query_free(query, 0);
-}
-
-
-/**
- * gas_query_deinit - Deinitialize GAS query component
- * @gas: GAS query data from gas_query_init()
- */
-void gas_query_deinit(struct gas_query *gas)
-{
- struct gas_query_pending *query, *next;
-
- if (gas == NULL)
- return;
-
- dl_list_for_each_safe(query, next, &gas->pending,
- struct gas_query_pending, list)
- gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
-
- os_free(gas);
-}
-
-
-static struct gas_query_pending *
-gas_query_get_pending(struct gas_query *gas, const u8 *addr, u8 dialog_token)
-{
- struct gas_query_pending *q;
- dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
- if (os_memcmp(q->addr, addr, ETH_ALEN) == 0 &&
- q->dialog_token == dialog_token)
- return q;
- }
- return NULL;
-}
-
-
-static int gas_query_append(struct gas_query_pending *query, const u8 *data,
- size_t len)
-{
- if (wpabuf_resize(&query->resp, len) < 0) {
- wpa_printf(MSG_DEBUG, "GAS: No memory to store the response");
- return -1;
- }
- wpabuf_put_data(query->resp, data, len);
- return 0;
-}
-
-
-static void gas_query_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- struct gas_query_pending *query;
- struct gas_query *gas = wpa_s->gas;
- int dur;
-
- if (gas->current == NULL) {
- wpa_printf(MSG_DEBUG, "GAS: Unexpected TX status: freq=%u dst="
- MACSTR " result=%d - no query in progress",
- freq, MAC2STR(dst), result);
- return;
- }
-
- query = gas->current;
-
- dur = ms_from_time(&query->last_oper);
- wpa_printf(MSG_DEBUG, "GAS: TX status: freq=%u dst=" MACSTR
- " result=%d query=%p dialog_token=%u dur=%d ms",
- freq, MAC2STR(dst), result, query, query->dialog_token, dur);
- if (os_memcmp(dst, query->addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "GAS: TX status for unexpected destination");
- return;
- }
- os_get_reltime(&query->last_oper);
-
- if (result == OFFCHANNEL_SEND_ACTION_SUCCESS ||
- result == OFFCHANNEL_SEND_ACTION_NO_ACK) {
- eloop_cancel_timeout(gas_query_timeout, gas, query);
- if (result == OFFCHANNEL_SEND_ACTION_NO_ACK) {
- wpa_printf(MSG_DEBUG, "GAS: No ACK to GAS request");
- eloop_register_timeout(0, 250000,
- gas_query_timeout, gas, query);
- } else {
- eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0,
- gas_query_timeout, gas, query);
- }
- if (query->wait_comeback && !query->retry) {
- eloop_cancel_timeout(gas_query_rx_comeback_timeout,
- gas, query);
- eloop_register_timeout(
- 0, (GAS_QUERY_WAIT_TIME_COMEBACK + 10) * 1000,
- gas_query_rx_comeback_timeout, gas, query);
- }
- }
- if (result == OFFCHANNEL_SEND_ACTION_FAILED) {
- eloop_cancel_timeout(gas_query_timeout, gas, query);
- eloop_register_timeout(0, 0, gas_query_timeout, gas, query);
- }
-}
-
-
-static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
- struct wpabuf *req, unsigned int wait_time)
-{
- int res, prot = pmf_in_use(gas->wpa_s, query->addr);
- const u8 *bssid;
- const u8 wildcard_bssid[ETH_ALEN] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
-
- wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
- "freq=%d prot=%d using src addr " MACSTR,
- MAC2STR(query->addr), (unsigned int) wpabuf_len(req),
- query->freq, prot, MAC2STR(query->sa));
- if (prot) {
- u8 *categ = wpabuf_mhead_u8(req);
- *categ = WLAN_ACTION_PROTECTED_DUAL;
- }
- os_get_reltime(&query->last_oper);
- if (gas->wpa_s->max_remain_on_chan &&
- wait_time > gas->wpa_s->max_remain_on_chan)
- wait_time = gas->wpa_s->max_remain_on_chan;
- if (!query->wildcard_bssid &&
- (!gas->wpa_s->conf->gas_address3 ||
- (gas->wpa_s->current_ssid &&
- gas->wpa_s->wpa_state >= WPA_ASSOCIATED &&
- os_memcmp(query->addr, gas->wpa_s->bssid, ETH_ALEN) == 0)))
- bssid = query->addr;
- else
- bssid = wildcard_bssid;
-
- res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
- query->sa, bssid, wpabuf_head(req),
- wpabuf_len(req), wait_time,
- gas_query_tx_status, 0);
-
- if (res == 0)
- query->offchannel_tx_started = 1;
- return res;
-}
-
-
-static void gas_query_tx_comeback_req(struct gas_query *gas,
- struct gas_query_pending *query)
-{
- struct wpabuf *req;
- unsigned int wait_time;
-
- req = gas_build_comeback_req(query->dialog_token);
- if (req == NULL) {
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- return;
- }
-
- wait_time = (query->retry || !query->offchannel_tx_started) ?
- GAS_QUERY_WAIT_TIME_INITIAL : GAS_QUERY_WAIT_TIME_COMEBACK;
-
- if (gas_query_tx(gas, query, req, wait_time) < 0) {
- wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
- MACSTR, MAC2STR(query->addr));
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- }
-
- wpabuf_free(req);
-}
-
-
-static void gas_query_rx_comeback_timeout(void *eloop_data, void *user_ctx)
-{
- struct gas_query *gas = eloop_data;
- struct gas_query_pending *query = user_ctx;
- int dialog_token;
-
- wpa_printf(MSG_DEBUG,
- "GAS: No response to comeback request received (retry=%u)",
- query->retry);
- if (gas->current != query || query->retry)
- return;
- dialog_token = gas_query_new_dialog_token(gas, query->addr);
- if (dialog_token < 0)
- return;
- wpa_printf(MSG_DEBUG,
- "GAS: Retry GAS query due to comeback response timeout");
- query->retry = 1;
- query->dialog_token = dialog_token;
- *(wpabuf_mhead_u8(query->req) + 2) = dialog_token;
- query->wait_comeback = 0;
- query->next_frag_id = 0;
- wpabuf_free(query->adv_proto);
- query->adv_proto = NULL;
- eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
- eloop_cancel_timeout(gas_query_timeout, gas, query);
- gas_query_tx_initial_req(gas, query);
-}
-
-
-static void gas_query_tx_comeback_timeout(void *eloop_data, void *user_ctx)
-{
- struct gas_query *gas = eloop_data;
- struct gas_query_pending *query = user_ctx;
-
- wpa_printf(MSG_DEBUG, "GAS: Comeback timeout for request to " MACSTR,
- MAC2STR(query->addr));
- gas_query_tx_comeback_req(gas, query);
-}
-
-
-static void gas_query_tx_comeback_req_delay(struct gas_query *gas,
- struct gas_query_pending *query,
- u16 comeback_delay)
-{
- unsigned int secs, usecs;
-
- if (comeback_delay > 1 && query->offchannel_tx_started) {
- offchannel_send_action_done(gas->wpa_s);
- query->offchannel_tx_started = 0;
- }
-
- secs = (comeback_delay * 1024) / 1000000;
- usecs = comeback_delay * 1024 - secs * 1000000;
- wpa_printf(MSG_DEBUG, "GAS: Send comeback request to " MACSTR
- " in %u secs %u usecs", MAC2STR(query->addr), secs, usecs);
- eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
- eloop_register_timeout(secs, usecs, gas_query_tx_comeback_timeout,
- gas, query);
-}
-
-
-static void gas_query_rx_initial(struct gas_query *gas,
- struct gas_query_pending *query,
- const u8 *adv_proto, const u8 *resp,
- size_t len, u16 comeback_delay)
-{
- wpa_printf(MSG_DEBUG, "GAS: Received initial response from "
- MACSTR " (dialog_token=%u comeback_delay=%u)",
- MAC2STR(query->addr), query->dialog_token, comeback_delay);
-
- query->adv_proto = wpabuf_alloc_copy(adv_proto, 2 + adv_proto[1]);
- if (query->adv_proto == NULL) {
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- return;
- }
-
- if (comeback_delay) {
- eloop_cancel_timeout(gas_query_timeout, gas, query);
- query->wait_comeback = 1;
- gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
- return;
- }
-
- /* Query was completed without comeback mechanism */
- if (gas_query_append(query, resp, len) < 0) {
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- return;
- }
-
- gas_query_done(gas, query, GAS_QUERY_SUCCESS);
-}
-
-
-static void gas_query_rx_comeback(struct gas_query *gas,
- struct gas_query_pending *query,
- const u8 *adv_proto, const u8 *resp,
- size_t len, u8 frag_id, u8 more_frags,
- u16 comeback_delay)
-{
- wpa_printf(MSG_DEBUG, "GAS: Received comeback response from "
- MACSTR " (dialog_token=%u frag_id=%u more_frags=%u "
- "comeback_delay=%u)",
- MAC2STR(query->addr), query->dialog_token, frag_id,
- more_frags, comeback_delay);
- eloop_cancel_timeout(gas_query_rx_comeback_timeout, gas, query);
-
- if ((size_t) 2 + adv_proto[1] != wpabuf_len(query->adv_proto) ||
- os_memcmp(adv_proto, wpabuf_head(query->adv_proto),
- wpabuf_len(query->adv_proto)) != 0) {
- wpa_printf(MSG_DEBUG, "GAS: Advertisement Protocol changed "
- "between initial and comeback response from "
- MACSTR, MAC2STR(query->addr));
- gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
- return;
- }
-
- if (comeback_delay) {
- if (frag_id) {
- wpa_printf(MSG_DEBUG, "GAS: Invalid comeback response "
- "with non-zero frag_id and comeback_delay "
- "from " MACSTR, MAC2STR(query->addr));
- gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
- return;
- }
- gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
- return;
- }
-
- if (frag_id != query->next_frag_id) {
- wpa_printf(MSG_DEBUG, "GAS: Unexpected frag_id in response "
- "from " MACSTR, MAC2STR(query->addr));
- if (frag_id + 1 == query->next_frag_id) {
- wpa_printf(MSG_DEBUG, "GAS: Drop frame as possible "
- "retry of previous fragment");
- return;
- }
- gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
- return;
- }
- query->next_frag_id++;
-
- if (gas_query_append(query, resp, len) < 0) {
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- return;
- }
-
- if (more_frags) {
- gas_query_tx_comeback_req(gas, query);
- return;
- }
-
- gas_query_done(gas, query, GAS_QUERY_SUCCESS);
-}
-
-
-/**
- * gas_query_rx - Indicate reception of a Public Action or Protected Dual frame
- * @gas: GAS query data from gas_query_init()
- * @da: Destination MAC address of the Action frame
- * @sa: Source MAC address of the Action frame
- * @bssid: BSSID of the Action frame
- * @categ: Category of the Action frame
- * @data: Payload of the Action frame
- * @len: Length of @data
- * @freq: Frequency (in MHz) on which the frame was received
- * Returns: 0 if the Public Action frame was a GAS frame or -1 if not
- */
-int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
- const u8 *bssid, u8 categ, const u8 *data, size_t len,
- int freq)
-{
- struct gas_query_pending *query;
- u8 action, dialog_token, frag_id = 0, more_frags = 0;
- u16 comeback_delay, resp_len;
- const u8 *pos, *adv_proto;
- int prot, pmf;
- unsigned int left;
-
- if (gas == NULL || len < 4)
- return -1;
-
- pos = data;
- action = *pos++;
- dialog_token = *pos++;
-
- if (action != WLAN_PA_GAS_INITIAL_RESP &&
- action != WLAN_PA_GAS_COMEBACK_RESP)
- return -1; /* Not a GAS response */
-
- prot = categ == WLAN_ACTION_PROTECTED_DUAL;
- pmf = pmf_in_use(gas->wpa_s, sa);
- if (prot && !pmf) {
- wpa_printf(MSG_DEBUG, "GAS: Drop unexpected protected GAS frame when PMF is disabled");
- return 0;
- }
- if (!prot && pmf) {
- wpa_printf(MSG_DEBUG, "GAS: Drop unexpected unprotected GAS frame when PMF is enabled");
- return 0;
- }
-
- query = gas_query_get_pending(gas, sa, dialog_token);
- if (query == NULL) {
- wpa_printf(MSG_DEBUG, "GAS: No pending query found for " MACSTR
- " dialog token %u", MAC2STR(sa), dialog_token);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "GAS: Response in %d ms from " MACSTR,
- ms_from_time(&query->last_oper), MAC2STR(sa));
-
- if (query->wait_comeback && action == WLAN_PA_GAS_INITIAL_RESP) {
- wpa_printf(MSG_DEBUG, "GAS: Unexpected initial response from "
- MACSTR " dialog token %u when waiting for comeback "
- "response", MAC2STR(sa), dialog_token);
- return 0;
- }
-
- if (!query->wait_comeback && action == WLAN_PA_GAS_COMEBACK_RESP) {
- wpa_printf(MSG_DEBUG, "GAS: Unexpected comeback response from "
- MACSTR " dialog token %u when waiting for initial "
- "response", MAC2STR(sa), dialog_token);
- return 0;
- }
-
- query->status_code = WPA_GET_LE16(pos);
- pos += 2;
-
- if (query->status_code == WLAN_STATUS_QUERY_RESP_OUTSTANDING &&
- action == WLAN_PA_GAS_COMEBACK_RESP) {
- wpa_printf(MSG_DEBUG, "GAS: Allow non-zero status for outstanding comeback response");
- } else if (query->status_code != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "GAS: Query to " MACSTR " dialog token "
- "%u failed - status code %u",
- MAC2STR(sa), dialog_token, query->status_code);
- gas_query_done(gas, query, GAS_QUERY_FAILURE);
- return 0;
- }
-
- if (action == WLAN_PA_GAS_COMEBACK_RESP) {
- if (pos + 1 > data + len)
- return 0;
- frag_id = *pos & 0x7f;
- more_frags = (*pos & 0x80) >> 7;
- pos++;
- }
-
- /* Comeback Delay */
- if (pos + 2 > data + len)
- return 0;
- comeback_delay = WPA_GET_LE16(pos);
- pos += 2;
-
- /* Advertisement Protocol element */
- if (pos + 2 > data + len || pos + 2 + pos[1] > data + len) {
- wpa_printf(MSG_DEBUG, "GAS: No room for Advertisement "
- "Protocol element in the response from " MACSTR,
- MAC2STR(sa));
- return 0;
- }
-
- if (*pos != WLAN_EID_ADV_PROTO) {
- wpa_printf(MSG_DEBUG, "GAS: Unexpected Advertisement "
- "Protocol element ID %u in response from " MACSTR,
- *pos, MAC2STR(sa));
- return 0;
- }
-
- adv_proto = pos;
- pos += 2 + pos[1];
-
- /* Query Response Length */
- if (pos + 2 > data + len) {
- wpa_printf(MSG_DEBUG, "GAS: No room for GAS Response Length");
- return 0;
- }
- resp_len = WPA_GET_LE16(pos);
- pos += 2;
-
- left = data + len - pos;
- if (resp_len > left) {
- wpa_printf(MSG_DEBUG, "GAS: Truncated Query Response in "
- "response from " MACSTR, MAC2STR(sa));
- return 0;
- }
-
- if (resp_len < left) {
- wpa_printf(MSG_DEBUG, "GAS: Ignore %u octets of extra data "
- "after Query Response from " MACSTR,
- left - resp_len, MAC2STR(sa));
- }
-
- if (action == WLAN_PA_GAS_COMEBACK_RESP)
- gas_query_rx_comeback(gas, query, adv_proto, pos, resp_len,
- frag_id, more_frags, comeback_delay);
- else
- gas_query_rx_initial(gas, query, adv_proto, pos, resp_len,
- comeback_delay);
-
- return 0;
-}
-
-
-static void gas_query_timeout(void *eloop_data, void *user_ctx)
-{
- struct gas_query *gas = eloop_data;
- struct gas_query_pending *query = user_ctx;
-
- wpa_printf(MSG_DEBUG, "GAS: No response received for query to " MACSTR
- " dialog token %u",
- MAC2STR(query->addr), query->dialog_token);
- gas_query_done(gas, query, GAS_QUERY_TIMEOUT);
-}
-
-
-static int gas_query_dialog_token_available(struct gas_query *gas,
- const u8 *dst, u8 dialog_token)
-{
- struct gas_query_pending *q;
- dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
- if (os_memcmp(dst, q->addr, ETH_ALEN) == 0 &&
- dialog_token == q->dialog_token)
- return 0;
- }
-
- return 1;
-}
-
-
-static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
-{
- struct gas_query_pending *query = work->ctx;
- struct gas_query *gas = query->gas;
- struct wpa_supplicant *wpa_s = gas->wpa_s;
-
- if (deinit) {
- if (work->started) {
- gas->work = NULL;
- gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
- return;
- }
-
- gas_query_free(query, 1);
- return;
- }
-
- if (!query->maintain_addr && !wpa_s->conf->gas_rand_mac_addr) {
- if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to assign random MAC address for GAS");
- gas_query_free(query, 1);
- radio_work_done(work);
- return;
- }
- os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN);
- }
-
- gas->work = work;
- gas_query_tx_initial_req(gas, query);
-}
-
-
-static void gas_query_tx_initial_req(struct gas_query *gas,
- struct gas_query_pending *query)
-{
- if (gas_query_tx(gas, query, query->req,
- GAS_QUERY_WAIT_TIME_INITIAL) < 0) {
- wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
- MACSTR, MAC2STR(query->addr));
- gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
- return;
- }
- gas->current = query;
-
- wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u",
- query->dialog_token);
- eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0,
- gas_query_timeout, gas, query);
-}
-
-
-static int gas_query_new_dialog_token(struct gas_query *gas, const u8 *dst)
-{
- u8 dialog_token;
- int i;
-
- /* There should never be more than couple active GAS queries in
- * progress, so it should be very likely to find an available dialog
- * token by checking random values. Use a limit on the number of
- * iterations to handle the unexpected case of large number of pending
- * queries cleanly. */
- for (i = 0; i < 256; i++) {
- /* Get a random number and check if the slot is available */
- if (os_get_random(&dialog_token, sizeof(dialog_token)) < 0)
- break;
- if (gas_query_dialog_token_available(gas, dst, dialog_token))
- return dialog_token;
- }
-
- /* No dialog token value available */
- return -1;
-}
-
-
-static int gas_query_set_sa(struct gas_query *gas,
- struct gas_query_pending *query)
-{
- struct wpa_supplicant *wpa_s = gas->wpa_s;
- struct os_reltime now;
-
- if (query->maintain_addr ||
- !wpa_s->conf->gas_rand_mac_addr ||
- !(wpa_s->current_bss ?
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) :
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA))) {
- /* Use own MAC address as the transmitter address */
- wpa_printf(MSG_DEBUG,
- "GAS: Use own MAC address as the transmitter address%s%s%s",
- query->maintain_addr ? " (maintain_addr)" : "",
- !wpa_s->conf->gas_rand_mac_addr ? " (no gas_rand_mac_adr set)" : "",
- !(wpa_s->current_bss ?
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) :
- (wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA)) ?
- " (no driver rand capa" : "");
- os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN);
- return 0;
- }
-
- os_get_reltime(&now);
-
- if (wpa_s->conf->gas_rand_mac_addr == gas->last_rand_sa_type &&
- gas->last_mac_addr_rand.sec != 0 &&
- !os_reltime_expired(&now, &gas->last_mac_addr_rand,
- wpa_s->conf->gas_rand_addr_lifetime)) {
- wpa_printf(MSG_DEBUG,
- "GAS: Use the previously selected random transmitter address "
- MACSTR, MAC2STR(gas->rand_addr));
- os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
- return 0;
- }
-
- if (wpa_s->conf->gas_rand_mac_addr == 1 &&
- random_mac_addr(gas->rand_addr) < 0) {
- wpa_printf(MSG_ERROR, "GAS: Failed to get random address");
- return -1;
- }
-
- if (wpa_s->conf->gas_rand_mac_addr == 2 &&
- random_mac_addr_keep_oui(gas->rand_addr) < 0) {
- wpa_printf(MSG_ERROR,
- "GAS: Failed to get random address with same OUI");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "GAS: Use a new random transmitter address "
- MACSTR, MAC2STR(gas->rand_addr));
- os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
- os_get_reltime(&gas->last_mac_addr_rand);
- gas->last_rand_sa_type = wpa_s->conf->gas_rand_mac_addr;
-
- return 0;
-}
-
-
-/**
- * gas_query_req - Request a GAS query
- * @gas: GAS query data from gas_query_init()
- * @dst: Destination MAC address for the query
- * @freq: Frequency (in MHz) for the channel on which to send the query
- * @wildcard_bssid: Force use of wildcard BSSID value
- * @maintain_addr: Maintain own MAC address for exchange (i.e., ignore MAC
- * address randomization rules)
- * @req: GAS query payload (to be freed by gas_query module in case of success
- * return)
- * @cb: Callback function for reporting GAS query result and response
- * @ctx: Context pointer to use with the @cb call
- * Returns: dialog token (>= 0) on success or -1 on failure
- */
-int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
- int wildcard_bssid, int maintain_addr, struct wpabuf *req,
- void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code),
- void *ctx)
-{
- struct gas_query_pending *query;
- int dialog_token;
-
- if (wpabuf_len(req) < 3)
- return -1;
-
- dialog_token = gas_query_new_dialog_token(gas, dst);
- if (dialog_token < 0)
- return -1;
-
- query = os_zalloc(sizeof(*query));
- if (query == NULL)
- return -1;
-
- query->gas = gas;
- query->maintain_addr = !!maintain_addr;
- if (gas_query_set_sa(gas, query)) {
- os_free(query);
- return -1;
- }
- os_memcpy(query->addr, dst, ETH_ALEN);
- query->dialog_token = dialog_token;
- query->wildcard_bssid = !!wildcard_bssid;
- query->freq = freq;
- query->cb = cb;
- query->ctx = ctx;
- query->req = req;
- dl_list_add(&gas->pending, &query->list);
-
- *(wpabuf_mhead_u8(req) + 2) = dialog_token;
-
- wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR
- " dialog_token=%u freq=%d",
- MAC2STR(query->addr), query->dialog_token, query->freq);
-
- if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb,
- query) < 0) {
- query->req = NULL; /* caller will free this in error case */
- gas_query_free(query, 1);
- return -1;
- }
-
- return dialog_token;
-}
-
-
-int gas_query_stop(struct gas_query *gas, u8 dialog_token)
-{
- struct gas_query_pending *query;
-
- dl_list_for_each(query, &gas->pending, struct gas_query_pending, list) {
- if (query->dialog_token == dialog_token) {
- if (!gas->work) {
- /* The pending radio work has not yet been
- * started, but the pending entry has a
- * reference to the soon to be freed query.
- * Need to remove that radio work now to avoid
- * leaving behind a reference to freed memory.
- */
- radio_remove_pending_work(gas->wpa_s, query);
- }
- gas_query_done(gas, query, GAS_QUERY_STOPPED);
- return 0;
- }
- }
-
- return -1;
-}
diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h
deleted file mode 100644
index 6ccecd4ddbe1..000000000000
--- a/wpa_supplicant/gas_query.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Generic advertisement service (GAS) query
- * Copyright (c) 2009, Atheros Communications
- * Copyright (c) 2011, Qualcomm Atheros
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef GAS_QUERY_H
-#define GAS_QUERY_H
-
-struct gas_query;
-
-#ifdef CONFIG_GAS
-
-struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s);
-void gas_query_deinit(struct gas_query *gas);
-int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
- const u8 *bssid, u8 categ, const u8 *data, size_t len,
- int freq);
-
-/**
- * enum gas_query_result - GAS query result
- */
-enum gas_query_result {
- GAS_QUERY_SUCCESS,
- GAS_QUERY_FAILURE,
- GAS_QUERY_TIMEOUT,
- GAS_QUERY_PEER_ERROR,
- GAS_QUERY_INTERNAL_ERROR,
- GAS_QUERY_STOPPED,
- GAS_QUERY_DELETED_AT_DEINIT
-};
-
-int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
- int wildcard_bssid, int maintain_addr, struct wpabuf *req,
- void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code),
- void *ctx);
-int gas_query_stop(struct gas_query *gas, u8 dialog_token);
-
-#else /* CONFIG_GAS */
-
-static inline struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s)
-{
- return (void *) 1;
-}
-
-static inline void gas_query_deinit(struct gas_query *gas)
-{
-}
-
-#endif /* CONFIG_GAS */
-
-
-#endif /* GAS_QUERY_H */
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
deleted file mode 100644
index c1c823f2a85e..000000000000
--- a/wpa_supplicant/hs20_supplicant.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Copyright (c) 2009, Atheros Communications, Inc.
- * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#include <sys/stat.h>
-
-#include "common.h"
-#include "eloop.h"
-#include "common/ieee802_11_common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/gas.h"
-#include "common/wpa_ctrl.h"
-#include "rsn_supp/wpa.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "config.h"
-#include "scan.h"
-#include "bss.h"
-#include "bssid_ignore.h"
-#include "gas_query.h"
-#include "interworking.h"
-#include "hs20_supplicant.h"
-#include "base64.h"
-
-
-#define OSU_MAX_ITEMS 10
-
-struct osu_lang_string {
- char lang[4];
- char text[253];
-};
-
-struct osu_icon {
- u16 width;
- u16 height;
- char lang[4];
- char icon_type[256];
- char filename[256];
- unsigned int id;
- unsigned int failed:1;
-};
-
-struct osu_provider {
- u8 bssid[ETH_ALEN];
- u8 osu_ssid[SSID_MAX_LEN];
- u8 osu_ssid_len;
- u8 osu_ssid2[SSID_MAX_LEN];
- u8 osu_ssid2_len;
- char server_uri[256];
- u32 osu_methods; /* bit 0 = OMA-DM, bit 1 = SOAP-XML SPP */
- char osu_nai[256];
- char osu_nai2[256];
- struct osu_lang_string friendly_name[OSU_MAX_ITEMS];
- size_t friendly_name_count;
- struct osu_lang_string serv_desc[OSU_MAX_ITEMS];
- size_t serv_desc_count;
- struct osu_icon icon[OSU_MAX_ITEMS];
- size_t icon_count;
-};
-
-
-void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss = wpa_s->current_bss;
- u8 *bssid = wpa_s->bssid;
- const u8 *ie;
- const u8 *ext_capa;
- u32 filter = 0;
-
- if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) {
- wpa_printf(MSG_DEBUG,
- "Not configuring frame filtering - BSS " MACSTR
- " is not a Hotspot 2.0 network", MAC2STR(bssid));
- return;
- }
-
- ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE);
-
- /* Check if DGAF disabled bit is zero (5th byte in the IE) */
- if (!ie || ie[1] < 5)
- wpa_printf(MSG_DEBUG,
- "Not configuring frame filtering - Can't extract DGAF bit");
- else if (!(ie[6] & HS20_DGAF_DISABLED))
- filter |= WPA_DATA_FRAME_FILTER_FLAG_GTK;
-
- ext_capa = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB);
- if (!ext_capa || ext_capa[1] < 2) {
- wpa_printf(MSG_DEBUG,
- "Not configuring frame filtering - Can't extract Proxy ARP bit");
- return;
- }
-
- if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_PROXY_ARP))
- filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP |
- WPA_DATA_FRAME_FILTER_FLAG_NA;
-
- wpa_drv_configure_frame_filters(wpa_s, filter);
-}
-
-
-void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id, int ap_release)
-{
- int release;
- u8 conf;
-
- release = (HS20_VERSION >> 4) + 1;
- if (ap_release > 0 && release > ap_release)
- release = ap_release;
- if (release < 2)
- pps_mo_id = -1;
-
- wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5);
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE);
- conf = (release - 1) << 4;
- if (pps_mo_id >= 0)
- conf |= HS20_PPS_MO_ID_PRESENT;
- wpabuf_put_u8(buf, conf);
- if (pps_mo_id >= 0)
- wpabuf_put_le16(buf, pps_mo_id);
-}
-
-
-void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf,
- const struct wpa_ssid *ssid)
-{
- if (!ssid->roaming_consortium_selection ||
- !ssid->roaming_consortium_selection_len)
- return;
-
- wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(buf, 4 + ssid->roaming_consortium_selection_len);
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, HS20_ROAMING_CONS_SEL_OUI_TYPE);
- wpabuf_put_data(buf, ssid->roaming_consortium_selection,
- ssid->roaming_consortium_selection_len);
-}
-
-
-int get_hs20_version(struct wpa_bss *bss)
-{
- const u8 *ie;
-
- if (!bss)
- return 0;
-
- ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE);
- if (!ie || ie[1] < 5)
- return 0;
-
- return ((ie[6] >> 4) & 0x0f) + 1;
-}
-
-
-int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_bss *bss)
-{
- if (!wpa_s->conf->hs20 || !ssid)
- return 0;
-
- if (ssid->parent_cred)
- return 1;
-
- if (bss && !wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE))
- return 0;
-
- /*
- * This may catch some non-Hotspot 2.0 cases, but it is safer to do that
- * than cause Hotspot 2.0 connections without indication element getting
- * added. Non-Hotspot 2.0 APs should ignore the unknown vendor element.
- */
-
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X))
- return 0;
- if (!(ssid->pairwise_cipher & WPA_CIPHER_CCMP))
- return 0;
- if (ssid->proto != WPA_PROTO_RSN)
- return 0;
-
- return 1;
-}
-
-
-int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- struct wpa_cred *cred;
-
- if (ssid == NULL)
- return 0;
-
- if (ssid->update_identifier)
- return ssid->update_identifier;
-
- if (ssid->parent_cred == NULL)
- return 0;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (ssid->parent_cred == cred)
- return cred->update_identifier;
- }
-
- return 0;
-}
-
-
-void hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len,
- struct wpabuf *buf)
-{
- u8 *len_pos;
-
- if (buf == NULL)
- return;
-
- len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
- if (stypes == BIT(HS20_STYPE_NAI_HOME_REALM_QUERY)) {
- wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY);
- wpabuf_put_u8(buf, 0); /* Reserved */
- if (payload)
- wpabuf_put_data(buf, payload, payload_len);
- } else if (stypes == BIT(HS20_STYPE_ICON_REQUEST)) {
- wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST);
- wpabuf_put_u8(buf, 0); /* Reserved */
- if (payload)
- wpabuf_put_data(buf, payload, payload_len);
- } else {
- u8 i;
- wpabuf_put_u8(buf, HS20_STYPE_QUERY_LIST);
- wpabuf_put_u8(buf, 0); /* Reserved */
- for (i = 0; i < 32; i++) {
- if (stypes & BIT(i))
- wpabuf_put_u8(buf, i);
- }
- }
- gas_anqp_set_element_len(buf, len_pos);
-
- gas_anqp_set_len(buf);
-}
-
-
-static struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
- size_t payload_len)
-{
- struct wpabuf *buf;
-
- buf = gas_anqp_build_initial_req(0, 100 + payload_len);
- if (buf == NULL)
- return NULL;
-
- hs20_put_anqp_req(stypes, payload, payload_len, buf);
-
- return buf;
-}
-
-
-int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
- const u8 *payload, size_t payload_len, int inmem)
-{
- struct wpabuf *buf;
- int ret = 0;
- int freq;
- struct wpa_bss *bss;
- int res;
- struct icon_entry *icon_entry;
-
- bss = wpa_bss_get_bssid(wpa_s, dst);
- if (!bss) {
- wpa_printf(MSG_WARNING,
- "ANQP: Cannot send query to unknown BSS "
- MACSTR, MAC2STR(dst));
- return -1;
- }
-
- wpa_bss_anqp_unshare_alloc(bss);
- freq = bss->freq;
-
- wpa_printf(MSG_DEBUG, "HS20: ANQP Query Request to " MACSTR " for "
- "subtypes 0x%x", MAC2STR(dst), stypes);
-
- buf = hs20_build_anqp_req(stypes, payload, payload_len);
- if (buf == NULL)
- return -1;
-
- res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb,
- wpa_s);
- if (res < 0) {
- wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request");
- wpabuf_free(buf);
- return -1;
- } else
- wpa_printf(MSG_DEBUG, "ANQP: Query started with dialog token "
- "%u", res);
-
- if (inmem) {
- icon_entry = os_zalloc(sizeof(struct icon_entry));
- if (!icon_entry)
- return -1;
- os_memcpy(icon_entry->bssid, dst, ETH_ALEN);
- icon_entry->file_name = os_malloc(payload_len + 1);
- if (!icon_entry->file_name) {
- os_free(icon_entry);
- return -1;
- }
- os_memcpy(icon_entry->file_name, payload, payload_len);
- icon_entry->file_name[payload_len] = '\0';
- icon_entry->dialog_token = res;
-
- dl_list_add(&wpa_s->icon_head, &icon_entry->list);
- }
-
- return ret;
-}
-
-
-static struct icon_entry * hs20_find_icon(struct wpa_supplicant *wpa_s,
- const u8 *bssid,
- const char *file_name)
-{
- struct icon_entry *icon;
-
- dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) {
- if (os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0 &&
- os_strcmp(icon->file_name, file_name) == 0 && icon->image)
- return icon;
- }
-
- return NULL;
-}
-
-
-int hs20_get_icon(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *file_name, size_t offset, size_t size,
- char *reply, size_t buf_len)
-{
- struct icon_entry *icon;
- size_t out_size;
- char *b64;
- size_t b64_size;
- int reply_size;
-
- wpa_printf(MSG_DEBUG, "HS20: Get icon " MACSTR " %s @ %u +%u (%u)",
- MAC2STR(bssid), file_name, (unsigned int) offset,
- (unsigned int) size, (unsigned int) buf_len);
-
- icon = hs20_find_icon(wpa_s, bssid, file_name);
- if (!icon || !icon->image || offset >= icon->image_len)
- return -1;
- if (size > icon->image_len - offset)
- size = icon->image_len - offset;
- out_size = buf_len - 3 /* max base64 padding */;
- if (size * 4 > out_size * 3)
- size = out_size * 3 / 4;
- if (size == 0)
- return -1;
-
- b64 = base64_encode(&icon->image[offset], size, &b64_size);
- if (b64 && buf_len >= b64_size) {
- os_memcpy(reply, b64, b64_size);
- reply_size = b64_size;
- } else {
- reply_size = -1;
- }
- os_free(b64);
- return reply_size;
-}
-
-
-static void hs20_free_icon_entry(struct icon_entry *icon)
-{
- wpa_printf(MSG_DEBUG, "HS20: Free stored icon from " MACSTR
- " dialog_token=%u file_name=%s image_len=%u",
- MAC2STR(icon->bssid), icon->dialog_token,
- icon->file_name ? icon->file_name : "N/A",
- (unsigned int) icon->image_len);
- os_free(icon->file_name);
- os_free(icon->image);
- os_free(icon);
-}
-
-
-int hs20_del_icon(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *file_name)
-{
- struct icon_entry *icon, *tmp;
- int count = 0;
-
- if (!bssid)
- wpa_printf(MSG_DEBUG, "HS20: Delete all stored icons");
- else if (!file_name)
- wpa_printf(MSG_DEBUG, "HS20: Delete all stored icons for "
- MACSTR, MAC2STR(bssid));
- else
- wpa_printf(MSG_DEBUG, "HS20: Delete stored icons for "
- MACSTR " file name %s", MAC2STR(bssid), file_name);
-
- dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry,
- list) {
- if ((!bssid || os_memcmp(icon->bssid, bssid, ETH_ALEN) == 0) &&
- (!file_name ||
- os_strcmp(icon->file_name, file_name) == 0)) {
- dl_list_del(&icon->list);
- hs20_free_icon_entry(icon);
- count++;
- }
- }
- return count == 0 ? -1 : 0;
-}
-
-
-static void hs20_set_osu_access_permission(const char *osu_dir,
- const char *fname)
-{
- struct stat statbuf;
-
- /* Get OSU directory information */
- if (stat(osu_dir, &statbuf) < 0) {
- wpa_printf(MSG_WARNING, "Cannot stat the OSU directory %s",
- osu_dir);
- return;
- }
-
- if (chmod(fname, statbuf.st_mode) < 0) {
- wpa_printf(MSG_WARNING,
- "Cannot change the permissions for %s", fname);
- return;
- }
-
- if (lchown(fname, statbuf.st_uid, statbuf.st_gid) < 0) {
- wpa_printf(MSG_WARNING, "Cannot change the ownership for %s",
- fname);
- }
-}
-
-
-static void hs20_remove_duplicate_icons(struct wpa_supplicant *wpa_s,
- struct icon_entry *new_icon)
-{
- struct icon_entry *icon, *tmp;
-
- dl_list_for_each_safe(icon, tmp, &wpa_s->icon_head, struct icon_entry,
- list) {
- if (icon == new_icon)
- continue;
- if (os_memcmp(icon->bssid, new_icon->bssid, ETH_ALEN) == 0 &&
- os_strcmp(icon->file_name, new_icon->file_name) == 0) {
- dl_list_del(&icon->list);
- hs20_free_icon_entry(icon);
- }
- }
-}
-
-
-static int hs20_process_icon_binary_file(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *pos,
- size_t slen, u8 dialog_token)
-{
- char fname[256];
- int png;
- FILE *f;
- u16 data_len;
- struct icon_entry *icon;
-
- dl_list_for_each(icon, &wpa_s->icon_head, struct icon_entry, list) {
- if (icon->dialog_token == dialog_token && !icon->image &&
- os_memcmp(icon->bssid, sa, ETH_ALEN) == 0) {
- icon->image = os_memdup(pos, slen);
- if (!icon->image)
- return -1;
- icon->image_len = slen;
- hs20_remove_duplicate_icons(wpa_s, icon);
- wpa_msg(wpa_s, MSG_INFO,
- RX_HS20_ICON MACSTR " %s %u",
- MAC2STR(sa), icon->file_name,
- (unsigned int) icon->image_len);
- return 0;
- }
- }
-
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR " Icon Binary File",
- MAC2STR(sa));
-
- if (slen < 4) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
- "value from " MACSTR, MAC2STR(sa));
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "HS 2.0: Download Status Code %u", *pos);
- if (*pos != 0)
- return -1;
- pos++;
- slen--;
-
- if ((size_t) 1 + pos[0] > slen) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
- "value from " MACSTR, MAC2STR(sa));
- return -1;
- }
- wpa_hexdump_ascii(MSG_DEBUG, "Icon Type", pos + 1, pos[0]);
- png = os_strncasecmp((char *) pos + 1, "image/png", 9) == 0;
- slen -= 1 + pos[0];
- pos += 1 + pos[0];
-
- if (slen < 2) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
- "value from " MACSTR, MAC2STR(sa));
- return -1;
- }
- data_len = WPA_GET_LE16(pos);
- pos += 2;
- slen -= 2;
-
- if (data_len > slen) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon Binary File "
- "value from " MACSTR, MAC2STR(sa));
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "Icon Binary Data: %u bytes", data_len);
- if (wpa_s->conf->osu_dir == NULL)
- return -1;
-
- wpa_s->osu_icon_id++;
- if (wpa_s->osu_icon_id == 0)
- wpa_s->osu_icon_id++;
- snprintf(fname, sizeof(fname), "%s/osu-icon-%u.%s",
- wpa_s->conf->osu_dir, wpa_s->osu_icon_id,
- png ? "png" : "icon");
- f = fopen(fname, "wb");
- if (f == NULL)
- return -1;
-
- hs20_set_osu_access_permission(wpa_s->conf->osu_dir, fname);
-
- if (fwrite(pos, slen, 1, f) != 1) {
- fclose(f);
- unlink(fname);
- return -1;
- }
- fclose(f);
-
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP_ICON "%s", fname);
- return 0;
-}
-
-
-static void hs20_continue_icon_fetch(void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- if (wpa_s->fetch_osu_icon_in_progress)
- hs20_next_osu_icon(wpa_s);
-}
-
-
-static void hs20_osu_icon_fetch_result(struct wpa_supplicant *wpa_s, int res)
-{
- size_t i, j;
- struct os_reltime now, tmp;
- int dur;
-
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->osu_icon_fetch_start, &tmp);
- dur = tmp.sec * 1000 + tmp.usec / 1000;
- wpa_printf(MSG_DEBUG, "HS 2.0: Icon fetch dur=%d ms res=%d",
- dur, res);
-
- for (i = 0; i < wpa_s->osu_prov_count; i++) {
- struct osu_provider *osu = &wpa_s->osu_prov[i];
- for (j = 0; j < osu->icon_count; j++) {
- struct osu_icon *icon = &osu->icon[j];
- if (icon->id || icon->failed)
- continue;
- if (res < 0)
- icon->failed = 1;
- else
- icon->id = wpa_s->osu_icon_id;
- return;
- }
- }
-}
-
-
-void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, const u8 *sa,
- const u8 *data, size_t slen, u8 dialog_token)
-{
- const u8 *pos = data;
- u8 subtype;
- struct wpa_bss_anqp *anqp = NULL;
- int ret;
-
- if (slen < 2)
- return;
-
- if (bss)
- anqp = bss->anqp;
-
- subtype = *pos++;
- slen--;
-
- pos++; /* Reserved */
- slen--;
-
- switch (subtype) {
- case HS20_STYPE_CAPABILITY_LIST:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " HS Capability List", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "HS Capability List", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->hs20_capability_list);
- anqp->hs20_capability_list =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_OPERATOR_FRIENDLY_NAME:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " Operator Friendly Name", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->hs20_operator_friendly_name);
- anqp->hs20_operator_friendly_name =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_WAN_METRICS:
- wpa_hexdump(MSG_DEBUG, "WAN Metrics", pos, slen);
- if (slen < 13) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short WAN "
- "Metrics value from " MACSTR, MAC2STR(sa));
- break;
- }
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " WAN Metrics %02x:%u:%u:%u:%u:%u", MAC2STR(sa),
- pos[0], WPA_GET_LE32(pos + 1), WPA_GET_LE32(pos + 5),
- pos[9], pos[10], WPA_GET_LE16(pos + 11));
- if (anqp) {
- wpabuf_free(anqp->hs20_wan_metrics);
- anqp->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_CONNECTION_CAPABILITY:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " Connection Capability", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->hs20_connection_capability);
- anqp->hs20_connection_capability =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_OPERATING_CLASS:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " Operating Class", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->hs20_operating_class);
- anqp->hs20_operating_class =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_OSU_PROVIDERS_LIST:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " OSU Providers list", MAC2STR(sa));
- wpa_s->num_prov_found++;
- if (anqp) {
- wpabuf_free(anqp->hs20_osu_providers_list);
- anqp->hs20_osu_providers_list =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_ICON_BINARY_FILE:
- ret = hs20_process_icon_binary_file(wpa_s, sa, pos, slen,
- dialog_token);
- if (wpa_s->fetch_osu_icon_in_progress) {
- hs20_osu_icon_fetch_result(wpa_s, ret);
- eloop_cancel_timeout(hs20_continue_icon_fetch,
- wpa_s, NULL);
- eloop_register_timeout(0, 0, hs20_continue_icon_fetch,
- wpa_s, NULL);
- }
- break;
- case HS20_STYPE_OPERATOR_ICON_METADATA:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " Operator Icon Metadata", MAC2STR(sa));
- wpa_hexdump(MSG_DEBUG, "Operator Icon Metadata", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->hs20_operator_icon_metadata);
- anqp->hs20_operator_icon_metadata =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case HS20_STYPE_OSU_PROVIDERS_NAI_LIST:
- wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
- " OSU Providers NAI List", MAC2STR(sa));
- if (anqp) {
- wpabuf_free(anqp->hs20_osu_providers_nai_list);
- anqp->hs20_osu_providers_nai_list =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- default:
- wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype);
- break;
- }
-}
-
-
-void hs20_notify_parse_done(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->fetch_osu_icon_in_progress)
- return;
- if (eloop_is_timeout_registered(hs20_continue_icon_fetch, wpa_s, NULL))
- return;
- /*
- * We are going through icon fetch, but no icon response was received.
- * Assume this means the current AP could not provide an answer to avoid
- * getting stuck in fetch iteration.
- */
- hs20_icon_fetch_failed(wpa_s);
-}
-
-
-static void hs20_free_osu_prov_entry(struct osu_provider *prov)
-{
-}
-
-
-void hs20_free_osu_prov(struct wpa_supplicant *wpa_s)
-{
- size_t i;
- for (i = 0; i < wpa_s->osu_prov_count; i++)
- hs20_free_osu_prov_entry(&wpa_s->osu_prov[i]);
- os_free(wpa_s->osu_prov);
- wpa_s->osu_prov = NULL;
- wpa_s->osu_prov_count = 0;
-}
-
-
-static void hs20_osu_fetch_done(struct wpa_supplicant *wpa_s)
-{
- char fname[256];
- FILE *f;
- size_t i, j;
-
- wpa_s->fetch_osu_info = 0;
- wpa_s->fetch_osu_icon_in_progress = 0;
-
- if (wpa_s->conf->osu_dir == NULL) {
- hs20_free_osu_prov(wpa_s);
- wpa_s->fetch_anqp_in_progress = 0;
- return;
- }
-
- snprintf(fname, sizeof(fname), "%s/osu-providers.txt",
- wpa_s->conf->osu_dir);
- f = fopen(fname, "w");
- if (f == NULL) {
- wpa_msg(wpa_s, MSG_INFO,
- "Could not write OSU provider information");
- hs20_free_osu_prov(wpa_s);
- wpa_s->fetch_anqp_in_progress = 0;
- return;
- }
-
- hs20_set_osu_access_permission(wpa_s->conf->osu_dir, fname);
-
- for (i = 0; i < wpa_s->osu_prov_count; i++) {
- struct osu_provider *osu = &wpa_s->osu_prov[i];
- if (i > 0)
- fprintf(f, "\n");
- fprintf(f, "OSU-PROVIDER " MACSTR "\n"
- "uri=%s\n"
- "methods=%08x\n",
- MAC2STR(osu->bssid), osu->server_uri, osu->osu_methods);
- if (osu->osu_ssid_len) {
- fprintf(f, "osu_ssid=%s\n",
- wpa_ssid_txt(osu->osu_ssid,
- osu->osu_ssid_len));
- }
- if (osu->osu_ssid2_len) {
- fprintf(f, "osu_ssid2=%s\n",
- wpa_ssid_txt(osu->osu_ssid2,
- osu->osu_ssid2_len));
- }
- if (osu->osu_nai[0])
- fprintf(f, "osu_nai=%s\n", osu->osu_nai);
- if (osu->osu_nai2[0])
- fprintf(f, "osu_nai2=%s\n", osu->osu_nai2);
- for (j = 0; j < osu->friendly_name_count; j++) {
- fprintf(f, "friendly_name=%s:%s\n",
- osu->friendly_name[j].lang,
- osu->friendly_name[j].text);
- }
- for (j = 0; j < osu->serv_desc_count; j++) {
- fprintf(f, "desc=%s:%s\n",
- osu->serv_desc[j].lang,
- osu->serv_desc[j].text);
- }
- for (j = 0; j < osu->icon_count; j++) {
- struct osu_icon *icon = &osu->icon[j];
- if (icon->failed)
- continue; /* could not fetch icon */
- fprintf(f, "icon=%u:%u:%u:%s:%s:%s\n",
- icon->id, icon->width, icon->height, icon->lang,
- icon->icon_type, icon->filename);
- }
- }
- fclose(f);
- hs20_free_osu_prov(wpa_s);
-
- wpa_msg(wpa_s, MSG_INFO, "OSU provider fetch completed");
- wpa_s->fetch_anqp_in_progress = 0;
-}
-
-
-void hs20_next_osu_icon(struct wpa_supplicant *wpa_s)
-{
- size_t i, j;
-
- wpa_printf(MSG_DEBUG, "HS 2.0: Ready to fetch next icon");
-
- for (i = 0; i < wpa_s->osu_prov_count; i++) {
- struct osu_provider *osu = &wpa_s->osu_prov[i];
- for (j = 0; j < osu->icon_count; j++) {
- struct osu_icon *icon = &osu->icon[j];
- if (icon->id || icon->failed)
- continue;
-
- wpa_printf(MSG_DEBUG, "HS 2.0: Try to fetch icon '%s' "
- "from " MACSTR, icon->filename,
- MAC2STR(osu->bssid));
- os_get_reltime(&wpa_s->osu_icon_fetch_start);
- if (hs20_anqp_send_req(wpa_s, osu->bssid,
- BIT(HS20_STYPE_ICON_REQUEST),
- (u8 *) icon->filename,
- os_strlen(icon->filename),
- 0) < 0) {
- icon->failed = 1;
- continue;
- }
- return;
- }
- }
-
- wpa_printf(MSG_DEBUG, "HS 2.0: No more icons to fetch");
- hs20_osu_fetch_done(wpa_s);
-}
-
-
-static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- const u8 *osu_ssid, u8 osu_ssid_len,
- const u8 *osu_ssid2, u8 osu_ssid2_len,
- const u8 *pos, size_t len)
-{
- struct osu_provider *prov;
- const u8 *end = pos + len;
- u16 len2;
- const u8 *pos2;
- u8 uri_len, osu_method_len, osu_nai_len;
-
- wpa_hexdump(MSG_DEBUG, "HS 2.0: Parsing OSU Provider", pos, len);
- prov = os_realloc_array(wpa_s->osu_prov,
- wpa_s->osu_prov_count + 1,
- sizeof(*prov));
- if (prov == NULL)
- return;
- wpa_s->osu_prov = prov;
- prov = &prov[wpa_s->osu_prov_count];
- os_memset(prov, 0, sizeof(*prov));
-
- os_memcpy(prov->bssid, bss->bssid, ETH_ALEN);
- os_memcpy(prov->osu_ssid, osu_ssid, osu_ssid_len);
- prov->osu_ssid_len = osu_ssid_len;
- if (osu_ssid2)
- os_memcpy(prov->osu_ssid2, osu_ssid2, osu_ssid2_len);
- prov->osu_ssid2_len = osu_ssid2_len;
-
- /* OSU Friendly Name Length */
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
- "Friendly Name Length");
- return;
- }
- len2 = WPA_GET_LE16(pos);
- pos += 2;
- if (len2 > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
- "Friendly Name Duples");
- return;
- }
- pos2 = pos;
- pos += len2;
-
- /* OSU Friendly Name Duples */
- while (pos - pos2 >= 4 && prov->friendly_name_count < OSU_MAX_ITEMS) {
- struct osu_lang_string *f;
- u8 slen;
-
- slen = pos2[0];
- if (1 + slen > pos - pos2) {
- wpa_printf(MSG_DEBUG, "Invalid OSU Friendly Name");
- break;
- }
- if (slen < 3) {
- wpa_printf(MSG_DEBUG,
- "Invalid OSU Friendly Name (no room for language)");
- break;
- }
- f = &prov->friendly_name[prov->friendly_name_count++];
- pos2++;
- os_memcpy(f->lang, pos2, 3);
- pos2 += 3;
- slen -= 3;
- os_memcpy(f->text, pos2, slen);
- pos2 += slen;
- }
-
- /* OSU Server URI */
- if (end - pos < 1) {
- wpa_printf(MSG_DEBUG,
- "HS 2.0: Not enough room for OSU Server URI length");
- return;
- }
- uri_len = *pos++;
- if (uri_len > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Server "
- "URI");
- return;
- }
- os_memcpy(prov->server_uri, pos, uri_len);
- pos += uri_len;
-
- /* OSU Method list */
- if (end - pos < 1) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method "
- "list length");
- return;
- }
- osu_method_len = pos[0];
- if (osu_method_len > end - pos - 1) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method "
- "list");
- return;
- }
- pos2 = pos + 1;
- pos += 1 + osu_method_len;
- while (pos2 < pos) {
- if (*pos2 < 32)
- prov->osu_methods |= BIT(*pos2);
- pos2++;
- }
-
- /* Icons Available Length */
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons "
- "Available Length");
- return;
- }
- len2 = WPA_GET_LE16(pos);
- pos += 2;
- if (len2 > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons "
- "Available");
- return;
- }
- pos2 = pos;
- pos += len2;
-
- /* Icons Available */
- while (pos2 < pos) {
- struct osu_icon *icon = &prov->icon[prov->icon_count];
- u8 flen;
-
- if (2 + 2 + 3 + 1 + 1 > pos - pos2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
- break;
- }
-
- icon->width = WPA_GET_LE16(pos2);
- pos2 += 2;
- icon->height = WPA_GET_LE16(pos2);
- pos2 += 2;
- os_memcpy(icon->lang, pos2, 3);
- pos2 += 3;
-
- flen = *pos2++;
- if (flen > pos - pos2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon Type");
- break;
- }
- os_memcpy(icon->icon_type, pos2, flen);
- pos2 += flen;
-
- if (pos - pos2 < 1) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon "
- "Filename length");
- break;
- }
- flen = *pos2++;
- if (flen > pos - pos2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon "
- "Filename");
- break;
- }
- os_memcpy(icon->filename, pos2, flen);
- pos2 += flen;
-
- prov->icon_count++;
- }
-
- /* OSU_NAI */
- if (end - pos < 1) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI");
- return;
- }
- osu_nai_len = *pos++;
- if (osu_nai_len > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI");
- return;
- }
- os_memcpy(prov->osu_nai, pos, osu_nai_len);
- pos += osu_nai_len;
-
- /* OSU Service Description Length */
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
- "Service Description Length");
- return;
- }
- len2 = WPA_GET_LE16(pos);
- pos += 2;
- if (len2 > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
- "Service Description Duples");
- return;
- }
- pos2 = pos;
- pos += len2;
-
- /* OSU Service Description Duples */
- while (pos - pos2 >= 4 && prov->serv_desc_count < OSU_MAX_ITEMS) {
- struct osu_lang_string *f;
- u8 descr_len;
-
- descr_len = *pos2++;
- if (descr_len > pos - pos2 || descr_len < 3) {
- wpa_printf(MSG_DEBUG, "Invalid OSU Service "
- "Description");
- break;
- }
- f = &prov->serv_desc[prov->serv_desc_count++];
- os_memcpy(f->lang, pos2, 3);
- os_memcpy(f->text, pos2 + 3, descr_len - 3);
- pos2 += descr_len;
- }
-
- wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR,
- MAC2STR(bss->bssid));
- wpa_s->osu_prov_count++;
-}
-
-
-void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
- struct wpabuf *prov_anqp;
- const u8 *pos, *end;
- u16 len;
- const u8 *osu_ssid, *osu_ssid2;
- u8 osu_ssid_len, osu_ssid2_len;
- u8 num_providers;
-
- hs20_free_osu_prov(wpa_s);
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- struct wpa_ie_data data;
- const u8 *ie;
-
- if (bss->anqp == NULL)
- continue;
- prov_anqp = bss->anqp->hs20_osu_providers_list;
- if (prov_anqp == NULL)
- continue;
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &data) == 0 &&
- (data.key_mgmt & WPA_KEY_MGMT_OSEN)) {
- osu_ssid2 = bss->ssid;
- osu_ssid2_len = bss->ssid_len;
- } else {
- osu_ssid2 = NULL;
- osu_ssid2_len = 0;
- }
- wpa_printf(MSG_DEBUG, "HS 2.0: Parsing OSU Providers list from "
- MACSTR, MAC2STR(bss->bssid));
- wpa_hexdump_buf(MSG_DEBUG, "HS 2.0: OSU Providers list",
- prov_anqp);
- pos = wpabuf_head(prov_anqp);
- end = pos + wpabuf_len(prov_anqp);
-
- /* OSU SSID */
- if (end - pos < 1)
- continue;
- if (1 + pos[0] > end - pos) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
- "OSU SSID");
- continue;
- }
- osu_ssid_len = *pos++;
- if (osu_ssid_len > SSID_MAX_LEN) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Invalid OSU SSID "
- "Length %u", osu_ssid_len);
- continue;
- }
- osu_ssid = pos;
- pos += osu_ssid_len;
-
- if (end - pos < 1) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
- "Number of OSU Providers");
- continue;
- }
- num_providers = *pos++;
- wpa_printf(MSG_DEBUG, "HS 2.0: Number of OSU Providers: %u",
- num_providers);
-
- /* OSU Providers */
- while (end - pos > 2 && num_providers > 0) {
- num_providers--;
- len = WPA_GET_LE16(pos);
- pos += 2;
- if (len > (unsigned int) (end - pos))
- break;
- hs20_osu_add_prov(wpa_s, bss, osu_ssid,
- osu_ssid_len, osu_ssid2,
- osu_ssid2_len, pos, len);
- pos += len;
- }
-
- if (pos != end) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Ignored %d bytes of "
- "extra data after OSU Providers",
- (int) (end - pos));
- }
-
- prov_anqp = bss->anqp->hs20_osu_providers_nai_list;
- if (!prov_anqp)
- continue;
- wpa_printf(MSG_DEBUG,
- "HS 2.0: Parsing OSU Providers NAI List from "
- MACSTR, MAC2STR(bss->bssid));
- wpa_hexdump_buf(MSG_DEBUG, "HS 2.0: OSU Providers NAI List",
- prov_anqp);
- pos = wpabuf_head(prov_anqp);
- end = pos + wpabuf_len(prov_anqp);
- num_providers = 0;
- while (end - pos > 0) {
- len = *pos++;
- if (end - pos < len) {
- wpa_printf(MSG_DEBUG,
- "HS 2.0: Not enough room for OSU_NAI");
- break;
- }
- if (num_providers >= wpa_s->osu_prov_count) {
- wpa_printf(MSG_DEBUG,
- "HS 2.0: Ignore unexpected OSU Provider NAI List entries");
- break;
- }
- os_memcpy(wpa_s->osu_prov[num_providers].osu_nai2,
- pos, len);
- pos += len;
- num_providers++;
- }
- }
-
- wpa_s->fetch_osu_icon_in_progress = 1;
- hs20_next_osu_icon(wpa_s);
-}
-
-
-static void hs20_osu_scan_res_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- wpa_printf(MSG_DEBUG, "OSU provisioning fetch scan completed");
- if (!wpa_s->fetch_osu_waiting_scan) {
- wpa_printf(MSG_DEBUG, "OSU fetch have been canceled");
- return;
- }
- wpa_s->network_select = 0;
- wpa_s->fetch_all_anqp = 1;
- wpa_s->fetch_osu_info = 1;
- wpa_s->fetch_osu_icon_in_progress = 0;
-
- interworking_start_fetch_anqp(wpa_s);
-}
-
-
-int hs20_fetch_osu(struct wpa_supplicant *wpa_s, int skip_scan)
-{
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - "
- "interface disabled");
- return -1;
- }
-
- if (wpa_s->scanning) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - "
- "scanning");
- return -1;
- }
-
- if (wpa_s->conf->osu_dir == NULL) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - "
- "osu_dir not configured");
- return -1;
- }
-
- if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Cannot start fetch_osu - "
- "fetch in progress (%d, %d)",
- wpa_s->fetch_anqp_in_progress,
- wpa_s->network_select);
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_INFO, "Starting OSU provisioning information fetch");
- wpa_s->num_osu_scans = 0;
- wpa_s->num_prov_found = 0;
- if (skip_scan) {
- wpa_s->network_select = 0;
- wpa_s->fetch_all_anqp = 1;
- wpa_s->fetch_osu_info = 1;
- wpa_s->fetch_osu_icon_in_progress = 0;
-
- interworking_start_fetch_anqp(wpa_s);
- } else {
- hs20_start_osu_scan(wpa_s);
- }
-
- return 0;
-}
-
-
-void hs20_start_osu_scan(struct wpa_supplicant *wpa_s)
-{
- wpa_s->fetch_osu_waiting_scan = 1;
- wpa_s->num_osu_scans++;
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_s->scan_res_handler = hs20_osu_scan_res_handler;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-void hs20_cancel_fetch_osu(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "Cancel OSU fetch");
- interworking_stop_fetch_anqp(wpa_s);
- wpa_s->fetch_osu_waiting_scan = 0;
- wpa_s->network_select = 0;
- wpa_s->fetch_osu_info = 0;
- wpa_s->fetch_osu_icon_in_progress = 0;
-}
-
-
-void hs20_icon_fetch_failed(struct wpa_supplicant *wpa_s)
-{
- hs20_osu_icon_fetch_result(wpa_s, -1);
- eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL);
- eloop_register_timeout(0, 0, hs20_continue_icon_fetch, wpa_s, NULL);
-}
-
-
-void hs20_rx_subscription_remediation(struct wpa_supplicant *wpa_s,
- const char *url, u8 osu_method)
-{
- if (url)
- wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION "%u %s",
- osu_method, url);
- else
- wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION);
-}
-
-
-void hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s, u8 code,
- u16 reauth_delay, const char *url)
-{
- if (!wpa_sm_pmf_enabled(wpa_s->wpa)) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Ignore deauthentication imminent notice since PMF was not enabled");
- return;
- }
-
- wpa_msg(wpa_s, MSG_INFO, HS20_DEAUTH_IMMINENT_NOTICE "%u %u %s",
- code, reauth_delay, url);
-
- if (code == HS20_DEAUTH_REASON_CODE_BSS) {
- wpa_printf(MSG_DEBUG, "HS 2.0: Add BSS to ignore list");
- wpa_bssid_ignore_add(wpa_s, wpa_s->bssid);
- /* TODO: For now, disable full ESS since some drivers may not
- * support disabling per BSS. */
- if (wpa_s->current_ssid) {
- struct os_reltime now;
- os_get_reltime(&now);
- if (now.sec + reauth_delay <=
- wpa_s->current_ssid->disabled_until.sec)
- return;
- wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds (BSS)",
- reauth_delay);
- wpa_s->current_ssid->disabled_until.sec =
- now.sec + reauth_delay;
- }
- }
-
- if (code == HS20_DEAUTH_REASON_CODE_ESS && wpa_s->current_ssid) {
- struct os_reltime now;
- os_get_reltime(&now);
- if (now.sec + reauth_delay <=
- wpa_s->current_ssid->disabled_until.sec)
- return;
- wpa_printf(MSG_DEBUG, "HS 2.0: Disable network for %u seconds",
- reauth_delay);
- wpa_s->current_ssid->disabled_until.sec =
- now.sec + reauth_delay;
- }
-}
-
-
-void hs20_rx_t_c_acceptance(struct wpa_supplicant *wpa_s, const char *url)
-{
- if (!wpa_sm_pmf_enabled(wpa_s->wpa)) {
- wpa_printf(MSG_DEBUG,
- "HS 2.0: Ignore Terms and Conditions Acceptance since PMF was not enabled");
- return;
- }
-
- wpa_msg(wpa_s, MSG_INFO, HS20_T_C_ACCEPTANCE "%s", url);
-}
-
-
-void hs20_init(struct wpa_supplicant *wpa_s)
-{
- dl_list_init(&wpa_s->icon_head);
-}
-
-
-void hs20_deinit(struct wpa_supplicant *wpa_s)
-{
- eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL);
- hs20_free_osu_prov(wpa_s);
- if (wpa_s->icon_head.next)
- hs20_del_icon(wpa_s, NULL, NULL);
-}
diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h
deleted file mode 100644
index e43414bc65c5..000000000000
--- a/wpa_supplicant/hs20_supplicant.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HS20_SUPPLICANT_H
-#define HS20_SUPPLICANT_H
-
-void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s);
-void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id,
- int ap_release);
-void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf,
- const struct wpa_ssid *ssid);
-
-int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
- const u8 *payload, size_t payload_len, int inmem);
-void hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len,
- struct wpabuf *buf);
-void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, const u8 *sa,
- const u8 *data, size_t slen, u8 dialog_token);
-int get_hs20_version(struct wpa_bss *bss);
-int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_bss *bss);
-int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-void hs20_notify_parse_done(struct wpa_supplicant *wpa_s);
-
-void hs20_rx_subscription_remediation(struct wpa_supplicant *wpa_s,
- const char *url, u8 osu_method);
-void hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s, u8 code,
- u16 reauth_delay, const char *url);
-void hs20_rx_t_c_acceptance(struct wpa_supplicant *wpa_s, const char *url);
-
-void hs20_free_osu_prov(struct wpa_supplicant *wpa_s);
-void hs20_next_osu_icon(struct wpa_supplicant *wpa_s);
-void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s);
-int hs20_fetch_osu(struct wpa_supplicant *wpa_s, int skip_scan);
-void hs20_cancel_fetch_osu(struct wpa_supplicant *wpa_s);
-void hs20_icon_fetch_failed(struct wpa_supplicant *wpa_s);
-void hs20_start_osu_scan(struct wpa_supplicant *wpa_s);
-void hs20_init(struct wpa_supplicant *wpa_s);
-void hs20_deinit(struct wpa_supplicant *wpa_s);
-int hs20_get_icon(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *file_name, size_t offset, size_t size,
- char *reply, size_t buf_len);
-int hs20_del_icon(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *file_name);
-
-#endif /* HS20_SUPPLICANT_H */
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
deleted file mode 100644
index 02e63904c5d7..000000000000
--- a/wpa_supplicant/ibss_rsn.c
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- * wpa_supplicant - IBSS RSN
- * Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "common/wpa_ctrl.h"
-#include "utils/eloop.h"
-#include "l2_packet/l2_packet.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/wpa_ie.h"
-#include "ap/wpa_auth.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "common/ieee802_11_defs.h"
-#include "ibss_rsn.h"
-
-
-static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx);
-
-
-static struct ibss_rsn_peer * ibss_rsn_get_peer(struct ibss_rsn *ibss_rsn,
- const u8 *addr)
-{
- struct ibss_rsn_peer *peer;
-
- for (peer = ibss_rsn->peers; peer; peer = peer->next)
- if (os_memcmp(addr, peer->addr, ETH_ALEN) == 0)
- break;
- return peer;
-}
-
-
-static void ibss_rsn_free(struct ibss_rsn_peer *peer)
-{
- eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
- wpa_auth_sta_deinit(peer->auth);
- wpa_sm_deinit(peer->supp);
- os_free(peer);
-}
-
-
-static void supp_set_state(void *ctx, enum wpa_states state)
-{
- struct ibss_rsn_peer *peer = ctx;
- peer->supp_state = state;
-}
-
-
-static enum wpa_states supp_get_state(void *ctx)
-{
- struct ibss_rsn_peer *peer = ctx;
- return peer->supp_state;
-}
-
-
-static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
- size_t len)
-{
- struct ibss_rsn_peer *peer = ctx;
- struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s;
- int encrypt = peer->authentication_status & IBSS_RSN_REPORTED_PTK;
-
- wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR
- " proto=0x%04x len=%lu no_encrypt=%d)",
- __func__, MAC2STR(dest), proto, (unsigned long) len,
- !encrypt);
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
- return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
- !encrypt);
-
- if (wpa_s->l2)
- return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
-
- return -1;
-}
-
-
-static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data,
- u16 data_len, size_t *msg_len, void **data_pos)
-{
- struct ieee802_1x_hdr *hdr;
-
- wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)",
- __func__, type, data_len);
-
- *msg_len = sizeof(*hdr) + data_len;
- hdr = os_malloc(*msg_len);
- if (hdr == NULL)
- return NULL;
-
- hdr->version = 2;
- hdr->type = type;
- hdr->length = host_to_be16(data_len);
-
- if (data)
- os_memcpy(hdr + 1, data, data_len);
- else
- os_memset(hdr + 1, 0, data_len);
-
- if (data_pos)
- *data_pos = hdr + 1;
-
- return (u8 *) hdr;
-}
-
-
-static int supp_get_beacon_ie(void *ctx)
-{
- struct ibss_rsn_peer *peer = ctx;
-
- wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
- /* TODO: get correct RSN IE */
- wpa_sm_set_ap_rsnxe(peer->supp, NULL, 0);
- return wpa_sm_set_ap_rsn_ie(peer->supp,
- (u8 *) "\x30\x14\x01\x00"
- "\x00\x0f\xac\x04"
- "\x01\x00\x00\x0f\xac\x04"
- "\x01\x00\x00\x0f\xac\x02"
- "\x00\x00", 22);
-}
-
-
-static void ibss_check_rsn_completed(struct ibss_rsn_peer *peer)
-{
- struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s;
-
- if ((peer->authentication_status &
- (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH)) !=
- (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH))
- return;
- if (peer->authentication_status & IBSS_RSN_REPORTED_PTK)
- return;
- peer->authentication_status |= IBSS_RSN_REPORTED_PTK;
- wpa_msg(wpa_s, MSG_INFO, IBSS_RSN_COMPLETED MACSTR,
- MAC2STR(peer->addr));
-}
-
-
-static int supp_set_key(void *ctx, enum wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len, enum key_flag key_flag)
-{
- struct ibss_rsn_peer *peer = ctx;
-
- wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
- "set_tx=%d)",
- __func__, alg, MAC2STR(addr), key_idx, set_tx);
- wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
- wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
-
- if (key_idx == 0) {
- peer->authentication_status |= IBSS_RSN_SET_PTK_SUPP;
- ibss_check_rsn_completed(peer);
- /*
- * In IBSS RSN, the pairwise key from the 4-way handshake
- * initiated by the peer with highest MAC address is used.
- */
- if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr,
- ETH_ALEN) > 0) {
- wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK");
- return 0;
- }
- }
-
- if (is_broadcast_ether_addr(addr))
- addr = peer->addr;
- return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx,
- set_tx, seq, seq_len, key, key_len, key_flag);
-}
-
-
-static void * supp_get_network_ctx(void *ctx)
-{
- struct ibss_rsn_peer *peer = ctx;
- return wpa_supplicant_get_ssid(peer->ibss_rsn->wpa_s);
-}
-
-
-static int supp_mlme_setprotection(void *ctx, const u8 *addr,
- int protection_type, int key_type)
-{
- wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d "
- "key_type=%d)",
- __func__, MAC2STR(addr), protection_type, key_type);
- return 0;
-}
-
-
-static void supp_cancel_auth_timeout(void *ctx)
-{
- wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
-}
-
-
-static void supp_deauthenticate(void *ctx, u16 reason_code)
-{
- wpa_printf(MSG_DEBUG, "SUPP: %s (TODO)", __func__);
-}
-
-
-static void supp_reconnect(void *ctx)
-{
- wpa_printf(MSG_DEBUG, "SUPP: %s (TODO)", __func__);
-}
-
-
-static int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr,
- const u8 *psk)
-{
- struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx));
- if (ctx == NULL)
- return -1;
-
- ctx->ctx = peer;
- ctx->msg_ctx = peer->ibss_rsn->wpa_s;
- ctx->set_state = supp_set_state;
- ctx->get_state = supp_get_state;
- ctx->ether_send = supp_ether_send;
- ctx->get_beacon_ie = supp_get_beacon_ie;
- ctx->alloc_eapol = supp_alloc_eapol;
- ctx->set_key = supp_set_key;
- ctx->get_network_ctx = supp_get_network_ctx;
- ctx->mlme_setprotection = supp_mlme_setprotection;
- ctx->cancel_auth_timeout = supp_cancel_auth_timeout;
- ctx->deauthenticate = supp_deauthenticate;
- ctx->reconnect = supp_reconnect;
- peer->supp = wpa_sm_init(ctx);
- if (peer->supp == NULL) {
- wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed");
- os_free(ctx);
- return -1;
- }
-
- wpa_sm_set_own_addr(peer->supp, own_addr);
- wpa_sm_set_param(peer->supp, WPA_PARAM_RSN_ENABLED, 1);
- wpa_sm_set_param(peer->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN);
- wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
- wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
- wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
- wpa_sm_set_pmk(peer->supp, psk, PMK_LEN, NULL, NULL);
-
- peer->supp_ie_len = sizeof(peer->supp_ie);
- if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie,
- &peer->supp_ie_len) < 0) {
- wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
- " failed");
- return -1;
- }
-
- wpa_sm_notify_assoc(peer->supp, peer->addr);
-
- return 0;
-}
-
-
-static void auth_logger(void *ctx, const u8 *addr, logger_level level,
- const char *txt)
-{
- if (addr)
- wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s",
- MAC2STR(addr), txt);
- else
- wpa_printf(MSG_DEBUG, "AUTH: %s", txt);
-}
-
-
-static const u8 * auth_get_psk(void *ctx, const u8 *addr,
- const u8 *p2p_dev_addr, const u8 *prev_psk,
- size_t *psk_len, int *vlan_id)
-{
- struct ibss_rsn *ibss_rsn = ctx;
-
- if (psk_len)
- *psk_len = PMK_LEN;
- if (vlan_id)
- *vlan_id = 0;
- wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
- __func__, MAC2STR(addr), prev_psk);
- if (prev_psk)
- return NULL;
- return ibss_rsn->psk;
-}
-
-
-static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
- size_t data_len, int encrypt)
-{
- struct ibss_rsn *ibss_rsn = ctx;
- struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s;
-
- wpa_printf(MSG_DEBUG, "AUTH: %s(addr=" MACSTR " data_len=%lu "
- "encrypt=%d)",
- __func__, MAC2STR(addr), (unsigned long) data_len, encrypt);
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT)
- return wpa_drv_tx_control_port(wpa_s, addr, ETH_P_EAPOL,
- data, data_len, !encrypt);
-
- if (wpa_s->l2)
- return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data,
- data_len);
-
- return -1;
-}
-
-
-static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
- const u8 *addr, int idx, u8 *key, size_t key_len,
- enum key_flag key_flag)
-{
- struct ibss_rsn *ibss_rsn = ctx;
- u8 seq[6];
-
- os_memset(seq, 0, sizeof(seq));
-
- if (addr) {
- wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
- " key_idx=%d)",
- __func__, alg, MAC2STR(addr), idx);
- } else {
- wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
- __func__, alg, idx);
- }
- wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);
-
- if (idx == 0) {
- if (addr) {
- struct ibss_rsn_peer *peer;
- peer = ibss_rsn_get_peer(ibss_rsn, addr);
- if (peer) {
- peer->authentication_status |=
- IBSS_RSN_SET_PTK_AUTH;
- ibss_check_rsn_completed(peer);
- }
- }
- /*
- * In IBSS RSN, the pairwise key from the 4-way handshake
- * initiated by the peer with highest MAC address is used.
- */
- if (addr == NULL ||
- os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) {
- wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK");
- return 0;
- }
- }
-
- return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
- 1, seq, 6, key, key_len, key_flag);
-}
-
-
-static void ibss_rsn_disconnect(void *ctx, const u8 *addr, u16 reason)
-{
- struct ibss_rsn *ibss_rsn = ctx;
- wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason);
-}
-
-
-static int auth_for_each_sta(void *ctx, int (*cb)(struct wpa_state_machine *sm,
- void *ctx),
- void *cb_ctx)
-{
- struct ibss_rsn *ibss_rsn = ctx;
- struct ibss_rsn_peer *peer;
-
- wpa_printf(MSG_DEBUG, "AUTH: for_each_sta");
-
- for (peer = ibss_rsn->peers; peer; peer = peer->next) {
- if (peer->auth && cb(peer->auth, cb_ctx))
- return 1;
- }
-
- return 0;
-}
-
-
-static void ibss_set_sta_authorized(struct ibss_rsn *ibss_rsn,
- struct ibss_rsn_peer *peer, int authorized)
-{
- int res;
-
- if (authorized) {
- res = wpa_drv_sta_set_flags(ibss_rsn->wpa_s, peer->addr,
- WPA_STA_AUTHORIZED,
- WPA_STA_AUTHORIZED, ~0);
- wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " authorizing port",
- MAC2STR(peer->addr));
- } else {
- res = wpa_drv_sta_set_flags(ibss_rsn->wpa_s, peer->addr,
- 0, 0, ~WPA_STA_AUTHORIZED);
- wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " unauthorizing port",
- MAC2STR(peer->addr));
- }
-
- if (res && errno != ENOENT) {
- wpa_printf(MSG_DEBUG, "Could not set station " MACSTR " flags "
- "for kernel driver (errno=%d)",
- MAC2STR(peer->addr), errno);
- }
-}
-
-
-static void auth_set_eapol(void *ctx, const u8 *addr,
- wpa_eapol_variable var, int value)
-{
- struct ibss_rsn *ibss_rsn = ctx;
- struct ibss_rsn_peer *peer = ibss_rsn_get_peer(ibss_rsn, addr);
-
- if (peer == NULL)
- return;
-
- switch (var) {
- case WPA_EAPOL_authorized:
- ibss_set_sta_authorized(ibss_rsn, peer, value);
- break;
- default:
- /* do not handle any other event */
- wpa_printf(MSG_DEBUG, "AUTH: eapol event not handled %d", var);
- break;
- }
-}
-
-
-static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
- const u8 *own_addr, struct wpa_ssid *ssid)
-{
- struct wpa_auth_config conf;
- static const struct wpa_auth_callbacks cb = {
- .logger = auth_logger,
- .set_eapol = auth_set_eapol,
- .send_eapol = auth_send_eapol,
- .get_psk = auth_get_psk,
- .set_key = auth_set_key,
- .for_each_sta = auth_for_each_sta,
- .disconnect = ibss_rsn_disconnect,
- };
-
- wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
-
- os_memset(&conf, 0, sizeof(conf));
- conf.wpa = 2;
- conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK;
- conf.wpa_pairwise = WPA_CIPHER_CCMP;
- conf.rsn_pairwise = WPA_CIPHER_CCMP;
- conf.wpa_group = WPA_CIPHER_CCMP;
- conf.eapol_version = 2;
- conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
- conf.wpa_group_update_count = 4;
- conf.wpa_pairwise_update_count = 4;
-
- ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb, ibss_rsn);
- if (ibss_rsn->auth_group == NULL) {
- wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
- return -1;
- }
-
- wpa_init_keys(ibss_rsn->auth_group);
-
- return 0;
-}
-
-
-static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
- struct ibss_rsn_peer *peer)
-{
- peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr, NULL);
- if (peer->auth == NULL) {
- wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed");
- return -1;
- }
-
- /* TODO: get peer RSN IE with Probe Request */
- if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, 0,
- (u8 *) "\x30\x14\x01\x00"
- "\x00\x0f\xac\x04"
- "\x01\x00\x00\x0f\xac\x04"
- "\x01\x00\x00\x0f\xac\x02"
- "\x00\x00", 22, NULL, 0, NULL, 0, NULL, 0) !=
- WPA_IE_OK) {
- wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed");
- return -1;
- }
-
- if (wpa_auth_sm_event(peer->auth, WPA_ASSOC))
- return -1;
-
- if (wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth))
- return -1;
-
- return 0;
-}
-
-
-static int ibss_rsn_send_auth(struct ibss_rsn *ibss_rsn, const u8 *da, int seq)
-{
- struct ieee80211_mgmt auth;
- const size_t auth_length = IEEE80211_HDRLEN + sizeof(auth.u.auth);
- struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s;
-
- os_memset(&auth, 0, sizeof(auth));
-
- auth.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_AUTH);
- os_memcpy(auth.da, da, ETH_ALEN);
- os_memcpy(auth.sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(auth.bssid, wpa_s->bssid, ETH_ALEN);
-
- auth.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
- auth.u.auth.auth_transaction = host_to_le16(seq);
- auth.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
-
- wpa_printf(MSG_DEBUG, "RSN: IBSS TX Auth frame (SEQ %d) to " MACSTR,
- seq, MAC2STR(da));
-
- return wpa_drv_send_mlme(wpa_s, (u8 *) &auth, auth_length, 0, 0, 0);
-}
-
-
-static int ibss_rsn_is_auth_started(struct ibss_rsn_peer * peer)
-{
- return peer->authentication_status &
- (IBSS_RSN_AUTH_BY_US | IBSS_RSN_AUTH_EAPOL_BY_US);
-}
-
-
-static struct ibss_rsn_peer *
-ibss_rsn_peer_init(struct ibss_rsn *ibss_rsn, const u8 *addr)
-{
- struct ibss_rsn_peer *peer;
- if (ibss_rsn == NULL)
- return NULL;
-
- peer = ibss_rsn_get_peer(ibss_rsn, addr);
- if (peer) {
- wpa_printf(MSG_DEBUG, "RSN: IBSS Supplicant for peer "MACSTR
- " already running", MAC2STR(addr));
- return peer;
- }
-
- wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Supplicant for peer "MACSTR,
- MAC2STR(addr));
-
- peer = os_zalloc(sizeof(*peer));
- if (peer == NULL) {
- wpa_printf(MSG_DEBUG, "RSN: Could not allocate memory.");
- return NULL;
- }
-
- peer->ibss_rsn = ibss_rsn;
- os_memcpy(peer->addr, addr, ETH_ALEN);
- peer->authentication_status = IBSS_RSN_AUTH_NOT_AUTHENTICATED;
-
- if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr,
- ibss_rsn->psk) < 0) {
- ibss_rsn_free(peer);
- return NULL;
- }
-
- peer->next = ibss_rsn->peers;
- ibss_rsn->peers = peer;
-
- return peer;
-}
-
-
-static void ibss_rsn_auth_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct ibss_rsn_peer *peer = eloop_ctx;
-
- /*
- * Assume peer does not support Authentication exchange or the frame was
- * lost somewhere - start EAPOL Authenticator.
- */
- wpa_printf(MSG_DEBUG,
- "RSN: Timeout on waiting Authentication frame response from "
- MACSTR " - start authenticator", MAC2STR(peer->addr));
-
- peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
- ibss_rsn_auth_init(peer->ibss_rsn, peer);
-}
-
-
-int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
-{
- struct ibss_rsn_peer *peer;
- int res;
-
- if (!ibss_rsn)
- return -1;
-
- /* if the peer already exists, exit immediately */
- peer = ibss_rsn_get_peer(ibss_rsn, addr);
- if (peer)
- return 0;
-
- peer = ibss_rsn_peer_init(ibss_rsn, addr);
- if (peer == NULL)
- return -1;
-
- /* Open Authentication: send first Authentication frame */
- res = ibss_rsn_send_auth(ibss_rsn, addr, 1);
- if (res) {
- /*
- * The driver may not support Authentication frame exchange in
- * IBSS. Ignore authentication and go through EAPOL exchange.
- */
- peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
- return ibss_rsn_auth_init(ibss_rsn, peer);
- } else {
- os_get_reltime(&peer->own_auth_tx);
- eloop_register_timeout(1, 0, ibss_rsn_auth_timeout, peer, NULL);
- }
-
- return 0;
-}
-
-
-static int ibss_rsn_peer_authenticated(struct ibss_rsn *ibss_rsn,
- struct ibss_rsn_peer *peer, int reason)
-{
- int already_started;
-
- if (ibss_rsn == NULL || peer == NULL)
- return -1;
-
- already_started = ibss_rsn_is_auth_started(peer);
- peer->authentication_status |= reason;
-
- if (already_started) {
- wpa_printf(MSG_DEBUG, "RSN: IBSS Authenticator already "
- "started for peer " MACSTR, MAC2STR(peer->addr));
- return 0;
- }
-
- wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Authenticator "
- "for now-authenticated peer " MACSTR, MAC2STR(peer->addr));
-
- return ibss_rsn_auth_init(ibss_rsn, peer);
-}
-
-
-void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac)
-{
- struct ibss_rsn_peer *peer, *prev;
-
- if (ibss_rsn == NULL)
- return;
-
- if (peermac == NULL) {
- /* remove all peers */
- wpa_printf(MSG_DEBUG, "%s: Remove all peers", __func__);
- peer = ibss_rsn->peers;
- while (peer) {
- prev = peer;
- peer = peer->next;
- ibss_rsn_free(prev);
- ibss_rsn->peers = peer;
- }
- } else {
- /* remove specific peer */
- wpa_printf(MSG_DEBUG, "%s: Remove specific peer " MACSTR,
- __func__, MAC2STR(peermac));
-
- for (prev = NULL, peer = ibss_rsn->peers; peer != NULL;
- prev = peer, peer = peer->next) {
- if (os_memcmp(peermac, peer->addr, ETH_ALEN) == 0) {
- if (prev == NULL)
- ibss_rsn->peers = peer->next;
- else
- prev->next = peer->next;
- ibss_rsn_free(peer);
- wpa_printf(MSG_DEBUG, "%s: Successfully "
- "removed a specific peer",
- __func__);
- break;
- }
- }
- }
-}
-
-
-struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct ibss_rsn *ibss_rsn;
-
- ibss_rsn = os_zalloc(sizeof(*ibss_rsn));
- if (ibss_rsn == NULL)
- return NULL;
- ibss_rsn->wpa_s = wpa_s;
-
- if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr, ssid) < 0) {
- ibss_rsn_deinit(ibss_rsn);
- return NULL;
- }
-
- return ibss_rsn;
-}
-
-
-void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn)
-{
- struct ibss_rsn_peer *peer, *prev;
-
- if (ibss_rsn == NULL)
- return;
-
- peer = ibss_rsn->peers;
- while (peer) {
- prev = peer;
- peer = peer->next;
- ibss_rsn_free(prev);
- }
-
- if (ibss_rsn->auth_group)
- wpa_deinit(ibss_rsn->auth_group);
- os_free(ibss_rsn);
-
-}
-
-
-static int ibss_rsn_eapol_dst_supp(const u8 *buf, size_t len)
-{
- const struct ieee802_1x_hdr *hdr;
- const struct wpa_eapol_key *key;
- u16 key_info;
- size_t plen;
-
- /* TODO: Support other EAPOL packets than just EAPOL-Key */
-
- if (len < sizeof(*hdr) + sizeof(*key))
- return -1;
-
- hdr = (const struct ieee802_1x_hdr *) buf;
- key = (const struct wpa_eapol_key *) (hdr + 1);
- plen = be_to_host16(hdr->length);
-
- if (hdr->version < EAPOL_VERSION) {
- /* TODO: backwards compatibility */
- }
- if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
- wpa_printf(MSG_DEBUG, "RSN: EAPOL frame (type %u) discarded, "
- "not a Key frame", hdr->type);
- return -1;
- }
- if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {
- wpa_printf(MSG_DEBUG, "RSN: EAPOL frame payload size %lu "
- "invalid (frame size %lu)",
- (unsigned long) plen, (unsigned long) len);
- return -1;
- }
-
- if (key->type != EAPOL_KEY_TYPE_RSN) {
- wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key type (%d) unknown, "
- "discarded", key->type);
- return -1;
- }
-
- key_info = WPA_GET_BE16(key->key_info);
-
- return !!(key_info & WPA_KEY_INFO_ACK);
-}
-
-
-static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn,
- struct ibss_rsn_peer *peer,
- const u8 *buf, size_t len)
-{
- int supp;
- u8 *tmp;
-
- supp = ibss_rsn_eapol_dst_supp(buf, len);
- if (supp < 0)
- return -1;
-
- tmp = os_memdup(buf, len);
- if (tmp == NULL)
- return -1;
- if (supp) {
- peer->authentication_status |= IBSS_RSN_AUTH_EAPOL_BY_PEER;
- wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Supplicant from "
- MACSTR, MAC2STR(peer->addr));
- wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len);
- } else {
- if (ibss_rsn_is_auth_started(peer) == 0) {
- wpa_printf(MSG_DEBUG, "RSN: IBSS EAPOL for "
- "Authenticator dropped as " MACSTR " is not "
- "authenticated", MAC2STR(peer->addr));
- os_free(tmp);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Authenticator "
- "from "MACSTR, MAC2STR(peer->addr));
- wpa_receive(ibss_rsn->auth_group, peer->auth, tmp, len);
- }
- os_free(tmp);
-
- return 1;
-}
-
-
-int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
- const u8 *buf, size_t len)
-{
- struct ibss_rsn_peer *peer;
-
- if (ibss_rsn == NULL)
- return -1;
-
- peer = ibss_rsn_get_peer(ibss_rsn, src_addr);
- if (peer)
- return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len);
-
- if (ibss_rsn_eapol_dst_supp(buf, len) > 0) {
- /*
- * Create new IBSS peer based on an EAPOL message from the peer
- * Authenticator.
- */
- peer = ibss_rsn_peer_init(ibss_rsn, src_addr);
- if (peer == NULL)
- return -1;
-
- /* assume the peer is authenticated already */
- wpa_printf(MSG_DEBUG, "RSN: IBSS Not using IBSS Auth for peer "
- MACSTR, MAC2STR(src_addr));
- ibss_rsn_peer_authenticated(ibss_rsn, peer,
- IBSS_RSN_AUTH_EAPOL_BY_US);
-
- return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers,
- buf, len);
- }
-
- return 0;
-}
-
-void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk)
-{
- if (ibss_rsn == NULL)
- return;
- os_memcpy(ibss_rsn->psk, psk, PMK_LEN);
-}
-
-
-static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn,
- struct ibss_rsn_peer *peer,
- const u8* addr)
-{
- wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR,
- MAC2STR(addr));
-
- if (peer &&
- peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP |
- IBSS_RSN_SET_PTK_AUTH)) {
- /* Clear the TK for this pair to allow recovery from the case
- * where the peer STA has restarted and lost its key while we
- * still have a pairwise key configured. */
- wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer "
- MACSTR, MAC2STR(addr));
- wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0,
- NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE);
- }
-
- if (peer &&
- peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
- if (peer->own_auth_tx.sec) {
- struct os_reltime now, diff;
- os_get_reltime(&now);
- os_reltime_sub(&now, &peer->own_auth_tx, &diff);
- if (diff.sec == 0 && diff.usec < 500000) {
- wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX",
- (int) diff.usec);
- goto skip_reinit;
- }
- }
- /*
- * A peer sent us an Authentication frame even though it already
- * started an EAPOL session. We should reinit state machines
- * here, but it's much more complicated than just deleting and
- * recreating the state machine
- */
- wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station "
- MACSTR, MAC2STR(addr));
-
- ibss_rsn_stop(ibss_rsn, addr);
- peer = NULL;
- }
-
- if (!peer) {
- peer = ibss_rsn_peer_init(ibss_rsn, addr);
- if (!peer)
- return;
-
- wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR,
- MAC2STR(addr));
- }
-
-skip_reinit:
- /* reply with an Authentication frame now, before sending an EAPOL */
- ibss_rsn_send_auth(ibss_rsn, addr, 2);
- /* no need to start another AUTH challenge in the other way.. */
- ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US);
-}
-
-
-void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame,
- size_t len)
-{
- const struct ieee80211_mgmt *header;
- struct ibss_rsn_peer *peer;
- size_t auth_length;
-
- header = (const struct ieee80211_mgmt *) auth_frame;
- auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
-
- if (ibss_rsn == NULL || len < auth_length)
- return;
-
- if (le_to_host16(header->u.auth.auth_alg) != WLAN_AUTH_OPEN ||
- le_to_host16(header->u.auth.status_code) != WLAN_STATUS_SUCCESS)
- return;
-
- peer = ibss_rsn_get_peer(ibss_rsn, header->sa);
-
- switch (le_to_host16(header->u.auth.auth_transaction)) {
- case 1:
- ibss_rsn_handle_auth_1_of_2(ibss_rsn, peer, header->sa);
- break;
- case 2:
- wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 2) from "
- MACSTR, MAC2STR(header->sa));
- if (!peer) {
- wpa_printf(MSG_DEBUG, "RSN: Received Auth seq 2 from "
- "unknown STA " MACSTR, MAC2STR(header->sa));
- break;
- }
-
- /* authentication has been completed */
- eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL);
- wpa_printf(MSG_DEBUG, "RSN: IBSS Auth completed with " MACSTR,
- MAC2STR(header->sa));
- ibss_rsn_peer_authenticated(ibss_rsn, peer,
- IBSS_RSN_AUTH_BY_US);
- break;
- }
-}
diff --git a/wpa_supplicant/ibss_rsn.h b/wpa_supplicant/ibss_rsn.h
deleted file mode 100644
index 626c543546c8..000000000000
--- a/wpa_supplicant/ibss_rsn.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * wpa_supplicant - IBSS RSN
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef IBSS_RSN_H
-#define IBSS_RSN_H
-
-struct ibss_rsn;
-
-/* not authenticated */
-#define IBSS_RSN_AUTH_NOT_AUTHENTICATED 0x00
-/* remote peer sent an EAPOL message */
-#define IBSS_RSN_AUTH_EAPOL_BY_PEER 0x01
-/* we sent an AUTH message with seq 1 */
-#define IBSS_RSN_AUTH_BY_US 0x02
-/* we sent an EAPOL message */
-#define IBSS_RSN_AUTH_EAPOL_BY_US 0x04
-/* PTK derived as supplicant */
-#define IBSS_RSN_SET_PTK_SUPP 0x08
-/* PTK derived as authenticator */
-#define IBSS_RSN_SET_PTK_AUTH 0x10
-/* PTK completion reported */
-#define IBSS_RSN_REPORTED_PTK 0x20
-
-struct ibss_rsn_peer {
- struct ibss_rsn_peer *next;
- struct ibss_rsn *ibss_rsn;
-
- u8 addr[ETH_ALEN];
-
- struct wpa_sm *supp;
- enum wpa_states supp_state;
- u8 supp_ie[80];
- size_t supp_ie_len;
-
- struct wpa_state_machine *auth;
- int authentication_status;
-
- struct os_reltime own_auth_tx;
-};
-
-struct ibss_rsn {
- struct wpa_supplicant *wpa_s;
- struct wpa_authenticator *auth_group;
- struct ibss_rsn_peer *peers;
- u8 psk[PMK_LEN];
-};
-
-
-struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn);
-int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
-void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac);
-int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
- const u8 *buf, size_t len);
-void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);
-void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame,
- size_t len);
-
-#endif /* IBSS_RSN_H */
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
deleted file mode 100644
index 71a5c16510d4..000000000000
--- a/wpa_supplicant/interworking.c
+++ /dev/null
@@ -1,3293 +0,0 @@
-/*
- * Interworking (IEEE 802.11u)
- * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
- * Copyright (c) 2011-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/gas.h"
-#include "common/wpa_ctrl.h"
-#include "utils/pcsc_funcs.h"
-#include "utils/eloop.h"
-#include "drivers/driver.h"
-#include "eap_common/eap_defs.h"
-#include "eap_peer/eap.h"
-#include "eap_peer/eap_methods.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "config_ssid.h"
-#include "bss.h"
-#include "scan.h"
-#include "notify.h"
-#include "driver_i.h"
-#include "gas_query.h"
-#include "hs20_supplicant.h"
-#include "interworking.h"
-
-
-#if defined(EAP_SIM) | defined(EAP_SIM_DYNAMIC)
-#define INTERWORKING_3GPP
-#else
-#if defined(EAP_AKA) | defined(EAP_AKA_DYNAMIC)
-#define INTERWORKING_3GPP
-#else
-#if defined(EAP_AKA_PRIME) | defined(EAP_AKA_PRIME_DYNAMIC)
-#define INTERWORKING_3GPP
-#endif
-#endif
-#endif
-
-static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s);
-static struct wpa_cred * interworking_credentials_available_realm(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded);
-static struct wpa_cred * interworking_credentials_available_3gpp(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded);
-
-
-static int cred_prio_cmp(const struct wpa_cred *a, const struct wpa_cred *b)
-{
- if (a->priority > b->priority)
- return 1;
- if (a->priority < b->priority)
- return -1;
- if (a->provisioning_sp == NULL || b->provisioning_sp == NULL ||
- os_strcmp(a->provisioning_sp, b->provisioning_sp) != 0)
- return 0;
- if (a->sp_priority < b->sp_priority)
- return 1;
- if (a->sp_priority > b->sp_priority)
- return -1;
- return 0;
-}
-
-
-static void interworking_reconnect(struct wpa_supplicant *wpa_s)
-{
- unsigned int tried;
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- }
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- tried = wpa_s->interworking_fast_assoc_tried;
- wpa_s->interworking_fast_assoc_tried = 1;
-
- if (!tried && wpa_supplicant_fast_associate(wpa_s) >= 0)
- return;
-
- wpa_s->interworking_fast_assoc_tried = 0;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-static struct wpabuf * anqp_build_req(u16 info_ids[], size_t num_ids,
- struct wpabuf *extra)
-{
- struct wpabuf *buf;
- size_t i;
- u8 *len_pos;
-
- buf = gas_anqp_build_initial_req(0, 4 + num_ids * 2 +
- (extra ? wpabuf_len(extra) : 0));
- if (buf == NULL)
- return NULL;
-
- if (num_ids > 0) {
- len_pos = gas_anqp_add_element(buf, ANQP_QUERY_LIST);
- for (i = 0; i < num_ids; i++)
- wpabuf_put_le16(buf, info_ids[i]);
- gas_anqp_set_element_len(buf, len_pos);
- }
- if (extra)
- wpabuf_put_buf(buf, extra);
-
- gas_anqp_set_len(buf);
-
- return buf;
-}
-
-
-static void interworking_anqp_resp_cb(void *ctx, const u8 *dst,
- u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp,
- u16 status_code)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_printf(MSG_DEBUG, "ANQP: Response callback dst=" MACSTR
- " dialog_token=%u result=%d status_code=%u",
- MAC2STR(dst), dialog_token, result, status_code);
- anqp_resp_cb(wpa_s, dst, dialog_token, result, adv_proto, resp,
- status_code);
- interworking_next_anqp_fetch(wpa_s);
-}
-
-
-static int cred_with_roaming_consortium(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->roaming_consortium_len)
- return 1;
- if (cred->required_roaming_consortium_len)
- return 1;
- if (cred->num_roaming_consortiums)
- return 1;
- }
- return 0;
-}
-
-
-static int cred_with_3gpp(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->pcsc || cred->imsi)
- return 1;
- }
- return 0;
-}
-
-
-static int cred_with_nai_realm(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->pcsc || cred->imsi)
- continue;
- if (!cred->eap_method)
- return 1;
- if (cred->realm)
- return 1;
- }
- return 0;
-}
-
-
-static int cred_with_domain(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->domain || cred->pcsc || cred->imsi ||
- cred->roaming_partner)
- return 1;
- }
- return 0;
-}
-
-
-#ifdef CONFIG_HS20
-
-static int cred_with_min_backhaul(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->min_dl_bandwidth_home ||
- cred->min_ul_bandwidth_home ||
- cred->min_dl_bandwidth_roaming ||
- cred->min_ul_bandwidth_roaming)
- return 1;
- }
- return 0;
-}
-
-
-static int cred_with_conn_capab(struct wpa_supplicant *wpa_s)
-{
- struct wpa_cred *cred;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->num_req_conn_capab)
- return 1;
- }
- return 0;
-}
-
-#endif /* CONFIG_HS20 */
-
-
-static int additional_roaming_consortiums(struct wpa_bss *bss)
-{
- const u8 *ie;
- ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM);
- if (ie == NULL || ie[1] == 0)
- return 0;
- return ie[2]; /* Number of ANQP OIs */
-}
-
-
-static void interworking_continue_anqp(void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- interworking_next_anqp_fetch(wpa_s);
-}
-
-
-static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
- struct wpabuf *buf;
- int ret = 0;
- int res;
- u16 info_ids[8];
- size_t num_info_ids = 0;
- struct wpabuf *extra = NULL;
- int all = wpa_s->fetch_all_anqp;
-
- wpa_msg(wpa_s, MSG_DEBUG, "Interworking: ANQP Query Request to " MACSTR,
- MAC2STR(bss->bssid));
- wpa_s->interworking_gas_bss = bss;
-
- info_ids[num_info_ids++] = ANQP_CAPABILITY_LIST;
- if (all) {
- info_ids[num_info_ids++] = ANQP_VENUE_NAME;
- info_ids[num_info_ids++] = ANQP_NETWORK_AUTH_TYPE;
- }
- if (all || (cred_with_roaming_consortium(wpa_s) &&
- additional_roaming_consortiums(bss)))
- info_ids[num_info_ids++] = ANQP_ROAMING_CONSORTIUM;
- if (all)
- info_ids[num_info_ids++] = ANQP_IP_ADDR_TYPE_AVAILABILITY;
- if (all || cred_with_nai_realm(wpa_s))
- info_ids[num_info_ids++] = ANQP_NAI_REALM;
- if (all || cred_with_3gpp(wpa_s)) {
- info_ids[num_info_ids++] = ANQP_3GPP_CELLULAR_NETWORK;
- wpa_supplicant_scard_init(wpa_s, NULL);
- }
- if (all || cred_with_domain(wpa_s))
- info_ids[num_info_ids++] = ANQP_DOMAIN_NAME;
- wpa_hexdump(MSG_DEBUG, "Interworking: ANQP Query info",
- (u8 *) info_ids, num_info_ids * 2);
-
-#ifdef CONFIG_HS20
- if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) {
- u8 *len_pos;
-
- extra = wpabuf_alloc(100);
- if (!extra)
- return -1;
-
- len_pos = gas_anqp_add_element(extra, ANQP_VENDOR_SPECIFIC);
- wpabuf_put_be24(extra, OUI_WFA);
- wpabuf_put_u8(extra, HS20_ANQP_OUI_TYPE);
- wpabuf_put_u8(extra, HS20_STYPE_QUERY_LIST);
- wpabuf_put_u8(extra, 0); /* Reserved */
- wpabuf_put_u8(extra, HS20_STYPE_CAPABILITY_LIST);
- if (all)
- wpabuf_put_u8(extra,
- HS20_STYPE_OPERATOR_FRIENDLY_NAME);
- if (all || cred_with_min_backhaul(wpa_s))
- wpabuf_put_u8(extra, HS20_STYPE_WAN_METRICS);
- if (all || cred_with_conn_capab(wpa_s))
- wpabuf_put_u8(extra, HS20_STYPE_CONNECTION_CAPABILITY);
- if (all)
- wpabuf_put_u8(extra, HS20_STYPE_OPERATING_CLASS);
- if (all) {
- wpabuf_put_u8(extra, HS20_STYPE_OSU_PROVIDERS_LIST);
- wpabuf_put_u8(extra, HS20_STYPE_OSU_PROVIDERS_NAI_LIST);
- }
- gas_anqp_set_element_len(extra, len_pos);
- }
-#endif /* CONFIG_HS20 */
-
- buf = anqp_build_req(info_ids, num_info_ids, extra);
- wpabuf_free(extra);
- if (buf == NULL)
- return -1;
-
- res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, 0, buf,
- interworking_anqp_resp_cb, wpa_s);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request");
- wpabuf_free(buf);
- ret = -1;
- eloop_register_timeout(0, 0, interworking_continue_anqp, wpa_s,
- NULL);
- } else
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Query started with dialog token %u", res);
-
- return ret;
-}
-
-
-struct nai_realm_eap {
- u8 method;
- u8 inner_method;
- enum nai_realm_eap_auth_inner_non_eap inner_non_eap;
- u8 cred_type;
- u8 tunneled_cred_type;
-};
-
-struct nai_realm {
- u8 encoding;
- char *realm;
- u8 eap_count;
- struct nai_realm_eap *eap;
-};
-
-
-static void nai_realm_free(struct nai_realm *realms, u16 count)
-{
- u16 i;
-
- if (realms == NULL)
- return;
- for (i = 0; i < count; i++) {
- os_free(realms[i].eap);
- os_free(realms[i].realm);
- }
- os_free(realms);
-}
-
-
-static const u8 * nai_realm_parse_eap(struct nai_realm_eap *e, const u8 *pos,
- const u8 *end)
-{
- u8 elen, auth_count, a;
- const u8 *e_end;
-
- if (end - pos < 3) {
- wpa_printf(MSG_DEBUG, "No room for EAP Method fixed fields");
- return NULL;
- }
-
- elen = *pos++;
- if (elen > end - pos || elen < 2) {
- wpa_printf(MSG_DEBUG, "No room for EAP Method subfield");
- return NULL;
- }
- e_end = pos + elen;
- e->method = *pos++;
- auth_count = *pos++;
- wpa_printf(MSG_DEBUG, "EAP Method: len=%u method=%u auth_count=%u",
- elen, e->method, auth_count);
-
- for (a = 0; a < auth_count; a++) {
- u8 id, len;
-
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG,
- "No room for Authentication Parameter subfield header");
- return NULL;
- }
-
- id = *pos++;
- len = *pos++;
- if (len > end - pos) {
- wpa_printf(MSG_DEBUG,
- "No room for Authentication Parameter subfield");
- return NULL;
- }
-
- switch (id) {
- case NAI_REALM_EAP_AUTH_NON_EAP_INNER_AUTH:
- if (len < 1)
- break;
- e->inner_non_eap = *pos;
- if (e->method != EAP_TYPE_TTLS)
- break;
- switch (*pos) {
- case NAI_REALM_INNER_NON_EAP_PAP:
- wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP");
- break;
- case NAI_REALM_INNER_NON_EAP_CHAP:
- wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP");
- break;
- case NAI_REALM_INNER_NON_EAP_MSCHAP:
- wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP");
- break;
- case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
- wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2");
- break;
- }
- break;
- case NAI_REALM_EAP_AUTH_INNER_AUTH_EAP_METHOD:
- if (len < 1)
- break;
- e->inner_method = *pos;
- wpa_printf(MSG_DEBUG, "Inner EAP method: %u",
- e->inner_method);
- break;
- case NAI_REALM_EAP_AUTH_CRED_TYPE:
- if (len < 1)
- break;
- e->cred_type = *pos;
- wpa_printf(MSG_DEBUG, "Credential Type: %u",
- e->cred_type);
- break;
- case NAI_REALM_EAP_AUTH_TUNNELED_CRED_TYPE:
- if (len < 1)
- break;
- e->tunneled_cred_type = *pos;
- wpa_printf(MSG_DEBUG, "Tunneled EAP Method Credential "
- "Type: %u", e->tunneled_cred_type);
- break;
- default:
- wpa_printf(MSG_DEBUG, "Unsupported Authentication "
- "Parameter: id=%u len=%u", id, len);
- wpa_hexdump(MSG_DEBUG, "Authentication Parameter "
- "Value", pos, len);
- break;
- }
-
- pos += len;
- }
-
- return e_end;
-}
-
-
-static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos,
- const u8 *end)
-{
- u16 len;
- const u8 *f_end;
- u8 realm_len, e;
-
- if (end - pos < 4) {
- wpa_printf(MSG_DEBUG, "No room for NAI Realm Data "
- "fixed fields");
- return NULL;
- }
-
- len = WPA_GET_LE16(pos); /* NAI Realm Data field Length */
- pos += 2;
- if (len > end - pos || len < 3) {
- wpa_printf(MSG_DEBUG, "No room for NAI Realm Data "
- "(len=%u; left=%u)",
- len, (unsigned int) (end - pos));
- return NULL;
- }
- f_end = pos + len;
-
- r->encoding = *pos++;
- realm_len = *pos++;
- if (realm_len > f_end - pos) {
- wpa_printf(MSG_DEBUG, "No room for NAI Realm "
- "(len=%u; left=%u)",
- realm_len, (unsigned int) (f_end - pos));
- return NULL;
- }
- wpa_hexdump_ascii(MSG_DEBUG, "NAI Realm", pos, realm_len);
- r->realm = dup_binstr(pos, realm_len);
- if (r->realm == NULL)
- return NULL;
- pos += realm_len;
-
- if (f_end - pos < 1) {
- wpa_printf(MSG_DEBUG, "No room for EAP Method Count");
- return NULL;
- }
- r->eap_count = *pos++;
- wpa_printf(MSG_DEBUG, "EAP Count: %u", r->eap_count);
- if (r->eap_count * 3 > f_end - pos) {
- wpa_printf(MSG_DEBUG, "No room for EAP Methods");
- return NULL;
- }
- r->eap = os_calloc(r->eap_count, sizeof(struct nai_realm_eap));
- if (r->eap == NULL)
- return NULL;
-
- for (e = 0; e < r->eap_count; e++) {
- pos = nai_realm_parse_eap(&r->eap[e], pos, f_end);
- if (pos == NULL)
- return NULL;
- }
-
- return f_end;
-}
-
-
-static struct nai_realm * nai_realm_parse(struct wpabuf *anqp, u16 *count)
-{
- struct nai_realm *realm;
- const u8 *pos, *end;
- u16 i, num;
- size_t left;
-
- if (anqp == NULL)
- return NULL;
- left = wpabuf_len(anqp);
- if (left < 2)
- return NULL;
-
- pos = wpabuf_head_u8(anqp);
- end = pos + left;
- num = WPA_GET_LE16(pos);
- wpa_printf(MSG_DEBUG, "NAI Realm Count: %u", num);
- pos += 2;
- left -= 2;
-
- if (num > left / 5) {
- wpa_printf(MSG_DEBUG, "Invalid NAI Realm Count %u - not "
- "enough data (%u octets) for that many realms",
- num, (unsigned int) left);
- return NULL;
- }
-
- realm = os_calloc(num, sizeof(struct nai_realm));
- if (realm == NULL)
- return NULL;
-
- for (i = 0; i < num; i++) {
- pos = nai_realm_parse_realm(&realm[i], pos, end);
- if (pos == NULL) {
- nai_realm_free(realm, num);
- return NULL;
- }
- }
-
- *count = num;
- return realm;
-}
-
-
-static int nai_realm_match(struct nai_realm *realm, const char *home_realm)
-{
- char *tmp, *pos, *end;
- int match = 0;
-
- if (realm->realm == NULL || home_realm == NULL)
- return 0;
-
- if (os_strchr(realm->realm, ';') == NULL)
- return os_strcasecmp(realm->realm, home_realm) == 0;
-
- tmp = os_strdup(realm->realm);
- if (tmp == NULL)
- return 0;
-
- pos = tmp;
- while (*pos) {
- end = os_strchr(pos, ';');
- if (end)
- *end = '\0';
- if (os_strcasecmp(pos, home_realm) == 0) {
- match = 1;
- break;
- }
- if (end == NULL)
- break;
- pos = end + 1;
- }
-
- os_free(tmp);
-
- return match;
-}
-
-
-static int nai_realm_cred_username(struct wpa_supplicant *wpa_s,
- struct nai_realm_eap *eap)
-{
- if (eap_get_name(EAP_VENDOR_IETF, eap->method) == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: EAP method not supported: %d",
- eap->method);
- return 0; /* method not supported */
- }
-
- if (eap->method != EAP_TYPE_TTLS && eap->method != EAP_TYPE_PEAP &&
- eap->method != EAP_TYPE_FAST) {
- /* Only tunneled methods with username/password supported */
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: Method: %d is not TTLS, PEAP, or FAST",
- eap->method);
- return 0;
- }
-
- if (eap->method == EAP_TYPE_PEAP || eap->method == EAP_TYPE_FAST) {
- if (eap->inner_method &&
- eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: PEAP/FAST: Inner method not supported: %d",
- eap->inner_method);
- return 0;
- }
- if (!eap->inner_method &&
- eap_get_name(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2) == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: MSCHAPv2 not supported");
- return 0;
- }
- }
-
- if (eap->method == EAP_TYPE_TTLS) {
- if (eap->inner_method == 0 && eap->inner_non_eap == 0)
- return 1; /* Assume TTLS/MSCHAPv2 is used */
- if (eap->inner_method &&
- eap_get_name(EAP_VENDOR_IETF, eap->inner_method) == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: TTLS, but inner not supported: %d",
- eap->inner_method);
- return 0;
- }
- if (eap->inner_non_eap &&
- eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_PAP &&
- eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_CHAP &&
- eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAP &&
- eap->inner_non_eap != NAI_REALM_INNER_NON_EAP_MSCHAPV2) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: TTLS, inner-non-eap not supported: %d",
- eap->inner_non_eap);
- return 0;
- }
- }
-
- if (eap->inner_method &&
- eap->inner_method != EAP_TYPE_GTC &&
- eap->inner_method != EAP_TYPE_MSCHAPV2) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-username: inner-method not GTC or MSCHAPv2: %d",
- eap->inner_method);
- return 0;
- }
-
- return 1;
-}
-
-
-static int nai_realm_cred_cert(struct wpa_supplicant *wpa_s,
- struct nai_realm_eap *eap)
-{
- if (eap_get_name(EAP_VENDOR_IETF, eap->method) == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-cert: Method not supported: %d",
- eap->method);
- return 0; /* method not supported */
- }
-
- if (eap->method != EAP_TYPE_TLS) {
- /* Only EAP-TLS supported for credential authentication */
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-cred-cert: Method not TLS: %d",
- eap->method);
- return 0;
- }
-
- return 1;
-}
-
-
-static struct nai_realm_eap * nai_realm_find_eap(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- struct nai_realm *realm)
-{
- u8 e;
-
- if (cred->username == NULL ||
- cred->username[0] == '\0' ||
- ((cred->password == NULL ||
- cred->password[0] == '\0') &&
- (cred->private_key == NULL ||
- cred->private_key[0] == '\0') &&
- (!cred->key_id || cred->key_id[0] == '\0'))) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "nai-realm-find-eap: incomplete cred info: username: %s password: %s private_key: %s key_id: %s",
- cred->username ? cred->username : "NULL",
- cred->password ? cred->password : "NULL",
- cred->private_key ? cred->private_key : "NULL",
- cred->key_id ? cred->key_id : "NULL");
- return NULL;
- }
-
- for (e = 0; e < realm->eap_count; e++) {
- struct nai_realm_eap *eap = &realm->eap[e];
- if (cred->password && cred->password[0] &&
- nai_realm_cred_username(wpa_s, eap))
- return eap;
- if (((cred->private_key && cred->private_key[0]) ||
- (cred->key_id && cred->key_id[0])) &&
- nai_realm_cred_cert(wpa_s, eap))
- return eap;
- }
-
- return NULL;
-}
-
-
-#ifdef INTERWORKING_3GPP
-
-static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len)
-{
- u8 plmn[3], plmn2[3];
- const u8 *pos, *end;
- u8 udhl;
-
- /*
- * See Annex A of 3GPP TS 24.234 v8.1.0 for description. The network
- * operator is allowed to include only two digits of the MNC, so allow
- * matches based on both two and three digit MNC assumptions. Since some
- * SIM/USIM cards may not expose MNC length conveniently, we may be
- * provided the default MNC length 3 here and as such, checking with MNC
- * length 2 is justifiable even though 3GPP TS 24.234 does not mention
- * that case. Anyway, MCC/MNC pair where both 2 and 3 digit MNC is used
- * with otherwise matching values would not be good idea in general, so
- * this should not result in selecting incorrect networks.
- */
- /* Match with 3 digit MNC */
- plmn[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
- plmn[1] = (imsi[2] - '0') | ((imsi[5] - '0') << 4);
- plmn[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
- /* Match with 2 digit MNC */
- plmn2[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
- plmn2[1] = (imsi[2] - '0') | 0xf0;
- plmn2[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
-
- if (anqp == NULL)
- return 0;
- pos = wpabuf_head_u8(anqp);
- end = pos + wpabuf_len(anqp);
- if (end - pos < 2)
- return 0;
- if (*pos != 0) {
- wpa_printf(MSG_DEBUG, "Unsupported GUD version 0x%x", *pos);
- return 0;
- }
- pos++;
- udhl = *pos++;
- if (udhl > end - pos) {
- wpa_printf(MSG_DEBUG, "Invalid UDHL");
- return 0;
- }
- end = pos + udhl;
-
- wpa_printf(MSG_DEBUG, "Interworking: Matching against MCC/MNC alternatives: %02x:%02x:%02x or %02x:%02x:%02x (IMSI %s, MNC length %d)",
- plmn[0], plmn[1], plmn[2], plmn2[0], plmn2[1], plmn2[2],
- imsi, mnc_len);
-
- while (end - pos >= 2) {
- u8 iei, len;
- const u8 *l_end;
- iei = *pos++;
- len = *pos++ & 0x7f;
- if (len > end - pos)
- break;
- l_end = pos + len;
-
- if (iei == 0 && len > 0) {
- /* PLMN List */
- u8 num, i;
- wpa_hexdump(MSG_DEBUG, "Interworking: PLMN List information element",
- pos, len);
- num = *pos++;
- for (i = 0; i < num; i++) {
- if (l_end - pos < 3)
- break;
- if (os_memcmp(pos, plmn, 3) == 0 ||
- os_memcmp(pos, plmn2, 3) == 0)
- return 1; /* Found matching PLMN */
- pos += 3;
- }
- } else {
- wpa_hexdump(MSG_DEBUG, "Interworking: Unrecognized 3GPP information element",
- pos, len);
- }
-
- pos = l_end;
- }
-
- return 0;
-}
-
-
-static int build_root_nai(char *nai, size_t nai_len, const char *imsi,
- size_t mnc_len, char prefix)
-{
- const char *sep, *msin;
- char *end, *pos;
- size_t msin_len, plmn_len;
-
- /*
- * TS 23.003, Clause 14 (3GPP to WLAN Interworking)
- * Root NAI:
- * <aka:0|sim:1><IMSI>@wlan.mnc<MNC>.mcc<MCC>.3gppnetwork.org
- * <MNC> is zero-padded to three digits in case two-digit MNC is used
- */
-
- if (imsi == NULL || os_strlen(imsi) > 16) {
- wpa_printf(MSG_DEBUG, "No valid IMSI available");
- return -1;
- }
- sep = os_strchr(imsi, '-');
- if (sep) {
- plmn_len = sep - imsi;
- msin = sep + 1;
- } else if (mnc_len && os_strlen(imsi) >= 3 + mnc_len) {
- plmn_len = 3 + mnc_len;
- msin = imsi + plmn_len;
- } else
- return -1;
- if (plmn_len != 5 && plmn_len != 6)
- return -1;
- msin_len = os_strlen(msin);
-
- pos = nai;
- end = nai + nai_len;
- if (prefix)
- *pos++ = prefix;
- os_memcpy(pos, imsi, plmn_len);
- pos += plmn_len;
- os_memcpy(pos, msin, msin_len);
- pos += msin_len;
- pos += os_snprintf(pos, end - pos, "@wlan.mnc");
- if (plmn_len == 5) {
- *pos++ = '0';
- *pos++ = imsi[3];
- *pos++ = imsi[4];
- } else {
- *pos++ = imsi[3];
- *pos++ = imsi[4];
- *pos++ = imsi[5];
- }
- os_snprintf(pos, end - pos, ".mcc%c%c%c.3gppnetwork.org",
- imsi[0], imsi[1], imsi[2]);
-
- return 0;
-}
-
-
-static int set_root_nai(struct wpa_ssid *ssid, const char *imsi, char prefix)
-{
- char nai[100];
- if (build_root_nai(nai, sizeof(nai), imsi, 0, prefix) < 0)
- return -1;
- return wpa_config_set_quoted(ssid, "identity", nai);
-}
-
-#endif /* INTERWORKING_3GPP */
-
-
-static int already_connected(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred, struct wpa_bss *bss)
-{
- struct wpa_ssid *ssid, *sel_ssid;
- struct wpa_bss *selected;
-
- if (wpa_s->wpa_state < WPA_ASSOCIATED || wpa_s->current_ssid == NULL)
- return 0;
-
- ssid = wpa_s->current_ssid;
- if (ssid->parent_cred != cred)
- return 0;
-
- if (ssid->ssid_len != bss->ssid_len ||
- os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0)
- return 0;
-
- sel_ssid = NULL;
- selected = wpa_supplicant_pick_network(wpa_s, &sel_ssid);
- if (selected && sel_ssid && sel_ssid->priority > ssid->priority)
- return 0; /* higher priority network in scan results */
-
- return 1;
-}
-
-
-static void remove_duplicate_network(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- struct wpa_bss *bss)
-{
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid->parent_cred != cred)
- continue;
- if (ssid->ssid_len != bss->ssid_len ||
- os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) != 0)
- continue;
-
- break;
- }
-
- if (ssid == NULL)
- return;
-
- wpa_printf(MSG_DEBUG, "Interworking: Remove duplicate network entry for the same credential");
-
- if (ssid == wpa_s->current_ssid) {
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- }
-
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
-}
-
-
-static int interworking_set_hs20_params(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- const char *key_mgmt = NULL;
-#ifdef CONFIG_IEEE80211R
- int res;
- struct wpa_driver_capa capa;
-
- res = wpa_drv_get_capa(wpa_s, &capa);
- if (res == 0 && capa.key_mgmt_iftype[WPA_IF_STATION] &
- WPA_DRIVER_CAPA_KEY_MGMT_FT) {
- key_mgmt = wpa_s->conf->pmf != NO_MGMT_FRAME_PROTECTION ?
- "WPA-EAP WPA-EAP-SHA256 FT-EAP" :
- "WPA-EAP FT-EAP";
- }
-#endif /* CONFIG_IEEE80211R */
-
- if (!key_mgmt)
- key_mgmt = wpa_s->conf->pmf != NO_MGMT_FRAME_PROTECTION ?
- "WPA-EAP WPA-EAP-SHA256" : "WPA-EAP";
- if (wpa_config_set(ssid, "key_mgmt", key_mgmt, 0) < 0 ||
- wpa_config_set(ssid, "proto", "RSN", 0) < 0 ||
- wpa_config_set(ssid, "ieee80211w",
- wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_REQUIRED ?
- "2" : "1", 0) < 0 ||
- wpa_config_set(ssid, "pairwise", "CCMP", 0) < 0)
- return -1;
- return 0;
-}
-
-
-static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- struct wpa_bss *bss, int only_add)
-{
-#ifdef INTERWORKING_3GPP
- struct wpa_ssid *ssid;
- int eap_type;
- int res;
- char prefix;
-
- if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL)
- return -1;
-
- wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Connect with " MACSTR
- " (3GPP)", MAC2STR(bss->bssid));
-
- if (already_connected(wpa_s, cred, bss)) {
- wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
- MAC2STR(bss->bssid));
- return wpa_s->current_ssid->id;
- }
-
- remove_duplicate_network(wpa_s, cred, bss);
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL)
- return -1;
- ssid->parent_cred = cred;
-
- wpas_notify_network_added(wpa_s, ssid);
- wpa_config_set_network_defaults(ssid);
- ssid->priority = cred->priority;
- ssid->temporary = 1;
- ssid->ssid = os_zalloc(bss->ssid_len + 1);
- if (ssid->ssid == NULL)
- goto fail;
- os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
- ssid->ssid_len = bss->ssid_len;
- ssid->eap.sim_num = cred->sim_num;
-
- if (interworking_set_hs20_params(wpa_s, ssid) < 0)
- goto fail;
-
- eap_type = EAP_TYPE_SIM;
- if (cred->pcsc && wpa_s->scard && scard_supports_umts(wpa_s->scard))
- eap_type = EAP_TYPE_AKA;
- if (cred->eap_method && cred->eap_method[0].vendor == EAP_VENDOR_IETF) {
- if (cred->eap_method[0].method == EAP_TYPE_SIM ||
- cred->eap_method[0].method == EAP_TYPE_AKA ||
- cred->eap_method[0].method == EAP_TYPE_AKA_PRIME)
- eap_type = cred->eap_method[0].method;
- }
-
- switch (eap_type) {
- case EAP_TYPE_SIM:
- prefix = '1';
- res = wpa_config_set(ssid, "eap", "SIM", 0);
- break;
- case EAP_TYPE_AKA:
- prefix = '0';
- res = wpa_config_set(ssid, "eap", "AKA", 0);
- break;
- case EAP_TYPE_AKA_PRIME:
- prefix = '6';
- res = wpa_config_set(ssid, "eap", "AKA'", 0);
- break;
- default:
- res = -1;
- break;
- }
- if (res < 0) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Selected EAP method (%d) not supported", eap_type);
- goto fail;
- }
-
- if (!cred->pcsc && set_root_nai(ssid, cred->imsi, prefix) < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "Failed to set Root NAI");
- goto fail;
- }
-
- if (cred->milenage && cred->milenage[0]) {
- if (wpa_config_set_quoted(ssid, "password",
- cred->milenage) < 0)
- goto fail;
- } else if (cred->pcsc) {
- if (wpa_config_set_quoted(ssid, "pcsc", "") < 0)
- goto fail;
- if (wpa_s->conf->pcsc_pin &&
- wpa_config_set_quoted(ssid, "pin", wpa_s->conf->pcsc_pin)
- < 0)
- goto fail;
- }
-
- wpa_s->next_ssid = ssid;
- wpa_config_update_prio_list(wpa_s->conf);
- if (!only_add)
- interworking_reconnect(wpa_s);
-
- return ssid->id;
-
-fail:
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
-#endif /* INTERWORKING_3GPP */
- return -1;
-}
-
-
-static int roaming_consortium_element_match(const u8 *ie, const u8 *rc_id,
- size_t rc_len)
-{
- const u8 *pos, *end;
- u8 lens;
-
- if (ie == NULL)
- return 0;
-
- pos = ie + 2;
- end = ie + 2 + ie[1];
-
- /* Roaming Consortium element:
- * Number of ANQP OIs
- * OI #1 and #2 lengths
- * OI #1, [OI #2], [OI #3]
- */
-
- if (end - pos < 2)
- return 0;
-
- pos++; /* skip Number of ANQP OIs */
- lens = *pos++;
- if ((lens & 0x0f) + (lens >> 4) > end - pos)
- return 0;
-
- if ((lens & 0x0f) == rc_len && os_memcmp(pos, rc_id, rc_len) == 0)
- return 1;
- pos += lens & 0x0f;
-
- if ((lens >> 4) == rc_len && os_memcmp(pos, rc_id, rc_len) == 0)
- return 1;
- pos += lens >> 4;
-
- if (pos < end && (size_t) (end - pos) == rc_len &&
- os_memcmp(pos, rc_id, rc_len) == 0)
- return 1;
-
- return 0;
-}
-
-
-static int roaming_consortium_anqp_match(const struct wpabuf *anqp,
- const u8 *rc_id, size_t rc_len)
-{
- const u8 *pos, *end;
- u8 len;
-
- if (anqp == NULL)
- return 0;
-
- pos = wpabuf_head(anqp);
- end = pos + wpabuf_len(anqp);
-
- /* Set of <OI Length, OI> duples */
- while (pos < end) {
- len = *pos++;
- if (len > end - pos)
- break;
- if (len == rc_len && os_memcmp(pos, rc_id, rc_len) == 0)
- return 1;
- pos += len;
- }
-
- return 0;
-}
-
-
-static int roaming_consortium_match(const u8 *ie, const struct wpabuf *anqp,
- const u8 *rc_id, size_t rc_len)
-{
- return roaming_consortium_element_match(ie, rc_id, rc_len) ||
- roaming_consortium_anqp_match(anqp, rc_id, rc_len);
-}
-
-
-static int cred_roaming_consortiums_match(const u8 *ie,
- const struct wpabuf *anqp,
- const struct wpa_cred *cred)
-{
- unsigned int i;
-
- for (i = 0; i < cred->num_roaming_consortiums; i++) {
- if (roaming_consortium_match(ie, anqp,
- cred->roaming_consortiums[i],
- cred->roaming_consortiums_len[i]))
- return 1;
- }
-
- return 0;
-}
-
-
-static int cred_no_required_oi_match(struct wpa_cred *cred, struct wpa_bss *bss)
-{
- const u8 *ie;
-
- if (cred->required_roaming_consortium_len == 0)
- return 0;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM);
-
- if (ie == NULL &&
- (bss->anqp == NULL || bss->anqp->roaming_consortium == NULL))
- return 1;
-
- return !roaming_consortium_match(ie,
- bss->anqp ?
- bss->anqp->roaming_consortium : NULL,
- cred->required_roaming_consortium,
- cred->required_roaming_consortium_len);
-}
-
-
-static int cred_excluded_ssid(struct wpa_cred *cred, struct wpa_bss *bss)
-{
- size_t i;
-
- if (!cred->excluded_ssid)
- return 0;
-
- for (i = 0; i < cred->num_excluded_ssid; i++) {
- struct excluded_ssid *e = &cred->excluded_ssid[i];
- if (bss->ssid_len == e->ssid_len &&
- os_memcmp(bss->ssid, e->ssid, e->ssid_len) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static int cred_below_min_backhaul(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred, struct wpa_bss *bss)
-{
-#ifdef CONFIG_HS20
- int res;
- unsigned int dl_bandwidth, ul_bandwidth;
- const u8 *wan;
- u8 wan_info, dl_load, ul_load;
- u16 lmd;
- u32 ul_speed, dl_speed;
-
- if (!cred->min_dl_bandwidth_home &&
- !cred->min_ul_bandwidth_home &&
- !cred->min_dl_bandwidth_roaming &&
- !cred->min_ul_bandwidth_roaming)
- return 0; /* No bandwidth constraint specified */
-
- if (bss->anqp == NULL || bss->anqp->hs20_wan_metrics == NULL)
- return 0; /* No WAN Metrics known - ignore constraint */
-
- wan = wpabuf_head(bss->anqp->hs20_wan_metrics);
- wan_info = wan[0];
- if (wan_info & BIT(3))
- return 1; /* WAN link at capacity */
- lmd = WPA_GET_LE16(wan + 11);
- if (lmd == 0)
- return 0; /* Downlink/Uplink Load was not measured */
- dl_speed = WPA_GET_LE32(wan + 1);
- ul_speed = WPA_GET_LE32(wan + 5);
- dl_load = wan[9];
- ul_load = wan[10];
-
- if (dl_speed >= 0xffffff)
- dl_bandwidth = dl_speed / 255 * (255 - dl_load);
- else
- dl_bandwidth = dl_speed * (255 - dl_load) / 255;
-
- if (ul_speed >= 0xffffff)
- ul_bandwidth = ul_speed / 255 * (255 - ul_load);
- else
- ul_bandwidth = ul_speed * (255 - ul_load) / 255;
-
- res = interworking_home_sp_cred(wpa_s, cred, bss->anqp ?
- bss->anqp->domain_name : NULL);
- if (res > 0) {
- if (cred->min_dl_bandwidth_home > dl_bandwidth)
- return 1;
- if (cred->min_ul_bandwidth_home > ul_bandwidth)
- return 1;
- } else {
- if (cred->min_dl_bandwidth_roaming > dl_bandwidth)
- return 1;
- if (cred->min_ul_bandwidth_roaming > ul_bandwidth)
- return 1;
- }
-#endif /* CONFIG_HS20 */
-
- return 0;
-}
-
-
-static int cred_over_max_bss_load(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred, struct wpa_bss *bss)
-{
- const u8 *ie;
- int res;
-
- if (!cred->max_bss_load)
- return 0; /* No BSS Load constraint specified */
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_BSS_LOAD);
- if (ie == NULL || ie[1] < 3)
- return 0; /* No BSS Load advertised */
-
- res = interworking_home_sp_cred(wpa_s, cred, bss->anqp ?
- bss->anqp->domain_name : NULL);
- if (res <= 0)
- return 0; /* Not a home network */
-
- return ie[4] > cred->max_bss_load;
-}
-
-
-#ifdef CONFIG_HS20
-
-static int has_proto_match(const u8 *pos, const u8 *end, u8 proto)
-{
- while (end - pos >= 4) {
- if (pos[0] == proto && pos[3] == 1 /* Open */)
- return 1;
- pos += 4;
- }
-
- return 0;
-}
-
-
-static int has_proto_port_match(const u8 *pos, const u8 *end, u8 proto,
- u16 port)
-{
- while (end - pos >= 4) {
- if (pos[0] == proto && WPA_GET_LE16(&pos[1]) == port &&
- pos[3] == 1 /* Open */)
- return 1;
- pos += 4;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_HS20 */
-
-
-static int cred_conn_capab_missing(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred, struct wpa_bss *bss)
-{
-#ifdef CONFIG_HS20
- int res;
- const u8 *capab, *end;
- unsigned int i, j;
- int *ports;
-
- if (!cred->num_req_conn_capab)
- return 0; /* No connection capability constraint specified */
-
- if (bss->anqp == NULL || bss->anqp->hs20_connection_capability == NULL)
- return 0; /* No Connection Capability known - ignore constraint
- */
-
- res = interworking_home_sp_cred(wpa_s, cred, bss->anqp ?
- bss->anqp->domain_name : NULL);
- if (res > 0)
- return 0; /* No constraint in home network */
-
- capab = wpabuf_head(bss->anqp->hs20_connection_capability);
- end = capab + wpabuf_len(bss->anqp->hs20_connection_capability);
-
- for (i = 0; i < cred->num_req_conn_capab; i++) {
- ports = cred->req_conn_capab_port[i];
- if (!ports) {
- if (!has_proto_match(capab, end,
- cred->req_conn_capab_proto[i]))
- return 1;
- } else {
- for (j = 0; ports[j] > -1; j++) {
- if (!has_proto_port_match(
- capab, end,
- cred->req_conn_capab_proto[i],
- ports[j]))
- return 1;
- }
- }
- }
-#endif /* CONFIG_HS20 */
-
- return 0;
-}
-
-
-static struct wpa_cred * interworking_credentials_available_roaming_consortium(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded)
-{
- struct wpa_cred *cred, *selected = NULL;
- const u8 *ie;
- const struct wpabuf *anqp;
- int is_excluded = 0;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM);
- anqp = bss->anqp ? bss->anqp->roaming_consortium : NULL;
-
- if (!ie && !anqp)
- return NULL;
-
- if (wpa_s->conf->cred == NULL)
- return NULL;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->roaming_consortium_len == 0 &&
- cred->num_roaming_consortiums == 0)
- continue;
-
- if (!cred->eap_method)
- continue;
-
- if ((cred->roaming_consortium_len == 0 ||
- !roaming_consortium_match(ie, anqp,
- cred->roaming_consortium,
- cred->roaming_consortium_len)) &&
- !cred_roaming_consortiums_match(ie, anqp, cred) &&
- (cred->required_roaming_consortium_len == 0 ||
- !roaming_consortium_match(
- ie, anqp, cred->required_roaming_consortium,
- cred->required_roaming_consortium_len)))
- continue;
-
- if (cred_no_required_oi_match(cred, bss))
- continue;
- if (!ignore_bw && cred_below_min_backhaul(wpa_s, cred, bss))
- continue;
- if (!ignore_bw && cred_over_max_bss_load(wpa_s, cred, bss))
- continue;
- if (!ignore_bw && cred_conn_capab_missing(wpa_s, cred, bss))
- continue;
- if (cred_excluded_ssid(cred, bss)) {
- if (excluded == NULL)
- continue;
- if (selected == NULL) {
- selected = cred;
- is_excluded = 1;
- }
- } else {
- if (selected == NULL || is_excluded ||
- cred_prio_cmp(selected, cred) < 0) {
- selected = cred;
- is_excluded = 0;
- }
- }
- }
-
- if (excluded)
- *excluded = is_excluded;
-
- return selected;
-}
-
-
-static int interworking_set_eap_params(struct wpa_ssid *ssid,
- struct wpa_cred *cred, int ttls)
-{
- if (cred->eap_method) {
- ttls = cred->eap_method->vendor == EAP_VENDOR_IETF &&
- cred->eap_method->method == EAP_TYPE_TTLS;
-
- os_free(ssid->eap.eap_methods);
- ssid->eap.eap_methods =
- os_malloc(sizeof(struct eap_method_type) * 2);
- if (ssid->eap.eap_methods == NULL)
- return -1;
- os_memcpy(ssid->eap.eap_methods, cred->eap_method,
- sizeof(*cred->eap_method));
- ssid->eap.eap_methods[1].vendor = EAP_VENDOR_IETF;
- ssid->eap.eap_methods[1].method = EAP_TYPE_NONE;
- }
-
- if (ttls && cred->username && cred->username[0]) {
- const char *pos;
- char *anon;
- /* Use anonymous NAI in Phase 1 */
- pos = os_strchr(cred->username, '@');
- if (pos) {
- size_t buflen = 9 + os_strlen(pos) + 1;
- anon = os_malloc(buflen);
- if (anon == NULL)
- return -1;
- os_snprintf(anon, buflen, "anonymous%s", pos);
- } else if (cred->realm) {
- size_t buflen = 10 + os_strlen(cred->realm) + 1;
- anon = os_malloc(buflen);
- if (anon == NULL)
- return -1;
- os_snprintf(anon, buflen, "anonymous@%s", cred->realm);
- } else {
- anon = os_strdup("anonymous");
- if (anon == NULL)
- return -1;
- }
- if (wpa_config_set_quoted(ssid, "anonymous_identity", anon) <
- 0) {
- os_free(anon);
- return -1;
- }
- os_free(anon);
- }
-
- if (!ttls && cred->username && cred->username[0] && cred->realm &&
- !os_strchr(cred->username, '@')) {
- char *id;
- size_t buflen;
- int res;
-
- buflen = os_strlen(cred->username) + 1 +
- os_strlen(cred->realm) + 1;
-
- id = os_malloc(buflen);
- if (!id)
- return -1;
- os_snprintf(id, buflen, "%s@%s", cred->username, cred->realm);
- res = wpa_config_set_quoted(ssid, "identity", id);
- os_free(id);
- if (res < 0)
- return -1;
- } else if (cred->username && cred->username[0] &&
- wpa_config_set_quoted(ssid, "identity", cred->username) < 0)
- return -1;
-
- if (cred->password && cred->password[0]) {
- if (cred->ext_password &&
- wpa_config_set(ssid, "password", cred->password, 0) < 0)
- return -1;
- if (!cred->ext_password &&
- wpa_config_set_quoted(ssid, "password", cred->password) <
- 0)
- return -1;
- }
-
- if (cred->client_cert && cred->client_cert[0] &&
- wpa_config_set_quoted(ssid, "client_cert", cred->client_cert) < 0)
- return -1;
-
-#ifdef ANDROID
- if (cred->private_key &&
- os_strncmp(cred->private_key, "keystore://", 11) == 0) {
- /* Use OpenSSL engine configuration for Android keystore */
- if (wpa_config_set_quoted(ssid, "engine_id", "keystore") < 0 ||
- wpa_config_set_quoted(ssid, "key_id",
- cred->private_key + 11) < 0 ||
- wpa_config_set(ssid, "engine", "1", 0) < 0)
- return -1;
- } else
-#endif /* ANDROID */
- if (cred->private_key && cred->private_key[0] &&
- wpa_config_set_quoted(ssid, "private_key", cred->private_key) < 0)
- return -1;
-
- if (cred->private_key_passwd && cred->private_key_passwd[0] &&
- wpa_config_set_quoted(ssid, "private_key_passwd",
- cred->private_key_passwd) < 0)
- return -1;
-
- if (cred->ca_cert_id && cred->ca_cert_id[0] &&
- wpa_config_set_quoted(ssid, "ca_cert_id", cred->ca_cert_id) < 0)
- return -1;
-
- if (cred->cert_id && cred->cert_id[0] &&
- wpa_config_set_quoted(ssid, "cert_id", cred->cert_id) < 0)
- return -1;
-
- if (cred->key_id && cred->key_id[0] &&
- wpa_config_set_quoted(ssid, "key_id", cred->key_id) < 0)
- return -1;
-
- if (cred->engine_id && cred->engine_id[0] &&
- wpa_config_set_quoted(ssid, "engine_id", cred->engine_id) < 0)
- return -1;
-
- ssid->eap.cert.engine = cred->engine;
-
- if (cred->phase1) {
- os_free(ssid->eap.phase1);
- ssid->eap.phase1 = os_strdup(cred->phase1);
- }
- if (cred->phase2) {
- os_free(ssid->eap.phase2);
- ssid->eap.phase2 = os_strdup(cred->phase2);
- }
-
- if (cred->ca_cert && cred->ca_cert[0] &&
- wpa_config_set_quoted(ssid, "ca_cert", cred->ca_cert) < 0)
- return -1;
-
- if (cred->domain_suffix_match && cred->domain_suffix_match[0] &&
- wpa_config_set_quoted(ssid, "domain_suffix_match",
- cred->domain_suffix_match) < 0)
- return -1;
-
- ssid->eap.cert.ocsp = cred->ocsp;
-
- return 0;
-}
-
-
-static int interworking_connect_roaming_consortium(
- struct wpa_supplicant *wpa_s, struct wpa_cred *cred,
- struct wpa_bss *bss, int only_add)
-{
- struct wpa_ssid *ssid;
- const u8 *ie;
- const struct wpabuf *anqp;
- unsigned int i;
-
- wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Connect with " MACSTR
- " based on roaming consortium match", MAC2STR(bss->bssid));
-
- if (already_connected(wpa_s, cred, bss)) {
- wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
- MAC2STR(bss->bssid));
- return wpa_s->current_ssid->id;
- }
-
- remove_duplicate_network(wpa_s, cred, bss);
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL)
- return -1;
- ssid->parent_cred = cred;
- wpas_notify_network_added(wpa_s, ssid);
- wpa_config_set_network_defaults(ssid);
- ssid->priority = cred->priority;
- ssid->temporary = 1;
- ssid->ssid = os_zalloc(bss->ssid_len + 1);
- if (ssid->ssid == NULL)
- goto fail;
- os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
- ssid->ssid_len = bss->ssid_len;
-
- if (interworking_set_hs20_params(wpa_s, ssid) < 0)
- goto fail;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM);
- anqp = bss->anqp ? bss->anqp->roaming_consortium : NULL;
- for (i = 0; (ie || anqp) && i < cred->num_roaming_consortiums; i++) {
- if (!roaming_consortium_match(
- ie, anqp, cred->roaming_consortiums[i],
- cred->roaming_consortiums_len[i]))
- continue;
-
- ssid->roaming_consortium_selection =
- os_malloc(cred->roaming_consortiums_len[i]);
- if (!ssid->roaming_consortium_selection)
- goto fail;
- os_memcpy(ssid->roaming_consortium_selection,
- cred->roaming_consortiums[i],
- cred->roaming_consortiums_len[i]);
- ssid->roaming_consortium_selection_len =
- cred->roaming_consortiums_len[i];
- break;
- }
-
- if (cred->eap_method == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: No EAP method set for credential using roaming consortium");
- goto fail;
- }
-
- if (interworking_set_eap_params(
- ssid, cred,
- cred->eap_method->vendor == EAP_VENDOR_IETF &&
- cred->eap_method->method == EAP_TYPE_TTLS) < 0)
- goto fail;
-
- wpa_s->next_ssid = ssid;
- wpa_config_update_prio_list(wpa_s->conf);
- if (!only_add)
- interworking_reconnect(wpa_s);
-
- return ssid->id;
-
-fail:
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return -1;
-}
-
-
-int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- int only_add)
-{
- struct wpa_cred *cred, *cred_rc, *cred_3gpp;
- struct wpa_ssid *ssid;
- struct nai_realm *realm;
- struct nai_realm_eap *eap = NULL;
- u16 count, i;
- char buf[100];
- int excluded = 0, *excl = &excluded;
- const char *name;
-
- if (wpa_s->conf->cred == NULL || bss == NULL)
- return -1;
- if (disallowed_bssid(wpa_s, bss->bssid) ||
- disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Reject connection to disallowed BSS "
- MACSTR, MAC2STR(bss->bssid));
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "Interworking: Considering BSS " MACSTR
- " for connection",
- MAC2STR(bss->bssid));
-
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
- /*
- * We currently support only HS 2.0 networks and those are
- * required to use WPA2-Enterprise.
- */
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Network does not use RSN");
- return -1;
- }
-
- cred_rc = interworking_credentials_available_roaming_consortium(
- wpa_s, bss, 0, excl);
- if (cred_rc) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest roaming consortium matching credential priority %d sp_priority %d",
- cred_rc->priority, cred_rc->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
-
- cred = interworking_credentials_available_realm(wpa_s, bss, 0, excl);
- if (cred) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest NAI Realm list matching credential priority %d sp_priority %d",
- cred->priority, cred->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
-
- cred_3gpp = interworking_credentials_available_3gpp(wpa_s, bss, 0,
- excl);
- if (cred_3gpp) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest 3GPP matching credential priority %d sp_priority %d",
- cred_3gpp->priority, cred_3gpp->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
-
- if (!cred_rc && !cred && !cred_3gpp) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: No full credential matches - consider options without BW(etc.) limits");
- cred_rc = interworking_credentials_available_roaming_consortium(
- wpa_s, bss, 1, excl);
- if (cred_rc) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest roaming consortium matching credential priority %d sp_priority %d (ignore BW)",
- cred_rc->priority, cred_rc->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
-
- cred = interworking_credentials_available_realm(wpa_s, bss, 1,
- excl);
- if (cred) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest NAI Realm list matching credential priority %d sp_priority %d (ignore BW)",
- cred->priority, cred->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
-
- cred_3gpp = interworking_credentials_available_3gpp(wpa_s, bss,
- 1, excl);
- if (cred_3gpp) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Highest 3GPP matching credential priority %d sp_priority %d (ignore BW)",
- cred_3gpp->priority, cred_3gpp->sp_priority);
- if (excl && !(*excl))
- excl = NULL;
- }
- }
-
- if (cred_rc &&
- (cred == NULL || cred_prio_cmp(cred_rc, cred) >= 0) &&
- (cred_3gpp == NULL || cred_prio_cmp(cred_rc, cred_3gpp) >= 0))
- return interworking_connect_roaming_consortium(wpa_s, cred_rc,
- bss, only_add);
-
- if (cred_3gpp &&
- (cred == NULL || cred_prio_cmp(cred_3gpp, cred) >= 0)) {
- return interworking_connect_3gpp(wpa_s, cred_3gpp, bss,
- only_add);
- }
-
- if (cred == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: No matching credentials found for "
- MACSTR, MAC2STR(bss->bssid));
- return -1;
- }
-
- realm = nai_realm_parse(bss->anqp ? bss->anqp->nai_realm : NULL,
- &count);
- if (realm == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Could not parse NAI Realm list from "
- MACSTR, MAC2STR(bss->bssid));
- return -1;
- }
-
- for (i = 0; i < count; i++) {
- if (!nai_realm_match(&realm[i], cred->realm))
- continue;
- eap = nai_realm_find_eap(wpa_s, cred, &realm[i]);
- if (eap)
- break;
- }
-
- if (!eap) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: No matching credentials and EAP method found for "
- MACSTR, MAC2STR(bss->bssid));
- nai_realm_free(realm, count);
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Connect with " MACSTR,
- MAC2STR(bss->bssid));
-
- if (already_connected(wpa_s, cred, bss)) {
- wpa_msg(wpa_s, MSG_INFO, INTERWORKING_ALREADY_CONNECTED MACSTR,
- MAC2STR(bss->bssid));
- nai_realm_free(realm, count);
- return 0;
- }
-
- remove_duplicate_network(wpa_s, cred, bss);
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL) {
- nai_realm_free(realm, count);
- return -1;
- }
- ssid->parent_cred = cred;
- wpas_notify_network_added(wpa_s, ssid);
- wpa_config_set_network_defaults(ssid);
- ssid->priority = cred->priority;
- ssid->temporary = 1;
- ssid->ssid = os_zalloc(bss->ssid_len + 1);
- if (ssid->ssid == NULL)
- goto fail;
- os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
- ssid->ssid_len = bss->ssid_len;
-
- if (interworking_set_hs20_params(wpa_s, ssid) < 0)
- goto fail;
-
- if (wpa_config_set(ssid, "eap", eap_get_name(EAP_VENDOR_IETF,
- eap->method), 0) < 0)
- goto fail;
-
- switch (eap->method) {
- case EAP_TYPE_TTLS:
- if (eap->inner_method) {
- name = eap_get_name(EAP_VENDOR_IETF, eap->inner_method);
- if (!name)
- goto fail;
- os_snprintf(buf, sizeof(buf), "\"autheap=%s\"", name);
- if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
- goto fail;
- break;
- }
- switch (eap->inner_non_eap) {
- case NAI_REALM_INNER_NON_EAP_PAP:
- if (wpa_config_set(ssid, "phase2", "\"auth=PAP\"", 0) <
- 0)
- goto fail;
- break;
- case NAI_REALM_INNER_NON_EAP_CHAP:
- if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
- < 0)
- goto fail;
- break;
- case NAI_REALM_INNER_NON_EAP_MSCHAP:
- if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAP\"",
- 0) < 0)
- goto fail;
- break;
- case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
- if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAPV2\"",
- 0) < 0)
- goto fail;
- break;
- default:
- /* EAP params were not set - assume TTLS/MSCHAPv2 */
- if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAPV2\"",
- 0) < 0)
- goto fail;
- break;
- }
- break;
- case EAP_TYPE_PEAP:
- case EAP_TYPE_FAST:
- if (wpa_config_set(ssid, "phase1", "\"fast_provisioning=2\"",
- 0) < 0)
- goto fail;
- if (wpa_config_set(ssid, "pac_file",
- "\"blob://pac_interworking\"", 0) < 0)
- goto fail;
- name = eap_get_name(EAP_VENDOR_IETF,
- eap->inner_method ? eap->inner_method :
- EAP_TYPE_MSCHAPV2);
- if (name == NULL)
- goto fail;
- os_snprintf(buf, sizeof(buf), "\"auth=%s\"", name);
- if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
- goto fail;
- break;
- case EAP_TYPE_TLS:
- break;
- }
-
- if (interworking_set_eap_params(ssid, cred,
- eap->method == EAP_TYPE_TTLS) < 0)
- goto fail;
-
- nai_realm_free(realm, count);
-
- wpa_s->next_ssid = ssid;
- wpa_config_update_prio_list(wpa_s->conf);
- if (!only_add)
- interworking_reconnect(wpa_s);
-
- return ssid->id;
-
-fail:
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- nai_realm_free(realm, count);
- return -1;
-}
-
-
-#ifdef PCSC_FUNCS
-static int interworking_pcsc_read_imsi(struct wpa_supplicant *wpa_s)
-{
- size_t len;
-
- if (wpa_s->imsi[0] && wpa_s->mnc_len)
- return 0;
-
- len = sizeof(wpa_s->imsi) - 1;
- if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
- scard_deinit(wpa_s->scard);
- wpa_s->scard = NULL;
- wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
- return -1;
- }
- wpa_s->imsi[len] = '\0';
- wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
- wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
- wpa_s->imsi, wpa_s->mnc_len);
-
- return 0;
-}
-#endif /* PCSC_FUNCS */
-
-
-static struct wpa_cred * interworking_credentials_available_3gpp(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded)
-{
- struct wpa_cred *selected = NULL;
-#ifdef INTERWORKING_3GPP
- struct wpa_cred *cred;
- int ret;
- int is_excluded = 0;
-
- if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "interworking-avail-3gpp: not avail, anqp: %p anqp_3gpp: %p",
- bss->anqp, bss->anqp ? bss->anqp->anqp_3gpp : NULL);
- return NULL;
- }
-
-#ifdef CONFIG_EAP_PROXY
- if (!wpa_s->imsi[0]) {
- size_t len;
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: IMSI not available - try to read again through eap_proxy");
- wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, -1,
- wpa_s->imsi,
- &len);
- if (wpa_s->mnc_len > 0) {
- wpa_s->imsi[len] = '\0';
- wpa_msg(wpa_s, MSG_DEBUG,
- "eap_proxy: IMSI %s (MNC length %d)",
- wpa_s->imsi, wpa_s->mnc_len);
- } else {
- wpa_msg(wpa_s, MSG_DEBUG,
- "eap_proxy: IMSI not available");
- }
- }
-#endif /* CONFIG_EAP_PROXY */
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- char *sep;
- const char *imsi;
- int mnc_len;
- char imsi_buf[16];
- size_t msin_len;
-
-#ifdef PCSC_FUNCS
- if (cred->pcsc && wpa_s->scard) {
- if (interworking_pcsc_read_imsi(wpa_s) < 0)
- continue;
- imsi = wpa_s->imsi;
- mnc_len = wpa_s->mnc_len;
- goto compare;
- }
-#endif /* PCSC_FUNCS */
-#ifdef CONFIG_EAP_PROXY
- if (cred->pcsc && wpa_s->mnc_len > 0 && wpa_s->imsi[0]) {
- imsi = wpa_s->imsi;
- mnc_len = wpa_s->mnc_len;
- goto compare;
- }
-#endif /* CONFIG_EAP_PROXY */
-
- if (cred->imsi == NULL || !cred->imsi[0] ||
- (!wpa_s->conf->external_sim &&
- (cred->milenage == NULL || !cred->milenage[0])))
- continue;
-
- sep = os_strchr(cred->imsi, '-');
- if (sep == NULL ||
- (sep - cred->imsi != 5 && sep - cred->imsi != 6))
- continue;
- mnc_len = sep - cred->imsi - 3;
- os_memcpy(imsi_buf, cred->imsi, 3 + mnc_len);
- sep++;
- msin_len = os_strlen(cred->imsi);
- if (3 + mnc_len + msin_len >= sizeof(imsi_buf) - 1)
- msin_len = sizeof(imsi_buf) - 3 - mnc_len - 1;
- os_memcpy(&imsi_buf[3 + mnc_len], sep, msin_len);
- imsi_buf[3 + mnc_len + msin_len] = '\0';
- imsi = imsi_buf;
-
-#if defined(PCSC_FUNCS) || defined(CONFIG_EAP_PROXY)
- compare:
-#endif /* PCSC_FUNCS || CONFIG_EAP_PROXY */
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Parsing 3GPP info from " MACSTR,
- MAC2STR(bss->bssid));
- ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
- wpa_msg(wpa_s, MSG_DEBUG, "PLMN match %sfound",
- ret ? "" : "not ");
- if (ret) {
- if (cred_no_required_oi_match(cred, bss))
- continue;
- if (!ignore_bw &&
- cred_below_min_backhaul(wpa_s, cred, bss))
- continue;
- if (!ignore_bw &&
- cred_over_max_bss_load(wpa_s, cred, bss))
- continue;
- if (!ignore_bw &&
- cred_conn_capab_missing(wpa_s, cred, bss))
- continue;
- if (cred_excluded_ssid(cred, bss)) {
- if (excluded == NULL)
- continue;
- if (selected == NULL) {
- selected = cred;
- is_excluded = 1;
- }
- } else {
- if (selected == NULL || is_excluded ||
- cred_prio_cmp(selected, cred) < 0) {
- selected = cred;
- is_excluded = 0;
- }
- }
- }
- }
-
- if (excluded)
- *excluded = is_excluded;
-#endif /* INTERWORKING_3GPP */
- return selected;
-}
-
-
-static struct wpa_cred * interworking_credentials_available_realm(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded)
-{
- struct wpa_cred *cred, *selected = NULL;
- struct nai_realm *realm;
- u16 count, i;
- int is_excluded = 0;
-
- if (bss->anqp == NULL || bss->anqp->nai_realm == NULL)
- return NULL;
-
- if (wpa_s->conf->cred == NULL)
- return NULL;
-
- wpa_msg(wpa_s, MSG_DEBUG, "Interworking: Parsing NAI Realm list from "
- MACSTR, MAC2STR(bss->bssid));
- realm = nai_realm_parse(bss->anqp->nai_realm, &count);
- if (realm == NULL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Could not parse NAI Realm list from "
- MACSTR, MAC2STR(bss->bssid));
- return NULL;
- }
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- if (cred->realm == NULL)
- continue;
-
- for (i = 0; i < count; i++) {
- if (!nai_realm_match(&realm[i], cred->realm))
- continue;
- if (nai_realm_find_eap(wpa_s, cred, &realm[i])) {
- if (cred_no_required_oi_match(cred, bss))
- continue;
- if (!ignore_bw &&
- cred_below_min_backhaul(wpa_s, cred, bss))
- continue;
- if (!ignore_bw &&
- cred_over_max_bss_load(wpa_s, cred, bss))
- continue;
- if (!ignore_bw &&
- cred_conn_capab_missing(wpa_s, cred, bss))
- continue;
- if (cred_excluded_ssid(cred, bss)) {
- if (excluded == NULL)
- continue;
- if (selected == NULL) {
- selected = cred;
- is_excluded = 1;
- }
- } else {
- if (selected == NULL || is_excluded ||
- cred_prio_cmp(selected, cred) < 0)
- {
- selected = cred;
- is_excluded = 0;
- }
- }
- break;
- } else {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: realm-find-eap returned false");
- }
- }
- }
-
- nai_realm_free(realm, count);
-
- if (excluded)
- *excluded = is_excluded;
-
- return selected;
-}
-
-
-static struct wpa_cred * interworking_credentials_available_helper(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ignore_bw,
- int *excluded)
-{
- struct wpa_cred *cred, *cred2;
- int excluded1, excluded2 = 0;
-
- if (disallowed_bssid(wpa_s, bss->bssid) ||
- disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
- wpa_printf(MSG_DEBUG, "Interworking: Ignore disallowed BSS "
- MACSTR, MAC2STR(bss->bssid));
- return NULL;
- }
-
- cred = interworking_credentials_available_realm(wpa_s, bss, ignore_bw,
- &excluded1);
- cred2 = interworking_credentials_available_3gpp(wpa_s, bss, ignore_bw,
- &excluded2);
- if (cred && cred2 &&
- (cred_prio_cmp(cred2, cred) >= 0 || (!excluded2 && excluded1))) {
- cred = cred2;
- excluded1 = excluded2;
- }
- if (!cred) {
- cred = cred2;
- excluded1 = excluded2;
- }
-
- cred2 = interworking_credentials_available_roaming_consortium(
- wpa_s, bss, ignore_bw, &excluded2);
- if (cred && cred2 &&
- (cred_prio_cmp(cred2, cred) >= 0 || (!excluded2 && excluded1))) {
- cred = cred2;
- excluded1 = excluded2;
- }
- if (!cred) {
- cred = cred2;
- excluded1 = excluded2;
- }
-
- if (excluded)
- *excluded = excluded1;
- return cred;
-}
-
-
-static struct wpa_cred * interworking_credentials_available(
- struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int *excluded)
-{
- struct wpa_cred *cred;
-
- if (excluded)
- *excluded = 0;
- cred = interworking_credentials_available_helper(wpa_s, bss, 0,
- excluded);
- if (cred)
- return cred;
- return interworking_credentials_available_helper(wpa_s, bss, 1,
- excluded);
-}
-
-
-int domain_name_list_contains(struct wpabuf *domain_names,
- const char *domain, int exact_match)
-{
- const u8 *pos, *end;
- size_t len;
-
- len = os_strlen(domain);
- pos = wpabuf_head(domain_names);
- end = pos + wpabuf_len(domain_names);
-
- while (end - pos > 1) {
- u8 elen;
-
- elen = *pos++;
- if (elen > end - pos)
- break;
-
- wpa_hexdump_ascii(MSG_DEBUG, "Interworking: AP domain name",
- pos, elen);
- if (elen == len &&
- os_strncasecmp(domain, (const char *) pos, len) == 0)
- return 1;
- if (!exact_match && elen > len && pos[elen - len - 1] == '.') {
- const char *ap = (const char *) pos;
- int offset = elen - len;
-
- if (os_strncasecmp(domain, ap + offset, len) == 0)
- return 1;
- }
-
- pos += elen;
- }
-
- return 0;
-}
-
-
-int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- struct wpabuf *domain_names)
-{
- size_t i;
- int ret = -1;
-#ifdef INTERWORKING_3GPP
- char nai[100], *realm;
-
- char *imsi = NULL;
- int mnc_len = 0;
- if (cred->imsi)
- imsi = cred->imsi;
-#ifdef PCSC_FUNCS
- else if (cred->pcsc && wpa_s->scard) {
- if (interworking_pcsc_read_imsi(wpa_s) < 0)
- return -1;
- imsi = wpa_s->imsi;
- mnc_len = wpa_s->mnc_len;
- }
-#endif /* PCSC_FUNCS */
-#ifdef CONFIG_EAP_PROXY
- else if (cred->pcsc && wpa_s->mnc_len > 0 && wpa_s->imsi[0]) {
- imsi = wpa_s->imsi;
- mnc_len = wpa_s->mnc_len;
- }
-#endif /* CONFIG_EAP_PROXY */
- if (domain_names &&
- imsi && build_root_nai(nai, sizeof(nai), imsi, mnc_len, 0) == 0) {
- realm = os_strchr(nai, '@');
- if (realm)
- realm++;
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Search for match with SIM/USIM domain %s",
- realm ? realm : "[NULL]");
- if (realm &&
- domain_name_list_contains(domain_names, realm, 1))
- return 1;
- if (realm)
- ret = 0;
- }
-#endif /* INTERWORKING_3GPP */
-
- if (domain_names == NULL || cred->domain == NULL)
- return ret;
-
- for (i = 0; i < cred->num_domain; i++) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Search for match with home SP FQDN %s",
- cred->domain[i]);
- if (domain_name_list_contains(domain_names, cred->domain[i], 1))
- return 1;
- }
-
- return 0;
-}
-
-
-static int interworking_home_sp(struct wpa_supplicant *wpa_s,
- struct wpabuf *domain_names)
-{
- struct wpa_cred *cred;
-
- if (domain_names == NULL || wpa_s->conf->cred == NULL)
- return -1;
-
- for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
- int res = interworking_home_sp_cred(wpa_s, cred, domain_names);
- if (res)
- return res;
- }
-
- return 0;
-}
-
-
-static int interworking_find_network_match(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
- struct wpa_ssid *ssid;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (wpas_network_disabled(wpa_s, ssid) ||
- ssid->mode != WPAS_MODE_INFRA)
- continue;
- if (ssid->ssid_len != bss->ssid_len ||
- os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) !=
- 0)
- continue;
- /*
- * TODO: Consider more accurate matching of security
- * configuration similarly to what is done in events.c
- */
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static int roaming_partner_match(struct wpa_supplicant *wpa_s,
- struct roaming_partner *partner,
- struct wpabuf *domain_names)
-{
- wpa_printf(MSG_DEBUG, "Interworking: Comparing roaming_partner info fqdn='%s' exact_match=%d priority=%u country='%s'",
- partner->fqdn, partner->exact_match, partner->priority,
- partner->country);
- wpa_hexdump_ascii(MSG_DEBUG, "Interworking: Domain names",
- wpabuf_head(domain_names),
- wpabuf_len(domain_names));
- if (!domain_name_list_contains(domain_names, partner->fqdn,
- partner->exact_match))
- return 0;
- /* TODO: match Country */
- return 1;
-}
-
-
-static u8 roaming_prio(struct wpa_supplicant *wpa_s, struct wpa_cred *cred,
- struct wpa_bss *bss)
-{
- size_t i;
-
- if (bss->anqp == NULL || bss->anqp->domain_name == NULL) {
- wpa_printf(MSG_DEBUG, "Interworking: No ANQP domain name info -> use default roaming partner priority 128");
- return 128; /* cannot check preference with domain name */
- }
-
- if (interworking_home_sp_cred(wpa_s, cred, bss->anqp->domain_name) > 0)
- {
- wpa_printf(MSG_DEBUG, "Interworking: Determined to be home SP -> use maximum preference 0 as roaming partner priority");
- return 0; /* max preference for home SP network */
- }
-
- for (i = 0; i < cred->num_roaming_partner; i++) {
- if (roaming_partner_match(wpa_s, &cred->roaming_partner[i],
- bss->anqp->domain_name)) {
- wpa_printf(MSG_DEBUG, "Interworking: Roaming partner preference match - priority %u",
- cred->roaming_partner[i].priority);
- return cred->roaming_partner[i].priority;
- }
- }
-
- wpa_printf(MSG_DEBUG, "Interworking: No roaming partner preference match - use default roaming partner priority 128");
- return 128;
-}
-
-
-static struct wpa_bss * pick_best_roaming_partner(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected,
- struct wpa_cred *cred)
-{
- struct wpa_bss *bss;
- u8 best_prio, prio;
- struct wpa_cred *cred2;
-
- /*
- * Check if any other BSS is operated by a more preferred roaming
- * partner.
- */
-
- best_prio = roaming_prio(wpa_s, cred, selected);
- wpa_printf(MSG_DEBUG, "Interworking: roaming_prio=%u for selected BSS "
- MACSTR " (cred=%d)", best_prio, MAC2STR(selected->bssid),
- cred->id);
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (bss == selected)
- continue;
- cred2 = interworking_credentials_available(wpa_s, bss, NULL);
- if (!cred2)
- continue;
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN))
- continue;
- prio = roaming_prio(wpa_s, cred2, bss);
- wpa_printf(MSG_DEBUG, "Interworking: roaming_prio=%u for BSS "
- MACSTR " (cred=%d)", prio, MAC2STR(bss->bssid),
- cred2->id);
- if (prio < best_prio) {
- int bh1, bh2, load1, load2, conn1, conn2;
- bh1 = cred_below_min_backhaul(wpa_s, cred, selected);
- load1 = cred_over_max_bss_load(wpa_s, cred, selected);
- conn1 = cred_conn_capab_missing(wpa_s, cred, selected);
- bh2 = cred_below_min_backhaul(wpa_s, cred2, bss);
- load2 = cred_over_max_bss_load(wpa_s, cred2, bss);
- conn2 = cred_conn_capab_missing(wpa_s, cred2, bss);
- wpa_printf(MSG_DEBUG, "Interworking: old: %d %d %d new: %d %d %d",
- bh1, load1, conn1, bh2, load2, conn2);
- if (bh1 || load1 || conn1 || !(bh2 || load2 || conn2)) {
- wpa_printf(MSG_DEBUG, "Interworking: Better roaming partner " MACSTR " selected", MAC2STR(bss->bssid));
- best_prio = prio;
- selected = bss;
- }
- }
- }
-
- return selected;
-}
-
-
-static void interworking_select_network(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss, *selected = NULL, *selected_home = NULL;
- struct wpa_bss *selected2 = NULL, *selected2_home = NULL;
- unsigned int count = 0;
- const char *type;
- int res;
- struct wpa_cred *cred, *selected_cred = NULL;
- struct wpa_cred *selected_home_cred = NULL;
- struct wpa_cred *selected2_cred = NULL;
- struct wpa_cred *selected2_home_cred = NULL;
-
- wpa_s->network_select = 0;
-
- wpa_printf(MSG_DEBUG, "Interworking: Select network (auto_select=%d)",
- wpa_s->auto_select);
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- int excluded = 0;
- int bh, bss_load, conn_capab;
- cred = interworking_credentials_available(wpa_s, bss,
- &excluded);
- if (!cred)
- continue;
-
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
- /*
- * We currently support only HS 2.0 networks and those
- * are required to use WPA2-Enterprise.
- */
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Credential match with " MACSTR
- " but network does not use RSN",
- MAC2STR(bss->bssid));
- continue;
- }
- if (!excluded)
- count++;
- res = interworking_home_sp(wpa_s, bss->anqp ?
- bss->anqp->domain_name : NULL);
- if (res > 0)
- type = "home";
- else if (res == 0)
- type = "roaming";
- else
- type = "unknown";
- bh = cred_below_min_backhaul(wpa_s, cred, bss);
- bss_load = cred_over_max_bss_load(wpa_s, cred, bss);
- conn_capab = cred_conn_capab_missing(wpa_s, cred, bss);
- wpas_notify_interworking_ap_added(wpa_s, bss, cred, excluded,
- type, bh, bss_load,
- conn_capab);
- if (excluded)
- continue;
- if (wpa_s->auto_select ||
- (wpa_s->conf->auto_interworking &&
- wpa_s->auto_network_select)) {
- if (bh || bss_load || conn_capab) {
- if (selected2_cred == NULL ||
- cred_prio_cmp(cred, selected2_cred) > 0) {
- wpa_printf(MSG_DEBUG, "Interworking: Mark as selected2");
- selected2 = bss;
- selected2_cred = cred;
- }
- if (res > 0 &&
- (selected2_home_cred == NULL ||
- cred_prio_cmp(cred, selected2_home_cred) >
- 0)) {
- wpa_printf(MSG_DEBUG, "Interworking: Mark as selected2_home");
- selected2_home = bss;
- selected2_home_cred = cred;
- }
- } else {
- if (selected_cred == NULL ||
- cred_prio_cmp(cred, selected_cred) > 0) {
- wpa_printf(MSG_DEBUG, "Interworking: Mark as selected");
- selected = bss;
- selected_cred = cred;
- }
- if (res > 0 &&
- (selected_home_cred == NULL ||
- cred_prio_cmp(cred, selected_home_cred) >
- 0)) {
- wpa_printf(MSG_DEBUG, "Interworking: Mark as selected_home");
- selected_home = bss;
- selected_home_cred = cred;
- }
- }
- }
- }
-
- if (selected_home && selected_home != selected &&
- selected_home_cred &&
- (selected_cred == NULL ||
- cred_prio_cmp(selected_home_cred, selected_cred) >= 0)) {
- /* Prefer network operated by the Home SP */
- wpa_printf(MSG_DEBUG, "Interworking: Overrode selected with selected_home");
- selected = selected_home;
- selected_cred = selected_home_cred;
- }
-
- if (!selected) {
- if (selected2_home) {
- wpa_printf(MSG_DEBUG, "Interworking: Use home BSS with BW limit mismatch since no other network could be selected");
- selected = selected2_home;
- selected_cred = selected2_home_cred;
- } else if (selected2) {
- wpa_printf(MSG_DEBUG, "Interworking: Use visited BSS with BW limit mismatch since no other network could be selected");
- selected = selected2;
- selected_cred = selected2_cred;
- }
- }
-
- if (count == 0) {
- /*
- * No matching network was found based on configured
- * credentials. Check whether any of the enabled network blocks
- * have matching APs.
- */
- if (interworking_find_network_match(wpa_s)) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Possible BSS match for enabled network configurations");
- if (wpa_s->auto_select) {
- interworking_reconnect(wpa_s);
- return;
- }
- }
-
- if (wpa_s->auto_network_select) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Continue scanning after ANQP fetch");
- wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval,
- 0);
- return;
- }
-
- wpa_msg(wpa_s, MSG_INFO, INTERWORKING_NO_MATCH "No network "
- "with matching credentials found");
- if (wpa_s->wpa_state == WPA_SCANNING)
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- }
-
- wpas_notify_interworking_select_done(wpa_s);
-
- if (selected) {
- wpa_printf(MSG_DEBUG, "Interworking: Selected " MACSTR,
- MAC2STR(selected->bssid));
- selected = pick_best_roaming_partner(wpa_s, selected,
- selected_cred);
- wpa_printf(MSG_DEBUG, "Interworking: Selected " MACSTR
- " (after best roaming partner selection)",
- MAC2STR(selected->bssid));
- wpa_msg(wpa_s, MSG_INFO, INTERWORKING_SELECTED MACSTR,
- MAC2STR(selected->bssid));
- interworking_connect(wpa_s, selected, 0);
- } else if (wpa_s->wpa_state == WPA_SCANNING)
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
-}
-
-
-static struct wpa_bss_anqp *
-interworking_match_anqp_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
- struct wpa_bss *other;
-
- if (is_zero_ether_addr(bss->hessid))
- return NULL; /* Cannot be in the same homegenous ESS */
-
- dl_list_for_each(other, &wpa_s->bss, struct wpa_bss, list) {
- if (other == bss)
- continue;
- if (other->anqp == NULL)
- continue;
- if (other->anqp->roaming_consortium == NULL &&
- other->anqp->nai_realm == NULL &&
- other->anqp->anqp_3gpp == NULL &&
- other->anqp->domain_name == NULL)
- continue;
- if (!(other->flags & WPA_BSS_ANQP_FETCH_TRIED))
- continue;
- if (os_memcmp(bss->hessid, other->hessid, ETH_ALEN) != 0)
- continue;
- if (bss->ssid_len != other->ssid_len ||
- os_memcmp(bss->ssid, other->ssid, bss->ssid_len) != 0)
- continue;
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Share ANQP data with already fetched BSSID "
- MACSTR " and " MACSTR,
- MAC2STR(other->bssid), MAC2STR(bss->bssid));
- other->anqp->users++;
- return other->anqp;
- }
-
- return NULL;
-}
-
-
-static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
- int found = 0;
-
- wpa_printf(MSG_DEBUG, "Interworking: next_anqp_fetch - "
- "fetch_anqp_in_progress=%d fetch_osu_icon_in_progress=%d",
- wpa_s->fetch_anqp_in_progress,
- wpa_s->fetch_osu_icon_in_progress);
-
- if (eloop_terminated() || !wpa_s->fetch_anqp_in_progress) {
- wpa_printf(MSG_DEBUG, "Interworking: Stop next-ANQP-fetch");
- return;
- }
-
-#ifdef CONFIG_HS20
- if (wpa_s->fetch_osu_icon_in_progress) {
- wpa_printf(MSG_DEBUG, "Interworking: Next icon (in progress)");
- hs20_next_osu_icon(wpa_s);
- return;
- }
-#endif /* CONFIG_HS20 */
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (!(bss->caps & IEEE80211_CAP_ESS))
- continue;
- if (!wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_INTERWORKING))
- continue; /* AP does not support Interworking */
- if (disallowed_bssid(wpa_s, bss->bssid) ||
- disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len))
- continue; /* Disallowed BSS */
-
- if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) {
- if (bss->anqp == NULL) {
- bss->anqp = interworking_match_anqp_info(wpa_s,
- bss);
- if (bss->anqp) {
- /* Shared data already fetched */
- continue;
- }
- bss->anqp = wpa_bss_anqp_alloc();
- if (bss->anqp == NULL)
- break;
- }
- found++;
- bss->flags |= WPA_BSS_ANQP_FETCH_TRIED;
- wpa_msg(wpa_s, MSG_INFO, "Starting ANQP fetch for "
- MACSTR " (HESSID " MACSTR ")",
- MAC2STR(bss->bssid), MAC2STR(bss->hessid));
- interworking_anqp_send_req(wpa_s, bss);
- break;
- }
- }
-
- if (found == 0) {
-#ifdef CONFIG_HS20
- if (wpa_s->fetch_osu_info) {
- if (wpa_s->num_prov_found == 0 &&
- wpa_s->fetch_osu_waiting_scan &&
- wpa_s->num_osu_scans < 3) {
- wpa_printf(MSG_DEBUG, "HS 2.0: No OSU providers seen - try to scan again");
- hs20_start_osu_scan(wpa_s);
- return;
- }
- wpa_printf(MSG_DEBUG, "Interworking: Next icon");
- hs20_osu_icon_fetch(wpa_s);
- return;
- }
-#endif /* CONFIG_HS20 */
- wpa_msg(wpa_s, MSG_INFO, "ANQP fetch completed");
- wpa_s->fetch_anqp_in_progress = 0;
- if (wpa_s->network_select)
- interworking_select_network(wpa_s);
- }
-}
-
-
-void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list)
- bss->flags &= ~WPA_BSS_ANQP_FETCH_TRIED;
-
- wpa_s->fetch_anqp_in_progress = 1;
-
- /*
- * Start actual ANQP operation from eloop call to make sure the loop
- * does not end up using excessive recursion.
- */
- eloop_register_timeout(0, 0, interworking_continue_anqp, wpa_s, NULL);
-}
-
-
-int interworking_fetch_anqp(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->fetch_anqp_in_progress || wpa_s->network_select)
- return 0;
-
- wpa_s->network_select = 0;
- wpa_s->fetch_all_anqp = 1;
- wpa_s->fetch_osu_info = 0;
-
- interworking_start_fetch_anqp(wpa_s);
-
- return 0;
-}
-
-
-void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->fetch_anqp_in_progress)
- return;
-
- wpa_s->fetch_anqp_in_progress = 0;
-}
-
-
-int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, int freq,
- u16 info_ids[], size_t num_ids, u32 subtypes,
- u32 mbo_subtypes)
-{
- struct wpabuf *buf;
- struct wpabuf *extra_buf = NULL;
- int ret = 0;
- struct wpa_bss *bss;
- int res;
-
- bss = wpa_bss_get_bssid(wpa_s, dst);
- if (!bss && !freq) {
- wpa_printf(MSG_WARNING,
- "ANQP: Cannot send query without BSS freq info");
- return -1;
- }
-
- if (bss)
- wpa_bss_anqp_unshare_alloc(bss);
- if (bss && !freq)
- freq = bss->freq;
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Query Request to " MACSTR " for %u id(s)",
- MAC2STR(dst), (unsigned int) num_ids);
-
-#ifdef CONFIG_HS20
- if (subtypes != 0) {
- extra_buf = wpabuf_alloc(100);
- if (extra_buf == NULL)
- return -1;
- hs20_put_anqp_req(subtypes, NULL, 0, extra_buf);
- }
-#endif /* CONFIG_HS20 */
-
-#ifdef CONFIG_MBO
- if (mbo_subtypes) {
- struct wpabuf *mbo;
-
- if (!bss) {
- wpa_printf(MSG_WARNING,
- "ANQP: Cannot send MBO query to unknown BSS "
- MACSTR, MAC2STR(dst));
- wpabuf_free(extra_buf);
- return -1;
- }
-
- mbo = mbo_build_anqp_buf(wpa_s, bss, mbo_subtypes);
- if (mbo) {
- if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) {
- wpabuf_free(extra_buf);
- wpabuf_free(mbo);
- return -1;
- }
- wpabuf_put_buf(extra_buf, mbo);
- wpabuf_free(mbo);
- }
- }
-#endif /* CONFIG_MBO */
-
- buf = anqp_build_req(info_ids, num_ids, extra_buf);
- wpabuf_free(extra_buf);
- if (buf == NULL)
- return -1;
-
- res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb,
- wpa_s);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request");
- wpabuf_free(buf);
- ret = -1;
- } else {
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Query started with dialog token %u", res);
- }
-
- return ret;
-}
-
-
-static void anqp_add_extra(struct wpa_supplicant *wpa_s,
- struct wpa_bss_anqp *anqp, u16 info_id,
- const u8 *data, size_t slen, bool protected_response)
-{
- struct wpa_bss_anqp_elem *tmp, *elem = NULL;
-
- if (!anqp)
- return;
-
- dl_list_for_each(tmp, &anqp->anqp_elems, struct wpa_bss_anqp_elem,
- list) {
- if (tmp->infoid == info_id) {
- elem = tmp;
- break;
- }
- }
-
- if (!elem) {
- elem = os_zalloc(sizeof(*elem));
- if (!elem)
- return;
- elem->infoid = info_id;
- dl_list_add(&anqp->anqp_elems, &elem->list);
- } else {
- wpabuf_free(elem->payload);
- }
-
- elem->protected_response = protected_response;
- elem->payload = wpabuf_alloc_copy(data, slen);
- if (!elem->payload) {
- dl_list_del(&elem->list);
- os_free(elem);
- }
-}
-
-
-static void interworking_parse_venue_url(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t len)
-{
- const u8 *pos = data, *end = data + len;
- char url[255];
-
- while (end - pos >= 2) {
- u8 slen, num;
-
- slen = *pos++;
- if (slen < 1 || slen > end - pos) {
- wpa_printf(MSG_DEBUG,
- "ANQP: Truncated Venue URL Duple field");
- return;
- }
-
- num = *pos++;
- os_memcpy(url, pos, slen - 1);
- url[slen - 1] = '\0';
- wpa_msg(wpa_s, MSG_INFO, RX_VENUE_URL "%u %s", num, url);
- pos += slen - 1;
- }
-}
-
-
-static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, const u8 *sa,
- u16 info_id,
- const u8 *data, size_t slen,
- u8 dialog_token)
-{
- const u8 *pos = data;
- struct wpa_bss_anqp *anqp = NULL;
- u8 type;
- bool protected_response;
-
- if (bss)
- anqp = bss->anqp;
-
- switch (info_id) {
- case ANQP_CAPABILITY_LIST:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " ANQP Capability list", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Capability list",
- pos, slen);
- if (anqp) {
- wpabuf_free(anqp->capability_list);
- anqp->capability_list = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_VENUE_NAME:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " Venue Name", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Venue Name", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->venue_name);
- anqp->venue_name = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_NETWORK_AUTH_TYPE:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " Network Authentication Type information",
- MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Network Authentication "
- "Type", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->network_auth_type);
- anqp->network_auth_type = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_ROAMING_CONSORTIUM:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " Roaming Consortium list", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Roaming Consortium",
- pos, slen);
- if (anqp) {
- wpabuf_free(anqp->roaming_consortium);
- anqp->roaming_consortium = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_IP_ADDR_TYPE_AVAILABILITY:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " IP Address Type Availability information",
- MAC2STR(sa));
- wpa_hexdump(MSG_MSGDUMP, "ANQP: IP Address Availability",
- pos, slen);
- if (anqp) {
- wpabuf_free(anqp->ip_addr_type_availability);
- anqp->ip_addr_type_availability =
- wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_NAI_REALM:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " NAI Realm list", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: NAI Realm", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->nai_realm);
- anqp->nai_realm = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_3GPP_CELLULAR_NETWORK:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " 3GPP Cellular Network information", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_DEBUG, "ANQP: 3GPP Cellular Network",
- pos, slen);
- if (anqp) {
- wpabuf_free(anqp->anqp_3gpp);
- anqp->anqp_3gpp = wpabuf_alloc_copy(pos, slen);
- }
- break;
- case ANQP_DOMAIN_NAME:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " Domain Name list", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: Domain Name", pos, slen);
- if (anqp) {
- wpabuf_free(anqp->domain_name);
- anqp->domain_name = wpabuf_alloc_copy(pos, slen);
- }
- break;
-#ifdef CONFIG_FILS
- case ANQP_FILS_REALM_INFO:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR
- " FILS Realm Information", MAC2STR(sa));
- wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: FILS Realm Information",
- pos, slen);
- if (anqp) {
- wpabuf_free(anqp->fils_realm_info);
- anqp->fils_realm_info = wpabuf_alloc_copy(pos, slen);
- }
- break;
-#endif /* CONFIG_FILS */
- case ANQP_VENUE_URL:
- wpa_msg(wpa_s, MSG_INFO, RX_ANQP MACSTR " Venue URL",
- MAC2STR(sa));
- protected_response = pmf_in_use(wpa_s, sa);
- anqp_add_extra(wpa_s, anqp, info_id, pos, slen,
- protected_response);
-
- if (!protected_response) {
- wpa_printf(MSG_DEBUG,
- "ANQP: Ignore Venue URL since PMF was not enabled");
- break;
- }
- interworking_parse_venue_url(wpa_s, pos, slen);
- break;
- case ANQP_VENDOR_SPECIFIC:
- if (slen < 3)
- return;
-
- switch (WPA_GET_BE24(pos)) {
- case OUI_WFA:
- pos += 3;
- slen -= 3;
-
- if (slen < 1)
- return;
- type = *pos++;
- slen--;
-
- switch (type) {
-#ifdef CONFIG_HS20
- case HS20_ANQP_OUI_TYPE:
- hs20_parse_rx_hs20_anqp_resp(wpa_s, bss, sa,
- pos, slen,
- dialog_token);
- break;
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_MBO
- case MBO_ANQP_OUI_TYPE:
- mbo_parse_rx_anqp_resp(wpa_s, bss, sa,
- pos, slen);
- break;
-#endif /* CONFIG_MBO */
- default:
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Unsupported ANQP vendor type %u",
- type);
- break;
- }
- break;
- default:
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Unsupported vendor-specific ANQP OUI %06x",
- WPA_GET_BE24(pos));
- return;
- }
- break;
- default:
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Unsupported ANQP Info ID %u", info_id);
- anqp_add_extra(wpa_s, anqp, info_id, data, slen,
- pmf_in_use(wpa_s, sa));
- break;
- }
-}
-
-
-void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const u8 *pos;
- const u8 *end;
- u16 info_id;
- u16 slen;
- struct wpa_bss *bss = NULL, *tmp;
- const char *anqp_result = "SUCCESS";
-
- wpa_printf(MSG_DEBUG, "Interworking: anqp_resp_cb dst=" MACSTR
- " dialog_token=%u result=%d status_code=%u",
- MAC2STR(dst), dialog_token, result, status_code);
- if (result != GAS_QUERY_SUCCESS) {
-#ifdef CONFIG_HS20
- if (wpa_s->fetch_osu_icon_in_progress)
- hs20_icon_fetch_failed(wpa_s);
-#endif /* CONFIG_HS20 */
- anqp_result = "FAILURE";
- goto out;
- }
-
- pos = wpabuf_head(adv_proto);
- if (wpabuf_len(adv_proto) < 4 || pos[0] != WLAN_EID_ADV_PROTO ||
- pos[1] < 2 || pos[3] != ACCESS_NETWORK_QUERY_PROTOCOL) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Unexpected Advertisement Protocol in response");
-#ifdef CONFIG_HS20
- if (wpa_s->fetch_osu_icon_in_progress)
- hs20_icon_fetch_failed(wpa_s);
-#endif /* CONFIG_HS20 */
- anqp_result = "INVALID_FRAME";
- goto out;
- }
-
- /*
- * If possible, select the BSS entry based on which BSS entry was used
- * for the request. This can help in cases where multiple BSS entries
- * may exist for the same AP.
- */
- dl_list_for_each_reverse(tmp, &wpa_s->bss, struct wpa_bss, list) {
- if (tmp == wpa_s->interworking_gas_bss &&
- os_memcmp(tmp->bssid, dst, ETH_ALEN) == 0) {
- bss = tmp;
- break;
- }
- }
- if (bss == NULL)
- bss = wpa_bss_get_bssid(wpa_s, dst);
-
- pos = wpabuf_head(resp);
- end = pos + wpabuf_len(resp);
-
- while (pos < end) {
- unsigned int left = end - pos;
-
- if (left < 4) {
- wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Invalid element");
- anqp_result = "INVALID_FRAME";
- goto out_parse_done;
- }
- info_id = WPA_GET_LE16(pos);
- pos += 2;
- slen = WPA_GET_LE16(pos);
- pos += 2;
- left -= 4;
- if (left < slen) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "ANQP: Invalid element length for Info ID %u",
- info_id);
- anqp_result = "INVALID_FRAME";
- goto out_parse_done;
- }
- interworking_parse_rx_anqp_resp(wpa_s, bss, dst, info_id, pos,
- slen, dialog_token);
- pos += slen;
- }
-
-out_parse_done:
-#ifdef CONFIG_HS20
- hs20_notify_parse_done(wpa_s);
-#endif /* CONFIG_HS20 */
-out:
- wpa_msg(wpa_s, MSG_INFO, ANQP_QUERY_DONE "addr=" MACSTR " result=%s",
- MAC2STR(dst), anqp_result);
-}
-
-
-static void interworking_scan_res_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Scan results available - start ANQP fetch");
- interworking_start_fetch_anqp(wpa_s);
-}
-
-
-int interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
- int *freqs)
-{
- interworking_stop_fetch_anqp(wpa_s);
- wpa_s->network_select = 1;
- wpa_s->auto_network_select = 0;
- wpa_s->auto_select = !!auto_select;
- wpa_s->fetch_all_anqp = 0;
- wpa_s->fetch_osu_info = 0;
- wpa_msg(wpa_s, MSG_DEBUG,
- "Interworking: Start scan for network selection");
- wpa_s->scan_res_handler = interworking_scan_res_handler;
- wpa_s->normal_scans = 0;
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- os_free(wpa_s->manual_scan_freqs);
- wpa_s->manual_scan_freqs = freqs;
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-
- return 0;
-}
-
-
-static void gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpabuf *n;
-
- wpa_msg(wpa_s, MSG_INFO, GAS_RESPONSE_INFO "addr=" MACSTR
- " dialog_token=%d status_code=%d resp_len=%d",
- MAC2STR(addr), dialog_token, status_code,
- resp ? (int) wpabuf_len(resp) : -1);
- if (!resp)
- return;
-
- n = wpabuf_dup(resp);
- if (n == NULL)
- return;
- wpabuf_free(wpa_s->prev_gas_resp);
- wpa_s->prev_gas_resp = wpa_s->last_gas_resp;
- os_memcpy(wpa_s->prev_gas_addr, wpa_s->last_gas_addr, ETH_ALEN);
- wpa_s->prev_gas_dialog_token = wpa_s->last_gas_dialog_token;
- wpa_s->last_gas_resp = n;
- os_memcpy(wpa_s->last_gas_addr, addr, ETH_ALEN);
- wpa_s->last_gas_dialog_token = dialog_token;
-}
-
-
-int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *adv_proto,
- const struct wpabuf *query)
-{
- struct wpabuf *buf;
- int ret = 0;
- int freq;
- struct wpa_bss *bss;
- int res;
- size_t len;
- u8 query_resp_len_limit = 0;
-
- freq = wpa_s->assoc_freq;
- bss = wpa_bss_get_bssid(wpa_s, dst);
- if (bss)
- freq = bss->freq;
- if (freq <= 0)
- return -1;
-
- wpa_msg(wpa_s, MSG_DEBUG, "GAS request to " MACSTR " (freq %d MHz)",
- MAC2STR(dst), freq);
- wpa_hexdump_buf(MSG_DEBUG, "Advertisement Protocol ID", adv_proto);
- wpa_hexdump_buf(MSG_DEBUG, "GAS Query", query);
-
- len = 3 + wpabuf_len(adv_proto) + 2;
- if (query)
- len += wpabuf_len(query);
- buf = gas_build_initial_req(0, len);
- if (buf == NULL)
- return -1;
-
- /* Advertisement Protocol IE */
- wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
- wpabuf_put_u8(buf, 1 + wpabuf_len(adv_proto)); /* Length */
- wpabuf_put_u8(buf, query_resp_len_limit & 0x7f);
- wpabuf_put_buf(buf, adv_proto);
-
- /* GAS Query */
- if (query) {
- wpabuf_put_le16(buf, wpabuf_len(query));
- wpabuf_put_buf(buf, query);
- } else
- wpabuf_put_le16(buf, 0);
-
- res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, gas_resp_cb,
- wpa_s);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
- wpabuf_free(buf);
- ret = -1;
- } else
- wpa_msg(wpa_s, MSG_DEBUG,
- "GAS: Query started with dialog token %u", res);
-
- return ret;
-}
diff --git a/wpa_supplicant/interworking.h b/wpa_supplicant/interworking.h
deleted file mode 100644
index 77b2c91bda52..000000000000
--- a/wpa_supplicant/interworking.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Interworking (IEEE 802.11u)
- * Copyright (c) 2011-2012, Qualcomm Atheros
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef INTERWORKING_H
-#define INTERWORKING_H
-
-enum gas_query_result;
-
-int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, int freq,
- u16 info_ids[], size_t num_ids, u32 subtypes,
- u32 mbo_subtypes);
-void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
- enum gas_query_result result,
- const struct wpabuf *adv_proto,
- const struct wpabuf *resp, u16 status_code);
-int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *adv_proto,
- const struct wpabuf *query);
-int interworking_fetch_anqp(struct wpa_supplicant *wpa_s);
-void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s);
-int interworking_select(struct wpa_supplicant *wpa_s, int auto_select,
- int *freqs);
-int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- int only_add);
-void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s);
-int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
- struct wpa_cred *cred,
- struct wpabuf *domain_names);
-int domain_name_list_contains(struct wpabuf *domain_names,
- const char *domain, int exact_match);
-
-#endif /* INTERWORKING_H */
diff --git a/wpa_supplicant/libwpa_test.c b/wpa_supplicant/libwpa_test.c
deleted file mode 100644
index e51ab7247665..000000000000
--- a/wpa_supplicant/libwpa_test.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * libwpa_test - Test program for libwpa_client.* library linking
- * Copyright (c) 2015, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common/wpa_ctrl.h"
-
-int main(int argc, char *argv[])
-{
- struct wpa_ctrl *ctrl;
-
- ctrl = wpa_ctrl_open("foo");
- if (!ctrl)
- return -1;
- if (wpa_ctrl_attach(ctrl) == 0)
- wpa_ctrl_detach(ctrl);
- if (wpa_ctrl_pending(ctrl)) {
- char buf[10];
- size_t len;
-
- len = sizeof(buf);
- wpa_ctrl_recv(ctrl, buf, &len);
- }
- wpa_ctrl_close(ctrl);
-
- return 0;
-}
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
deleted file mode 100644
index 51a8a0298a9b..000000000000
--- a/wpa_supplicant/main.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * WPA Supplicant / main() function for UNIX like OSes and MinGW
- * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#ifdef __linux__
-#include <fcntl.h>
-#endif /* __linux__ */
-
-#include "common.h"
-#include "fst/fst.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "p2p_supplicant.h"
-
-
-static void usage(void)
-{
- int i;
- printf("%s\n\n%s\n"
- "usage:\n"
- " wpa_supplicant [-BddhKLqq"
-#ifdef CONFIG_DEBUG_SYSLOG
- "s"
-#endif /* CONFIG_DEBUG_SYSLOG */
- "t"
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- "u"
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
- "vW] [-P<pid file>] "
- "[-g<global ctrl>] \\\n"
- " [-G<group>] \\\n"
- " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
- "[-p<driver_param>] \\\n"
- " [-b<br_ifname>] [-e<entropy file>]"
-#ifdef CONFIG_DEBUG_FILE
- " [-f<debug file>]"
-#endif /* CONFIG_DEBUG_FILE */
- " \\\n"
- " [-o<override driver>] [-O<override ctrl>] \\\n"
- " [-N -i<ifname> -c<conf> [-C<ctrl>] "
- "[-D<driver>] \\\n"
-#ifdef CONFIG_P2P
- " [-m<P2P Device config file>] \\\n"
-#endif /* CONFIG_P2P */
- " [-p<driver_param>] [-b<br_ifname>] [-I<config file>] "
- "...]\n"
- "\n"
- "drivers:\n",
- wpa_supplicant_version, wpa_supplicant_license);
-
- for (i = 0; wpa_drivers[i]; i++) {
- printf(" %s = %s\n",
- wpa_drivers[i]->name,
- wpa_drivers[i]->desc);
- }
-
-#ifndef CONFIG_NO_STDOUT_DEBUG
- printf("options:\n"
- " -b = optional bridge interface name\n"
- " -B = run daemon in the background\n"
- " -c = Configuration file\n"
- " -C = ctrl_interface parameter (only used if -c is not)\n"
- " -d = increase debugging verbosity (-dd even more)\n"
- " -D = driver name (can be multiple drivers: nl80211,wext)\n"
- " -e = entropy file\n"
-#ifdef CONFIG_DEBUG_FILE
- " -f = log output to debug file instead of stdout\n"
-#endif /* CONFIG_DEBUG_FILE */
- " -g = global ctrl_interface\n"
- " -G = global ctrl_interface group\n"
- " -h = show this help text\n"
- " -i = interface name\n"
- " -I = additional configuration file\n"
- " -K = include keys (passwords, etc.) in debug output\n"
- " -L = show license (BSD)\n"
-#ifdef CONFIG_P2P
- " -m = Configuration file for the P2P Device interface\n"
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_MATCH_IFACE
- " -M = start describing new matching interface\n"
-#endif /* CONFIG_MATCH_IFACE */
- " -N = start describing new interface\n"
- " -o = override driver parameter for new interfaces\n"
- " -O = override ctrl_interface parameter for new interfaces\n"
- " -p = driver parameters\n"
- " -P = PID file\n"
- " -q = decrease debugging verbosity (-qq even less)\n"
-#ifdef CONFIG_DEBUG_SYSLOG
- " -s = log output to syslog instead of stdout\n"
-#endif /* CONFIG_DEBUG_SYSLOG */
- " -t = include timestamp in debug messages\n"
-#ifdef CONFIG_DEBUG_LINUX_TRACING
- " -T = record to Linux tracing in addition to logging\n"
- " (records all messages regardless of debug verbosity)\n"
-#endif /* CONFIG_DEBUG_LINUX_TRACING */
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- " -u = enable DBus control interface\n"
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
- " -v = show version\n"
- " -W = wait for a control interface monitor before starting\n");
-
- printf("example:\n"
- " wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n",
- wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211");
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-}
-
-
-static void license(void)
-{
-#ifndef CONFIG_NO_STDOUT_DEBUG
- printf("%s\n\n%s%s%s%s%s\n",
- wpa_supplicant_version,
- wpa_supplicant_full_license1,
- wpa_supplicant_full_license2,
- wpa_supplicant_full_license3,
- wpa_supplicant_full_license4,
- wpa_supplicant_full_license5);
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-}
-
-
-static void wpa_supplicant_fd_workaround(int start)
-{
-#ifdef __linux__
- static int fd[3] = { -1, -1, -1 };
- int i;
- /* When started from pcmcia-cs scripts, wpa_supplicant might start with
- * fd 0, 1, and 2 closed. This will cause some issues because many
- * places in wpa_supplicant are still printing out to stdout. As a
- * workaround, make sure that fd's 0, 1, and 2 are not used for other
- * sockets. */
- if (start) {
- for (i = 0; i < 3; i++) {
- fd[i] = open("/dev/null", O_RDWR);
- if (fd[i] > 2) {
- close(fd[i]);
- fd[i] = -1;
- break;
- }
- }
- } else {
- for (i = 0; i < 3; i++) {
- if (fd[i] >= 0) {
- close(fd[i]);
- fd[i] = -1;
- }
- }
- }
-#endif /* __linux__ */
-}
-
-
-#ifdef CONFIG_MATCH_IFACE
-static int wpa_supplicant_init_match(struct wpa_global *global)
-{
- /*
- * The assumption is that the first driver is the primary driver and
- * will handle the arrival / departure of interfaces.
- */
- if (wpa_drivers[0]->global_init && !global->drv_priv[0]) {
- global->drv_priv[0] = wpa_drivers[0]->global_init(global);
- if (!global->drv_priv[0]) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize driver '%s'",
- wpa_drivers[0]->name);
- return -1;
- }
- }
-
- return 0;
-}
-#endif /* CONFIG_MATCH_IFACE */
-
-
-int main(int argc, char *argv[])
-{
- int c, i;
- struct wpa_interface *ifaces, *iface;
- int iface_count, exitcode = -1;
- struct wpa_params params;
- struct wpa_global *global;
-
- if (os_program_init())
- return -1;
-
- os_memset(&params, 0, sizeof(params));
- params.wpa_debug_level = MSG_INFO;
-
- iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
- if (ifaces == NULL)
- return -1;
- iface_count = 1;
-
- wpa_supplicant_fd_workaround(1);
-
- for (;;) {
- c = getopt(argc, argv,
- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW");
- if (c < 0)
- break;
- switch (c) {
- case 'b':
- iface->bridge_ifname = optarg;
- break;
- case 'B':
- params.daemonize++;
- break;
- case 'c':
- iface->confname = optarg;
- break;
- case 'C':
- iface->ctrl_interface = optarg;
- break;
- case 'D':
- iface->driver = optarg;
- break;
- case 'd':
-#ifdef CONFIG_NO_STDOUT_DEBUG
- printf("Debugging disabled with "
- "CONFIG_NO_STDOUT_DEBUG=y build time "
- "option.\n");
- goto out;
-#else /* CONFIG_NO_STDOUT_DEBUG */
- params.wpa_debug_level--;
- break;
-#endif /* CONFIG_NO_STDOUT_DEBUG */
- case 'e':
- params.entropy_file = optarg;
- break;
-#ifdef CONFIG_DEBUG_FILE
- case 'f':
- params.wpa_debug_file_path = optarg;
- break;
-#endif /* CONFIG_DEBUG_FILE */
- case 'g':
- params.ctrl_interface = optarg;
- break;
- case 'G':
- params.ctrl_interface_group = optarg;
- break;
- case 'h':
- usage();
- exitcode = 0;
- goto out;
- case 'i':
- iface->ifname = optarg;
- break;
- case 'I':
- iface->confanother = optarg;
- break;
- case 'K':
- params.wpa_debug_show_keys++;
- break;
- case 'L':
- license();
- exitcode = 0;
- goto out;
-#ifdef CONFIG_P2P
- case 'm':
- params.conf_p2p_dev = optarg;
- break;
-#endif /* CONFIG_P2P */
- case 'o':
- params.override_driver = optarg;
- break;
- case 'O':
- params.override_ctrl_interface = optarg;
- break;
- case 'p':
- iface->driver_param = optarg;
- break;
- case 'P':
- os_free(params.pid_file);
- params.pid_file = os_rel2abs_path(optarg);
- break;
- case 'q':
- params.wpa_debug_level++;
- break;
-#ifdef CONFIG_DEBUG_SYSLOG
- case 's':
- params.wpa_debug_syslog++;
- break;
-#endif /* CONFIG_DEBUG_SYSLOG */
-#ifdef CONFIG_DEBUG_LINUX_TRACING
- case 'T':
- params.wpa_debug_tracing++;
- break;
-#endif /* CONFIG_DEBUG_LINUX_TRACING */
- case 't':
- params.wpa_debug_timestamp++;
- break;
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- case 'u':
- params.dbus_ctrl_interface = 1;
- break;
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
- case 'v':
- printf("%s\n", wpa_supplicant_version);
- exitcode = 0;
- goto out;
- case 'W':
- params.wait_for_monitor++;
- break;
-#ifdef CONFIG_MATCH_IFACE
- case 'M':
- params.match_iface_count++;
- iface = os_realloc_array(params.match_ifaces,
- params.match_iface_count,
- sizeof(struct wpa_interface));
- if (!iface)
- goto out;
- params.match_ifaces = iface;
- iface = &params.match_ifaces[params.match_iface_count -
- 1];
- os_memset(iface, 0, sizeof(*iface));
- break;
-#endif /* CONFIG_MATCH_IFACE */
- case 'N':
- iface_count++;
- iface = os_realloc_array(ifaces, iface_count,
- sizeof(struct wpa_interface));
- if (iface == NULL)
- goto out;
- ifaces = iface;
- iface = &ifaces[iface_count - 1];
- os_memset(iface, 0, sizeof(*iface));
- break;
- default:
- usage();
- exitcode = 0;
- goto out;
- }
- }
-
- exitcode = 0;
- global = wpa_supplicant_init(&params);
- if (global == NULL) {
- wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
- exitcode = -1;
- goto out;
- } else {
- wpa_printf(MSG_INFO, "Successfully initialized "
- "wpa_supplicant");
- }
-
- if (fst_global_init()) {
- wpa_printf(MSG_ERROR, "Failed to initialize FST");
- exitcode = -1;
- goto out;
- }
-
-#if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE)
- if (!fst_global_add_ctrl(fst_ctrl_cli))
- wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl");
-#endif
-
- for (i = 0; exitcode == 0 && i < iface_count; i++) {
- struct wpa_supplicant *wpa_s;
-
- if ((ifaces[i].confname == NULL &&
- ifaces[i].ctrl_interface == NULL) ||
- ifaces[i].ifname == NULL) {
- if (iface_count == 1 && (params.ctrl_interface ||
-#ifdef CONFIG_MATCH_IFACE
- params.match_iface_count ||
-#endif /* CONFIG_MATCH_IFACE */
- params.dbus_ctrl_interface))
- break;
- usage();
- exitcode = -1;
- break;
- }
- wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
- if (wpa_s == NULL) {
- exitcode = -1;
- break;
- }
- }
-
-#ifdef CONFIG_MATCH_IFACE
- if (exitcode == 0)
- exitcode = wpa_supplicant_init_match(global);
-#endif /* CONFIG_MATCH_IFACE */
-
- if (exitcode == 0)
- exitcode = wpa_supplicant_run(global);
-
- wpa_supplicant_deinit(global);
-
- fst_global_deinit();
-
-out:
- wpa_supplicant_fd_workaround(0);
- os_free(ifaces);
-#ifdef CONFIG_MATCH_IFACE
- os_free(params.match_ifaces);
-#endif /* CONFIG_MATCH_IFACE */
- os_free(params.pid_file);
-
- os_program_deinit();
-
- return exitcode;
-}
diff --git a/wpa_supplicant/main_none.c b/wpa_supplicant/main_none.c
deleted file mode 100644
index 4d3caf2a4da3..000000000000
--- a/wpa_supplicant/main_none.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * WPA Supplicant / Example program entrypoint
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-
-int main(int argc, char *argv[])
-{
- struct wpa_interface iface;
- int exitcode = 0;
- struct wpa_params params;
- struct wpa_global *global;
-
- memset(&params, 0, sizeof(params));
- params.wpa_debug_level = MSG_INFO;
-
- global = wpa_supplicant_init(&params);
- if (global == NULL)
- return -1;
-
- memset(&iface, 0, sizeof(iface));
- /* TODO: set interface parameters */
-
- if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL)
- exitcode = -1;
-
- if (exitcode == 0)
- exitcode = wpa_supplicant_run(global);
-
- wpa_supplicant_deinit(global);
-
- return exitcode;
-}
diff --git a/wpa_supplicant/main_winmain.c b/wpa_supplicant/main_winmain.c
deleted file mode 100644
index e1dded0c349a..000000000000
--- a/wpa_supplicant/main_winmain.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * WPA Supplicant / WinMain() function for Windows-based applications
- * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-
-#ifdef _WIN32_WCE
-#define CMDLINE LPWSTR
-#else /* _WIN32_WCE */
-#define CMDLINE LPSTR
-#endif /* _WIN32_WCE */
-
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- CMDLINE lpCmdLine, int nShowCmd)
-{
- int i;
- struct wpa_interface *ifaces, *iface;
- int iface_count, exitcode = -1;
- struct wpa_params params;
- struct wpa_global *global;
-
- if (os_program_init())
- return -1;
-
- os_memset(&params, 0, sizeof(params));
- params.wpa_debug_level = MSG_MSGDUMP;
- params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
- params.wpa_debug_show_keys = 1;
-
- iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
- if (ifaces == NULL)
- return -1;
- iface_count = 1;
-
- iface->confname = "default";
- iface->driver = "ndis";
- iface->ifname = "";
-
- exitcode = 0;
- global = wpa_supplicant_init(&params);
- if (global == NULL) {
- printf("Failed to initialize wpa_supplicant\n");
- exitcode = -1;
- }
-
- for (i = 0; exitcode == 0 && i < iface_count; i++) {
- if ((ifaces[i].confname == NULL &&
- ifaces[i].ctrl_interface == NULL) ||
- ifaces[i].ifname == NULL) {
- if (iface_count == 1 && (params.ctrl_interface ||
- params.dbus_ctrl_interface))
- break;
- exitcode = -1;
- break;
- }
- if (wpa_supplicant_add_iface(global, &ifaces[i], NULL) == NULL)
- exitcode = -1;
- }
-
- if (exitcode == 0)
- exitcode = wpa_supplicant_run(global);
-
- wpa_supplicant_deinit(global);
-
- os_free(ifaces);
-
- os_program_deinit();
-
- return exitcode;
-}
diff --git a/wpa_supplicant/main_winsvc.c b/wpa_supplicant/main_winsvc.c
deleted file mode 100644
index 9950aa99ae7a..000000000000
--- a/wpa_supplicant/main_winsvc.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * WPA Supplicant / main() function for Win32 service
- * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * The root of wpa_supplicant configuration in registry is
- * HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant. This level includes global
- * parameters and a 'interfaces' subkey with all the interface configuration
- * (adapter to confname mapping). Each such mapping is a subkey that has
- * 'adapter' and 'config' values.
- *
- * This program can be run either as a normal command line application, e.g.,
- * for debugging, with 'wpasvc.exe app' or as a Windows service. Service need
- * to be registered with 'wpasvc.exe reg <full path to wpasvc.exe>'. After
- * this, it can be started like any other Windows service (e.g., 'net start
- * wpasvc') or it can be configured to start automatically through the Services
- * tool in administrative tasks. The service can be unregistered with
- * 'wpasvc.exe unreg'.
- */
-
-#include "includes.h"
-#include <windows.h>
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "eloop.h"
-
-#ifndef WPASVC_NAME
-#define WPASVC_NAME TEXT("wpasvc")
-#endif
-#ifndef WPASVC_DISPLAY_NAME
-#define WPASVC_DISPLAY_NAME TEXT("wpa_supplicant service")
-#endif
-#ifndef WPASVC_DESCRIPTION
-#define WPASVC_DESCRIPTION \
-TEXT("Provides IEEE 802.1X and WPA/WPA2 supplicant functionality")
-#endif
-
-static HANDLE kill_svc;
-
-static SERVICE_STATUS_HANDLE svc_status_handle;
-static SERVICE_STATUS svc_status;
-
-
-#ifndef WPA_KEY_ROOT
-#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
-#endif
-#ifndef WPA_KEY_PREFIX
-#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
-#endif
-
-#ifdef UNICODE
-#define TSTR "%S"
-#else /* UNICODE */
-#define TSTR "%s"
-#endif /* UNICODE */
-
-
-static int read_interface(struct wpa_global *global, HKEY _hk,
- const TCHAR *name)
-{
- HKEY hk;
-#define TBUFLEN 255
- TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN];
- DWORD buflen, val;
- LONG ret;
- struct wpa_interface iface;
- int skip_on_error = 0;
-
- ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk);
- if (ret != ERROR_SUCCESS) {
- printf("Could not open wpa_supplicant interface key\n");
- return -1;
- }
-
- os_memset(&iface, 0, sizeof(iface));
- iface.driver = "ndis";
-
- buflen = sizeof(ctrl_interface);
- ret = RegQueryValueEx(hk, TEXT("ctrl_interface"), NULL, NULL,
- (LPBYTE) ctrl_interface, &buflen);
- if (ret == ERROR_SUCCESS) {
- ctrl_interface[TBUFLEN - 1] = TEXT('\0');
- wpa_unicode2ascii_inplace(ctrl_interface);
- printf("ctrl_interface[len=%d] '%s'\n",
- (int) buflen, (char *) ctrl_interface);
- iface.ctrl_interface = (char *) ctrl_interface;
- }
-
- buflen = sizeof(adapter);
- ret = RegQueryValueEx(hk, TEXT("adapter"), NULL, NULL,
- (LPBYTE) adapter, &buflen);
- if (ret == ERROR_SUCCESS) {
- adapter[TBUFLEN - 1] = TEXT('\0');
- wpa_unicode2ascii_inplace(adapter);
- printf("adapter[len=%d] '%s'\n",
- (int) buflen, (char *) adapter);
- iface.ifname = (char *) adapter;
- }
-
- buflen = sizeof(config);
- ret = RegQueryValueEx(hk, TEXT("config"), NULL, NULL,
- (LPBYTE) config, &buflen);
- if (ret == ERROR_SUCCESS) {
- config[sizeof(config) - 1] = '\0';
- wpa_unicode2ascii_inplace(config);
- printf("config[len=%d] '%s'\n",
- (int) buflen, (char *) config);
- iface.confname = (char *) config;
- }
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, TEXT("skip_on_error"), NULL, NULL,
- (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val))
- skip_on_error = val;
-
- RegCloseKey(hk);
-
- if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL) {
- if (skip_on_error)
- wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to "
- "initialization failure", iface.ifname);
- else
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpa_supplicant_thread(void)
-{
- int exitcode;
- struct wpa_params params;
- struct wpa_global *global;
- HKEY hk, ihk;
- DWORD val, buflen, i;
- LONG ret;
-
- if (os_program_init())
- return -1;
-
- os_memset(&params, 0, sizeof(params));
- params.wpa_debug_level = MSG_INFO;
-
- ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX,
- 0, KEY_QUERY_VALUE, &hk);
- if (ret != ERROR_SUCCESS) {
- printf("Could not open wpa_supplicant registry key\n");
- return -1;
- }
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, TEXT("debug_level"), NULL, NULL,
- (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
- params.wpa_debug_level = val;
- }
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, TEXT("debug_show_keys"), NULL, NULL,
- (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
- params.wpa_debug_show_keys = val;
- }
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, TEXT("debug_timestamp"), NULL, NULL,
- (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
- params.wpa_debug_timestamp = val;
- }
-
- buflen = sizeof(val);
- ret = RegQueryValueEx(hk, TEXT("debug_use_file"), NULL, NULL,
- (LPBYTE) &val, &buflen);
- if (ret == ERROR_SUCCESS && buflen == sizeof(val) && val) {
- params.wpa_debug_file_path = "\\Temp\\wpa_supplicant-log.txt";
- }
-
- exitcode = 0;
- global = wpa_supplicant_init(&params);
- if (global == NULL) {
- printf("Failed to initialize wpa_supplicant\n");
- exitcode = -1;
- }
-
- ret = RegOpenKeyEx(hk, TEXT("interfaces"), 0, KEY_ENUMERATE_SUB_KEYS,
- &ihk);
- RegCloseKey(hk);
- if (ret != ERROR_SUCCESS) {
- printf("Could not open wpa_supplicant interfaces registry "
- "key\n");
- return -1;
- }
-
- for (i = 0; ; i++) {
- TCHAR name[255];
- DWORD namelen;
-
- namelen = 255;
- ret = RegEnumKeyEx(ihk, i, name, &namelen, NULL, NULL, NULL,
- NULL);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS) {
- printf("RegEnumKeyEx failed: 0x%x\n",
- (unsigned int) ret);
- break;
- }
-
- if (namelen >= 255)
- namelen = 255 - 1;
- name[namelen] = '\0';
-
- wpa_printf(MSG_DEBUG, "interface %d: %s\n", (int) i, name);
- if (read_interface(global, ihk, name) < 0)
- exitcode = -1;
- }
-
- RegCloseKey(ihk);
-
- if (exitcode == 0)
- exitcode = wpa_supplicant_run(global);
-
- wpa_supplicant_deinit(global);
-
- os_program_deinit();
-
- return exitcode;
-}
-
-
-static DWORD svc_thread(LPDWORD param)
-{
- int ret = wpa_supplicant_thread();
-
- svc_status.dwCurrentState = SERVICE_STOPPED;
- svc_status.dwWaitHint = 0;
- if (!SetServiceStatus(svc_status_handle, &svc_status)) {
- printf("SetServiceStatus() failed: %d\n",
- (int) GetLastError());
- }
-
- return ret;
-}
-
-
-static int register_service(const TCHAR *exe)
-{
- SC_HANDLE svc, scm;
- SERVICE_DESCRIPTION sd;
-
- printf("Registering service: " TSTR "\n", WPASVC_NAME);
-
- scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
- if (!scm) {
- printf("OpenSCManager failed: %d\n", (int) GetLastError());
- return -1;
- }
-
- svc = CreateService(scm, WPASVC_NAME, WPASVC_DISPLAY_NAME,
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
- exe, NULL, NULL, NULL, NULL, NULL);
-
- if (!svc) {
- printf("CreateService failed: %d\n\n", (int) GetLastError());
- CloseServiceHandle(scm);
- return -1;
- }
-
- os_memset(&sd, 0, sizeof(sd));
- sd.lpDescription = WPASVC_DESCRIPTION;
- if (!ChangeServiceConfig2(svc, SERVICE_CONFIG_DESCRIPTION, &sd)) {
- printf("ChangeServiceConfig2 failed: %d\n",
- (int) GetLastError());
- /* This is not a fatal error, so continue anyway. */
- }
-
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
-
- printf("Service registered successfully.\n");
-
- return 0;
-}
-
-
-static int unregister_service(void)
-{
- SC_HANDLE svc, scm;
- SERVICE_STATUS status;
-
- printf("Unregistering service: " TSTR "\n", WPASVC_NAME);
-
- scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
- if (!scm) {
- printf("OpenSCManager failed: %d\n", (int) GetLastError());
- return -1;
- }
-
- svc = OpenService(scm, WPASVC_NAME, SERVICE_ALL_ACCESS | DELETE);
- if (!svc) {
- printf("OpenService failed: %d\n\n", (int) GetLastError());
- CloseServiceHandle(scm);
- return -1;
- }
-
- if (QueryServiceStatus(svc, &status)) {
- if (status.dwCurrentState != SERVICE_STOPPED) {
- printf("Service currently active - stopping "
- "service...\n");
- if (!ControlService(svc, SERVICE_CONTROL_STOP,
- &status)) {
- printf("ControlService failed: %d\n",
- (int) GetLastError());
- }
- Sleep(500);
- }
- }
-
- if (DeleteService(svc)) {
- printf("Service unregistered successfully.\n");
- } else {
- printf("DeleteService failed: %d\n", (int) GetLastError());
- }
-
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
-
- return 0;
-}
-
-
-static void WINAPI service_ctrl_handler(DWORD control_code)
-{
- switch (control_code) {
- case SERVICE_CONTROL_INTERROGATE:
- break;
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- svc_status.dwCurrentState = SERVICE_STOP_PENDING;
- svc_status.dwWaitHint = 2000;
- eloop_terminate();
- SetEvent(kill_svc);
- break;
- }
-
- if (!SetServiceStatus(svc_status_handle, &svc_status)) {
- printf("SetServiceStatus() failed: %d\n",
- (int) GetLastError());
- }
-}
-
-
-static void WINAPI service_start(DWORD argc, LPTSTR *argv)
-{
- DWORD id;
-
- svc_status_handle = RegisterServiceCtrlHandler(WPASVC_NAME,
- service_ctrl_handler);
- if (svc_status_handle == (SERVICE_STATUS_HANDLE) 0) {
- printf("RegisterServiceCtrlHandler failed: %d\n",
- (int) GetLastError());
- return;
- }
-
- os_memset(&svc_status, 0, sizeof(svc_status));
- svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- svc_status.dwCurrentState = SERVICE_START_PENDING;
- svc_status.dwWaitHint = 1000;
-
- if (!SetServiceStatus(svc_status_handle, &svc_status)) {
- printf("SetServiceStatus() failed: %d\n",
- (int) GetLastError());
- return;
- }
-
- kill_svc = CreateEvent(0, TRUE, FALSE, 0);
- if (!kill_svc) {
- printf("CreateEvent failed: %d\n", (int) GetLastError());
- return;
- }
-
- if (CreateThread(0, 0, (LPTHREAD_START_ROUTINE) svc_thread, 0, 0, &id)
- == 0) {
- printf("CreateThread failed: %d\n", (int) GetLastError());
- return;
- }
-
- if (svc_status.dwCurrentState == SERVICE_START_PENDING) {
- svc_status.dwCurrentState = SERVICE_RUNNING;
- svc_status.dwWaitHint = 0;
- svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
- SERVICE_ACCEPT_SHUTDOWN;
- }
-
- if (!SetServiceStatus(svc_status_handle, &svc_status)) {
- printf("SetServiceStatus() failed: %d\n",
- (int) GetLastError());
- return;
- }
-
- /* wait until service gets killed */
- WaitForSingleObject(kill_svc, INFINITE);
-}
-
-
-int main(int argc, char *argv[])
-{
- SERVICE_TABLE_ENTRY dt[] = {
- { WPASVC_NAME, service_start },
- { NULL, NULL }
- };
-
- if (argc > 1) {
- if (os_strcmp(argv[1], "reg") == 0) {
- TCHAR *path;
- int ret;
-
- if (argc < 3) {
- path = os_malloc(MAX_PATH * sizeof(TCHAR));
- if (path == NULL)
- return -1;
- if (!GetModuleFileName(NULL, path, MAX_PATH)) {
- printf("GetModuleFileName failed: "
- "%d\n", (int) GetLastError());
- os_free(path);
- return -1;
- }
- } else {
- path = wpa_strdup_tchar(argv[2]);
- if (path == NULL)
- return -1;
- }
- ret = register_service(path);
- os_free(path);
- return ret;
- } else if (os_strcmp(argv[1], "unreg") == 0) {
- return unregister_service();
- } else if (os_strcmp(argv[1], "app") == 0) {
- return wpa_supplicant_thread();
- }
- }
-
- if (!StartServiceCtrlDispatcher(dt)) {
- printf("StartServiceCtrlDispatcher failed: %d\n",
- (int) GetLastError());
- }
-
- return 0;
-}
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
deleted file mode 100644
index 3df86ef0724e..000000000000
--- a/wpa_supplicant/mbo.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * wpa_supplicant - MBO
- *
- * Copyright(c) 2015 Intel Deutschland GmbH
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/gas.h"
-#include "rsn_supp/wpa.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "bss.h"
-#include "scan.h"
-
-/* type + length + oui + oui type */
-#define MBO_IE_HEADER 6
-
-
-static int wpas_mbo_validate_non_pref_chan(u8 oper_class, u8 chan, u8 reason)
-{
- if (reason > MBO_NON_PREF_CHAN_REASON_INT_INTERFERENCE)
- return -1;
-
- /* Only checking the validity of the channel and oper_class */
- if (ieee80211_chan_to_freq(NULL, oper_class, chan) == -1)
- return -1;
-
- return 0;
-}
-
-
-const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr)
-{
- const u8 *mbo;
- u8 ie_len = mbo_ie[1];
-
- if (ie_len < MBO_IE_HEADER - 2)
- return NULL;
- mbo = mbo_ie + MBO_IE_HEADER;
-
- return get_ie(mbo, 2 + ie_len - MBO_IE_HEADER, attr);
-}
-
-
-const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len,
- enum mbo_attr_id attr)
-{
- const u8 *mbo_ie;
-
- mbo_ie = get_vendor_ie(ies, ies_len, MBO_IE_VENDOR_TYPE);
- if (!mbo_ie)
- return NULL;
-
- return mbo_attr_from_mbo_ie(mbo_ie, attr);
-}
-
-
-const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr)
-{
- const u8 *mbo, *end;
-
- if (!bss)
- return NULL;
-
- mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
- if (!mbo)
- return NULL;
-
- end = mbo + 2 + mbo[1];
- mbo += MBO_IE_HEADER;
-
- return get_ie(mbo, end - mbo, attr);
-}
-
-
-void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- struct wpa_ssid *ssid)
-{
- const u8 *rsne, *mbo, *oce;
- struct wpa_ie_data ie;
-
- wpa_s->disable_mbo_oce = 0;
- if (!bss)
- return;
- mbo = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND);
- oce = wpas_mbo_get_bss_attr(bss, OCE_ATTR_ID_CAPA_IND);
- if (!mbo && !oce)
- return;
- if (oce && oce[1] >= 1 && (oce[2] & OCE_IS_STA_CFON))
- return; /* STA-CFON is not required to enable PMF */
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (!rsne || wpa_parse_wpa_ie(rsne, 2 + rsne[1], &ie) < 0)
- return; /* AP is not using RSN */
-
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC))
- wpa_s->disable_mbo_oce = 1; /* AP uses RSN without PMF */
- if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
- wpa_s->disable_mbo_oce = 1; /* STA uses RSN without PMF */
- if (wpa_s->disable_mbo_oce)
- wpa_printf(MSG_INFO,
- "MBO: Disable MBO/OCE due to misbehaving AP not having enabled PMF");
-}
-
-
-static void wpas_mbo_non_pref_chan_attr_body(struct wpa_supplicant *wpa_s,
- struct wpabuf *mbo,
- u8 start, u8 end)
-{
- u8 i;
-
- wpabuf_put_u8(mbo, wpa_s->non_pref_chan[start].oper_class);
-
- for (i = start; i < end; i++)
- wpabuf_put_u8(mbo, wpa_s->non_pref_chan[i].chan);
-
- wpabuf_put_u8(mbo, wpa_s->non_pref_chan[start].preference);
- wpabuf_put_u8(mbo, wpa_s->non_pref_chan[start].reason);
-}
-
-
-static void wpas_mbo_non_pref_chan_attr_hdr(struct wpabuf *mbo, size_t size)
-{
- wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
- wpabuf_put_u8(mbo, size); /* Length */
-}
-
-
-static void wpas_mbo_non_pref_chan_attr(struct wpa_supplicant *wpa_s,
- struct wpabuf *mbo, u8 start, u8 end)
-{
- size_t size = end - start + 3;
-
- if (size + 2 > wpabuf_tailroom(mbo))
- return;
-
- wpas_mbo_non_pref_chan_attr_hdr(mbo, size);
- wpas_mbo_non_pref_chan_attr_body(wpa_s, mbo, start, end);
-}
-
-
-static void wpas_mbo_non_pref_chan_subelem_hdr(struct wpabuf *mbo, u8 len)
-{
- wpabuf_put_u8(mbo, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(mbo, len); /* Length */
- wpabuf_put_be24(mbo, OUI_WFA);
- wpabuf_put_u8(mbo, MBO_ATTR_ID_NON_PREF_CHAN_REPORT);
-}
-
-
-static void wpas_mbo_non_pref_chan_subelement(struct wpa_supplicant *wpa_s,
- struct wpabuf *mbo, u8 start,
- u8 end)
-{
- size_t size = end - start + 7;
-
- if (size + 2 > wpabuf_tailroom(mbo))
- return;
-
- wpas_mbo_non_pref_chan_subelem_hdr(mbo, size);
- wpas_mbo_non_pref_chan_attr_body(wpa_s, mbo, start, end);
-}
-
-
-static void wpas_mbo_non_pref_chan_attrs(struct wpa_supplicant *wpa_s,
- struct wpabuf *mbo, int subelement)
-{
- u8 i, start = 0;
- struct wpa_mbo_non_pref_channel *start_pref;
-
- if (!wpa_s->non_pref_chan || !wpa_s->non_pref_chan_num) {
- if (subelement)
- wpas_mbo_non_pref_chan_subelem_hdr(mbo, 4);
- else
- wpas_mbo_non_pref_chan_attr_hdr(mbo, 0);
- return;
- }
- start_pref = &wpa_s->non_pref_chan[0];
-
- for (i = 1; i <= wpa_s->non_pref_chan_num; i++) {
- struct wpa_mbo_non_pref_channel *non_pref = NULL;
-
- if (i < wpa_s->non_pref_chan_num)
- non_pref = &wpa_s->non_pref_chan[i];
- if (!non_pref ||
- non_pref->oper_class != start_pref->oper_class ||
- non_pref->reason != start_pref->reason ||
- non_pref->preference != start_pref->preference) {
- if (subelement)
- wpas_mbo_non_pref_chan_subelement(wpa_s, mbo,
- start, i);
- else
- wpas_mbo_non_pref_chan_attr(wpa_s, mbo, start,
- i);
-
- if (!non_pref)
- return;
-
- start = i;
- start_pref = non_pref;
- }
- }
-}
-
-
-int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len,
- int add_oce_capa)
-{
- struct wpabuf *mbo;
- int res;
-
- if (len < MBO_IE_HEADER + 3 + 7 +
- ((wpa_s->enable_oce & OCE_STA) ? 3 : 0))
- return 0;
-
- /* Leave room for the MBO IE header */
- mbo = wpabuf_alloc(len - MBO_IE_HEADER);
- if (!mbo)
- return 0;
-
- /* Add non-preferred channels attribute */
- wpas_mbo_non_pref_chan_attrs(wpa_s, mbo, 0);
-
- /*
- * Send cellular capabilities attribute even if AP does not advertise
- * cellular capabilities.
- */
- wpabuf_put_u8(mbo, MBO_ATTR_ID_CELL_DATA_CAPA);
- wpabuf_put_u8(mbo, 1);
- wpabuf_put_u8(mbo, wpa_s->conf->mbo_cell_capa);
-
- /* Add OCE capability indication attribute if OCE is enabled */
- if ((wpa_s->enable_oce & OCE_STA) && add_oce_capa) {
- wpabuf_put_u8(mbo, OCE_ATTR_ID_CAPA_IND);
- wpabuf_put_u8(mbo, 1);
- wpabuf_put_u8(mbo, OCE_RELEASE);
- }
-
- res = mbo_add_ie(buf, len, wpabuf_head_u8(mbo), wpabuf_len(mbo));
- if (!res)
- wpa_printf(MSG_ERROR, "Failed to add MBO/OCE IE");
-
- wpabuf_free(mbo);
- return res;
-}
-
-
-static void wpas_mbo_send_wnm_notification(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t len)
-{
- struct wpabuf *buf;
- int res;
-
- /*
- * Send WNM-Notification Request frame only in case of a change in
- * non-preferred channels list during association, if the AP supports
- * MBO.
- */
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_bss ||
- !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE))
- return;
-
- buf = wpabuf_alloc(4 + len);
- if (!buf)
- return;
-
- wpabuf_put_u8(buf, WLAN_ACTION_WNM);
- wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
- wpa_s->mbo_wnm_token++;
- if (wpa_s->mbo_wnm_token == 0)
- wpa_s->mbo_wnm_token++;
- wpabuf_put_u8(buf, wpa_s->mbo_wnm_token);
- wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); /* Type */
-
- wpabuf_put_data(buf, data, len);
-
- res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (res < 0)
- wpa_printf(MSG_DEBUG,
- "Failed to send WNM-Notification Request frame with non-preferred channel list");
-
- wpabuf_free(buf);
-}
-
-
-static void wpas_mbo_non_pref_chan_changed(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *buf;
-
- buf = wpabuf_alloc(512);
- if (!buf)
- return;
-
- wpas_mbo_non_pref_chan_attrs(wpa_s, buf, 1);
- wpas_mbo_send_wnm_notification(wpa_s, wpabuf_head_u8(buf),
- wpabuf_len(buf));
- wpas_update_mbo_connect_params(wpa_s);
- wpabuf_free(buf);
-}
-
-
-static int wpa_non_pref_chan_is_eq(struct wpa_mbo_non_pref_channel *a,
- struct wpa_mbo_non_pref_channel *b)
-{
- return a->oper_class == b->oper_class && a->chan == b->chan;
-}
-
-
-/*
- * wpa_non_pref_chan_cmp - Compare two channels for sorting
- *
- * In MBO IE non-preferred channel subelement we can put many channels in an
- * attribute if they are in the same operating class and have the same
- * preference and reason. To make it easy for the functions that build
- * the IE attributes and WNM Request subelements, save the channels sorted
- * by their oper_class and reason.
- */
-static int wpa_non_pref_chan_cmp(const void *_a, const void *_b)
-{
- const struct wpa_mbo_non_pref_channel *a = _a, *b = _b;
-
- if (a->oper_class != b->oper_class)
- return (int) a->oper_class - (int) b->oper_class;
- if (a->reason != b->reason)
- return (int) a->reason - (int) b->reason;
- return (int) a->preference - (int) b->preference;
-}
-
-
-int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s,
- const char *non_pref_chan)
-{
- char *cmd, *token, *context = NULL;
- struct wpa_mbo_non_pref_channel *chans = NULL, *tmp_chans;
- size_t num = 0, size = 0;
- unsigned i;
-
- wpa_printf(MSG_DEBUG, "MBO: Update non-preferred channels, non_pref_chan=%s",
- non_pref_chan ? non_pref_chan : "N/A");
-
- /*
- * The shortest channel configuration is 7 characters - 3 colons and
- * 4 values.
- */
- if (!non_pref_chan || os_strlen(non_pref_chan) < 7)
- goto update;
-
- cmd = os_strdup(non_pref_chan);
- if (!cmd)
- return -1;
-
- while ((token = str_token(cmd, " ", &context))) {
- struct wpa_mbo_non_pref_channel *chan;
- int ret;
- unsigned int _oper_class;
- unsigned int _chan;
- unsigned int _preference;
- unsigned int _reason;
-
- if (num == size) {
- size = size ? size * 2 : 1;
- tmp_chans = os_realloc_array(chans, size,
- sizeof(*chans));
- if (!tmp_chans) {
- wpa_printf(MSG_ERROR,
- "Couldn't reallocate non_pref_chan");
- goto fail;
- }
- chans = tmp_chans;
- }
-
- chan = &chans[num];
-
- ret = sscanf(token, "%u:%u:%u:%u", &_oper_class,
- &_chan, &_preference, &_reason);
- if (ret != 4 ||
- _oper_class > 255 || _chan > 255 ||
- _preference > 255 || _reason > 65535 ) {
- wpa_printf(MSG_ERROR, "Invalid non-pref chan input %s",
- token);
- goto fail;
- }
- chan->oper_class = _oper_class;
- chan->chan = _chan;
- chan->preference = _preference;
- chan->reason = _reason;
-
- if (wpas_mbo_validate_non_pref_chan(chan->oper_class,
- chan->chan, chan->reason)) {
- wpa_printf(MSG_ERROR,
- "Invalid non_pref_chan: oper class %d chan %d reason %d",
- chan->oper_class, chan->chan, chan->reason);
- goto fail;
- }
-
- for (i = 0; i < num; i++)
- if (wpa_non_pref_chan_is_eq(chan, &chans[i]))
- break;
- if (i != num) {
- wpa_printf(MSG_ERROR,
- "oper class %d chan %d is duplicated",
- chan->oper_class, chan->chan);
- goto fail;
- }
-
- num++;
- }
-
- os_free(cmd);
-
- if (chans) {
- qsort(chans, num, sizeof(struct wpa_mbo_non_pref_channel),
- wpa_non_pref_chan_cmp);
- }
-
-update:
- os_free(wpa_s->non_pref_chan);
- wpa_s->non_pref_chan = chans;
- wpa_s->non_pref_chan_num = num;
- wpas_mbo_non_pref_chan_changed(wpa_s);
-
- return 0;
-
-fail:
- os_free(chans);
- os_free(cmd);
- return -1;
-}
-
-
-void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie)
-{
- u8 *len;
-
- wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
- len = wpabuf_put(ie, 1);
-
- wpabuf_put_be24(ie, OUI_WFA);
- wpabuf_put_u8(ie, MBO_OUI_TYPE);
-
- wpabuf_put_u8(ie, MBO_ATTR_ID_CELL_DATA_CAPA);
- wpabuf_put_u8(ie, 1);
- wpabuf_put_u8(ie, wpa_s->conf->mbo_cell_capa);
- if (wpa_s->enable_oce & OCE_STA) {
- wpabuf_put_u8(ie, OCE_ATTR_ID_CAPA_IND);
- wpabuf_put_u8(ie, 1);
- wpabuf_put_u8(ie, OCE_RELEASE);
- }
- *len = (u8 *) wpabuf_put(ie, 0) - len - 1;
-}
-
-
-void wpas_mbo_ie_trans_req(struct wpa_supplicant *wpa_s, const u8 *mbo_ie,
- size_t len)
-{
- const u8 *pos, *cell_pref = NULL;
- u8 id, elen;
- u16 disallowed_sec = 0;
-
- if (len <= 4 || WPA_GET_BE24(mbo_ie) != OUI_WFA ||
- mbo_ie[3] != MBO_OUI_TYPE)
- return;
-
- pos = mbo_ie + 4;
- len -= 4;
-
- while (len >= 2) {
- id = *pos++;
- elen = *pos++;
- len -= 2;
-
- if (elen > len)
- goto fail;
-
- switch (id) {
- case MBO_ATTR_ID_CELL_DATA_PREF:
- if (elen != 1)
- goto fail;
-
- if (wpa_s->conf->mbo_cell_capa ==
- MBO_CELL_CAPA_AVAILABLE)
- cell_pref = pos;
- else
- wpa_printf(MSG_DEBUG,
- "MBO: Station does not support Cellular data connection");
- break;
- case MBO_ATTR_ID_TRANSITION_REASON:
- if (elen != 1)
- goto fail;
-
- wpa_s->wnm_mbo_trans_reason_present = 1;
- wpa_s->wnm_mbo_transition_reason = *pos;
- break;
- case MBO_ATTR_ID_ASSOC_RETRY_DELAY:
- if (elen != 2)
- goto fail;
-
- if (wpa_s->wnm_mode &
- WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
- wpa_printf(MSG_DEBUG,
- "MBO: Unexpected association retry delay, BSS is terminating");
- goto fail;
- } else if (wpa_s->wnm_mode &
- WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
- disallowed_sec = WPA_GET_LE16(pos);
- wpa_printf(MSG_DEBUG,
- "MBO: Association retry delay: %u",
- disallowed_sec);
- } else {
- wpa_printf(MSG_DEBUG,
- "MBO: Association retry delay attribute not in disassoc imminent mode");
- }
-
- break;
- case MBO_ATTR_ID_AP_CAPA_IND:
- case MBO_ATTR_ID_NON_PREF_CHAN_REPORT:
- case MBO_ATTR_ID_CELL_DATA_CAPA:
- case MBO_ATTR_ID_ASSOC_DISALLOW:
- case MBO_ATTR_ID_TRANSITION_REJECT_REASON:
- wpa_printf(MSG_DEBUG,
- "MBO: Attribute %d should not be included in BTM Request frame",
- id);
- break;
- default:
- wpa_printf(MSG_DEBUG, "MBO: Unknown attribute id %u",
- id);
- return;
- }
-
- pos += elen;
- len -= elen;
- }
-
- if (cell_pref)
- wpa_msg(wpa_s, MSG_INFO, MBO_CELL_PREFERENCE "preference=%u",
- *cell_pref);
-
- if (wpa_s->wnm_mbo_trans_reason_present)
- wpa_msg(wpa_s, MSG_INFO, MBO_TRANSITION_REASON "reason=%u",
- wpa_s->wnm_mbo_transition_reason);
-
- if (disallowed_sec && wpa_s->current_bss)
- wpa_bss_tmp_disallow(wpa_s, wpa_s->current_bss->bssid,
- disallowed_sec, 0);
-
- return;
-fail:
- wpa_printf(MSG_DEBUG, "MBO IE parsing failed (id=%u len=%u left=%zu)",
- id, elen, len);
-}
-
-
-size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos,
- size_t len,
- enum mbo_transition_reject_reason reason)
-{
- u8 reject_attr[3];
-
- reject_attr[0] = MBO_ATTR_ID_TRANSITION_REJECT_REASON;
- reject_attr[1] = 1;
- reject_attr[2] = reason;
-
- return mbo_add_ie(pos, len, reject_attr, sizeof(reject_attr));
-}
-
-
-void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa)
-{
- u8 cell_capa[7];
-
- if (wpa_s->conf->mbo_cell_capa == mbo_cell_capa) {
- wpa_printf(MSG_DEBUG,
- "MBO: Cellular capability already set to %u",
- mbo_cell_capa);
- return;
- }
-
- wpa_s->conf->mbo_cell_capa = mbo_cell_capa;
-
- cell_capa[0] = WLAN_EID_VENDOR_SPECIFIC;
- cell_capa[1] = 5; /* Length */
- WPA_PUT_BE24(cell_capa + 2, OUI_WFA);
- cell_capa[5] = MBO_ATTR_ID_CELL_DATA_CAPA;
- cell_capa[6] = mbo_cell_capa;
-
- wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
- wpa_supplicant_set_default_scan_ies(wpa_s);
- wpas_update_mbo_connect_params(wpa_s);
-}
-
-
-struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, u32 mbo_subtypes)
-{
- struct wpabuf *anqp_buf;
- u8 *len_pos;
- u8 i;
-
- if (!wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
- wpa_printf(MSG_INFO, "MBO: " MACSTR
- " does not support MBO - cannot request MBO ANQP elements from it",
- MAC2STR(bss->bssid));
- return NULL;
- }
-
- /* Allocate size for the maximum case - all MBO subtypes are set */
- anqp_buf = wpabuf_alloc(9 + MAX_MBO_ANQP_SUBTYPE);
- if (!anqp_buf)
- return NULL;
-
- len_pos = gas_anqp_add_element(anqp_buf, ANQP_VENDOR_SPECIFIC);
- wpabuf_put_be24(anqp_buf, OUI_WFA);
- wpabuf_put_u8(anqp_buf, MBO_ANQP_OUI_TYPE);
-
- wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_QUERY_LIST);
-
- /* The first valid MBO subtype is 1 */
- for (i = 1; i <= MAX_MBO_ANQP_SUBTYPE; i++) {
- if (mbo_subtypes & BIT(i))
- wpabuf_put_u8(anqp_buf, i);
- }
-
- gas_anqp_set_element_len(anqp_buf, len_pos);
-
- return anqp_buf;
-}
-
-
-void mbo_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, const u8 *sa,
- const u8 *data, size_t slen)
-{
- const u8 *pos = data;
- u8 subtype;
-
- if (slen < 1)
- return;
-
- subtype = *pos++;
- slen--;
-
- switch (subtype) {
- case MBO_ANQP_SUBTYPE_CELL_CONN_PREF:
- if (slen < 1)
- break;
- wpa_msg(wpa_s, MSG_INFO, RX_MBO_ANQP MACSTR
- " cell_conn_pref=%u", MAC2STR(sa), *pos);
- break;
- default:
- wpa_printf(MSG_DEBUG, "MBO: Unsupported ANQP subtype %u",
- subtype);
- break;
- }
-}
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
deleted file mode 100644
index d6b8a1ad9e36..000000000000
--- a/wpa_supplicant/mesh.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * WPA Supplicant - Basic mesh mode routines
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/uuid.h"
-#include "common/ieee802_11_defs.h"
-#include "common/wpa_ctrl.h"
-#include "common/hw_features_common.h"
-#include "ap/sta_info.h"
-#include "ap/hostapd.h"
-#include "ap/ieee802_11.h"
-#include "config_ssid.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "notify.h"
-#include "ap.h"
-#include "mesh_mpm.h"
-#include "mesh_rsn.h"
-#include "mesh.h"
-
-
-static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s,
- bool also_clear_hostapd)
-{
- wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh,
- also_clear_hostapd);
-
- if (also_clear_hostapd) {
- wpa_s->ifmsh = NULL;
- wpa_s->current_ssid = NULL;
- os_free(wpa_s->mesh_params);
- wpa_s->mesh_params = NULL;
- }
-
- os_free(wpa_s->mesh_rsn);
- wpa_s->mesh_rsn = NULL;
-
- if (!also_clear_hostapd)
- wpa_supplicant_leave_mesh(wpa_s, false);
-}
-
-
-void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
- struct hostapd_iface *ifmsh,
- bool also_clear_hostapd)
-{
- if (!ifmsh)
- return;
-
- if (ifmsh->mconf) {
- mesh_mpm_deinit(wpa_s, ifmsh);
- if (ifmsh->mconf->rsn_ie) {
- ifmsh->mconf->rsn_ie = NULL;
- /* We cannot free this struct
- * because wpa_authenticator on
- * hostapd side is also using it
- * for now just set to NULL and
- * let hostapd code free it.
- */
- }
- os_free(ifmsh->mconf);
- ifmsh->mconf = NULL;
- }
-
- /* take care of shared data */
- if (also_clear_hostapd) {
- hostapd_interface_deinit(ifmsh);
- hostapd_interface_free(ifmsh);
- }
-}
-
-
-static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct mesh_conf *conf;
- int cipher;
-
- conf = os_zalloc(sizeof(struct mesh_conf));
- if (!conf)
- return NULL;
-
- os_memcpy(conf->meshid, ssid->ssid, ssid->ssid_len);
- conf->meshid_len = ssid->ssid_len;
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
- conf->security |= MESH_CONF_SEC_AUTH |
- MESH_CONF_SEC_AMPE;
- else
- conf->security |= MESH_CONF_SEC_NONE;
- conf->ieee80211w = ssid->ieee80211w;
- if (conf->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
- if (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)
- conf->ieee80211w = wpa_s->conf->pmf;
- else
- conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
- }
-#ifdef CONFIG_OCV
- conf->ocv = ssid->ocv;
-#endif /* CONFIG_OCV */
-
- cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher, 0);
- if (cipher < 0 || cipher == WPA_CIPHER_TKIP) {
- wpa_msg(wpa_s, MSG_INFO, "mesh: Invalid pairwise cipher");
- os_free(conf);
- return NULL;
- }
- conf->pairwise_cipher = cipher;
-
- cipher = wpa_pick_group_cipher(ssid->group_cipher);
- if (cipher < 0 || cipher == WPA_CIPHER_TKIP ||
- cipher == WPA_CIPHER_GTK_NOT_USED) {
- wpa_msg(wpa_s, MSG_INFO, "mesh: Invalid group cipher");
- os_free(conf);
- return NULL;
- }
-
- conf->group_cipher = cipher;
- if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
- if (ssid->group_mgmt_cipher == WPA_CIPHER_BIP_GMAC_128 ||
- ssid->group_mgmt_cipher == WPA_CIPHER_BIP_GMAC_256 ||
- ssid->group_mgmt_cipher == WPA_CIPHER_BIP_CMAC_256)
- conf->mgmt_group_cipher = ssid->group_mgmt_cipher;
- else
- conf->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
- }
-
- /* defaults */
- conf->mesh_pp_id = MESH_PATH_PROTOCOL_HWMP;
- conf->mesh_pm_id = MESH_PATH_METRIC_AIRTIME;
- conf->mesh_cc_id = 0;
- conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
- conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
- conf->mesh_fwding = ssid->mesh_fwding;
- conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
- conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
- conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
- conf->dot11MeshHoldingTimeout = ssid->dot11MeshHoldingTimeout;
-
- return conf;
-}
-
-
-static void wpas_mesh_copy_groups(struct hostapd_data *bss,
- struct wpa_supplicant *wpa_s)
-{
- int num_groups;
- size_t groups_size;
-
- for (num_groups = 0; wpa_s->conf->sae_groups[num_groups] > 0;
- num_groups++)
- ;
-
- groups_size = (num_groups + 1) * sizeof(wpa_s->conf->sae_groups[0]);
- bss->conf->sae_groups = os_malloc(groups_size);
- if (bss->conf->sae_groups)
- os_memcpy(bss->conf->sae_groups, wpa_s->conf->sae_groups,
- groups_size);
-}
-
-
-static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct hostapd_data *bss = ifmsh->bss[0];
- static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
- const char *password;
- size_t len;
-
- password = ssid->sae_password;
- if (!password)
- password = ssid->passphrase;
- if (!password) {
- wpa_printf(MSG_ERROR,
- "mesh: Passphrase for SAE not configured");
- return -1;
- }
-
- bss->conf->wpa = ssid->proto;
- bss->conf->wpa_key_mgmt = ssid->key_mgmt;
-
- if (wpa_s->conf->sae_groups && wpa_s->conf->sae_groups[0] > 0) {
- wpas_mesh_copy_groups(bss, wpa_s);
- } else {
- bss->conf->sae_groups = os_memdup(default_groups,
- sizeof(default_groups));
- if (!bss->conf->sae_groups)
- return -1;
- }
-
- len = os_strlen(password);
- bss->conf->ssid.wpa_passphrase = dup_binstr(password, len);
-
- wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, ifmsh->mconf);
- return !wpa_s->mesh_rsn ? -1 : 0;
-}
-
-
-static int wpas_mesh_update_freq_params(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- struct he_capabilities *he_capab = NULL;
-
- if (ifmsh->current_mode)
- he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
-
- if (hostapd_set_freq_params(
- &params->freq,
- ifmsh->conf->hw_mode,
- ifmsh->freq,
- ifmsh->conf->channel,
- ifmsh->conf->enable_edmg,
- ifmsh->conf->edmg_channel,
- ifmsh->conf->ieee80211n,
- ifmsh->conf->ieee80211ac,
- ifmsh->conf->ieee80211ax,
- ifmsh->conf->secondary_channel,
- hostapd_get_oper_chwidth(ifmsh->conf),
- hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
- hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
- ifmsh->conf->vht_capab,
- he_capab)) {
- wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
- wpa_supplicant_mesh_deinit(wpa_s, true);
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int ret;
-
- if (!params || !ssid || !ifmsh) {
- wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
- __func__);
- return -1;
- }
-
- /*
- * Update channel configuration if the channel has changed since the
- * initial setting, i.e., due to DFS radar detection during CAC.
- */
- if (ifmsh->freq > 0 && ifmsh->freq != params->freq.freq) {
- wpa_s->assoc_freq = ifmsh->freq;
- ssid->frequency = ifmsh->freq;
- if (wpas_mesh_update_freq_params(wpa_s) < 0)
- return -1;
- }
-
- if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
- wpas_mesh_init_rsn(wpa_s)) {
- wpa_printf(MSG_ERROR,
- "mesh: RSN initialization failed - deinit mesh");
- wpa_supplicant_mesh_deinit(wpa_s, false);
- return -1;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
- wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
- wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
- wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
- }
-
- params->ies = ifmsh->mconf->rsn_ie;
- params->ie_len = ifmsh->mconf->rsn_ie_len;
- params->basic_rates = ifmsh->basic_rates;
- params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
- params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
-
- wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- ret = wpa_drv_join_mesh(wpa_s, params);
- if (ret)
- wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
-
- /* hostapd sets the interface down until we associate */
- wpa_drv_set_operstate(wpa_s, 1);
-
- if (!ret) {
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-
- wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
- ssid->id);
- wpas_notify_mesh_group_started(wpa_s, ssid);
- }
-
- return ret;
-}
-
-
-static void wpas_mesh_complete_cb(void *arg)
-{
- struct wpa_supplicant *wpa_s = arg;
-
- wpas_mesh_complete(wpa_s);
-}
-
-
-static int wpa_supplicant_mesh_enable_iface_cb(struct hostapd_iface *ifmsh)
-{
- struct wpa_supplicant *wpa_s = ifmsh->owner;
- struct hostapd_data *bss;
-
- ifmsh->mconf = mesh_config_create(wpa_s, wpa_s->current_ssid);
-
- bss = ifmsh->bss[0];
- bss->msg_ctx = wpa_s;
- os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
- bss->driver = wpa_s->driver;
- bss->drv_priv = wpa_s->drv_priv;
- bss->iface = ifmsh;
- bss->mesh_sta_free_cb = mesh_mpm_free_sta;
- bss->setup_complete_cb = wpas_mesh_complete_cb;
- bss->setup_complete_cb_ctx = wpa_s;
-
- bss->conf->start_disabled = 1;
- bss->conf->mesh = MESH_ENABLED;
- bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
-
- if (wpa_drv_init_mesh(wpa_s)) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
- return -1;
- }
-
- if (hostapd_setup_interface(ifmsh)) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize hostapd interface for mesh");
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface *ifmsh)
-{
- struct wpa_supplicant *wpa_s = ifmsh->owner;
- size_t j;
-
- wpa_supplicant_mesh_deinit(wpa_s, false);
-
-#ifdef NEED_AP_MLME
- for (j = 0; j < ifmsh->num_bss; j++)
- hostapd_cleanup_cs_params(ifmsh->bss[j]);
-#endif /* NEED_AP_MLME */
-
- /* Same as hostapd_interface_deinit() without deinitializing control
- * interface */
- for (j = 0; j < ifmsh->num_bss; j++) {
- struct hostapd_data *hapd = ifmsh->bss[j];
-
- hostapd_bss_deinit_no_free(hapd);
- hostapd_free_hapd_data(hapd);
- }
-
- hostapd_cleanup_iface_partial(ifmsh);
-
- return 0;
-}
-
-
-static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_freq_params *freq)
-{
- struct hostapd_iface *ifmsh;
- struct hostapd_data *bss;
- struct hostapd_config *conf;
- struct mesh_conf *mconf;
- int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
- int rate_len;
- int frequency;
-
- if (!wpa_s->conf->user_mpm) {
- /* not much for us to do here */
- wpa_msg(wpa_s, MSG_WARNING,
- "user_mpm is not enabled in configuration");
- return 0;
- }
-
- wpa_s->ifmsh = ifmsh = hostapd_alloc_iface();
- if (!ifmsh)
- return -ENOMEM;
-
- ifmsh->owner = wpa_s;
- ifmsh->drv_flags = wpa_s->drv_flags;
- ifmsh->drv_flags2 = wpa_s->drv_flags2;
- ifmsh->num_bss = 1;
- ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb;
- ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb;
- ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
- sizeof(struct hostapd_data *));
- if (!ifmsh->bss)
- goto out_free;
-
- ifmsh->bss[0] = bss = hostapd_alloc_bss_data(NULL, NULL, NULL);
- if (!bss)
- goto out_free;
-
- ifmsh->bss[0]->msg_ctx = wpa_s;
- os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
- bss->driver = wpa_s->driver;
- bss->drv_priv = wpa_s->drv_priv;
- bss->iface = ifmsh;
- bss->mesh_sta_free_cb = mesh_mpm_free_sta;
- bss->setup_complete_cb = wpas_mesh_complete_cb;
- bss->setup_complete_cb_ctx = wpa_s;
- frequency = ssid->frequency;
- if (frequency != freq->freq &&
- frequency == freq->freq + freq->sec_channel_offset * 20) {
- wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
- frequency = freq->freq;
- ssid->frequency = frequency;
- }
- wpa_s->assoc_freq = frequency;
- wpa_s->current_ssid = ssid;
-
- /* setup an AP config for auth processing */
- conf = hostapd_config_defaults();
- if (!conf)
- goto out_free;
-
- if (is_6ghz_freq(freq->freq)) {
- /*
- * IEEE Std 802.11ax-2021, 12.12.2:
- * The STA shall use management frame protection (MFPR=1) when
- * using RSN.
- */
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
-
- /* Set mandatory op_class parameter for setting up BSS */
- switch (freq->bandwidth) {
- case 20:
- if (freq->freq == 5935)
- conf->op_class = 136;
- else
- conf->op_class = 131;
- break;
- case 40:
- conf->op_class = 132;
- break;
- case 80:
- conf->op_class = 133;
- break;
- case 160:
- conf->op_class = 134;
- break;
- default:
- conf->op_class = 131;
- break;
- }
- }
-
- bss->conf = *conf->bss;
- bss->conf->start_disabled = 1;
- bss->conf->mesh = MESH_ENABLED;
- bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
- bss->conf->mesh_fwding = wpa_s->conf->mesh_fwding;
-
- if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
- wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
- conf->ieee80211h = 1;
- conf->ieee80211d = 1;
- conf->country[0] = wpa_s->conf->country[0];
- conf->country[1] = wpa_s->conf->country[1];
- conf->country[2] = ' ';
- wpa_s->mesh_params->handle_dfs = true;
- }
-
- bss->iconf = conf;
- ifmsh->conf = conf;
-
- ifmsh->bss[0]->max_plinks = wpa_s->conf->max_peer_links;
- ifmsh->bss[0]->dot11RSNASAERetransPeriod =
- wpa_s->conf->dot11RSNASAERetransPeriod;
- os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface));
-
- mconf = mesh_config_create(wpa_s, ssid);
- if (!mconf)
- goto out_free;
- ifmsh->mconf = mconf;
-
- /* need conf->hw_mode for supported rates. */
- conf->hw_mode = ieee80211_freq_to_chan(frequency, &conf->channel);
- if (conf->hw_mode == NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_ERROR, "Unsupported mesh mode frequency: %d MHz",
- frequency);
- goto out_free;
- }
-
- if (ssid->mesh_basic_rates == NULL) {
- /*
- * XXX: Hack! This is so an MPM which correctly sets the ERP
- * mandatory rates as BSSBasicRateSet doesn't reject us. We
- * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
- * this is way easier. This also makes our BSSBasicRateSet
- * advertised in beacons match the one in peering frames, sigh.
- */
- if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
- conf->basic_rates = os_memdup(basic_rates_erp,
- sizeof(basic_rates_erp));
- if (!conf->basic_rates)
- goto out_free;
- }
- } else {
- rate_len = 0;
- while (1) {
- if (ssid->mesh_basic_rates[rate_len] < 1)
- break;
- rate_len++;
- }
- conf->basic_rates = os_calloc(rate_len + 1, sizeof(int));
- if (conf->basic_rates == NULL)
- goto out_free;
- os_memcpy(conf->basic_rates, ssid->mesh_basic_rates,
- rate_len * sizeof(int));
- conf->basic_rates[rate_len] = -1;
- }
-
- /* While it can enhance performance to switch the primary channel, which
- * is also the secondary channel of another network at the same time),
- * to the other primary channel, problems exist with this in mesh
- * networks.
- *
- * Example with problems:
- * - 3 mesh nodes M1-M3, freq (5200, 5180)
- * - other node O1, e.g. AP mode, freq (5180, 5200),
- * Locations: O1 M1 M2 M3
- *
- * M3 can only send frames to M1 over M2, no direct connection is
- * possible
- * Start O1, M1 and M3 first, M1 or O1 will switch channels to align
- * with* each other. M3 does not swap, because M1 or O1 cannot be
- * reached. M2 is started afterwards and can either connect to M3 or M1
- * because of this primary secondary channel switch.
- *
- * Solutions: (1) central coordination -> not always possible
- * (2) disable pri/sec channel switch in mesh networks
- *
- * In AP mode, when all nodes can work independently, this poses of
- * course no problem, therefore disable it only in mesh mode. */
- conf->no_pri_sec_switch = 1;
- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-
- if (wpa_drv_init_mesh(wpa_s)) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
- return -1;
- }
-
- if (hostapd_setup_interface(ifmsh)) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize hostapd interface for mesh");
- return -1;
- }
-
- return 0;
-out_free:
- wpa_supplicant_mesh_deinit(wpa_s, true);
- return -ENOMEM;
-}
-
-
-void wpa_mesh_notify_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- const u8 *ies, size_t ie_len)
-{
- struct ieee802_11_elems elems;
-
- wpa_msg(wpa_s, MSG_INFO,
- "new peer notification for " MACSTR, MAC2STR(addr));
-
- if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
- wpa_msg(wpa_s, MSG_INFO, "Could not parse beacon from " MACSTR,
- MAC2STR(addr));
- return;
- }
- wpa_mesh_new_mesh_peer(wpa_s, addr, &elems);
-}
-
-
-void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
- struct wpabuf **extra_ie)
-{
- /* EID + 0-length (wildcard) mesh-id */
- size_t ielen = 2;
-
- if (wpabuf_resize(extra_ie, ielen) == 0) {
- wpabuf_put_u8(*extra_ie, WLAN_EID_MESH_ID);
- wpabuf_put_u8(*extra_ie, 0);
- }
-}
-
-
-int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpa_driver_mesh_join_params *params = os_zalloc(sizeof(*params));
- int ret = 0;
-
- if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency ||
- !params) {
- ret = -ENOENT;
- os_free(params);
- goto out;
- }
-
- wpa_supplicant_mesh_deinit(wpa_s, true);
-
- wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
- wpa_s->group_cipher = WPA_CIPHER_NONE;
- wpa_s->mgmt_group_cipher = 0;
-
- params->meshid = ssid->ssid;
- params->meshid_len = ssid->ssid_len;
- ibss_mesh_setup_freq(wpa_s, ssid, &params->freq);
- wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
- wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
- wpa_s->mesh_he_enabled = !!params->freq.he_enabled;
- if (params->freq.ht_enabled && params->freq.sec_channel_offset)
- ssid->ht40 = params->freq.sec_channel_offset;
-
- if (wpa_s->mesh_vht_enabled) {
- ssid->vht = 1;
- ssid->vht_center_freq1 = params->freq.center_freq1;
- switch (params->freq.bandwidth) {
- case 80:
- if (params->freq.center_freq2) {
- ssid->max_oper_chwidth = CHANWIDTH_80P80MHZ;
- ssid->vht_center_freq2 =
- params->freq.center_freq2;
- } else {
- ssid->max_oper_chwidth = CHANWIDTH_80MHZ;
- }
- break;
- case 160:
- ssid->max_oper_chwidth = CHANWIDTH_160MHZ;
- break;
- default:
- ssid->max_oper_chwidth = CHANWIDTH_USE_HT;
- break;
- }
- }
- if (wpa_s->mesh_he_enabled)
- ssid->he = 1;
- if (ssid->beacon_int > 0)
- params->beacon_int = ssid->beacon_int;
- else if (wpa_s->conf->beacon_int > 0)
- params->beacon_int = wpa_s->conf->beacon_int;
- if (ssid->dtim_period > 0)
- params->dtim_period = ssid->dtim_period;
- else if (wpa_s->conf->dtim_period > 0)
- params->dtim_period = wpa_s->conf->dtim_period;
- params->conf.max_peer_links = wpa_s->conf->max_peer_links;
- if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
- params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
- params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
- params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
- params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
- wpa_s->conf->user_mpm = 1;
- }
-
- if (wpa_s->conf->user_mpm) {
- params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
- params->conf.auto_plinks = 0;
- } else {
- params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
- params->conf.auto_plinks = 1;
- }
- params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
-
- /* Always explicitely set forwarding to on or off for now */
- params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING;
- params->conf.forwarding = ssid->mesh_fwding;
-
- os_free(wpa_s->mesh_params);
- wpa_s->mesh_params = params;
- if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
- wpa_supplicant_leave_mesh(wpa_s, true);
- ret = -1;
- goto out;
- }
-
-out:
- return ret;
-}
-
-
-int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s, bool need_deinit)
-{
- int ret = 0;
-
- wpa_msg(wpa_s, MSG_INFO, "leaving mesh");
-
- /* Need to send peering close messages first */
- if (need_deinit)
- wpa_supplicant_mesh_deinit(wpa_s, true);
-
- ret = wpa_drv_leave_mesh(wpa_s);
- if (ret)
- wpa_msg(wpa_s, MSG_ERROR, "mesh leave error=%d", ret);
-
- wpa_drv_set_operstate(wpa_s, 1);
-
- return ret;
-}
-
-
-static int mesh_attr_text(const u8 *ies, size_t ies_len, char *buf, char *end)
-{
- struct ieee802_11_elems elems;
- char *mesh_id, *pos = buf;
- u8 *bss_basic_rate_set;
- int bss_basic_rate_set_len, ret, i;
-
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed)
- return -1;
-
- if (elems.mesh_id_len < 1)
- return 0;
-
- mesh_id = os_malloc(elems.mesh_id_len + 1);
- if (mesh_id == NULL)
- return -1;
-
- os_memcpy(mesh_id, elems.mesh_id, elems.mesh_id_len);
- mesh_id[elems.mesh_id_len] = '\0';
- ret = os_snprintf(pos, end - pos, "mesh_id=%s\n", mesh_id);
- os_free(mesh_id);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
-
- if (elems.mesh_config_len > 6) {
- ret = os_snprintf(pos, end - pos,
- "active_path_selection_protocol_id=0x%02x\n"
- "active_path_selection_metric_id=0x%02x\n"
- "congestion_control_mode_id=0x%02x\n"
- "synchronization_method_id=0x%02x\n"
- "authentication_protocol_id=0x%02x\n"
- "mesh_formation_info=0x%02x\n"
- "mesh_capability=0x%02x\n",
- elems.mesh_config[0], elems.mesh_config[1],
- elems.mesh_config[2], elems.mesh_config[3],
- elems.mesh_config[4], elems.mesh_config[5],
- elems.mesh_config[6]);
- if (os_snprintf_error(end - pos, ret))
- return pos - buf;
- pos += ret;
- }
-
- bss_basic_rate_set = os_malloc(elems.supp_rates_len +
- elems.ext_supp_rates_len);
- if (bss_basic_rate_set == NULL)
- return -1;
-
- bss_basic_rate_set_len = 0;
- for (i = 0; i < elems.supp_rates_len; i++) {
- if (elems.supp_rates[i] & 0x80) {
- bss_basic_rate_set[bss_basic_rate_set_len++] =
- (elems.supp_rates[i] & 0x7f) * 5;
- }
- }
- for (i = 0; i < elems.ext_supp_rates_len; i++) {
- if (elems.ext_supp_rates[i] & 0x80) {
- bss_basic_rate_set[bss_basic_rate_set_len++] =
- (elems.ext_supp_rates[i] & 0x7f) * 5;
- }
- }
- if (bss_basic_rate_set_len > 0) {
- ret = os_snprintf(pos, end - pos, "bss_basic_rate_set=%d",
- bss_basic_rate_set[0]);
- if (os_snprintf_error(end - pos, ret))
- goto fail;
- pos += ret;
-
- for (i = 1; i < bss_basic_rate_set_len; i++) {
- ret = os_snprintf(pos, end - pos, " %d",
- bss_basic_rate_set[i]);
- if (os_snprintf_error(end - pos, ret))
- goto fail;
- pos += ret;
- }
-
- ret = os_snprintf(pos, end - pos, "\n");
- if (os_snprintf_error(end - pos, ret))
- goto fail;
- pos += ret;
- }
-fail:
- os_free(bss_basic_rate_set);
-
- return pos - buf;
-}
-
-
-int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
- char *end)
-{
- return mesh_attr_text(ies, ies_len, buf, end);
-}
-
-
-static int wpas_mesh_get_ifname(struct wpa_supplicant *wpa_s, char *ifname,
- size_t len)
-{
- char *ifname_ptr = wpa_s->ifname;
- int res;
-
- res = os_snprintf(ifname, len, "mesh-%s-%d", ifname_ptr,
- wpa_s->mesh_if_idx);
- if (os_snprintf_error(len, res) ||
- (os_strlen(ifname) >= IFNAMSIZ &&
- os_strlen(wpa_s->ifname) < IFNAMSIZ)) {
- /* Try to avoid going over the IFNAMSIZ length limit */
- res = os_snprintf(ifname, len, "mesh-%d", wpa_s->mesh_if_idx);
- if (os_snprintf_error(len, res))
- return -1;
- }
- wpa_s->mesh_if_idx++;
- return 0;
-}
-
-
-int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,
- size_t len)
-{
- struct wpa_interface iface;
- struct wpa_supplicant *mesh_wpa_s;
- u8 addr[ETH_ALEN];
-
- if (ifname[0] == '\0' && wpas_mesh_get_ifname(wpa_s, ifname, len) < 0)
- return -1;
-
- if (wpa_drv_if_add(wpa_s, WPA_IF_MESH, ifname, NULL, NULL, NULL, addr,
- NULL) < 0) {
- wpa_printf(MSG_ERROR,
- "mesh: Failed to create new mesh interface");
- return -1;
- }
- wpa_printf(MSG_INFO, "mesh: Created virtual interface %s addr "
- MACSTR, ifname, MAC2STR(addr));
-
- os_memset(&iface, 0, sizeof(iface));
- iface.ifname = ifname;
- iface.driver = wpa_s->driver->name;
- iface.driver_param = wpa_s->conf->driver_param;
- iface.ctrl_interface = wpa_s->conf->ctrl_interface;
-
- mesh_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
- if (!mesh_wpa_s) {
- wpa_printf(MSG_ERROR,
- "mesh: Failed to create new wpa_supplicant interface");
- wpa_drv_if_remove(wpa_s, WPA_IF_MESH, ifname);
- return -1;
- }
- mesh_wpa_s->mesh_if_created = 1;
- return 0;
-}
-
-
-int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- return mesh_mpm_close_peer(wpa_s, addr);
-}
-
-
-int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration)
-{
- return mesh_mpm_connect_peer(wpa_s, addr, duration);
-}
diff --git a/wpa_supplicant/mesh.h b/wpa_supplicant/mesh.h
deleted file mode 100644
index a429e5e27358..000000000000
--- a/wpa_supplicant/mesh.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * WPA Supplicant - Basic mesh mode routines
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef MESH_H
-#define MESH_H
-
-int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s,
- bool need_deinit);
-void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
- struct hostapd_iface *ifmsh,
- bool also_clear_hostapd);
-int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
- char *end);
-int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,
- size_t len);
-int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
-int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration);
-
-#ifdef CONFIG_MESH
-
-void wpa_mesh_notify_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- const u8 *ies, size_t ie_len);
-void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
- struct wpabuf **extra_ie);
-
-#else /* CONFIG_MESH */
-
-static inline void wpa_mesh_notify_peer(struct wpa_supplicant *wpa_s,
- const u8 *addr,
- const u8 *ies, size_t ie_len)
-{
-}
-
-static inline void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
- struct wpabuf **extra_ie)
-{
-}
-
-#endif /* CONFIG_MESH */
-
-#endif /* MESH_H */
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
deleted file mode 100644
index 2eb9a7ef6182..000000000000
--- a/wpa_supplicant/mesh_mpm.c
+++ /dev/null
@@ -1,1403 +0,0 @@
-/*
- * WPA Supplicant - Basic mesh peer management
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_defs.h"
-#include "common/hw_features_common.h"
-#include "common/ocv.h"
-#include "ap/hostapd.h"
-#include "ap/sta_info.h"
-#include "ap/ieee802_11.h"
-#include "ap/wpa_auth.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "mesh_mpm.h"
-#include "mesh_rsn.h"
-#include "notify.h"
-
-struct mesh_peer_mgmt_ie {
- const u8 *proto_id; /* Mesh Peering Protocol Identifier (2 octets) */
- const u8 *llid; /* Local Link ID (2 octets) */
- const u8 *plid; /* Peer Link ID (conditional, 2 octets) */
- const u8 *reason; /* Reason Code (conditional, 2 octets) */
- const u8 *chosen_pmk; /* Chosen PMK (optional, 16 octets) */
-};
-
-static void plink_timer(void *eloop_ctx, void *user_data);
-
-
-enum plink_event {
- PLINK_UNDEFINED,
- OPN_ACPT,
- OPN_RJCT,
- CNF_ACPT,
- CNF_RJCT,
- CLS_ACPT,
- REQ_RJCT
-};
-
-static const char * const mplstate[] = {
- [0] = "UNINITIALIZED",
- [PLINK_IDLE] = "IDLE",
- [PLINK_OPN_SNT] = "OPN_SNT",
- [PLINK_OPN_RCVD] = "OPN_RCVD",
- [PLINK_CNF_RCVD] = "CNF_RCVD",
- [PLINK_ESTAB] = "ESTAB",
- [PLINK_HOLDING] = "HOLDING",
- [PLINK_BLOCKED] = "BLOCKED"
-};
-
-static const char * const mplevent[] = {
- [PLINK_UNDEFINED] = "UNDEFINED",
- [OPN_ACPT] = "OPN_ACPT",
- [OPN_RJCT] = "OPN_RJCT",
- [CNF_ACPT] = "CNF_ACPT",
- [CNF_RJCT] = "CNF_RJCT",
- [CLS_ACPT] = "CLS_ACPT",
- [REQ_RJCT] = "REQ_RJCT",
-};
-
-
-static int mesh_mpm_parse_peer_mgmt(struct wpa_supplicant *wpa_s,
- u8 action_field,
- const u8 *ie, size_t len,
- struct mesh_peer_mgmt_ie *mpm_ie)
-{
- os_memset(mpm_ie, 0, sizeof(*mpm_ie));
-
- /* Remove optional Chosen PMK field at end */
- if (len >= SAE_PMKID_LEN) {
- mpm_ie->chosen_pmk = ie + len - SAE_PMKID_LEN;
- len -= SAE_PMKID_LEN;
- }
-
- if ((action_field == PLINK_OPEN && len != 4) ||
- (action_field == PLINK_CONFIRM && len != 6) ||
- (action_field == PLINK_CLOSE && len != 6 && len != 8)) {
- wpa_msg(wpa_s, MSG_DEBUG, "MPM: Invalid peer mgmt ie");
- return -1;
- }
-
- /* required fields */
- if (len < 4)
- return -1;
- mpm_ie->proto_id = ie;
- mpm_ie->llid = ie + 2;
- ie += 4;
- len -= 4;
-
- /* close reason is always present at end for close */
- if (action_field == PLINK_CLOSE) {
- if (len < 2)
- return -1;
- mpm_ie->reason = ie + len - 2;
- len -= 2;
- }
-
- /* Peer Link ID, present for confirm, and possibly close */
- if (len >= 2)
- mpm_ie->plid = ie;
-
- return 0;
-}
-
-
-static int plink_free_count(struct hostapd_data *hapd)
-{
- if (hapd->max_plinks > hapd->num_plinks)
- return hapd->max_plinks - hapd->num_plinks;
- return 0;
-}
-
-
-static u16 copy_supp_rates(struct wpa_supplicant *wpa_s,
- struct sta_info *sta,
- struct ieee802_11_elems *elems)
-{
- if (!elems->supp_rates) {
- wpa_msg(wpa_s, MSG_ERROR, "no supported rates from " MACSTR,
- MAC2STR(sta->addr));
- return WLAN_STATUS_UNSPECIFIED_FAILURE;
- }
-
- if (elems->supp_rates_len + elems->ext_supp_rates_len >
- sizeof(sta->supported_rates)) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Invalid supported rates element length " MACSTR
- " %d+%d", MAC2STR(sta->addr), elems->supp_rates_len,
- elems->ext_supp_rates_len);
- return WLAN_STATUS_UNSPECIFIED_FAILURE;
- }
-
- sta->supported_rates_len = merge_byte_arrays(
- sta->supported_rates, sizeof(sta->supported_rates),
- elems->supp_rates, elems->supp_rates_len,
- elems->ext_supp_rates, elems->ext_supp_rates_len);
-
- return WLAN_STATUS_SUCCESS;
-}
-
-
-/* return true if elems from a neighbor match this MBSS */
-static bool matches_local(struct wpa_supplicant *wpa_s,
- struct ieee802_11_elems *elems)
-{
- struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
-
- if (elems->mesh_config_len < 5)
- return false;
-
- return (mconf->meshid_len == elems->mesh_id_len &&
- os_memcmp(mconf->meshid, elems->mesh_id,
- elems->mesh_id_len) == 0 &&
- mconf->mesh_pp_id == elems->mesh_config[0] &&
- mconf->mesh_pm_id == elems->mesh_config[1] &&
- mconf->mesh_cc_id == elems->mesh_config[2] &&
- mconf->mesh_sp_id == elems->mesh_config[3] &&
- mconf->mesh_auth_id == elems->mesh_config[4]);
-}
-
-
-/* check if local link id is already used with another peer */
-static bool llid_in_use(struct wpa_supplicant *wpa_s, u16 llid)
-{
- struct sta_info *sta;
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
-
- for (sta = hapd->sta_list; sta; sta = sta->next) {
- if (sta->my_lid == llid)
- return true;
- }
-
- return false;
-}
-
-
-/* generate an llid for a link and set to initial state */
-static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
- struct sta_info *sta)
-{
- u16 llid;
-
- do {
- if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
- llid = 0; /* continue */
- } while (!llid || llid_in_use(wpa_s, llid));
-
- sta->my_lid = llid;
- sta->peer_lid = 0;
- sta->peer_aid = 0;
-
- /*
- * We do not use wpa_mesh_set_plink_state() here because there is no
- * entry in kernel yet.
- */
- sta->plink_state = PLINK_IDLE;
-}
-
-
-static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
- struct sta_info *sta,
- enum plink_action_field type,
- u16 close_reason)
-{
- struct wpabuf *buf;
- struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- struct hostapd_data *bss = ifmsh->bss[0];
- struct mesh_conf *conf = ifmsh->mconf;
- u8 supp_rates[2 + 2 + 32];
- u8 *pos, *cat;
- u8 ie_len, add_plid = 0;
- int ret;
- int ampe = conf->security & MESH_CONF_SEC_AMPE;
- size_t buf_len;
-
- if (!sta)
- return;
-
- buf_len = 2 + /* Category and Action */
- 2 + /* capability info */
- 2 + /* AID */
- 2 + 8 + /* supported rates */
- 2 + (32 - 8) +
- 2 + 32 + /* mesh ID */
- 2 + 7 + /* mesh config */
- 2 + 24 + /* peering management */
- 2 + 96 + 32 + 32 + /* AMPE (96 + max GTKlen + max IGTKlen) */
- 2 + 16; /* MIC */
- if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
- buf_len += 2 + 26 + /* HT capabilities */
- 2 + 22; /* HT operation */
- }
-#ifdef CONFIG_IEEE80211AC
- if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
- buf_len += 2 + 12 + /* VHT Capabilities */
- 2 + 5; /* VHT Operation */
- }
-#endif /* CONFIG_IEEE80211AC */
-#ifdef CONFIG_IEEE80211AX
- if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
- buf_len += 3 +
- HE_MAX_MAC_CAPAB_SIZE +
- HE_MAX_PHY_CAPAB_SIZE +
- HE_MAX_MCS_CAPAB_SIZE +
- HE_MAX_PPET_CAPAB_SIZE;
- buf_len += 3 + sizeof(struct ieee80211_he_operation);
- if (is_6ghz_op_class(bss->iconf->op_class))
- buf_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
- 3 + sizeof(struct ieee80211_he_6ghz_band_cap);
- }
-#endif /* CONFIG_IEEE80211AX */
- if (type != PLINK_CLOSE)
- buf_len += conf->rsn_ie_len; /* RSN IE */
-#ifdef CONFIG_OCV
- /* OCI is included even when the other STA doesn't support OCV */
- if (type != PLINK_CLOSE && conf->ocv)
- buf_len += OCV_OCI_EXTENDED_LEN;
-#endif /* CONFIG_OCV */
-
- buf = wpabuf_alloc(buf_len);
- if (!buf)
- return;
-
- cat = wpabuf_mhead_u8(buf);
- wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
- wpabuf_put_u8(buf, type);
-
- if (type != PLINK_CLOSE) {
- u8 info;
-
- /* capability info */
- wpabuf_put_le16(buf, ampe ? IEEE80211_CAP_PRIVACY : 0);
-
- /* aid */
- if (type == PLINK_CONFIRM)
- wpabuf_put_le16(buf, sta->aid);
-
- /* IE: supp + ext. supp rates */
- pos = hostapd_eid_supp_rates(bss, supp_rates);
- pos = hostapd_eid_ext_supp_rates(bss, pos);
- wpabuf_put_data(buf, supp_rates, pos - supp_rates);
-
- /* IE: RSN IE */
- wpabuf_put_data(buf, conf->rsn_ie, conf->rsn_ie_len);
-
- /* IE: Mesh ID */
- wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
- wpabuf_put_u8(buf, conf->meshid_len);
- wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
-
- /* IE: mesh conf */
- wpabuf_put_u8(buf, WLAN_EID_MESH_CONFIG);
- wpabuf_put_u8(buf, 7);
- wpabuf_put_u8(buf, conf->mesh_pp_id);
- wpabuf_put_u8(buf, conf->mesh_pm_id);
- wpabuf_put_u8(buf, conf->mesh_cc_id);
- wpabuf_put_u8(buf, conf->mesh_sp_id);
- wpabuf_put_u8(buf, conf->mesh_auth_id);
- info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
- /* TODO: Add Connected to Mesh Gate/AS subfields */
- wpabuf_put_u8(buf, info);
- /* Set forwarding based on configuration and always accept
- * plinks for now */
- wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER |
- (conf->mesh_fwding ? MESH_CAP_FORWARDING : 0));
- } else { /* Peer closing frame */
- /* IE: Mesh ID */
- wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
- wpabuf_put_u8(buf, conf->meshid_len);
- wpabuf_put_data(buf, conf->meshid, conf->meshid_len);
- }
-
- /* IE: Mesh Peering Management element */
- ie_len = 4;
- if (ampe)
- ie_len += PMKID_LEN;
- switch (type) {
- case PLINK_OPEN:
- break;
- case PLINK_CONFIRM:
- ie_len += 2;
- add_plid = 1;
- break;
- case PLINK_CLOSE:
- ie_len += 2;
- add_plid = 1;
- ie_len += 2; /* reason code */
- break;
- }
-
- wpabuf_put_u8(buf, WLAN_EID_PEER_MGMT);
- wpabuf_put_u8(buf, ie_len);
- /* peering protocol */
- if (ampe)
- wpabuf_put_le16(buf, 1);
- else
- wpabuf_put_le16(buf, 0);
- wpabuf_put_le16(buf, sta->my_lid);
- if (add_plid)
- wpabuf_put_le16(buf, sta->peer_lid);
- if (type == PLINK_CLOSE)
- wpabuf_put_le16(buf, close_reason);
- if (ampe) {
- if (sta->sae == NULL) {
- wpa_msg(wpa_s, MSG_INFO, "Mesh MPM: no SAE session");
- goto fail;
- }
- mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
- wpabuf_put(buf, PMKID_LEN));
- }
-
- if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
- u8 ht_capa_oper[2 + 26 + 2 + 22];
-
- pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
- pos = hostapd_eid_ht_operation(bss, pos);
- wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
- }
-#ifdef CONFIG_IEEE80211AC
- if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
- u8 vht_capa_oper[2 + 12 + 2 + 5];
-
- pos = hostapd_eid_vht_capabilities(bss, vht_capa_oper, 0);
- pos = hostapd_eid_vht_operation(bss, pos);
- wpabuf_put_data(buf, vht_capa_oper, pos - vht_capa_oper);
- }
-#endif /* CONFIG_IEEE80211AC */
-#ifdef CONFIG_IEEE80211AX
- if (type != PLINK_CLOSE && wpa_s->mesh_he_enabled) {
- u8 he_capa_oper[3 +
- HE_MAX_MAC_CAPAB_SIZE +
- HE_MAX_PHY_CAPAB_SIZE +
- HE_MAX_MCS_CAPAB_SIZE +
- HE_MAX_PPET_CAPAB_SIZE +
- 3 + sizeof(struct ieee80211_he_operation) +
- sizeof(struct ieee80211_he_6ghz_oper_info) +
- 3 + sizeof(struct ieee80211_he_6ghz_band_cap)];
-
- pos = hostapd_eid_he_capab(bss, he_capa_oper,
- IEEE80211_MODE_MESH);
- pos = hostapd_eid_he_operation(bss, pos);
- pos = hostapd_eid_he_6ghz_band_cap(bss, pos);
- wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
- }
-#endif /* CONFIG_IEEE80211AX */
-
-#ifdef CONFIG_OCV
- if (type != PLINK_CLOSE && conf->ocv) {
- struct wpa_channel_info ci;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "Mesh MPM: Failed to get channel info for OCI element");
- goto fail;
- }
-
- pos = wpabuf_put(buf, OCV_OCI_EXTENDED_LEN);
- if (ocv_insert_extended_oci(&ci, pos) < 0)
- goto fail;
- }
-#endif /* CONFIG_OCV */
-
- if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
- wpa_msg(wpa_s, MSG_INFO,
- "Mesh MPM: failed to add AMPE and MIC IE");
- goto fail;
- }
-
- wpa_msg(wpa_s, MSG_DEBUG, "Mesh MPM: Sending peering frame type %d to "
- MACSTR " (my_lid=0x%x peer_lid=0x%x)",
- type, MAC2STR(sta->addr), sta->my_lid, sta->peer_lid);
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
- sta->addr, wpa_s->own_addr, wpa_s->own_addr,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret < 0)
- wpa_msg(wpa_s, MSG_INFO,
- "Mesh MPM: failed to send peering frame");
-
-fail:
- wpabuf_free(buf);
-}
-
-
-/* configure peering state in ours and driver's station entry */
-void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
- struct sta_info *sta,
- enum mesh_plink_state state)
-{
- struct hostapd_sta_add_params params;
- int ret;
-
- wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
- MAC2STR(sta->addr), mplstate[sta->plink_state],
- mplstate[state]);
- sta->plink_state = state;
-
- os_memset(&params, 0, sizeof(params));
- params.addr = sta->addr;
- params.plink_state = state;
- params.peer_aid = sta->peer_aid;
- params.set = 1;
-
- ret = wpa_drv_sta_add(wpa_s, &params);
- if (ret) {
- wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
- ": %d", MAC2STR(sta->addr), ret);
- }
-}
-
-
-static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
- struct sta_info *sta)
-{
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
-
- eloop_cancel_timeout(plink_timer, wpa_s, sta);
-
- ap_free_sta(hapd, sta);
-}
-
-
-static void plink_timer(void *eloop_ctx, void *user_data)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct sta_info *sta = user_data;
- u16 reason = 0;
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
-
- switch (sta->plink_state) {
- case PLINK_OPN_RCVD:
- case PLINK_OPN_SNT:
- /* retry timer */
- if (sta->mpm_retries < conf->dot11MeshMaxRetries) {
- eloop_register_timeout(
- conf->dot11MeshRetryTimeout / 1000,
- (conf->dot11MeshRetryTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
- sta->mpm_retries++;
- break;
- }
- reason = WLAN_REASON_MESH_MAX_RETRIES;
- /* fall through */
-
- case PLINK_CNF_RCVD:
- /* confirm timer */
- if (!reason)
- reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- eloop_register_timeout(conf->dot11MeshHoldingTimeout / 1000,
- (conf->dot11MeshHoldingTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
- break;
- case PLINK_HOLDING:
- /* holding timer */
-
- if (sta->mesh_sae_pmksa_caching) {
- wpa_printf(MSG_DEBUG, "MPM: Peer " MACSTR
- " looks like it does not support mesh SAE PMKSA caching, so remove the cached entry for it",
- MAC2STR(sta->addr));
- wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
- }
- mesh_mpm_fsm_restart(wpa_s, sta);
- break;
- default:
- break;
- }
-}
-
-
-/* initiate peering with station */
-static void
-mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
- enum mesh_plink_state next_state)
-{
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
-
- eloop_cancel_timeout(plink_timer, wpa_s, sta);
- eloop_register_timeout(conf->dot11MeshRetryTimeout / 1000,
- (conf->dot11MeshRetryTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- mesh_mpm_send_plink_action(wpa_s, sta, PLINK_OPEN, 0);
- wpa_mesh_set_plink_state(wpa_s, sta, next_state);
-}
-
-
-static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
- void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- int reason = WLAN_REASON_MESH_PEERING_CANCELLED;
-
- if (sta) {
- if (sta->plink_state == PLINK_ESTAB)
- hapd->num_plinks--;
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
- wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
- MAC2STR(sta->addr));
- eloop_cancel_timeout(plink_timer, wpa_s, sta);
- eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
- return 0;
- }
-
- return 1;
-}
-
-
-int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- struct hostapd_data *hapd;
- struct sta_info *sta;
-
- if (!wpa_s->ifmsh) {
- wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
- return -1;
- }
-
- hapd = wpa_s->ifmsh->bss[0];
- sta = ap_get_sta(hapd, addr);
- if (!sta) {
- wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
- return -1;
- }
-
- return mesh_mpm_plink_close(hapd, sta, wpa_s) == 0 ? 0 : -1;
-}
-
-
-static void peer_add_timer(void *eloop_ctx, void *user_data)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
-
- os_memset(hapd->mesh_required_peer, 0, ETH_ALEN);
-}
-
-
-int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct hostapd_data *hapd;
- struct sta_info *sta;
- struct mesh_conf *conf;
-
- if (!wpa_s->ifmsh) {
- wpa_msg(wpa_s, MSG_INFO, "Mesh is not prepared yet");
- return -1;
- }
-
- if (!ssid || !ssid->no_auto_peer) {
- wpa_msg(wpa_s, MSG_INFO,
- "This command is available only with no_auto_peer mesh network");
- return -1;
- }
-
- hapd = wpa_s->ifmsh->bss[0];
- conf = wpa_s->ifmsh->mconf;
-
- sta = ap_get_sta(hapd, addr);
- if (!sta) {
- wpa_msg(wpa_s, MSG_INFO, "No such mesh peer");
- return -1;
- }
-
- if ((PLINK_OPN_SNT <= sta->plink_state &&
- sta->plink_state <= PLINK_ESTAB) ||
- (sta->sae && sta->sae->state > SAE_NOTHING)) {
- wpa_msg(wpa_s, MSG_INFO,
- "Specified peer is connecting/connected");
- return -1;
- }
-
- if (conf->security == MESH_CONF_SEC_NONE) {
- mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
- } else {
- mesh_rsn_auth_sae_sta(wpa_s, sta);
- os_memcpy(hapd->mesh_required_peer, addr, ETH_ALEN);
- eloop_register_timeout(duration == -1 ? 10 : duration, 0,
- peer_add_timer, wpa_s, NULL);
- }
-
- return 0;
-}
-
-
-void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
-{
- struct hostapd_data *hapd = ifmsh->bss[0];
-
- /* notify peers we're leaving */
- ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
-
- hapd->num_plinks = 0;
- hostapd_free_stas(hapd);
- eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
-}
-
-
-/* for mesh_rsn to indicate this peer has completed authentication, and we're
- * ready to start AMPE */
-void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- struct hostapd_data *data = wpa_s->ifmsh->bss[0];
- struct hostapd_sta_add_params params;
- struct sta_info *sta;
- int ret;
-
- sta = ap_get_sta(data, addr);
- if (!sta) {
- wpa_msg(wpa_s, MSG_DEBUG, "no such mesh peer");
- return;
- }
-
- /* TODO: Should do nothing if this STA is already authenticated, but
- * the AP code already sets this flag. */
- sta->flags |= WLAN_STA_AUTH;
-
- mesh_rsn_init_ampe_sta(wpa_s, sta);
-
- os_memset(&params, 0, sizeof(params));
- params.addr = sta->addr;
- params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
- params.set = 1;
-
- wpa_msg(wpa_s, MSG_DEBUG, "MPM authenticating " MACSTR,
- MAC2STR(sta->addr));
- ret = wpa_drv_sta_add(wpa_s, &params);
- if (ret) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Driver failed to set " MACSTR ": %d",
- MAC2STR(sta->addr), ret);
- }
-
- if (!sta->my_lid)
- mesh_mpm_init_link(wpa_s, sta);
-
- mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
-}
-
-/*
- * Initialize a sta_info structure for a peer and upload it into the driver
- * in preparation for beginning authentication or peering. This is done when a
- * Beacon (secure or open mesh) or a peering open frame (for open mesh) is
- * received from the peer for the first time.
- */
-static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
- const u8 *addr,
- struct ieee802_11_elems *elems)
-{
- struct hostapd_sta_add_params params;
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
- struct hostapd_data *data = wpa_s->ifmsh->bss[0];
- struct sta_info *sta;
- struct ieee80211_ht_operation *oper;
- int ret;
-
- if (elems->mesh_config_len >= 7 &&
- !(elems->mesh_config[6] & MESH_CAP_ACCEPT_ADDITIONAL_PEER)) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "mesh: Ignore a crowded peer " MACSTR,
- MAC2STR(addr));
- return NULL;
- }
-
- sta = ap_get_sta(data, addr);
- if (sta)
- return NULL;
-
- sta = ap_sta_add(data, addr);
- if (!sta)
- return NULL;
-
- /* Set WMM by default since Mesh STAs are QoS STAs */
- sta->flags |= WLAN_STA_WMM;
-
- /* initialize sta */
- if (copy_supp_rates(wpa_s, sta, elems)) {
- ap_free_sta(data, sta);
- return NULL;
- }
-
- if (!sta->my_lid)
- mesh_mpm_init_link(wpa_s, sta);
-
- copy_sta_ht_capab(data, sta, elems->ht_capabilities);
-
- oper = (struct ieee80211_ht_operation *) elems->ht_operation;
- if (oper &&
- !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) &&
- sta->ht_capabilities) {
- wpa_msg(wpa_s, MSG_DEBUG, MACSTR
- " does not support 40 MHz bandwidth",
- MAC2STR(sta->addr));
- set_disable_ht40(sta->ht_capabilities, 1);
- }
-
- update_ht_state(data, sta);
-
-#ifdef CONFIG_IEEE80211AC
- copy_sta_vht_capab(data, sta, elems->vht_capabilities);
- copy_sta_vht_oper(data, sta, elems->vht_operation);
- set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
-#endif /* CONFIG_IEEE80211AC */
-
-#ifdef CONFIG_IEEE80211AX
- copy_sta_he_capab(data, sta, IEEE80211_MODE_MESH,
- elems->he_capabilities, elems->he_capabilities_len);
- copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap);
-#endif /* CONFIG_IEEE80211AX */
-
- if (hostapd_get_aid(data, sta) < 0) {
- wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
- ap_free_sta(data, sta);
- return NULL;
- }
-
- /* insert into driver */
- os_memset(&params, 0, sizeof(params));
- params.supp_rates = sta->supported_rates;
- params.supp_rates_len = sta->supported_rates_len;
- params.addr = addr;
- params.plink_state = sta->plink_state;
- params.aid = sta->aid;
- params.peer_aid = sta->peer_aid;
- params.listen_interval = 100;
- params.ht_capabilities = sta->ht_capabilities;
- params.vht_capabilities = sta->vht_capabilities;
- params.he_capab = sta->he_capab;
- params.he_capab_len = sta->he_capab_len;
- params.he_6ghz_capab = sta->he_6ghz_capab;
- params.flags |= WPA_STA_WMM;
- params.flags_mask |= WPA_STA_AUTHENTICATED;
- if (conf->security == MESH_CONF_SEC_NONE) {
- params.flags |= WPA_STA_AUTHORIZED;
- params.flags |= WPA_STA_AUTHENTICATED;
- } else {
- sta->flags |= WLAN_STA_MFP;
- params.flags |= WPA_STA_MFP;
- }
-
- ret = wpa_drv_sta_add(wpa_s, &params);
- if (ret) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Driver failed to insert " MACSTR ": %d",
- MAC2STR(addr), ret);
- ap_free_sta(data, sta);
- return NULL;
- }
-
- return sta;
-}
-
-
-void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- struct ieee802_11_elems *elems)
-{
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
- struct hostapd_data *data = wpa_s->ifmsh->bss[0];
- struct sta_info *sta;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- sta = mesh_mpm_add_peer(wpa_s, addr, elems);
- if (!sta)
- return;
-
- if (ssid && ssid->no_auto_peer &&
- (is_zero_ether_addr(data->mesh_required_peer) ||
- os_memcmp(data->mesh_required_peer, addr, ETH_ALEN) != 0)) {
- wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with "
- MACSTR " because of no_auto_peer", MAC2STR(addr));
- if (data->mesh_pending_auth) {
- struct os_reltime age;
- const struct ieee80211_mgmt *mgmt;
- struct hostapd_frame_info fi;
-
- mgmt = wpabuf_head(data->mesh_pending_auth);
- os_reltime_age(&data->mesh_pending_auth_time, &age);
- if (age.sec < 2 &&
- os_memcmp(mgmt->sa, addr, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "mesh: Process pending Authentication frame from %u.%06u seconds ago",
- (unsigned int) age.sec,
- (unsigned int) age.usec);
- os_memset(&fi, 0, sizeof(fi));
- ieee802_11_mgmt(
- data,
- wpabuf_head(data->mesh_pending_auth),
- wpabuf_len(data->mesh_pending_auth),
- &fi);
- }
- wpabuf_free(data->mesh_pending_auth);
- data->mesh_pending_auth = NULL;
- }
- return;
- }
-
- if (conf->security == MESH_CONF_SEC_NONE) {
- if (sta->plink_state < PLINK_OPN_SNT ||
- sta->plink_state > PLINK_ESTAB)
- mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_SNT);
- } else {
- mesh_rsn_auth_sae_sta(wpa_s, sta);
- }
-}
-
-
-void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt)
-{
- struct hostapd_frame_info fi;
-
- os_memset(&fi, 0, sizeof(fi));
- fi.datarate = rx_mgmt->datarate;
- fi.ssi_signal = rx_mgmt->ssi_signal;
- ieee802_11_mgmt(wpa_s->ifmsh->bss[0], rx_mgmt->frame,
- rx_mgmt->frame_len, &fi);
-}
-
-
-static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
- struct sta_info *sta)
-{
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
- u8 seq[6] = {};
-
- wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
- MAC2STR(sta->addr));
-
- if (conf->security & MESH_CONF_SEC_AMPE) {
- wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
- wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
- sta->addr, 0, 0, seq, sizeof(seq),
- sta->mtk, sta->mtk_len,
- KEY_FLAG_PAIRWISE_RX_TX);
-
- wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
- sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
- wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
- sta->mgtk, sta->mgtk_len);
- wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
- sta->addr, sta->mgtk_key_id, 0,
- sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
- sta->mgtk, sta->mgtk_len,
- KEY_FLAG_GROUP_RX);
-
- if (sta->igtk_len) {
- wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
- sta->igtk_rsc, sizeof(sta->igtk_rsc));
- wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK",
- sta->igtk, sta->igtk_len);
- wpa_drv_set_key(
- wpa_s,
- wpa_cipher_to_alg(conf->mgmt_group_cipher),
- sta->addr, sta->igtk_key_id, 0,
- sta->igtk_rsc, sizeof(sta->igtk_rsc),
- sta->igtk, sta->igtk_len,
- KEY_FLAG_GROUP_RX);
- }
- }
-
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
- hapd->num_plinks++;
-
- sta->flags |= WLAN_STA_ASSOC;
- sta->mesh_sae_pmksa_caching = 0;
-
- eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
- peer_add_timer(wpa_s, NULL);
- eloop_cancel_timeout(plink_timer, wpa_s, sta);
-
- /* Send ctrl event */
- wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
- MAC2STR(sta->addr));
-
- /* Send D-Bus event */
- wpas_notify_mesh_peer_connected(wpa_s, sta->addr);
-}
-
-
-static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
- enum plink_event event, u16 reason)
-{
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
- struct mesh_conf *conf = wpa_s->ifmsh->mconf;
-
- wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
- MAC2STR(sta->addr), mplstate[sta->plink_state],
- mplevent[event]);
-
- switch (sta->plink_state) {
- case PLINK_IDLE:
- switch (event) {
- case CLS_ACPT:
- mesh_mpm_fsm_restart(wpa_s, sta);
- break;
- case OPN_ACPT:
- mesh_mpm_plink_open(wpa_s, sta, PLINK_OPN_RCVD);
- mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CONFIRM,
- 0);
- break;
- case REQ_RJCT:
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- default:
- break;
- }
- break;
- case PLINK_OPN_SNT:
- switch (event) {
- case OPN_RJCT:
- case CNF_RJCT:
- if (!reason)
- reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
- /* fall-through */
- case CLS_ACPT:
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- if (!reason)
- reason = WLAN_REASON_MESH_CLOSE_RCVD;
- eloop_register_timeout(
- conf->dot11MeshHoldingTimeout / 1000,
- (conf->dot11MeshHoldingTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- case OPN_ACPT:
- /* retry timer is left untouched */
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_OPN_RCVD);
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CONFIRM, 0);
- break;
- case CNF_ACPT:
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_CNF_RCVD);
- eloop_cancel_timeout(plink_timer, wpa_s, sta);
- eloop_register_timeout(
- conf->dot11MeshConfirmTimeout / 1000,
- (conf->dot11MeshConfirmTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- break;
- default:
- break;
- }
- break;
- case PLINK_OPN_RCVD:
- switch (event) {
- case OPN_RJCT:
- case CNF_RJCT:
- if (!reason)
- reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
- /* fall-through */
- case CLS_ACPT:
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- if (!reason)
- reason = WLAN_REASON_MESH_CLOSE_RCVD;
- eloop_register_timeout(
- conf->dot11MeshHoldingTimeout / 1000,
- (conf->dot11MeshHoldingTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- sta->mpm_close_reason = reason;
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- case OPN_ACPT:
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CONFIRM, 0);
- break;
- case CNF_ACPT:
- if (conf->security & MESH_CONF_SEC_AMPE)
- mesh_rsn_derive_mtk(wpa_s, sta);
- mesh_mpm_plink_estab(wpa_s, sta);
- break;
- default:
- break;
- }
- break;
- case PLINK_CNF_RCVD:
- switch (event) {
- case OPN_RJCT:
- case CNF_RJCT:
- if (!reason)
- reason = WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION;
- /* fall-through */
- case CLS_ACPT:
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- if (!reason)
- reason = WLAN_REASON_MESH_CLOSE_RCVD;
- eloop_register_timeout(
- conf->dot11MeshHoldingTimeout / 1000,
- (conf->dot11MeshHoldingTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- sta->mpm_close_reason = reason;
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- case OPN_ACPT:
- if (conf->security & MESH_CONF_SEC_AMPE)
- mesh_rsn_derive_mtk(wpa_s, sta);
- mesh_mpm_plink_estab(wpa_s, sta);
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CONFIRM, 0);
- break;
- default:
- break;
- }
- break;
- case PLINK_ESTAB:
- switch (event) {
- case OPN_RJCT:
- case CNF_RJCT:
- case CLS_ACPT:
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
- if (!reason)
- reason = WLAN_REASON_MESH_CLOSE_RCVD;
-
- eloop_register_timeout(
- conf->dot11MeshHoldingTimeout / 1000,
- (conf->dot11MeshHoldingTimeout % 1000) * 1000,
- plink_timer, wpa_s, sta);
- sta->mpm_close_reason = reason;
-
- wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR
- " closed with reason %d",
- MAC2STR(sta->addr), reason);
-
- wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
- MAC2STR(sta->addr));
-
- /* Send D-Bus event */
- wpas_notify_mesh_peer_disconnected(wpa_s, sta->addr,
- reason);
-
- hapd->num_plinks--;
-
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- case OPN_ACPT:
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CONFIRM, 0);
- break;
- default:
- break;
- }
- break;
- case PLINK_HOLDING:
- switch (event) {
- case CLS_ACPT:
- mesh_mpm_fsm_restart(wpa_s, sta);
- break;
- case OPN_ACPT:
- case CNF_ACPT:
- case OPN_RJCT:
- case CNF_RJCT:
- reason = sta->mpm_close_reason;
- mesh_mpm_send_plink_action(wpa_s, sta,
- PLINK_CLOSE, reason);
- break;
- default:
- break;
- }
- break;
- default:
- wpa_msg(wpa_s, MSG_DEBUG,
- "Unsupported MPM event %s for state %s",
- mplevent[event], mplstate[sta->plink_state]);
- break;
- }
-}
-
-
-void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len)
-{
- u8 action_field;
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
- struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
- struct sta_info *sta;
- u16 plid = 0, llid = 0, aid = 0;
- enum plink_event event;
- struct ieee802_11_elems elems;
- struct mesh_peer_mgmt_ie peer_mgmt_ie;
- const u8 *ies;
- size_t ie_len;
- int ret;
- u16 reason = 0;
-
- if (mgmt->u.action.category != WLAN_ACTION_SELF_PROTECTED)
- return;
-
- action_field = mgmt->u.action.u.slf_prot_action.action;
- if (action_field != PLINK_OPEN &&
- action_field != PLINK_CONFIRM &&
- action_field != PLINK_CLOSE)
- return;
-
- ies = mgmt->u.action.u.slf_prot_action.variable;
- ie_len = (const u8 *) mgmt + len -
- mgmt->u.action.u.slf_prot_action.variable;
-
- /* at least expect mesh id and peering mgmt */
- if (ie_len < 2 + 2) {
- wpa_printf(MSG_DEBUG,
- "MPM: Ignore too short action frame %u ie_len %u",
- action_field, (unsigned int) ie_len);
- return;
- }
- wpa_printf(MSG_DEBUG, "MPM: Received PLINK action %u", action_field);
-
- if (action_field == PLINK_OPEN || action_field == PLINK_CONFIRM) {
- wpa_printf(MSG_DEBUG, "MPM: Capability 0x%x",
- WPA_GET_LE16(ies));
- ies += 2; /* capability */
- ie_len -= 2;
- }
- if (action_field == PLINK_CONFIRM) {
- aid = WPA_GET_LE16(ies);
- wpa_printf(MSG_DEBUG, "MPM: AID 0x%x", aid);
- ies += 2; /* aid */
- ie_len -= 2;
- }
-
- /* check for mesh peering, mesh id and mesh config IEs */
- if (ieee802_11_parse_elems(ies, ie_len, &elems, 0) == ParseFailed) {
- wpa_printf(MSG_DEBUG, "MPM: Failed to parse PLINK IEs");
- return;
- }
- if (!elems.peer_mgmt) {
- wpa_printf(MSG_DEBUG,
- "MPM: No Mesh Peering Management element");
- return;
- }
- if (action_field != PLINK_CLOSE) {
- if (!elems.mesh_id || !elems.mesh_config) {
- wpa_printf(MSG_DEBUG,
- "MPM: No Mesh ID or Mesh Configuration element");
- return;
- }
-
- if (!matches_local(wpa_s, &elems)) {
- wpa_printf(MSG_DEBUG,
- "MPM: Mesh ID or Mesh Configuration element do not match local MBSS");
- return;
- }
- }
-
- ret = mesh_mpm_parse_peer_mgmt(wpa_s, action_field,
- elems.peer_mgmt,
- elems.peer_mgmt_len,
- &peer_mgmt_ie);
- if (ret) {
- wpa_printf(MSG_DEBUG, "MPM: Mesh parsing rejected frame");
- return;
- }
-
- /* the sender's llid is our plid and vice-versa */
- plid = WPA_GET_LE16(peer_mgmt_ie.llid);
- if (peer_mgmt_ie.plid)
- llid = WPA_GET_LE16(peer_mgmt_ie.plid);
- wpa_printf(MSG_DEBUG, "MPM: plid=0x%x llid=0x%x", plid, llid);
-
- if (action_field == PLINK_CLOSE)
- wpa_printf(MSG_DEBUG, "MPM: close reason=%u",
- WPA_GET_LE16(peer_mgmt_ie.reason));
-
- sta = ap_get_sta(hapd, mgmt->sa);
-
- /*
- * If this is an open frame from an unknown STA, and this is an
- * open mesh, then go ahead and add the peer before proceeding.
- */
- if (!sta && action_field == PLINK_OPEN &&
- (!(mconf->security & MESH_CONF_SEC_AMPE) ||
- wpa_auth_pmksa_get(hapd->wpa_auth, mgmt->sa, NULL)))
- sta = mesh_mpm_add_peer(wpa_s, mgmt->sa, &elems);
-
- if (!sta) {
- wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
- return;
- }
-
-#ifdef CONFIG_SAE
- /* peer is in sae_accepted? */
- if (sta->sae && sta->sae->state != SAE_ACCEPTED) {
- wpa_printf(MSG_DEBUG, "MPM: SAE not yet accepted for peer");
- return;
- }
-#endif /* CONFIG_SAE */
-
- if (!sta->my_lid)
- mesh_mpm_init_link(wpa_s, sta);
-
- if (mconf->security & MESH_CONF_SEC_AMPE) {
- int res;
-
- res = mesh_rsn_process_ampe(wpa_s, sta, &elems,
- &mgmt->u.action.category,
- peer_mgmt_ie.chosen_pmk,
- ies, ie_len);
- if (res) {
- wpa_printf(MSG_DEBUG,
- "MPM: RSN process rejected frame (res=%d)",
- res);
- if (action_field == PLINK_OPEN && res == -2) {
- /* AES-SIV decryption failed */
- mesh_mpm_fsm(wpa_s, sta, OPN_RJCT,
- WLAN_REASON_MESH_INVALID_GTK);
- }
- return;
- }
-
-#ifdef CONFIG_OCV
- if (action_field == PLINK_OPEN && elems.rsn_ie) {
- struct wpa_state_machine *sm = sta->wpa_sm;
- struct wpa_ie_data data;
-
- res = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2,
- elems.rsn_ie_len + 2,
- &data);
- if (res) {
- wpa_printf(MSG_DEBUG,
- "Failed to parse RSN IE (res=%d)",
- res);
- wpa_hexdump(MSG_DEBUG, "RSN IE", elems.rsn_ie,
- elems.rsn_ie_len);
- return;
- }
-
- wpa_auth_set_ocv(sm, mconf->ocv &&
- (data.capabilities &
- WPA_CAPABILITY_OCVC));
- }
-
- if (action_field != PLINK_CLOSE &&
- wpa_auth_uses_ocv(sta->wpa_sm)) {
- struct wpa_channel_info ci;
- int tx_chanwidth;
- int tx_seg1_idx;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "MPM: Failed to get channel info to validate received OCI in MPM Confirm");
- return;
- }
-
- if (get_tx_parameters(
- sta, channel_width_to_int(ci.chanwidth),
- ci.seg1_idx, &tx_chanwidth,
- &tx_seg1_idx) < 0)
- return;
-
- if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
- tx_chanwidth, tx_seg1_idx) !=
- OCI_SUCCESS) {
- wpa_printf(MSG_WARNING, "MPM: OCV failed: %s",
- ocv_errorstr);
- return;
- }
- }
-#endif /* CONFIG_OCV */
- }
-
- if (sta->plink_state == PLINK_BLOCKED) {
- wpa_printf(MSG_DEBUG, "MPM: PLINK_BLOCKED");
- return;
- }
-
- /* Now we will figure out the appropriate event... */
- switch (action_field) {
- case PLINK_OPEN:
- if (plink_free_count(hapd) == 0) {
- event = REQ_RJCT;
- reason = WLAN_REASON_MESH_MAX_PEERS;
- wpa_printf(MSG_INFO,
- "MPM: Peer link num over quota(%d)",
- hapd->max_plinks);
- } else if (sta->peer_lid && sta->peer_lid != plid) {
- wpa_printf(MSG_DEBUG,
- "MPM: peer_lid mismatch: 0x%x != 0x%x",
- sta->peer_lid, plid);
- return; /* no FSM event */
- } else {
- sta->peer_lid = plid;
- event = OPN_ACPT;
- }
- break;
- case PLINK_CONFIRM:
- if (plink_free_count(hapd) == 0) {
- event = REQ_RJCT;
- reason = WLAN_REASON_MESH_MAX_PEERS;
- wpa_printf(MSG_INFO,
- "MPM: Peer link num over quota(%d)",
- hapd->max_plinks);
- } else if (sta->my_lid != llid ||
- (sta->peer_lid && sta->peer_lid != plid)) {
- wpa_printf(MSG_DEBUG,
- "MPM: lid mismatch: my_lid: 0x%x != 0x%x or peer_lid: 0x%x != 0x%x",
- sta->my_lid, llid, sta->peer_lid, plid);
- return; /* no FSM event */
- } else {
- if (!sta->peer_lid)
- sta->peer_lid = plid;
- sta->peer_aid = aid;
- event = CNF_ACPT;
- }
- break;
- case PLINK_CLOSE:
- if (sta->plink_state == PLINK_ESTAB)
- /* Do not check for llid or plid. This does not
- * follow the standard but since multiple plinks
- * per cand are not supported, it is necessary in
- * order to avoid a livelock when MP A sees an
- * establish peer link to MP B but MP B does not
- * see it. This can be caused by a timeout in
- * B's peer link establishment or B being
- * restarted.
- */
- event = CLS_ACPT;
- else if (sta->peer_lid != plid) {
- wpa_printf(MSG_DEBUG,
- "MPM: peer_lid mismatch: 0x%x != 0x%x",
- sta->peer_lid, plid);
- return; /* no FSM event */
- } else if (peer_mgmt_ie.plid && sta->my_lid != llid) {
- wpa_printf(MSG_DEBUG,
- "MPM: my_lid mismatch: 0x%x != 0x%x",
- sta->my_lid, llid);
- return; /* no FSM event */
- } else {
- event = CLS_ACPT;
- }
- break;
- default:
- /*
- * This cannot be hit due to the action_field check above, but
- * compilers may not be able to figure that out and can warn
- * about uninitialized event below.
- */
- return;
- }
- mesh_mpm_fsm(wpa_s, sta, event, reason);
-}
-
-
-/* called by ap_free_sta */
-void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
-{
- if (sta->plink_state == PLINK_ESTAB)
- hapd->num_plinks--;
- eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
- eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
-}
diff --git a/wpa_supplicant/mesh_mpm.h b/wpa_supplicant/mesh_mpm.h
deleted file mode 100644
index 5fc1e6184bcb..000000000000
--- a/wpa_supplicant/mesh_mpm.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * WPA Supplicant - Basic mesh peer management
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef MESH_MPM_H
-#define MESH_MPM_H
-
-/* notify MPM of new mesh peer to be inserted in MPM and driver */
-void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- struct ieee802_11_elems *elems);
-void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
-void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
-void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
-void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
- struct sta_info *sta,
- enum mesh_plink_state state);
-int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
-int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration);
-
-#ifdef CONFIG_MESH
-
-void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len);
-void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt);
-
-#else /* CONFIG_MESH */
-
-static inline void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt,
- size_t len)
-{
-}
-
-static inline void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s,
- struct rx_mgmt *rx_mgmt)
-{
-}
-
-#endif /* CONFIG_MESH */
-
-#endif /* MESH_MPM_H */
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
deleted file mode 100644
index 65daa77c2c98..000000000000
--- a/wpa_supplicant/mesh_rsn.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * WPA Supplicant - Mesh RSN routines
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "crypto/sha256.h"
-#include "crypto/random.h"
-#include "crypto/aes.h"
-#include "crypto/aes_siv.h"
-#include "rsn_supp/wpa.h"
-#include "ap/hostapd.h"
-#include "ap/wpa_auth.h"
-#include "ap/sta_info.h"
-#include "ap/ieee802_11.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "wpas_glue.h"
-#include "mesh_mpm.h"
-#include "mesh_rsn.h"
-
-#define MESH_AUTH_TIMEOUT 10
-#define MESH_AUTH_RETRY 3
-
-void mesh_auth_timer(void *eloop_ctx, void *user_data)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct sta_info *sta = user_data;
- struct hostapd_data *hapd;
-
- if (sta->sae->state != SAE_ACCEPTED) {
- wpa_printf(MSG_DEBUG, "AUTH: Re-authenticate with " MACSTR
- " (attempt %d) ",
- MAC2STR(sta->addr), sta->sae_auth_retry);
- wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_FAILURE "addr=" MACSTR,
- MAC2STR(sta->addr));
- if (sta->sae_auth_retry < MESH_AUTH_RETRY) {
- mesh_rsn_auth_sae_sta(wpa_s, sta);
- } else {
- hapd = wpa_s->ifmsh->bss[0];
-
- if (sta->sae_auth_retry > MESH_AUTH_RETRY) {
- ap_free_sta(hapd, sta);
- return;
- }
-
- /* block the STA if exceeded the number of attempts */
- wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED);
- sta->sae->state = SAE_NOTHING;
- wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr="
- MACSTR " duration=%d",
- MAC2STR(sta->addr),
- hapd->conf->ap_max_inactivity);
- }
- sta->sae_auth_retry++;
- }
-}
-
-
-static void auth_logger(void *ctx, const u8 *addr, logger_level level,
- const char *txt)
-{
- if (addr)
- wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s",
- MAC2STR(addr), txt);
- else
- wpa_printf(MSG_DEBUG, "AUTH: %s", txt);
-}
-
-
-static const u8 *auth_get_psk(void *ctx, const u8 *addr,
- const u8 *p2p_dev_addr, const u8 *prev_psk,
- size_t *psk_len, int *vlan_id)
-{
- struct mesh_rsn *mesh_rsn = ctx;
- struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
- struct sta_info *sta = ap_get_sta(hapd, addr);
-
- if (psk_len)
- *psk_len = PMK_LEN;
- if (vlan_id)
- *vlan_id = 0;
- wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
- __func__, MAC2STR(addr), prev_psk);
-
- if (sta && sta->auth_alg == WLAN_AUTH_SAE) {
- if (!sta->sae || prev_psk)
- return NULL;
- return sta->sae->pmk;
- }
-
- return NULL;
-}
-
-
-static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
- const u8 *addr, int idx, u8 *key, size_t key_len,
- enum key_flag key_flag)
-{
- struct mesh_rsn *mesh_rsn = ctx;
- u8 seq[6];
-
- os_memset(seq, 0, sizeof(seq));
-
- if (addr) {
- wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
- " key_idx=%d)",
- __func__, alg, MAC2STR(addr), idx);
- } else {
- wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
- __func__, alg, idx);
- }
- wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);
-
- return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx,
- 1, seq, 6, key, key_len, key_flag);
-}
-
-
-static int auth_start_ampe(void *ctx, const u8 *addr)
-{
- struct mesh_rsn *mesh_rsn = ctx;
- struct hostapd_data *hapd;
- struct sta_info *sta;
-
- if (mesh_rsn->wpa_s->current_ssid->mode != WPAS_MODE_MESH)
- return -1;
-
- hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
- sta = ap_get_sta(hapd, addr);
- if (sta)
- eloop_cancel_timeout(mesh_auth_timer, mesh_rsn->wpa_s, sta);
-
- mesh_mpm_auth_peer(mesh_rsn->wpa_s, addr);
- return 0;
-}
-
-
-static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
- enum mfp_options ieee80211w, int ocv)
-{
- struct wpa_auth_config conf;
- static const struct wpa_auth_callbacks cb = {
- .logger = auth_logger,
- .get_psk = auth_get_psk,
- .set_key = auth_set_key,
- .start_ampe = auth_start_ampe,
- };
- u8 seq[6] = {};
-
- wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
-
- os_memset(&conf, 0, sizeof(conf));
- conf.wpa = WPA_PROTO_RSN;
- conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE;
- conf.wpa_pairwise = rsn->pairwise_cipher;
- conf.rsn_pairwise = rsn->pairwise_cipher;
- conf.wpa_group = rsn->group_cipher;
- conf.eapol_version = 0;
- conf.wpa_group_rekey = -1;
- conf.wpa_group_update_count = 4;
- conf.wpa_pairwise_update_count = 4;
- conf.ieee80211w = ieee80211w;
- if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
- conf.group_mgmt_cipher = rsn->mgmt_group_cipher;
-#ifdef CONFIG_OCV
- conf.ocv = ocv;
-#endif /* CONFIG_OCV */
-
- rsn->auth = wpa_init(addr, &conf, &cb, rsn);
- if (rsn->auth == NULL) {
- wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
- return -1;
- }
-
- /* TODO: support rekeying */
- rsn->mgtk_len = wpa_cipher_key_len(conf.wpa_group);
- if (random_get_bytes(rsn->mgtk, rsn->mgtk_len) < 0)
- return -1;
- rsn->mgtk_key_id = 1;
-
- if (ieee80211w != NO_MGMT_FRAME_PROTECTION) {
- rsn->igtk_len = wpa_cipher_key_len(conf.group_mgmt_cipher);
- if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0)
- return -1;
- rsn->igtk_key_id = 4;
-
- /* group mgmt */
- wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK",
- rsn->igtk, rsn->igtk_len);
- wpa_drv_set_key(rsn->wpa_s,
- wpa_cipher_to_alg(rsn->mgmt_group_cipher),
- broadcast_ether_addr,
- rsn->igtk_key_id, 1,
- seq, sizeof(seq), rsn->igtk, rsn->igtk_len,
- KEY_FLAG_GROUP_TX_DEFAULT);
- }
-
- /* group privacy / data frames */
- wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK",
- rsn->mgtk, rsn->mgtk_len);
- wpa_drv_set_key(rsn->wpa_s, wpa_cipher_to_alg(rsn->group_cipher),
- broadcast_ether_addr,
- rsn->mgtk_key_id, 1, seq, sizeof(seq),
- rsn->mgtk, rsn->mgtk_len, KEY_FLAG_GROUP_TX_DEFAULT);
-
- return 0;
-}
-
-
-static void mesh_rsn_deinit(struct mesh_rsn *rsn)
-{
- os_memset(rsn->mgtk, 0, sizeof(rsn->mgtk));
- rsn->mgtk_len = 0;
- os_memset(rsn->igtk, 0, sizeof(rsn->igtk));
- rsn->igtk_len = 0;
- if (rsn->auth)
- wpa_deinit(rsn->auth);
-}
-
-
-struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s,
- struct mesh_conf *conf)
-{
- struct mesh_rsn *mesh_rsn;
- struct hostapd_data *bss = wpa_s->ifmsh->bss[0];
- const u8 *ie;
- size_t ie_len;
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- struct external_pmksa_cache *entry;
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
- mesh_rsn = os_zalloc(sizeof(*mesh_rsn));
- if (mesh_rsn == NULL)
- return NULL;
- mesh_rsn->wpa_s = wpa_s;
- mesh_rsn->pairwise_cipher = conf->pairwise_cipher;
- mesh_rsn->group_cipher = conf->group_cipher;
- mesh_rsn->mgmt_group_cipher = conf->mgmt_group_cipher;
-
- if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr,
- conf->ieee80211w, conf->ocv) < 0) {
- mesh_rsn_deinit(mesh_rsn);
- os_free(mesh_rsn);
- return NULL;
- }
-
- bss->wpa_auth = mesh_rsn->auth;
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- while ((entry = dl_list_last(&wpa_s->mesh_external_pmksa_cache,
- struct external_pmksa_cache,
- list)) != NULL) {
- int ret;
-
- ret = wpa_auth_pmksa_add_entry(bss->wpa_auth,
- entry->pmksa_cache);
- dl_list_del(&entry->list);
- os_free(entry);
-
- if (ret < 0)
- return NULL;
- }
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
- ie = wpa_auth_get_wpa_ie(mesh_rsn->auth, &ie_len);
- conf->rsn_ie = (u8 *) ie;
- conf->rsn_ie_len = ie_len;
-
- wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
-
- return mesh_rsn;
-}
-
-
-static int index_within_array(const int *array, int idx)
-{
- int i;
-
- for (i = 0; i < idx; i++) {
- if (array[i] == -1)
- return 0;
- }
-
- return 1;
-}
-
-
-static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s,
- struct sae_data *sae)
-{
- int *groups = wpa_s->ifmsh->bss[0]->conf->sae_groups;
-
- /* Configuration may have changed, so validate current index */
- if (!index_within_array(groups, wpa_s->mesh_rsn->sae_group_index))
- return -1;
-
- for (;;) {
- int group = groups[wpa_s->mesh_rsn->sae_group_index];
-
- if (group <= 0)
- break;
- if (sae_set_group(sae, group) == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
- sae->group);
- return 0;
- }
- wpa_s->mesh_rsn->sae_group_index++;
- }
-
- return -1;
-}
-
-
-static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct sta_info *sta)
-{
- const char *password;
-
- password = ssid->sae_password;
- if (!password)
- password = ssid->passphrase;
- if (!password) {
- wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
- return -1;
- }
-
- if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
- return -1;
- }
-
- if (sta->sae->tmp && !sta->sae->tmp->pw_id && ssid->sae_password_id) {
- sta->sae->tmp->pw_id = os_strdup(ssid->sae_password_id);
- if (!sta->sae->tmp->pw_id)
- return -1;
- }
- return sae_prepare_commit(wpa_s->own_addr, sta->addr,
- (u8 *) password, os_strlen(password),
- sta->sae);
-}
-
-
-/* initiate new SAE authentication with sta */
-int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
- struct sta_info *sta)
-{
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct rsn_pmksa_cache_entry *pmksa;
- unsigned int rnd;
- int ret;
-
- if (!ssid) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "AUTH: No current_ssid known to initiate new SAE");
- return -1;
- }
-
- if (!sta->sae) {
- sta->sae = os_zalloc(sizeof(*sta->sae));
- if (sta->sae == NULL)
- return -1;
- }
-
- pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL);
- if (pmksa) {
- if (!sta->wpa_sm)
- sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
- sta->addr, NULL);
- if (!sta->wpa_sm) {
- wpa_printf(MSG_ERROR,
- "mesh: Failed to initialize RSN state machine");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG,
- "AUTH: Mesh PMKSA cache entry found for " MACSTR
- " - try to use PMKSA caching instead of new SAE authentication",
- MAC2STR(sta->addr));
- wpa_auth_pmksa_set_to_sm(pmksa, sta->wpa_sm, hapd->wpa_auth,
- sta->sae->pmkid, sta->sae->pmk);
- sae_accept_sta(hapd, sta);
- sta->mesh_sae_pmksa_caching = 1;
- return 0;
- }
- sta->mesh_sae_pmksa_caching = 0;
-
- if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
- return -1;
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "AUTH: started authentication with SAE peer: " MACSTR,
- MAC2STR(sta->addr));
-
- ret = auth_sae_init_committed(hapd, sta);
- if (ret)
- return ret;
-
- eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
- rnd = rand() % MESH_AUTH_TIMEOUT;
- eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
- wpa_s, sta);
- return 0;
-}
-
-
-void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid)
-{
- os_memcpy(pmkid, sta->sae->pmkid, SAE_PMKID_LEN);
-}
-
-
-static void
-mesh_rsn_derive_aek(struct mesh_rsn *rsn, struct sta_info *sta)
-{
- u8 *myaddr = rsn->wpa_s->own_addr;
- u8 *peer = sta->addr;
- u8 *addr1, *addr2;
- u8 context[RSN_SELECTOR_LEN + 2 * ETH_ALEN], *ptr = context;
-
- /*
- * AEK = KDF-Hash-256(PMK, "AEK Derivation", Selected AKM Suite ||
- * min(localMAC, peerMAC) || max(localMAC, peerMAC))
- */
- /* Selected AKM Suite: SAE */
- RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE);
- ptr += RSN_SELECTOR_LEN;
-
- if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) {
- addr1 = myaddr;
- addr2 = peer;
- } else {
- addr1 = peer;
- addr2 = myaddr;
- }
- os_memcpy(ptr, addr1, ETH_ALEN);
- ptr += ETH_ALEN;
- os_memcpy(ptr, addr2, ETH_ALEN);
-
- sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk), "AEK Derivation",
- context, sizeof(context), sta->aek, sizeof(sta->aek));
-}
-
-
-/* derive mesh temporal key from pmk */
-int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta)
-{
- u8 *ptr;
- u8 *min, *max;
- u8 *myaddr = wpa_s->own_addr;
- u8 *peer = sta->addr;
- u8 context[2 * WPA_NONCE_LEN + 2 * 2 + RSN_SELECTOR_LEN + 2 * ETH_ALEN];
-
- /*
- * MTK = KDF-Hash-Length(PMK, "Temporal Key Derivation", min(localNonce,
- * peerNonce) || max(localNonce, peerNonce) || min(localLinkID,
- * peerLinkID) || max(localLinkID, peerLinkID) || Selected AKM Suite ||
- * min(localMAC, peerMAC) || max(localMAC, peerMAC))
- */
- ptr = context;
- if (os_memcmp(sta->my_nonce, sta->peer_nonce, WPA_NONCE_LEN) < 0) {
- min = sta->my_nonce;
- max = sta->peer_nonce;
- } else {
- min = sta->peer_nonce;
- max = sta->my_nonce;
- }
- os_memcpy(ptr, min, WPA_NONCE_LEN);
- ptr += WPA_NONCE_LEN;
- os_memcpy(ptr, max, WPA_NONCE_LEN);
- ptr += WPA_NONCE_LEN;
-
- if (sta->my_lid < sta->peer_lid) {
- WPA_PUT_LE16(ptr, sta->my_lid);
- ptr += 2;
- WPA_PUT_LE16(ptr, sta->peer_lid);
- ptr += 2;
- } else {
- WPA_PUT_LE16(ptr, sta->peer_lid);
- ptr += 2;
- WPA_PUT_LE16(ptr, sta->my_lid);
- ptr += 2;
- }
-
- /* Selected AKM Suite: SAE */
- RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE);
- ptr += RSN_SELECTOR_LEN;
-
- if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) {
- min = myaddr;
- max = peer;
- } else {
- min = peer;
- max = myaddr;
- }
- os_memcpy(ptr, min, ETH_ALEN);
- ptr += ETH_ALEN;
- os_memcpy(ptr, max, ETH_ALEN);
-
- sta->mtk_len = wpa_cipher_key_len(wpa_s->mesh_rsn->pairwise_cipher);
- sha256_prf(sta->sae->pmk, SAE_PMK_LEN,
- "Temporal Key Derivation", context, sizeof(context),
- sta->mtk, sta->mtk_len);
- return 0;
-}
-
-
-void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta)
-{
- if (random_get_bytes(sta->my_nonce, WPA_NONCE_LEN) < 0) {
- wpa_printf(MSG_INFO, "mesh: Failed to derive random nonce");
- /* TODO: How to handle this more cleanly? */
- }
- os_memset(sta->peer_nonce, 0, WPA_NONCE_LEN);
- mesh_rsn_derive_aek(wpa_s->mesh_rsn, sta);
-}
-
-
-/* insert AMPE and encrypted MIC at @ie.
- * @mesh_rsn: mesh RSN context
- * @sta: STA we're sending to
- * @cat: pointer to category code in frame header.
- * @buf: wpabuf to add encrypted AMPE and MIC to.
- * */
-int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
- const u8 *cat, struct wpabuf *buf)
-{
- struct ieee80211_ampe_ie *ampe;
- u8 const *ie = wpabuf_head_u8(buf) + wpabuf_len(buf);
- u8 *ampe_ie, *pos, *mic_payload;
- const u8 *aad[] = { rsn->wpa_s->own_addr, sta->addr, cat };
- const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, ie - cat };
- int ret = 0;
- size_t len;
-
- len = sizeof(*ampe);
- if (cat[1] == PLINK_OPEN)
- len += rsn->mgtk_len + WPA_KEY_RSC_LEN + 4;
- if (cat[1] == PLINK_OPEN && rsn->igtk_len)
- len += 2 + 6 + rsn->igtk_len;
-
- if (2 + AES_BLOCK_SIZE + 2 + len > wpabuf_tailroom(buf)) {
- wpa_printf(MSG_ERROR, "protect frame: buffer too small");
- return -EINVAL;
- }
-
- ampe_ie = os_zalloc(2 + len);
- if (!ampe_ie) {
- wpa_printf(MSG_ERROR, "protect frame: out of memory");
- return -ENOMEM;
- }
-
- /* IE: AMPE */
- ampe_ie[0] = WLAN_EID_AMPE;
- ampe_ie[1] = len;
- ampe = (struct ieee80211_ampe_ie *) (ampe_ie + 2);
-
- RSN_SELECTOR_PUT(ampe->selected_pairwise_suite,
- RSN_CIPHER_SUITE_CCMP);
- os_memcpy(ampe->local_nonce, sta->my_nonce, WPA_NONCE_LEN);
- os_memcpy(ampe->peer_nonce, sta->peer_nonce, WPA_NONCE_LEN);
-
- pos = (u8 *) (ampe + 1);
- if (cat[1] != PLINK_OPEN)
- goto skip_keys;
-
- /* TODO: Key Replay Counter[8] optionally for
- * Mesh Group Key Inform/Acknowledge frames */
-
- /* TODO: static mgtk for now since we don't support rekeying! */
- /*
- * GTKdata[variable]:
- * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
- */
- os_memcpy(pos, rsn->mgtk, rsn->mgtk_len);
- pos += rsn->mgtk_len;
- wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->mgtk_key_id, pos);
- pos += WPA_KEY_RSC_LEN;
- /* Use fixed GTKExpirationTime for now */
- WPA_PUT_LE32(pos, 0xffffffff);
- pos += 4;
-
- /*
- * IGTKdata[variable]:
- * Key ID[2], IPN[6], IGTK[variable]
- */
- if (rsn->igtk_len) {
- WPA_PUT_LE16(pos, rsn->igtk_key_id);
- pos += 2;
- wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->igtk_key_id, pos);
- pos += 6;
- os_memcpy(pos, rsn->igtk, rsn->igtk_len);
- }
-
-skip_keys:
- wpa_hexdump_key(MSG_DEBUG, "mesh: Plaintext AMPE element",
- ampe_ie, 2 + len);
-
- /* IE: MIC */
- wpabuf_put_u8(buf, WLAN_EID_MIC);
- wpabuf_put_u8(buf, AES_BLOCK_SIZE);
- /* MIC field is output ciphertext */
-
- /* encrypt after MIC */
- mic_payload = wpabuf_put(buf, 2 + len + AES_BLOCK_SIZE);
-
- if (aes_siv_encrypt(sta->aek, sizeof(sta->aek), ampe_ie, 2 + len, 3,
- aad, aad_len, mic_payload)) {
- wpa_printf(MSG_ERROR, "protect frame: failed to encrypt");
- ret = -ENOMEM;
- }
-
- os_free(ampe_ie);
-
- return ret;
-}
-
-
-int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
- struct ieee802_11_elems *elems, const u8 *cat,
- const u8 *chosen_pmk,
- const u8 *start, size_t elems_len)
-{
- int ret = 0;
- struct ieee80211_ampe_ie *ampe;
- u8 null_nonce[WPA_NONCE_LEN] = {};
- u8 ampe_eid;
- u8 ampe_ie_len;
- u8 *ampe_buf, *crypt = NULL, *pos, *end;
- size_t crypt_len;
- const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat };
- const size_t aad_len[] = { ETH_ALEN, ETH_ALEN,
- elems->mic ? (elems->mic - 2) - cat : 0 };
- size_t key_len;
-
- if (!sta->sae) {
- struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
-
- if (!wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL)) {
- wpa_printf(MSG_INFO,
- "Mesh RSN: SAE is not prepared yet");
- return -1;
- }
- mesh_rsn_auth_sae_sta(wpa_s, sta);
- }
-
- if (chosen_pmk &&
- (!sta->sae ||
- os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN) != 0)) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
- return -1;
- }
-
- if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) {
- wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie");
- return -1;
- }
-
- ampe_buf = (u8 *) elems->mic + elems->mic_len;
- if ((int) elems_len < ampe_buf - start)
- return -1;
-
- crypt_len = elems_len - (elems->mic - start);
- if (crypt_len < 2 + AES_BLOCK_SIZE) {
- wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing ampe ie");
- return -1;
- }
-
- /* crypt is modified by siv_decrypt */
- crypt = os_zalloc(crypt_len);
- if (!crypt) {
- wpa_printf(MSG_ERROR, "Mesh RSN: out of memory");
- ret = -ENOMEM;
- goto free;
- }
-
- os_memcpy(crypt, elems->mic, crypt_len);
-
- if (aes_siv_decrypt(sta->aek, sizeof(sta->aek), crypt, crypt_len, 3,
- aad, aad_len, ampe_buf)) {
- wpa_printf(MSG_ERROR, "Mesh RSN: frame verification failed!");
- ret = -2;
- goto free;
- }
-
- crypt_len -= AES_BLOCK_SIZE;
- wpa_hexdump_key(MSG_DEBUG, "mesh: Decrypted AMPE element",
- ampe_buf, crypt_len);
-
- ampe_eid = *ampe_buf++;
- ampe_ie_len = *ampe_buf++;
-
- if (ampe_eid != WLAN_EID_AMPE ||
- (size_t) 2 + ampe_ie_len > crypt_len ||
- ampe_ie_len < sizeof(struct ieee80211_ampe_ie)) {
- wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid ampe ie");
- ret = -1;
- goto free;
- }
-
- ampe = (struct ieee80211_ampe_ie *) ampe_buf;
- pos = (u8 *) (ampe + 1);
- end = ampe_buf + ampe_ie_len;
- if (os_memcmp(ampe->peer_nonce, null_nonce, WPA_NONCE_LEN) != 0 &&
- os_memcmp(ampe->peer_nonce, sta->my_nonce, WPA_NONCE_LEN) != 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid peer nonce");
- ret = -1;
- goto free;
- }
- os_memcpy(sta->peer_nonce, ampe->local_nonce,
- sizeof(ampe->local_nonce));
-
- /* TODO: Key Replay Counter[8] in Mesh Group Key Inform/Acknowledge
- * frames */
-
- /*
- * GTKdata shall not be included in Mesh Peering Confirm. While the
- * standard does not state the same about IGTKdata, that same constraint
- * needs to apply for it. It makes no sense to include the keys in Mesh
- * Peering Close frames either, so while the standard does not seem to
- * have a shall statement for these, they are described without
- * mentioning GTKdata.
- *
- * An earlier implementation used to add GTKdata to both Mesh Peering
- * Open and Mesh Peering Confirm frames, so ignore the possibly present
- * GTKdata frame without rejecting the frame as a backwards
- * compatibility mechanism.
- */
- if (cat[1] != PLINK_OPEN) {
- if (end > pos) {
- wpa_hexdump_key(MSG_DEBUG,
- "mesh: Ignore unexpected GTKdata(etc.) fields in the end of AMPE element in Mesh Peering Confirm/Close",
- pos, end - pos);
- }
- goto free;
- }
-
- /*
- * GTKdata[variable]:
- * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
- */
- sta->mgtk_key_id = 1; /* FIX: Where to get Key ID? */
- key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->group_cipher);
- if ((int) key_len + WPA_KEY_RSC_LEN + 4 > end - pos) {
- wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element");
- ret = -1;
- goto free;
- }
- sta->mgtk_len = key_len;
- os_memcpy(sta->mgtk, pos, sta->mgtk_len);
- wpa_hexdump_key(MSG_DEBUG, "mesh: GTKdata - MGTK",
- sta->mgtk, sta->mgtk_len);
- pos += sta->mgtk_len;
- wpa_hexdump(MSG_DEBUG, "mesh: GTKdata - MGTK - Key RSC",
- pos, WPA_KEY_RSC_LEN);
- os_memcpy(sta->mgtk_rsc, pos, sizeof(sta->mgtk_rsc));
- pos += WPA_KEY_RSC_LEN;
- wpa_printf(MSG_DEBUG,
- "mesh: GTKdata - MGTK - GTKExpirationTime: %u seconds",
- WPA_GET_LE32(pos));
- pos += 4;
-
- /*
- * IGTKdata[variable]:
- * Key ID[2], IPN[6], IGTK[variable]
- */
- key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->mgmt_group_cipher);
- if (end - pos >= (int) (2 + 6 + key_len)) {
- sta->igtk_key_id = WPA_GET_LE16(pos);
- wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u",
- sta->igtk_key_id);
- pos += 2;
- os_memcpy(sta->igtk_rsc, pos, sizeof(sta->igtk_rsc));
- wpa_hexdump(MSG_DEBUG, "mesh: IGTKdata - IPN",
- sta->igtk_rsc, sizeof(sta->igtk_rsc));
- pos += 6;
- os_memcpy(sta->igtk, pos, key_len);
- sta->igtk_len = key_len;
- wpa_hexdump_key(MSG_DEBUG, "mesh: IGTKdata - IGTK",
- sta->igtk, sta->igtk_len);
- }
-
-free:
- os_free(crypt);
- return ret;
-}
diff --git a/wpa_supplicant/mesh_rsn.h b/wpa_supplicant/mesh_rsn.h
deleted file mode 100644
index 8775cedc3b27..000000000000
--- a/wpa_supplicant/mesh_rsn.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * WPA Supplicant - Mesh RSN routines
- * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef MESH_RSN_H
-#define MESH_RSN_H
-
-struct mesh_rsn {
- struct wpa_supplicant *wpa_s;
- struct wpa_authenticator *auth;
- unsigned int pairwise_cipher;
- unsigned int group_cipher;
- u8 mgtk[WPA_TK_MAX_LEN];
- size_t mgtk_len;
- u8 mgtk_key_id;
- unsigned int mgmt_group_cipher;
- u8 igtk_key_id;
- u8 igtk[WPA_TK_MAX_LEN];
- size_t igtk_len;
-#ifdef CONFIG_SAE
- struct wpabuf *sae_token;
- int sae_group_index;
-#endif /* CONFIG_SAE */
-};
-
-struct mesh_rsn * mesh_rsn_auth_init(struct wpa_supplicant *wpa_s,
- struct mesh_conf *conf);
-int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta);
-int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta);
-void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid);
-void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s,
- struct sta_info *sta);
-int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
- const u8 *cat, struct wpabuf *buf);
-int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
- struct ieee802_11_elems *elems, const u8 *cat,
- const u8 *chosen_pmk,
- const u8 *start, size_t elems_len);
-void mesh_auth_timer(void *eloop_ctx, void *user_data);
-
-#endif /* MESH_RSN_H */
diff --git a/wpa_supplicant/nfc_pw_token.c b/wpa_supplicant/nfc_pw_token.c
deleted file mode 100644
index 11afb5b97fbf..000000000000
--- a/wpa_supplicant/nfc_pw_token.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * nfc_pw_token - Tool for building NFC password tokens for WPS
- * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "utils/common.h"
-#include "crypto/random.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "wps_supplicant.h"
-
-
-static void print_bin(const char *title, const struct wpabuf *buf)
-{
- size_t i, len;
- const u8 *pos;
-
- if (buf == NULL)
- return;
-
- printf("%s=", title);
-
- pos = wpabuf_head(buf);
- len = wpabuf_len(buf);
- for (i = 0; i < len; i++)
- printf("%02X", *pos++);
-
- printf("\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- struct wpa_supplicant wpa_s;
- int ret = -1;
- struct wpabuf *buf = NULL, *ndef = NULL;
- char txt[1000];
-
- if (os_program_init())
- return -1;
- random_init(NULL);
-
- os_memset(&wpa_s, 0, sizeof(wpa_s));
- wpa_s.conf = os_zalloc(sizeof(*wpa_s.conf));
- if (wpa_s.conf == NULL)
- goto fail;
-
- buf = wpas_wps_nfc_token(&wpa_s, 0);
- if (buf == NULL)
- goto fail;
-
- ndef = ndef_build_wifi(buf);
- if (ndef == NULL)
- goto fail;
-
- wpa_snprintf_hex_uppercase(txt, sizeof(txt), wpabuf_head(buf),
- wpabuf_len(buf));
- printf("#WPS=%s\n", txt);
-
- wpa_snprintf_hex_uppercase(txt, sizeof(txt), wpabuf_head(ndef),
- wpabuf_len(ndef));
- printf("#NDEF=%s\n", txt);
-
- printf("wps_nfc_dev_pw_id=%d\n", wpa_s.conf->wps_nfc_dev_pw_id);
- print_bin("wps_nfc_dh_pubkey", wpa_s.conf->wps_nfc_dh_pubkey);
- print_bin("wps_nfc_dh_privkey", wpa_s.conf->wps_nfc_dh_privkey);
- print_bin("wps_nfc_dev_pw", wpa_s.conf->wps_nfc_dev_pw);
-
- ret = 0;
-fail:
- wpabuf_free(ndef);
- wpabuf_free(buf);
- wpa_config_free(wpa_s.conf);
- random_deinit();
- os_program_deinit();
-
- return ret;
-}
diff --git a/wpa_supplicant/nmake.mak b/wpa_supplicant/nmake.mak
deleted file mode 100644
index 617df036a9d2..000000000000
--- a/wpa_supplicant/nmake.mak
+++ /dev/null
@@ -1,240 +0,0 @@
-# Makefile for Microsoft nmake to build wpa_supplicant
-
-# This can be run in Visual Studio 2005 Command Prompt
-
-# Note: Make sure that cl.exe is configured to include Platform SDK
-# include and lib directories (vsvars32.bat)
-
-all: wpa_supplicant.exe wpa_cli.exe wpa_passphrase.exe wpasvc.exe win_if_list.exe
-
-# Root directory for WinPcap developer's pack
-# (http://www.winpcap.org/install/bin/WpdPack_3_1.zip)
-WINPCAPDIR=C:\dev\WpdPack
-
-# Root directory for OpenSSL
-# (http://www.openssl.org/source/openssl-0.9.8a.tar.gz)
-# Build and installed following instructions in INSTALL.W32
-# Note: If EAP-FAST is included in the build, OpenSSL needs to be patched to
-# support it (openssl-tls-extensions.patch)
-# Alternatively, see README-Windows.txt for information about binary
-# installation package for OpenSSL.
-OPENSSLDIR=C:\dev\openssl
-
-CC = cl
-OBJDIR = objs
-
-CFLAGS = /DCONFIG_NATIVE_WINDOWS
-CFLAGS = $(CFLAGS) /DCONFIG_NDIS_EVENTS_INTEGRATED
-CFLAGS = $(CFLAGS) /DCONFIG_ANSI_C_EXTRA
-CFLAGS = $(CFLAGS) /DCONFIG_WINPCAP
-CFLAGS = $(CFLAGS) /DIEEE8021X_EAPOL
-CFLAGS = $(CFLAGS) /DPKCS12_FUNCS
-CFLAGS = $(CFLAGS) /DEAP_MD5
-CFLAGS = $(CFLAGS) /DEAP_TLS
-CFLAGS = $(CFLAGS) /DEAP_MSCHAPv2
-CFLAGS = $(CFLAGS) /DEAP_PEAP
-CFLAGS = $(CFLAGS) /DEAP_TTLS
-CFLAGS = $(CFLAGS) /DEAP_GTC
-CFLAGS = $(CFLAGS) /DEAP_OTP
-CFLAGS = $(CFLAGS) /DEAP_SIM
-CFLAGS = $(CFLAGS) /DEAP_LEAP
-CFLAGS = $(CFLAGS) /DEAP_PSK
-CFLAGS = $(CFLAGS) /DEAP_AKA
-#CFLAGS = $(CFLAGS) /DEAP_FAST
-CFLAGS = $(CFLAGS) /DEAP_PAX
-CFLAGS = $(CFLAGS) /DEAP_TNC
-CFLAGS = $(CFLAGS) /DPCSC_FUNCS
-CFLAGS = $(CFLAGS) /DCONFIG_CTRL_IFACE
-CFLAGS = $(CFLAGS) /DCONFIG_CTRL_IFACE_NAMED_PIPE
-CFLAGS = $(CFLAGS) /DCONFIG_DRIVER_NDIS
-CFLAGS = $(CFLAGS) /I..\src /I..\src\utils
-CFLAGS = $(CFLAGS) /I.
-CFLAGS = $(CFLAGS) /DWIN32
-CFLAGS = $(CFLAGS) /Fo$(OBJDIR)\\ /c
-CFLAGS = $(CFLAGS) /W3
-
-#CFLAGS = $(CFLAGS) /WX
-
-# VS 2005 complains about lot of deprecated string functions; let's ignore them
-# at least for now since snprintf and strncpy can be used in a safe way
-CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE
-
-OBJS = \
- $(OBJDIR)\os_win32.obj \
- $(OBJDIR)\eloop_win.obj \
- $(OBJDIR)\sha1.obj \
- $(OBJDIR)\sha1-tlsprf.obj \
- $(OBJDIR)\sha1-pbkdf2.obj \
- $(OBJDIR)\md5.obj \
- $(OBJDIR)\aes-cbc.obj \
- $(OBJDIR)\aes-ctr.obj \
- $(OBJDIR)\aes-eax.obj \
- $(OBJDIR)\aes-encblock.obj \
- $(OBJDIR)\aes-omac1.obj \
- $(OBJDIR)\aes-unwrap.obj \
- $(OBJDIR)\aes-wrap.obj \
- $(OBJDIR)\common.obj \
- $(OBJDIR)\wpa_debug.obj \
- $(OBJDIR)\wpabuf.obj \
- $(OBJDIR)\wpa_supplicant.obj \
- $(OBJDIR)\wpa.obj \
- $(OBJDIR)\wpa_common.obj \
- $(OBJDIR)\wpa_ie.obj \
- $(OBJDIR)\preauth.obj \
- $(OBJDIR)\pmksa_cache.obj \
- $(OBJDIR)\eapol_supp_sm.obj \
- $(OBJDIR)\eap.obj \
- $(OBJDIR)\eap_common.obj \
- $(OBJDIR)\chap.obj \
- $(OBJDIR)\eap_methods.obj \
- $(OBJDIR)\eap_md5.obj \
- $(OBJDIR)\eap_tls.obj \
- $(OBJDIR)\eap_tls_common.obj \
- $(OBJDIR)\eap_mschapv2.obj \
- $(OBJDIR)\mschapv2.obj \
- $(OBJDIR)\eap_peap.obj \
- $(OBJDIR)\eap_peap_common.obj \
- $(OBJDIR)\eap_ttls.obj \
- $(OBJDIR)\eap_gtc.obj \
- $(OBJDIR)\eap_otp.obj \
- $(OBJDIR)\eap_leap.obj \
- $(OBJDIR)\eap_sim.obj \
- $(OBJDIR)\eap_sim_common.obj \
- $(OBJDIR)\eap_aka.obj \
- $(OBJDIR)\eap_pax.obj \
- $(OBJDIR)\eap_pax_common.obj \
- $(OBJDIR)\eap_psk.obj \
- $(OBJDIR)\eap_psk_common.obj \
- $(OBJDIR)\eap_tnc.obj \
- $(OBJDIR)\tncc.obj \
- $(OBJDIR)\base64.obj \
- $(OBJDIR)\ctrl_iface.obj \
- $(OBJDIR)\ctrl_iface_named_pipe.obj \
- $(OBJDIR)\driver_ndis.obj \
- $(OBJDIR)\driver_ndis_.obj \
- $(OBJDIR)\scan_helpers.obj \
- $(OBJDIR)\events.obj \
- $(OBJDIR)\bssid_ignore.obj \
- $(OBJDIR)\scan.obj \
- $(OBJDIR)\wpas_glue.obj \
- $(OBJDIR)\eap_register.obj \
- $(OBJDIR)\config.obj \
- $(OBJDIR)\l2_packet_winpcap.obj \
- $(OBJDIR)\tls_openssl.obj \
- $(OBJDIR)\ms_funcs.obj \
- $(OBJDIR)\crypto_openssl.obj \
- $(OBJDIR)\fips_prf_openssl.obj \
- $(OBJDIR)\pcsc_funcs.obj \
- $(OBJDIR)\notify.obj \
- $(OBJDIR)\ndis_events.obj
-
-# OBJS = $(OBJS) $(OBJDIR)\eap_fast.obj
-
-OBJS_t = $(OBJS) \
- $(OBJDIR)\eapol_test.obj \
- $(OBJDIR)\radius.obj \
- $(OBJDIR)\radius_client.obj \
- $(OBJDIR)\config_file.obj $(OBJDIR)\base64.obj
-
-OBJS_t2 = $(OBJS) \
- $(OBJDIR)\preauth_test.obj \
- $(OBJDIR)\config_file.obj $(OBJDIR)\base64.obj
-
-OBJS2 = $(OBJDIR)\drivers.obj \
- $(OBJDIR)\config_file.obj \
- $(OBJS2) $(OBJDIR)\main.obj
-
-OBJS3 = $(OBJDIR)\drivers.obj \
- $(OBJDIR)\config_winreg.obj \
- $(OBJS3) $(OBJDIR)\main_winsvc.obj
-
-OBJS_c = \
- $(OBJDIR)\os_win32.obj \
- $(OBJDIR)\wpa_cli.obj \
- $(OBJDIR)\wpa_ctrl.obj \
- $(OBJDIR)\common.obj
-
-OBJS_p = \
- $(OBJDIR)\os_win32.obj \
- $(OBJDIR)\common.obj \
- $(OBJDIR)\wpa_debug.obj \
- $(OBJDIR)\wpabuf.obj \
- $(OBJDIR)\sha1.obj \
- $(OBJDIR)\md5.obj \
- $(OBJDIR)\crypto_openssl.obj \
- $(OBJDIR)\sha1-pbkdf2.obj \
- $(OBJDIR)\wpa_passphrase.obj
-
-LIBS = wbemuuid.lib libcmt.lib kernel32.lib uuid.lib ole32.lib oleaut32.lib \
- ws2_32.lib Advapi32.lib Crypt32.lib Winscard.lib \
- Packet.lib wpcap.lib \
- libeay32.lib ssleay32.lib
-# If using Win32 OpenSSL binary installation from Shining Light Productions,
-# replace the last line with this for dynamic libraries
-# libeay32MT.lib ssleay32MT.lib
-# and this for static libraries
-# libeay32MT.lib ssleay32MT.lib Gdi32.lib User32.lib
-
-CFLAGS = $(CFLAGS) /I"$(WINPCAPDIR)/Include" /I"$(OPENSSLDIR)\include"
-LFLAGS = /libpath:"$(WINPCAPDIR)\Lib" /libpath:"$(OPENSSLDIR)\lib"
-
-wpa_supplicant.exe: $(OBJDIR) $(OBJS) $(OBJS2)
- link.exe /out:wpa_supplicant.exe $(LFLAGS) $(OBJS) $(OBJS2) $(LIBS)
-
-wpasvc.exe: $(OBJDIR) $(OBJS) $(OBJS3)
- link.exe /out:wpasvc.exe $(LFLAGS) $(OBJS) $(OBJS3) $(LIBS)
-
-wpa_cli.exe: $(OBJDIR) $(OBJS_c)
- link.exe /out:wpa_cli.exe $(LFLAGS) $(OBJS_c) $(LIBS)
-
-wpa_passphrase.exe: $(OBJDIR) $(OBJS_p)
- link.exe /out:wpa_passphrase.exe $(LFLAGS) $(OBJS_p) $(LIBS)
-
-eapol_test.exe: $(OBJDIR) $(OBJS_t)
- link.exe /out:eapol_test.exe $(LFLAGS) $(OBJS_t) $(LIBS)
-
-preauth_test.exe: $(OBJDIR) $(OBJS_t2)
- link.exe /out:preauth_test.exe $(LFLAGS) $(OBJS_t2) $(LIBS)
-
-win_if_list.exe: $(OBJDIR) $(OBJDIR)\win_if_list.obj
- link.exe /out:win_if_list.exe $(LFLAGS) $(OBJDIR)\win_if_list.obj $(LIBS)
-
-
-{..\src\utils}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\common}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\rsn_supp}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\eapol_supp}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\crypto}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\eap_peer}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\eap_common}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\drivers}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{..\src\l2_packet}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{.\}.c{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-{.\}.cpp{$(OBJDIR)}.obj::
- $(CC) $(CFLAGS) $<
-
-$(OBJDIR):
- if not exist "$(OBJDIR)" mkdir "$(OBJDIR)"
-
-clean:
- erase $(OBJDIR)\*.obj wpa_supplicant.exe
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
deleted file mode 100644
index 821c916c153f..000000000000
--- a/wpa_supplicant/notify.c
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * wpa_supplicant - Event notifications
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/wpa_ctrl.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "wps_supplicant.h"
-#include "binder/binder.h"
-#include "dbus/dbus_common.h"
-#include "dbus/dbus_new.h"
-#include "rsn_supp/wpa.h"
-#include "fst/fst.h"
-#include "crypto/tls.h"
-#include "bss.h"
-#include "driver_i.h"
-#include "scan.h"
-#include "p2p_supplicant.h"
-#include "sme.h"
-#include "notify.h"
-
-int wpas_notify_supplicant_initialized(struct wpa_global *global)
-{
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- if (global->params.dbus_ctrl_interface) {
- global->dbus = wpas_dbus_init(global);
- if (global->dbus == NULL)
- return -1;
- }
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-
-#ifdef CONFIG_BINDER
- global->binder = wpas_binder_init(global);
- if (!global->binder)
- return -1;
-#endif /* CONFIG_BINDER */
-
- return 0;
-}
-
-
-void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
-{
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- if (global->dbus)
- wpas_dbus_deinit(global->dbus);
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-
-#ifdef CONFIG_BINDER
- if (global->binder)
- wpas_binder_deinit(global->binder);
-#endif /* CONFIG_BINDER */
-}
-
-
-int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return 0;
-
- if (wpas_dbus_register_interface(wpa_s))
- return -1;
-
- return 0;
-}
-
-
-void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- /* unregister interface in new DBus ctrl iface */
- wpas_dbus_unregister_interface(wpa_s);
-}
-
-
-void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
- enum wpa_states new_state,
- enum wpa_states old_state)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- /* notify the new DBus API */
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
-
-#ifdef CONFIG_FST
- if (wpa_s->fst && !is_zero_ether_addr(wpa_s->bssid)) {
- if (new_state == WPA_COMPLETED)
- fst_notify_peer_connected(wpa_s->fst, wpa_s->bssid);
- else if (old_state >= WPA_ASSOCIATED &&
- new_state < WPA_ASSOCIATED)
- fst_notify_peer_disconnected(wpa_s->fst, wpa_s->bssid);
- }
-#endif /* CONFIG_FST */
-
- if (new_state == WPA_COMPLETED)
- wpas_p2p_notif_connected(wpa_s);
- else if (old_state >= WPA_ASSOCIATED && new_state < WPA_ASSOCIATED)
- wpas_p2p_notif_disconnected(wpa_s);
-
- sme_state_changed(wpa_s);
-
-#ifdef ANDROID
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
- "id=%d state=%d BSSID=" MACSTR " SSID=%s",
- wpa_s->current_ssid ? wpa_s->current_ssid->id : -1,
- new_state,
- MAC2STR(wpa_s->bssid),
- wpa_s->current_ssid && wpa_s->current_ssid->ssid ?
- wpa_ssid_txt(wpa_s->current_ssid->ssid,
- wpa_s->current_ssid->ssid_len) : "");
-#endif /* ANDROID */
-}
-
-
-void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_DISCONNECT_REASON);
-}
-
-
-void wpas_notify_auth_status_code(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AUTH_STATUS_CODE);
-}
-
-
-void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ASSOC_STATUS_CODE);
-}
-
-
-void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_TIME);
-}
-
-
-void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ROAM_COMPLETE);
-}
-
-
-void wpas_notify_session_length(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SESSION_LENGTH);
-}
-
-
-void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
-}
-
-
-void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK);
-}
-
-
-void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_AP_SCAN);
-}
-
-
-void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_BSS);
-}
-
-
-void wpas_notify_auth_changed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_AUTH_MODE);
-}
-
-
-void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_network_enabled_changed(wpa_s, ssid);
-}
-
-
-void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_network_selected(wpa_s, ssid->id);
-}
-
-
-void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- enum wpa_ctrl_req_type rtype,
- const char *default_txt)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
-}
-
-
-void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- /* notify the new DBus API */
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
-}
-
-
-void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_scan_done(wpa_s, success);
-}
-
-
-void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_wps_notify_scan_results(wpa_s);
-}
-
-
-void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- /* notify the new DBus API */
- wpas_dbus_signal_wps_cred(wpa_s, cred);
-#endif /* CONFIG_WPS */
-}
-
-
-void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- wpas_dbus_signal_wps_event_m2d(wpa_s, m2d);
-#endif /* CONFIG_WPS */
-}
-
-
-void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- wpas_dbus_signal_wps_event_fail(wpa_s, fail);
-#endif /* CONFIG_WPS */
-}
-
-
-void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- wpas_dbus_signal_wps_event_success(wpa_s);
-#endif /* CONFIG_WPS */
-}
-
-void wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- wpas_dbus_signal_wps_event_pbc_overlap(wpa_s);
-#endif /* CONFIG_WPS */
-}
-
-
-void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- /*
- * Networks objects created during any P2P activities should not be
- * exposed out. They might/will confuse certain non-P2P aware
- * applications since these network objects won't behave like
- * regular ones.
- */
- if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
- wpas_dbus_register_network(wpa_s, ssid);
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_ADDED "%d",
- ssid->id);
- }
-}
-
-
-void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_P2P
- wpas_dbus_register_persistent_group(wpa_s, ssid);
-#endif /* CONFIG_P2P */
-}
-
-
-void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_P2P
- wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
-#endif /* CONFIG_P2P */
-}
-
-
-void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->next_ssid == ssid)
- wpa_s->next_ssid = NULL;
- if (wpa_s->wpa)
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
- if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s &&
- !wpa_s->p2p_mgmt) {
- wpas_dbus_unregister_network(wpa_s, ssid->id);
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_REMOVED "%d",
- ssid->id);
- }
- if (network_is_persistent_group(ssid))
- wpas_notify_persistent_group_removed(wpa_s, ssid);
-
- wpas_p2p_network_removed(wpa_s, ssid);
-
-#ifdef CONFIG_PASN
- if (wpa_s->pasn.ssid == ssid)
- wpa_s->pasn.ssid = NULL;
-#endif /* CONFIG_PASN */
-}
-
-
-void wpas_notify_bss_added(struct wpa_supplicant *wpa_s,
- u8 bssid[], unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_register_bss(wpa_s, bssid, id);
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_ADDED "%u " MACSTR,
- id, MAC2STR(bssid));
-}
-
-
-void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s,
- u8 bssid[], unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_unregister_bss(wpa_s, bssid, id);
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_BSS_REMOVED "%u " MACSTR,
- id, MAC2STR(bssid));
-}
-
-
-void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
-}
-
-
-void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_SIGNAL,
- id);
-}
-
-
-void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_PRIVACY,
- id);
-}
-
-
-void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_MODE, id);
-}
-
-
-void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id);
-}
-
-
-void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id);
-}
-
-
-void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
-#ifdef CONFIG_WPS
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPS, id);
-#endif /* CONFIG_WPS */
-}
-
-
-void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id);
-}
-
-
-void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
- unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RATES, id);
-}
-
-
-void wpas_notify_bss_seen(struct wpa_supplicant *wpa_s, unsigned int id)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_AGE, id);
-}
-
-
-void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_blob_added(wpa_s, name);
-}
-
-
-void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_blob_removed(wpa_s, name);
-}
-
-
-void wpas_notify_debug_level_changed(struct wpa_global *global)
-{
- wpas_dbus_signal_debug_level_changed(global);
-}
-
-
-void wpas_notify_debug_timestamp_changed(struct wpa_global *global)
-{
- wpas_dbus_signal_debug_timestamp_changed(global);
-}
-
-
-void wpas_notify_debug_show_keys_changed(struct wpa_global *global)
-{
- wpas_dbus_signal_debug_show_keys_changed(global);
-}
-
-
-void wpas_notify_suspend(struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s;
-
- os_get_time(&global->suspend_time);
- wpa_printf(MSG_DEBUG, "System suspend notification");
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
- wpa_drv_suspend(wpa_s);
-}
-
-
-void wpas_notify_resume(struct wpa_global *global)
-{
- struct os_time now;
- int slept;
- struct wpa_supplicant *wpa_s;
-
- if (global->suspend_time.sec == 0)
- slept = -1;
- else {
- os_get_time(&now);
- slept = now.sec - global->suspend_time.sec;
- }
- wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)",
- slept);
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- wpa_drv_resume(wpa_s);
- if (wpa_s->wpa_state == WPA_DISCONNECTED)
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- }
-}
-
-
-#ifdef CONFIG_P2P
-
-void wpas_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
-{
- /* Notify P2P find has stopped */
- wpas_dbus_signal_p2p_find_stopped(wpa_s);
-}
-
-
-void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int new_device)
-{
- if (new_device) {
- /* Create the new peer object */
- wpas_dbus_register_peer(wpa_s, dev_addr);
- }
-
- /* Notify a new peer has been detected*/
- wpas_dbus_signal_peer_device_found(wpa_s, dev_addr);
-}
-
-
-void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr)
-{
- wpas_dbus_unregister_peer(wpa_s, dev_addr);
-
- /* Create signal on interface object*/
- wpas_dbus_signal_peer_device_lost(wpa_s, dev_addr);
-}
-
-
-void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- const char *role)
-{
- wpas_dbus_signal_p2p_group_removed(wpa_s, role);
-
- wpas_dbus_unregister_p2p_group(wpa_s, ssid);
-}
-
-
-void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
- const u8 *src, u16 dev_passwd_id, u8 go_intent)
-{
- wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
-}
-
-
-void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res)
-{
- wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
-}
-
-
-void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
- int status, const u8 *bssid)
-{
- wpas_dbus_signal_p2p_invitation_result(wpa_s, status, bssid);
-}
-
-
-void wpas_notify_p2p_sd_request(struct wpa_supplicant *wpa_s,
- int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs,
- size_t tlvs_len)
-{
- wpas_dbus_signal_p2p_sd_request(wpa_s, freq, sa, dialog_token,
- update_indic, tlvs, tlvs_len);
-}
-
-
-void wpas_notify_p2p_sd_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
- wpas_dbus_signal_p2p_sd_response(wpa_s, sa, update_indic,
- tlvs, tlvs_len);
-}
-
-
-/**
- * wpas_notify_p2p_provision_discovery - Notification of provision discovery
- * @dev_addr: Who sent the request or responded to our request.
- * @request: Will be 1 if request, 0 for response.
- * @status: Valid only in case of response (0 in case of success)
- * @config_methods: WPS config methods
- * @generated_pin: PIN to be displayed in case of WPS_CONFIG_DISPLAY method
- *
- * This can be used to notify:
- * - Requests or responses
- * - Various config methods
- * - Failure condition in case of response
- */
-void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int request,
- enum p2p_prov_disc_status status,
- u16 config_methods,
- unsigned int generated_pin)
-{
- wpas_dbus_signal_p2p_provision_discovery(wpa_s, dev_addr, request,
- status, config_methods,
- generated_pin);
-}
-
-
-void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int persistent,
- int client, const u8 *ip)
-{
- /* Notify a group has been started */
- wpas_dbus_register_p2p_group(wpa_s, ssid);
-
- wpas_dbus_signal_p2p_group_started(wpa_s, client, persistent, ip);
-}
-
-
-void wpas_notify_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
- const char *reason)
-{
- /* Notify a group formation failed */
- wpas_dbus_signal_p2p_group_formation_failure(wpa_s, reason);
-}
-
-
-void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
- wpas_dbus_signal_p2p_wps_failed(wpa_s, fail);
-}
-
-
-void wpas_notify_p2p_invitation_received(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *go_dev_addr,
- const u8 *bssid, int id, int op_freq)
-{
- /* Notify a P2P Invitation Request */
- wpas_dbus_signal_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
- id, op_freq);
-}
-
-#endif /* CONFIG_P2P */
-
-
-static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *sta,
- const u8 *p2p_dev_addr)
-{
-#ifdef CONFIG_P2P
- wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
-
- /*
- * Create 'peer-joined' signal on group object -- will also
- * check P2P itself.
- */
- if (p2p_dev_addr)
- wpas_dbus_signal_p2p_peer_joined(wpa_s, p2p_dev_addr);
-#endif /* CONFIG_P2P */
-
- /* Register the station */
- wpas_dbus_register_sta(wpa_s, sta);
-
- /* Notify listeners a new station has been authorized */
- wpas_dbus_signal_sta_authorized(wpa_s, sta);
-}
-
-
-static void wpas_notify_ap_sta_deauthorized(struct wpa_supplicant *wpa_s,
- const u8 *sta,
- const u8 *p2p_dev_addr)
-{
-#ifdef CONFIG_P2P
- /*
- * Create 'peer-disconnected' signal on group object if this
- * is a P2P group.
- */
- if (p2p_dev_addr)
- wpas_dbus_signal_p2p_peer_disconnected(wpa_s, p2p_dev_addr);
-#endif /* CONFIG_P2P */
-
- /* Notify listeners a station has been deauthorized */
- wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
-
- /* Unregister the station */
- wpas_dbus_unregister_sta(wpa_s, sta);
-}
-
-
-void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized,
- const u8 *p2p_dev_addr)
-{
- if (authorized)
- wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr);
- else
- wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr, p2p_dev_addr);
-}
-
-
-void wpas_notify_certification(struct wpa_supplicant *wpa_s,
- struct tls_cert_data *cert,
- const char *cert_hash)
-{
- int i;
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
- "depth=%d subject='%s'%s%s%s%s",
- cert->depth, cert->subject, cert_hash ? " hash=" : "",
- cert_hash ? cert_hash : "",
- cert->tod == 2 ? " tod=2" : "",
- cert->tod == 1 ? " tod=1" : "");
-
- if (cert->cert) {
- char *cert_hex;
- size_t len = wpabuf_len(cert->cert) * 2 + 1;
- cert_hex = os_malloc(len);
- if (cert_hex) {
- wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert),
- wpabuf_len(cert->cert));
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- WPA_EVENT_EAP_PEER_CERT
- "depth=%d subject='%s' cert=%s",
- cert->depth, cert->subject, cert_hex);
- os_free(cert_hex);
- }
- }
-
- for (i = 0; i < cert->num_altsubject; i++)
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
- "depth=%d %s", cert->depth, cert->altsubject[i]);
-
- /* notify the new DBus API */
- wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
- cert->altsubject, cert->num_altsubject,
- cert_hash, cert->cert);
-}
-
-
-void wpas_notify_preq(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len, u32 ssi_signal)
-{
-#ifdef CONFIG_AP
- wpas_dbus_signal_preq(wpa_s, addr, dst, bssid, ie, ie_len, ssi_signal);
-#endif /* CONFIG_AP */
-}
-
-
-void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
- const char *parameter)
-{
- wpas_dbus_signal_eap_status(wpa_s, status, parameter);
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_EAP_STATUS
- "status='%s' parameter='%s'",
- status, parameter);
-}
-
-
-void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
-{
- wpa_msg(wpa_s, MSG_ERROR, WPA_EVENT_EAP_ERROR_CODE "%d", error_code);
-}
-
-
-void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->current_ssid != ssid)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Network bssid config changed for the current network - within-ESS roaming %s",
- ssid->bssid_set ? "disabled" : "enabled");
-
- wpa_drv_roaming(wpa_s, !ssid->bssid_set,
- ssid->bssid_set ? ssid->bssid : NULL);
-}
-
-
-void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_P2P
- if (ssid->disabled == 2) {
- /* Changed from normal network profile to persistent group */
- ssid->disabled = 0;
- wpas_dbus_unregister_network(wpa_s, ssid->id);
- ssid->disabled = 2;
- ssid->p2p_persistent_group = 1;
- wpas_dbus_register_persistent_group(wpa_s, ssid);
- } else {
- /* Changed from persistent group to normal network profile */
- wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
- ssid->p2p_persistent_group = 0;
- wpas_dbus_register_network(wpa_s, ssid);
- }
-#endif /* CONFIG_P2P */
-}
-
-
-#ifdef CONFIG_MESH
-
-void wpas_notify_mesh_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_mesh_group_started(wpa_s, ssid);
-}
-
-
-void wpas_notify_mesh_group_removed(struct wpa_supplicant *wpa_s,
- const u8 *meshid, u8 meshid_len,
- u16 reason_code)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_mesh_group_removed(wpa_s, meshid, meshid_len,
- reason_code);
-}
-
-
-void wpas_notify_mesh_peer_connected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_mesh_peer_connected(wpa_s, peer_addr);
-}
-
-
-void wpas_notify_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, u16 reason_code)
-{
- if (wpa_s->p2p_mgmt)
- return;
-
- wpas_dbus_signal_mesh_peer_disconnected(wpa_s, peer_addr, reason_code);
-}
-
-#endif /* CONFIG_MESH */
-
-
-#ifdef CONFIG_INTERWORKING
-
-void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_cred *cred, int excluded,
- const char *type, int bh, int bss_load,
- int conn_capab)
-{
- wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
- excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP,
- MAC2STR(bss->bssid), type,
- bh ? " below_min_backhaul=1" : "",
- bss_load ? " over_max_bss_load=1" : "",
- conn_capab ? " conn_capab_missing=1" : "",
- cred->id, cred->priority, cred->sp_priority);
-
- wpas_dbus_signal_interworking_ap_added(wpa_s, bss, cred, type, excluded,
- bh, bss_load, conn_capab);
-}
-
-
-void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s)
-{
- wpas_dbus_signal_interworking_select_done(wpa_s);
-}
-
-#endif /* CONFIG_INTERWORKING */
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
deleted file mode 100644
index c46e7986e3b3..000000000000
--- a/wpa_supplicant/notify.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * wpa_supplicant - Event notifications
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef NOTIFY_H
-#define NOTIFY_H
-
-#include "p2p/p2p.h"
-
-struct wps_credential;
-struct wps_event_m2d;
-struct wps_event_fail;
-struct tls_cert_data;
-struct wpa_cred;
-
-int wpas_notify_supplicant_initialized(struct wpa_global *global);
-void wpas_notify_supplicant_deinitialized(struct wpa_global *global);
-int wpas_notify_iface_added(struct wpa_supplicant *wpa_s);
-void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s);
-void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
- enum wpa_states new_state,
- enum wpa_states old_state);
-void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
-void wpas_notify_auth_status_code(struct wpa_supplicant *wpa_s);
-void wpas_notify_assoc_status_code(struct wpa_supplicant *wpa_s);
-void wpas_notify_roam_time(struct wpa_supplicant *wpa_s);
-void wpas_notify_roam_complete(struct wpa_supplicant *wpa_s);
-void wpas_notify_session_length(struct wpa_supplicant *wpa_s);
-void wpas_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
-void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);
-void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);
-void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);
-void wpas_notify_auth_changed(struct wpa_supplicant *wpa_s);
-void wpas_notify_network_enabled_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_network_selected(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- enum wpa_ctrl_req_type rtype,
- const char *default_txt);
-void wpas_notify_scanning(struct wpa_supplicant *wpa_s);
-void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success);
-void wpas_notify_scan_results(struct wpa_supplicant *wpa_s);
-void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
- const struct wps_credential *cred);
-void wpas_notify_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d);
-void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail);
-void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s);
-void wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s);
-void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_bss_added(struct wpa_supplicant *wpa_s, u8 bssid[],
- unsigned int id);
-void wpas_notify_bss_removed(struct wpa_supplicant *wpa_s, u8 bssid[],
- unsigned int id);
-void wpas_notify_bss_freq_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_signal_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_privacy_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
- unsigned int id);
-void wpas_notify_bss_seen(struct wpa_supplicant *wpa_s, unsigned int id);
-void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name);
-void wpas_notify_blob_removed(struct wpa_supplicant *wpa_s, const char *name);
-
-void wpas_notify_debug_level_changed(struct wpa_global *global);
-void wpas_notify_debug_timestamp_changed(struct wpa_global *global);
-void wpas_notify_debug_show_keys_changed(struct wpa_global *global);
-void wpas_notify_suspend(struct wpa_global *global);
-void wpas_notify_resume(struct wpa_global *global);
-
-void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *mac_addr, int authorized,
- const u8 *p2p_dev_addr);
-void wpas_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
-void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int new_device);
-void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr);
-void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- const char *role);
-void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
- const u8 *src, u16 dev_passwd_id, u8 go_intent);
-void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res);
-void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
- int status, const u8 *bssid);
-void wpas_notify_p2p_sd_request(struct wpa_supplicant *wpa_s,
- int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs,
- size_t tlvs_len);
-void wpas_notify_p2p_sd_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len);
-void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, int request,
- enum p2p_prov_disc_status status,
- u16 config_methods,
- unsigned int generated_pin);
-void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int persistent,
- int client, const u8 *ip);
-void wpas_notify_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
- const char *reason);
-void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail);
-
-void wpas_notify_certification(struct wpa_supplicant *wpa_s,
- struct tls_cert_data *cert,
- const char *cert_hash);
-void wpas_notify_preq(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len, u32 ssi_signal);
-void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
- const char *parameter);
-void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code);
-void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_p2p_invitation_received(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *go_dev_addr,
- const u8 *bssid, int id, int op_freq);
-void wpas_notify_mesh_group_started(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpas_notify_mesh_group_removed(struct wpa_supplicant *wpa_s,
- const u8 *meshid, u8 meshid_len,
- u16 reason_code);
-void wpas_notify_mesh_peer_connected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr);
-void wpas_notify_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, u16 reason_code);
-void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_cred *cred, int excluded,
- const char *type, int bh, int bss_load,
- int conn_capab);
-void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s);
-
-#endif /* NOTIFY_H */
diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c
deleted file mode 100644
index e40cf5bbebcd..000000000000
--- a/wpa_supplicant/offchannel.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * wpa_supplicant - Off-channel Action frame TX/RX
- * Copyright (c) 2009-2010, Atheros Communications
- * Copyright (c) 2011, Qualcomm Atheros
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "utils/eloop.h"
-#include "wpa_supplicant_i.h"
-#include "p2p_supplicant.h"
-#include "driver_i.h"
-#include "offchannel.h"
-
-
-
-static struct wpa_supplicant *
-wpas_get_tx_interface(struct wpa_supplicant *wpa_s, const u8 *src)
-{
- struct wpa_supplicant *iface;
-
- if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0) {
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_mgmt && wpa_s != wpa_s->parent &&
- wpa_s->parent->ap_iface &&
- os_memcmp(wpa_s->parent->own_addr,
- wpa_s->own_addr, ETH_ALEN) == 0 &&
- wpabuf_len(wpa_s->pending_action_tx) >= 2 &&
- *wpabuf_head_u8(wpa_s->pending_action_tx) !=
- WLAN_ACTION_PUBLIC) {
- /*
- * When P2P Device interface has same MAC address as
- * the GO interface, make sure non-Public Action frames
- * are sent through the GO interface. The P2P Device
- * interface can only send Public Action frames.
- */
- wpa_printf(MSG_DEBUG,
- "P2P: Use GO interface %s instead of interface %s for Action TX",
- wpa_s->parent->ifname, wpa_s->ifname);
- return wpa_s->parent;
- }
-#endif /* CONFIG_P2P */
- return wpa_s;
- }
-
- /*
- * Try to find a group interface that matches with the source address.
- */
- iface = wpa_s->global->ifaces;
- while (iface) {
- if (os_memcmp(src, iface->own_addr, ETH_ALEN) == 0)
- break;
- iface = iface->next;
- }
- if (iface) {
- wpa_printf(MSG_DEBUG, "P2P: Use group interface %s "
- "instead of interface %s for Action TX",
- iface->ifname, wpa_s->ifname);
- return iface;
- }
-
- return wpa_s;
-}
-
-
-static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_supplicant *iface;
- int res;
- int without_roc;
-
- without_roc = wpa_s->pending_action_without_roc;
- wpa_s->pending_action_without_roc = 0;
- wpa_printf(MSG_DEBUG,
- "Off-channel: Send Action callback (without_roc=%d pending_action_tx=%p pending_action_tx_done=%d)",
- without_roc, wpa_s->pending_action_tx,
- !!wpa_s->pending_action_tx_done);
-
- if (wpa_s->pending_action_tx == NULL || wpa_s->pending_action_tx_done)
- return;
-
- /*
- * This call is likely going to be on the P2P device instance if the
- * driver uses a separate interface for that purpose. However, some
- * Action frames are actually sent within a P2P Group and when that is
- * the case, we need to follow power saving (e.g., GO buffering the
- * frame for a client in PS mode or a client following the advertised
- * NoA from its GO). To make that easier for the driver, select the
- * correct group interface here.
- */
- iface = wpas_get_tx_interface(wpa_s, wpa_s->pending_action_src);
-
- if (wpa_s->off_channel_freq != wpa_s->pending_action_freq &&
- wpa_s->pending_action_freq != 0 &&
- wpa_s->pending_action_freq != iface->assoc_freq) {
- wpa_printf(MSG_DEBUG, "Off-channel: Pending Action frame TX "
- "waiting for another freq=%u (off_channel_freq=%u "
- "assoc_freq=%u)",
- wpa_s->pending_action_freq,
- wpa_s->off_channel_freq,
- iface->assoc_freq);
- if (without_roc && wpa_s->off_channel_freq == 0) {
- unsigned int duration = 200;
- /*
- * We may get here if wpas_send_action() found us to be
- * on the correct channel, but remain-on-channel cancel
- * event was received before getting here.
- */
- wpa_printf(MSG_DEBUG, "Off-channel: Schedule "
- "remain-on-channel to send Action frame");
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->extra_roc_dur) {
- wpa_printf(MSG_DEBUG,
- "TESTING: Increase ROC duration %u -> %u",
- duration,
- duration + wpa_s->extra_roc_dur);
- duration += wpa_s->extra_roc_dur;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_drv_remain_on_channel(
- wpa_s, wpa_s->pending_action_freq,
- duration) < 0) {
- wpa_printf(MSG_DEBUG, "Off-channel: Failed to "
- "request driver to remain on "
- "channel (%u MHz) for Action Frame "
- "TX", wpa_s->pending_action_freq);
- } else {
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq =
- wpa_s->pending_action_freq;
- }
- }
- return;
- }
-
- wpa_printf(MSG_DEBUG, "Off-channel: Sending pending Action frame to "
- MACSTR " using interface %s (pending_action_tx=%p)",
- MAC2STR(wpa_s->pending_action_dst), iface->ifname,
- wpa_s->pending_action_tx);
- res = wpa_drv_send_action(iface, wpa_s->pending_action_freq, 0,
- wpa_s->pending_action_dst,
- wpa_s->pending_action_src,
- wpa_s->pending_action_bssid,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx),
- wpa_s->pending_action_no_cck);
- if (res) {
- wpa_printf(MSG_DEBUG, "Off-channel: Failed to send the "
- "pending Action frame");
- /*
- * Use fake TX status event to allow state machines to
- * continue.
- */
- offchannel_send_action_tx_status(
- wpa_s, wpa_s->pending_action_dst,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx),
- OFFCHANNEL_SEND_ACTION_FAILED);
- }
-}
-
-
-/**
- * offchannel_send_action_tx_status - TX status callback
- * @wpa_s: Pointer to wpa_supplicant data
- * @dst: Destination MAC address of the transmitted Action frame
- * @data: Transmitted frame payload
- * @data_len: Length of @data in bytes
- * @result: TX status
- *
- * This function is called whenever the driver indicates a TX status event for
- * a frame sent by offchannel_send_action() using wpa_drv_send_action().
- */
-void offchannel_send_action_tx_status(
- struct wpa_supplicant *wpa_s, const u8 *dst, const u8 *data,
- size_t data_len, enum offchannel_send_action_result result)
-{
- if (wpa_s->pending_action_tx == NULL) {
- wpa_printf(MSG_DEBUG, "Off-channel: Ignore Action TX status - "
- "no pending operation");
- return;
- }
-
- if (os_memcmp(dst, wpa_s->pending_action_dst, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "Off-channel: Ignore Action TX status - "
- "unknown destination address");
- return;
- }
-
- /* Accept report only if the contents of the frame matches */
- if (data_len - wpabuf_len(wpa_s->pending_action_tx) != 24 ||
- os_memcmp(data + 24, wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx)) != 0) {
- wpa_printf(MSG_DEBUG, "Off-channel: Ignore Action TX status - "
- "mismatching contents with pending frame");
- wpa_hexdump(MSG_MSGDUMP, "TX status frame data",
- data, data_len);
- wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame",
- wpa_s->pending_action_tx);
- return;
- }
-
- wpa_printf(MSG_DEBUG,
- "Off-channel: Delete matching pending action frame (dst="
- MACSTR " pending_action_tx=%p)", MAC2STR(dst),
- wpa_s->pending_action_tx);
- wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame",
- wpa_s->pending_action_tx);
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
-
- wpa_printf(MSG_DEBUG, "Off-channel: TX status result=%d cb=%p",
- result, wpa_s->pending_action_tx_status_cb);
-
- if (wpa_s->pending_action_tx_status_cb) {
- wpa_s->pending_action_tx_status_cb(
- wpa_s, wpa_s->pending_action_freq,
- wpa_s->pending_action_dst, wpa_s->pending_action_src,
- wpa_s->pending_action_bssid,
- data, data_len, result);
- }
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p_long_listen > 0) {
- /* Continue the listen */
- wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
- wpas_p2p_listen_start(wpa_s, wpa_s->global->p2p_long_listen);
- }
-#endif /* CONFIG_P2P */
-}
-
-
-/**
- * offchannel_send_action - Request off-channel Action frame TX
- * @wpa_s: Pointer to wpa_supplicant data
- * @freq: The frequency in MHz indicating the channel on which the frame is to
- * transmitted or 0 for the current channel (only if associated)
- * @dst: Action frame destination MAC address
- * @src: Action frame source MAC address
- * @bssid: Action frame BSSID
- * @buf: Frame to transmit starting from the Category field
- * @len: Length of @buf in bytes
- * @wait_time: Wait time for response in milliseconds
- * @tx_cb: Callback function for indicating TX status or %NULL for no callback
- * @no_cck: Whether CCK rates are to be disallowed for TX rate selection
- * Returns: 0 on success or -1 on failure
- *
- * This function is used to request an Action frame to be transmitted on the
- * current operating channel or on another channel (off-channel). The actual
- * frame transmission will be delayed until the driver is ready on the specified
- * channel. The @wait_time parameter can be used to request the driver to remain
- * awake on the channel to wait for a response.
- */
-int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
- const u8 *dst, const u8 *src, const u8 *bssid,
- const u8 *buf, size_t len, unsigned int wait_time,
- void (*tx_cb)(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result
- result),
- int no_cck)
-{
- wpa_printf(MSG_DEBUG, "Off-channel: Send action frame: freq=%d dst="
- MACSTR " src=" MACSTR " bssid=" MACSTR " len=%d",
- freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
- (int) len);
-
- wpa_s->pending_action_tx_status_cb = tx_cb;
-
- if (wpa_s->pending_action_tx) {
- wpa_printf(MSG_DEBUG, "Off-channel: Dropped pending Action "
- "frame TX to " MACSTR " (pending_action_tx=%p)",
- MAC2STR(wpa_s->pending_action_dst),
- wpa_s->pending_action_tx);
- wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame",
- wpa_s->pending_action_tx);
- wpabuf_free(wpa_s->pending_action_tx);
- }
- wpa_s->pending_action_tx_done = 0;
- wpa_s->pending_action_tx = wpabuf_alloc(len);
- if (wpa_s->pending_action_tx == NULL) {
- wpa_printf(MSG_DEBUG, "Off-channel: Failed to allocate Action "
- "frame TX buffer (len=%llu)",
- (unsigned long long) len);
- return -1;
- }
- wpabuf_put_data(wpa_s->pending_action_tx, buf, len);
- os_memcpy(wpa_s->pending_action_src, src, ETH_ALEN);
- os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN);
- os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
- wpa_s->pending_action_freq = freq;
- wpa_s->pending_action_no_cck = no_cck;
- wpa_printf(MSG_DEBUG,
- "Off-channel: Stored pending action frame (dst=" MACSTR
- " pending_action_tx=%p)",
- MAC2STR(dst), wpa_s->pending_action_tx);
- wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame",
- wpa_s->pending_action_tx);
-
- if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
- struct wpa_supplicant *iface;
- int ret;
-
- iface = wpas_get_tx_interface(wpa_s, src);
- wpa_s->action_tx_wait_time = wait_time;
- if (wait_time)
- wpa_s->action_tx_wait_time_used = 1;
-
- ret = wpa_drv_send_action(
- iface, wpa_s->pending_action_freq,
- wait_time, wpa_s->pending_action_dst,
- wpa_s->pending_action_src, wpa_s->pending_action_bssid,
- wpabuf_head(wpa_s->pending_action_tx),
- wpabuf_len(wpa_s->pending_action_tx),
- wpa_s->pending_action_no_cck);
- if (ret == 0)
- wpa_s->pending_action_tx_done = 1;
- return ret;
- }
-
- if (freq) {
- struct wpa_supplicant *tx_iface;
- tx_iface = wpas_get_tx_interface(wpa_s, src);
- if (tx_iface->assoc_freq == freq) {
- wpa_printf(MSG_DEBUG, "Off-channel: Already on "
- "requested channel (TX interface operating "
- "channel)");
- freq = 0;
- }
- }
-
- if (wpa_s->off_channel_freq == freq || freq == 0) {
- wpa_printf(MSG_DEBUG, "Off-channel: Already on requested "
- "channel; send Action frame immediately");
- /* TODO: Would there ever be need to extend the current
- * duration on the channel? */
- wpa_s->pending_action_without_roc = 1;
- eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
- eloop_register_timeout(0, 0, wpas_send_action_cb, wpa_s, NULL);
- return 0;
- }
- wpa_s->pending_action_without_roc = 0;
-
- if (wpa_s->roc_waiting_drv_freq == freq) {
- wpa_printf(MSG_DEBUG, "Off-channel: Already waiting for "
- "driver to get to frequency %u MHz; continue "
- "waiting to send the Action frame", freq);
- return 0;
- }
-
- wpa_printf(MSG_DEBUG, "Off-channel: Schedule Action frame to be "
- "transmitted once the driver gets to the requested "
- "channel");
- if (wait_time > wpa_s->max_remain_on_chan)
- wait_time = wpa_s->max_remain_on_chan;
- else if (wait_time == 0)
- wait_time = 20;
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->extra_roc_dur) {
- wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u",
- wait_time, wait_time + wpa_s->extra_roc_dur);
- wait_time += wpa_s->extra_roc_dur;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_drv_remain_on_channel(wpa_s, freq, wait_time) < 0) {
- wpa_printf(MSG_DEBUG, "Off-channel: Failed to request driver "
- "to remain on channel (%u MHz) for Action "
- "Frame TX", freq);
- return -1;
- }
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = freq;
-
- return 0;
-}
-
-
-/**
- * offchannel_send_send_action_done - Notify completion of Action frame sequence
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function can be used to cancel a wait for additional response frames on
- * the channel that was used with offchannel_send_action().
- */
-void offchannel_send_action_done(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG,
- "Off-channel: Action frame sequence done notification: pending_action_tx=%p drv_offchan_tx=%d action_tx_wait_time=%d off_channel_freq=%d roc_waiting_drv_freq=%d",
- wpa_s->pending_action_tx,
- !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX),
- wpa_s->action_tx_wait_time, wpa_s->off_channel_freq,
- wpa_s->roc_waiting_drv_freq);
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX &&
- (wpa_s->action_tx_wait_time || wpa_s->action_tx_wait_time_used))
- wpa_drv_send_action_cancel_wait(wpa_s);
- else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = 0;
- }
- wpa_s->action_tx_wait_time_used = 0;
-}
-
-
-/**
- * offchannel_remain_on_channel_cb - Remain-on-channel callback function
- * @wpa_s: Pointer to wpa_supplicant data
- * @freq: Frequency (in MHz) of the selected channel
- * @duration: Duration of the remain-on-channel operation in milliseconds
- *
- * This function is called whenever the driver notifies beginning of a
- * remain-on-channel operation.
- */
-void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration)
-{
- wpa_s->roc_waiting_drv_freq = 0;
- wpa_s->off_channel_freq = freq;
- wpas_send_action_cb(wpa_s, NULL);
-}
-
-
-/**
- * offchannel_cancel_remain_on_channel_cb - Remain-on-channel stopped callback
- * @wpa_s: Pointer to wpa_supplicant data
- * @freq: Frequency (in MHz) of the selected channel
- *
- * This function is called whenever the driver notifies termination of a
- * remain-on-channel operation.
- */
-void offchannel_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- wpa_s->off_channel_freq = 0;
-}
-
-
-/**
- * offchannel_pending_action_tx - Check whether there is a pending Action TX
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: Pointer to pending frame or %NULL if no pending operation
- *
- * This function can be used to check whether there is a pending Action frame TX
- * operation. The returned pointer should be used only for checking whether it
- * is %NULL (no pending frame) or to print the pointer value in debug
- * information (i.e., the pointer should not be dereferenced).
- */
-const void * offchannel_pending_action_tx(struct wpa_supplicant *wpa_s)
-{
- return wpa_s->pending_action_tx;
-}
-
-
-/**
- * offchannel_clear_pending_action_tx - Clear pending Action frame TX
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void offchannel_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG,
- "Off-channel: Clear pending Action frame TX (pending_action_tx=%p",
- wpa_s->pending_action_tx);
- wpabuf_free(wpa_s->pending_action_tx);
- wpa_s->pending_action_tx = NULL;
-}
-
-
-/**
- * offchannel_deinit - Deinit off-channel operations
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to free up any allocated resources for off-channel
- * operations.
- */
-void offchannel_deinit(struct wpa_supplicant *wpa_s)
-{
- offchannel_clear_pending_action_tx(wpa_s);
- eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
-}
diff --git a/wpa_supplicant/offchannel.h b/wpa_supplicant/offchannel.h
deleted file mode 100644
index 0ad7e18fae88..000000000000
--- a/wpa_supplicant/offchannel.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * wpa_supplicant - Off-channel Action frame TX/RX
- * Copyright (c) 2009-2010, Atheros Communications
- * Copyright (c) 2011, Qualcomm Atheros
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef OFFCHANNEL_H
-#define OFFCHANNEL_H
-
-int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
- const u8 *dst, const u8 *src, const u8 *bssid,
- const u8 *buf, size_t len, unsigned int wait_time,
- void (*tx_cb)(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result
- result),
- int no_cck);
-void offchannel_send_action_done(struct wpa_supplicant *wpa_s);
-void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration);
-void offchannel_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq);
-void offchannel_deinit(struct wpa_supplicant *wpa_s);
-void offchannel_send_action_tx_status(
- struct wpa_supplicant *wpa_s, const u8 *dst, const u8 *data,
- size_t data_len, enum offchannel_send_action_result result);
-const void * offchannel_pending_action_tx(struct wpa_supplicant *wpa_s);
-void offchannel_clear_pending_action_tx(struct wpa_supplicant *wpa_s);
-
-#endif /* OFFCHANNEL_H */
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
deleted file mode 100644
index bd53c5ceceaf..000000000000
--- a/wpa_supplicant/op_classes.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Operating classes
- * Copyright(c) 2015 Intel Deutschland GmbH
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_common.h"
-#include "wpa_supplicant_i.h"
-#include "bss.h"
-
-
-static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode,
- u8 op_class, u8 chan,
- unsigned int *flags)
-{
- int i;
- bool is_6ghz = op_class >= 131 && op_class <= 136;
-
- for (i = 0; i < mode->num_channels; i++) {
- bool chan_is_6ghz;
-
- chan_is_6ghz = mode->channels[i].freq >= 5935 &&
- mode->channels[i].freq <= 7115;
- if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
- break;
- }
-
- if (i == mode->num_channels ||
- (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED))
- return NOT_ALLOWED;
-
- if (flags)
- *flags = mode->channels[i].flag;
-
- if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
- return NO_IR;
-
- return ALLOWED;
-}
-
-
-static int get_center_80mhz(struct hostapd_hw_modes *mode, u8 channel,
- const u8 *center_channels, size_t num_chan)
-{
- size_t i;
-
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return 0;
-
- for (i = 0; i < num_chan; i++) {
- /*
- * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
- * so the center channel is 6 channels away from the start/end.
- */
- if (channel >= center_channels[i] - 6 &&
- channel <= center_channels[i] + 6)
- return center_channels[i];
- }
-
- return 0;
-}
-
-
-static enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode,
- u8 op_class, u8 channel)
-{
- u8 center_chan;
- unsigned int i;
- unsigned int no_ir = 0;
- const u8 *center_channels;
- size_t num_chan;
- const u8 center_channels_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
- const u8 center_channels_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119,
- 135, 151, 167, 183, 199, 215 };
-
- if (is_6ghz_op_class(op_class)) {
- center_channels = center_channels_6ghz;
- num_chan = ARRAY_SIZE(center_channels_6ghz);
- } else {
- center_channels = center_channels_5ghz;
- num_chan = ARRAY_SIZE(center_channels_5ghz);
- }
-
- center_chan = get_center_80mhz(mode, channel, center_channels,
- num_chan);
- if (!center_chan)
- return NOT_ALLOWED;
-
- /* check all the channels are available */
- for (i = 0; i < 4; i++) {
- unsigned int flags;
- u8 adj_chan = center_chan - 6 + i * 4;
-
- if (allow_channel(mode, op_class, adj_chan, &flags) ==
- NOT_ALLOWED)
- return NOT_ALLOWED;
-
- if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
- (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) ||
- (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) ||
- (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)))
- return NOT_ALLOWED;
-
- if (flags & HOSTAPD_CHAN_NO_IR)
- no_ir = 1;
- }
-
- if (no_ir)
- return NO_IR;
-
- return ALLOWED;
-}
-
-
-static int get_center_160mhz(struct hostapd_hw_modes *mode, u8 channel,
- const u8 *center_channels, size_t num_chan)
-{
- unsigned int i;
-
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return 0;
-
- for (i = 0; i < num_chan; i++) {
- /*
- * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
- * so the center channel is 14 channels away from the start/end.
- */
- if (channel >= center_channels[i] - 14 &&
- channel <= center_channels[i] + 14)
- return center_channels[i];
- }
-
- return 0;
-}
-
-
-static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
- u8 op_class, u8 channel)
-{
- u8 center_chan;
- unsigned int i;
- unsigned int no_ir = 0;
- const u8 *center_channels;
- size_t num_chan;
- const u8 center_channels_5ghz[] = { 50, 114, 163 };
- const u8 center_channels_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
-
- if (is_6ghz_op_class(op_class)) {
- center_channels = center_channels_6ghz;
- num_chan = ARRAY_SIZE(center_channels_6ghz);
- } else {
- center_channels = center_channels_5ghz;
- num_chan = ARRAY_SIZE(center_channels_5ghz);
- }
-
- center_chan = get_center_160mhz(mode, channel, center_channels,
- num_chan);
- if (!center_chan)
- return NOT_ALLOWED;
-
- /* Check all the channels are available */
- for (i = 0; i < 8; i++) {
- unsigned int flags;
- u8 adj_chan = center_chan - 14 + i * 4;
-
- if (allow_channel(mode, op_class, adj_chan, &flags) ==
- NOT_ALLOWED)
- return NOT_ALLOWED;
-
- if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
- (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130)) ||
- (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110)) ||
- (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90)) ||
- (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70)) ||
- (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50)) ||
- (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30)) ||
- (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10)))
- return NOT_ALLOWED;
-
- if (flags & HOSTAPD_CHAN_NO_IR)
- no_ir = 1;
- }
-
- if (no_ir)
- return NO_IR;
-
- return ALLOWED;
-}
-
-
-enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
- u8 channel, u8 bw)
-{
- unsigned int flag = 0;
- enum chan_allowed res, res2;
-
- res2 = res = allow_channel(mode, op_class, channel, &flag);
- if (bw == BW40MINUS || (bw == BW40 && (((channel - 1) / 4) % 2))) {
- if (!(flag & HOSTAPD_CHAN_HT40MINUS))
- return NOT_ALLOWED;
- res2 = allow_channel(mode, op_class, channel - 4, NULL);
- } else if (bw == BW40PLUS) {
- if (!(flag & HOSTAPD_CHAN_HT40PLUS))
- return NOT_ALLOWED;
- res2 = allow_channel(mode, op_class, channel + 4, NULL);
- } else if (is_6ghz_op_class(op_class) && bw == BW40) {
- if (get_6ghz_sec_channel(channel) < 0)
- res2 = allow_channel(mode, op_class, channel - 4, NULL);
- else
- res2 = allow_channel(mode, op_class, channel + 4, NULL);
- } else if (bw == BW80) {
- /*
- * channel is a center channel and as such, not necessarily a
- * valid 20 MHz channels. Override earlier allow_channel()
- * result and use only the 80 MHz specific version.
- */
- res2 = res = verify_80mhz(mode, op_class, channel);
- } else if (bw == BW160) {
- /*
- * channel is a center channel and as such, not necessarily a
- * valid 20 MHz channels. Override earlier allow_channel()
- * result and use only the 160 MHz specific version.
- */
- res2 = res = verify_160mhz(mode, op_class, channel);
- } else if (bw == BW80P80) {
- /*
- * channel is a center channel and as such, not necessarily a
- * valid 20 MHz channels. Override earlier allow_channel()
- * result and use only the 80 MHz specific version.
- */
- res2 = res = verify_80mhz(mode, op_class, channel);
- }
-
- if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
- return NOT_ALLOWED;
-
- if (res == NO_IR || res2 == NO_IR)
- return NO_IR;
-
- return ALLOWED;
-}
-
-
-static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const struct oper_class_map *op_class)
-{
- int chan;
- size_t i;
- struct hostapd_hw_modes *mode;
- int found;
- int z;
- int freq2 = 0;
- int freq5 = 0;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode,
- is_6ghz_op_class(op_class->op_class));
- if (!mode)
- return 0;
-
- /* If we are configured to disable certain things, take that into
- * account here. */
- if (ssid && ssid->freq_list && ssid->freq_list[0]) {
- for (z = 0; ; z++) {
- int f = ssid->freq_list[z];
-
- if (f == 0)
- break; /* end of list */
- if (f > 4000 && f < 6000)
- freq5 = 1;
- else if (f > 2400 && f < 2500)
- freq2 = 1;
- }
- } else {
- /* No frequencies specified, can use anything hardware supports.
- */
- freq2 = freq5 = 1;
- }
-
- if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5)
- return 0;
- if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2)
- return 0;
-
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid && ssid->disable_ht) {
- switch (op_class->op_class) {
- case 83:
- case 84:
- case 104:
- case 105:
- case 116:
- case 117:
- case 119:
- case 120:
- case 122:
- case 123:
- case 126:
- case 127:
- case 128:
- case 129:
- case 130:
- /* Disable >= 40 MHz channels if HT is disabled */
- return 0;
- }
- }
-#endif /* CONFIG_HT_OVERRIDES */
-
-#ifdef CONFIG_VHT_OVERRIDES
- if (ssid && ssid->disable_vht) {
- if (op_class->op_class >= 128 && op_class->op_class <= 130) {
- /* Disable >= 80 MHz channels if VHT is disabled */
- return 0;
- }
- }
-#endif /* CONFIG_VHT_OVERRIDES */
-
- if (op_class->op_class == 128) {
- u8 channels[] = { 42, 58, 106, 122, 138, 155, 171 };
-
- for (i = 0; i < ARRAY_SIZE(channels); i++) {
- if (verify_channel(mode, op_class->op_class,
- channels[i], op_class->bw) !=
- NOT_ALLOWED)
- return 1;
- }
-
- return 0;
- }
-
- if (op_class->op_class == 129) {
- /* Check if either 160 MHz channels is allowed */
- return verify_channel(mode, op_class->op_class, 50,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 114,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 163,
- op_class->bw) != NOT_ALLOWED;
- }
-
- if (op_class->op_class == 130) {
- /* Need at least two non-contiguous 80 MHz segments */
- found = 0;
-
- if (verify_channel(mode, op_class->op_class, 42,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 58,
- op_class->bw) != NOT_ALLOWED)
- found++;
- if (verify_channel(mode, op_class->op_class, 106,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 122,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 138,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 155,
- op_class->bw) != NOT_ALLOWED ||
- verify_channel(mode, op_class->op_class, 171,
- op_class->bw) != NOT_ALLOWED)
- found++;
- if (verify_channel(mode, op_class->op_class, 106,
- op_class->bw) != NOT_ALLOWED &&
- verify_channel(mode, op_class->op_class, 138,
- op_class->bw) != NOT_ALLOWED)
- found++;
- if (verify_channel(mode, op_class->op_class, 122,
- op_class->bw) != NOT_ALLOWED &&
- verify_channel(mode, op_class->op_class, 155,
- op_class->bw) != NOT_ALLOWED)
- found++;
- if (verify_channel(mode, op_class->op_class, 138,
- op_class->bw) != NOT_ALLOWED &&
- verify_channel(mode, op_class->op_class, 171,
- op_class->bw) != NOT_ALLOWED)
- found++;
-
- if (found >= 2)
- return 1;
-
- return 0;
- }
-
- if (op_class->op_class == 135) {
- /* Need at least two 80 MHz segments which do not fall under the
- * same 160 MHz segment to support 80+80 in 6 GHz.
- */
- int first_seg = 0;
- int curr_seg = 0;
-
- for (chan = op_class->min_chan; chan <= op_class->max_chan;
- chan += op_class->inc) {
- curr_seg++;
- if (verify_channel(mode, op_class->op_class, chan,
- op_class->bw) != NOT_ALLOWED) {
- if (!first_seg) {
- first_seg = curr_seg;
- continue;
- }
-
- /* Supported if at least two non-consecutive 80
- * MHz segments allowed.
- */
- if ((curr_seg - first_seg) > 1)
- return 1;
-
- /* Supported even if the 80 MHz segments are
- * consecutive when they do not fall under the
- * same 160 MHz segment.
- */
- if ((first_seg % 2) == 0)
- return 1;
- }
- }
-
- return 0;
- }
-
- found = 0;
- for (chan = op_class->min_chan; chan <= op_class->max_chan;
- chan += op_class->inc) {
- if (verify_channel(mode, op_class->op_class, chan,
- op_class->bw) != NOT_ALLOWED) {
- found = 1;
- break;
- }
- }
-
- return found;
-}
-
-
-static int wpas_sta_secondary_channel_offset(struct wpa_bss *bss, u8 *current,
- u8 *channel)
-{
-
- const u8 *ies;
- u8 phy_type;
- size_t ies_len;
-
- if (!bss)
- return -1;
- ies = wpa_bss_ie_ptr(bss);
- ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
- return wpas_get_op_chan_phy(bss->freq, ies, ies_len, current,
- channel, &phy_type);
-}
-
-
-size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss, u8 *pos, size_t len)
-{
- struct wpabuf *buf;
- u8 op, current, chan;
- u8 *ie_len;
- size_t res;
-
- /*
- * Determine the current operating class correct mode based on
- * advertised BSS capabilities, if available. Fall back to a less
- * accurate guess based on frequency if the needed IEs are not available
- * or used.
- */
- if (wpas_sta_secondary_channel_offset(bss, &current, &chan) < 0 &&
- ieee80211_freq_to_channel_ext(bss->freq, 0, CHANWIDTH_USE_HT,
- &current, &chan) == NUM_HOSTAPD_MODES)
- return 0;
-
- /*
- * Need 3 bytes for EID, length, and current operating class, plus
- * 1 byte for every other supported operating class.
- */
- buf = wpabuf_alloc(global_op_class_size + 3);
- if (!buf)
- return 0;
-
- wpabuf_put_u8(buf, WLAN_EID_SUPPORTED_OPERATING_CLASSES);
- /* Will set the length later, putting a placeholder */
- ie_len = wpabuf_put(buf, 1);
- wpabuf_put_u8(buf, current);
-
- for (op = 0; global_op_class[op].op_class; op++) {
- if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op]))
- wpabuf_put_u8(buf, global_op_class[op].op_class);
- }
-
- *ie_len = wpabuf_len(buf) - 2;
- if (*ie_len < 2) {
- wpa_printf(MSG_DEBUG,
- "No supported operating classes IE to add");
- res = 0;
- } else if (wpabuf_len(buf) > len) {
- wpa_printf(MSG_ERROR,
- "Supported operating classes IE exceeds maximum buffer length");
- res = 0;
- } else {
- os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
- res = wpabuf_len(buf);
- wpa_hexdump_buf(MSG_DEBUG,
- "Added supported operating classes IE", buf);
- }
-
- wpabuf_free(buf);
- return res;
-}
-
-
-int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s)
-{
- int op;
- unsigned int pos, max_num = 0;
- int *classes;
-
- for (op = 0; global_op_class[op].op_class; op++)
- max_num++;
- classes = os_zalloc((max_num + 1) * sizeof(int));
- if (!classes)
- return NULL;
-
- for (op = 0, pos = 0; global_op_class[op].op_class; op++) {
- if (wpas_op_class_supported(wpa_s, NULL, &global_op_class[op]))
- classes[pos++] = global_op_class[op].op_class;
- }
-
- return classes;
-}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
deleted file mode 100644
index ce44dfb9e053..000000000000
--- a/wpa_supplicant/p2p_supplicant.c
+++ /dev/null
@@ -1,10107 +0,0 @@
-/*
- * wpa_supplicant - P2P
- * Copyright (c) 2009-2010, Atheros Communications
- * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "common/ieee802_11_common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/wpa_ctrl.h"
-#include "wps/wps_i.h"
-#include "p2p/p2p.h"
-#include "ap/hostapd.h"
-#include "ap/ap_config.h"
-#include "ap/sta_info.h"
-#include "ap/ap_drv_ops.h"
-#include "ap/wps_hostapd.h"
-#include "ap/p2p_hostapd.h"
-#include "ap/dfs.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "ap.h"
-#include "config_ssid.h"
-#include "config.h"
-#include "notify.h"
-#include "scan.h"
-#include "bss.h"
-#include "offchannel.h"
-#include "wps_supplicant.h"
-#include "p2p_supplicant.h"
-#include "wifi_display.h"
-
-
-/*
- * How many times to try to scan to find the GO before giving up on join
- * request.
- */
-#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
-
-#define P2P_AUTO_PD_SCAN_ATTEMPTS 5
-
-/**
- * Defines time interval in seconds when a GO needs to evacuate a frequency that
- * it is currently using, but is no longer valid for P2P use cases.
- */
-#define P2P_GO_FREQ_CHANGE_TIME 5
-
-/**
- * Defines CSA parameters which are used when GO evacuates the no longer valid
- * channel (and if the driver supports channel switch).
- */
-#define P2P_GO_CSA_COUNT 7
-#define P2P_GO_CSA_BLOCK_TX 0
-
-#ifndef P2P_MAX_CLIENT_IDLE
-/*
- * How many seconds to try to reconnect to the GO when connection in P2P client
- * role has been lost.
- */
-#define P2P_MAX_CLIENT_IDLE 10
-#endif /* P2P_MAX_CLIENT_IDLE */
-
-#ifndef P2P_MAX_INITIAL_CONN_WAIT
-/*
- * How many seconds to wait for initial 4-way handshake to get completed after
- * WPS provisioning step or after the re-invocation of a persistent group on a
- * P2P Client.
- */
-#define P2P_MAX_INITIAL_CONN_WAIT 10
-#endif /* P2P_MAX_INITIAL_CONN_WAIT */
-
-#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO
-/*
- * How many seconds to wait for initial 4-way handshake to get completed after
- * WPS provisioning step on the GO. This controls the extra time the P2P
- * operation is considered to be in progress (e.g., to delay other scans) after
- * WPS provisioning has been completed on the GO during group formation.
- */
-#define P2P_MAX_INITIAL_CONN_WAIT_GO 10
-#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */
-
-#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE
-/*
- * How many seconds to wait for initial 4-way handshake to get completed after
- * re-invocation of a persistent group on the GO when the client is expected
- * to connect automatically (no user interaction).
- */
-#define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15
-#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */
-
-#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
-
-/*
- * How many seconds to wait to re-attempt to move GOs, in case previous attempt
- * was not possible.
- */
-#define P2P_RECONSIDER_GO_MOVE_DELAY 30
-
-enum p2p_group_removal_reason {
- P2P_GROUP_REMOVAL_UNKNOWN,
- P2P_GROUP_REMOVAL_SILENT,
- P2P_GROUP_REMOVAL_FORMATION_FAILED,
- P2P_GROUP_REMOVAL_REQUESTED,
- P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
- P2P_GROUP_REMOVAL_UNAVAILABLE,
- P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
- P2P_GROUP_REMOVAL_PSK_FAILURE,
- P2P_GROUP_REMOVAL_FREQ_CONFLICT,
- P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL
-};
-
-
-static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
-static struct wpa_supplicant *
-wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
- int go);
-static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
- const u8 *ssid, size_t ssid_len);
-static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
- int *force_freq, int *pref_freq, int go,
- unsigned int *pref_freq_list,
- unsigned int *num_pref_freq);
-static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
- const u8 *ssid, size_t ssid_len);
-static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
-static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
- const u8 *dev_addr, enum p2p_wps_method wps_method,
- int auto_join, int freq,
- const u8 *ssid, size_t ssid_len);
-static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
-static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
-static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
-static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
-static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
- void *timeout_ctx);
-static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx);
-static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
- int group_added);
-static void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
-static void wpas_stop_listen(void *ctx);
-static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx);
-static void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s);
-static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type type);
-static void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
- int already_deleted);
-static void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs,
- unsigned int num);
-static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx);
-static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq);
-static void
-wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs, unsigned int num,
- enum wpas_p2p_channel_update_trig trig);
-static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx);
-
-
-static int wpas_get_6ghz_he_chwidth_capab(struct hostapd_hw_modes *mode)
-{
- int he_capab = 0;
-
- if (mode)
- he_capab = mode->he_capab[WPAS_MODE_INFRA].phy_cap[
- HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
- return he_capab;
-}
-
-
-/*
- * Get the number of concurrent channels that the HW can operate, but that are
- * currently not in use by any of the wpa_supplicant interfaces.
- */
-static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
-{
- int *freqs;
- int num, unused;
-
- freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
- if (!freqs)
- return -1;
-
- num = get_shared_radio_freqs(wpa_s, freqs,
- wpa_s->num_multichan_concurrent);
- os_free(freqs);
-
- unused = wpa_s->num_multichan_concurrent - num;
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused);
- return unused;
-}
-
-
-/*
- * Get the frequencies that are currently in use by one or more of the virtual
- * interfaces, and that are also valid for P2P operation.
- */
-static unsigned int
-wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *p2p_freqs,
- unsigned int len)
-{
- struct wpa_used_freq_data *freqs;
- unsigned int num, i, j;
-
- freqs = os_calloc(wpa_s->num_multichan_concurrent,
- sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return 0;
-
- num = get_shared_radio_freqs_data(wpa_s, freqs,
- wpa_s->num_multichan_concurrent);
-
- os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len);
-
- for (i = 0, j = 0; i < num && j < len; i++) {
- if (p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
- p2p_freqs[j++] = freqs[i];
- }
-
- os_free(freqs);
-
- dump_freq_data(wpa_s, "valid for P2P", p2p_freqs, j);
-
- return j;
-}
-
-
-static void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
- int freq)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
-
- /* Use the wpa_s used to control the P2P Device operation */
- wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- if (wpa_s->conf->p2p_ignore_shared_freq &&
- freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
- wpas_p2p_num_unused_channels(wpa_s) > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration",
- freq);
- freq = 0;
- }
- p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
-}
-
-
-static void wpas_p2p_scan_res_handled(struct wpa_supplicant *wpa_s)
-{
- unsigned int delay = wpas_p2p_search_delay(wpa_s);
-
- /* In case of concurrent P2P and external scans, delay P2P search. */
- if (external_scan_running(wpa_s->radio)) {
- delay = wpa_s->conf->p2p_search_delay;
- wpa_printf(MSG_DEBUG,
- "P2P: Delay next P2P search by %d ms to let externally triggered scan complete",
- delay);
- }
-
- p2p_scan_res_handled(wpa_s->global->p2p, delay);
-}
-
-
-static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- size_t i;
-
- if (wpa_s->p2p_scan_work) {
- struct wpa_radio_work *work = wpa_s->p2p_scan_work;
- wpa_s->p2p_scan_work = NULL;
- radio_work_done(work);
- }
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
-
- wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)",
- (int) scan_res->num);
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *bss = scan_res->res[i];
- struct os_reltime time_tmp_age, entry_ts;
- const u8 *ies;
- size_t ies_len;
-
- time_tmp_age.sec = bss->age / 1000;
- time_tmp_age.usec = (bss->age % 1000) * 1000;
- os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);
-
- ies = (const u8 *) (bss + 1);
- ies_len = bss->ie_len;
- if (bss->beacon_ie_len > 0 &&
- !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
- wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
- wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
- MACSTR, MAC2STR(bss->bssid));
- ies = ies + ies_len;
- ies_len = bss->beacon_ie_len;
- }
-
-
- if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
- bss->freq, &entry_ts, bss->level,
- ies, ies_len) > 0)
- break;
- }
-
- wpas_p2p_scan_res_handled(wpa_s);
-}
-
-
-static void wpas_p2p_scan_res_fail_handler(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_scan_work) {
- struct wpa_radio_work *work = wpa_s->p2p_scan_work;
-
- wpa_s->p2p_scan_work = NULL;
- radio_work_done(work);
- }
-
- if (wpa_s->global->p2p_disabled || !wpa_s->global->p2p)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Failed to get scan results - try to continue");
- wpas_p2p_scan_res_handled(wpa_s);
-}
-
-
-static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpa_driver_scan_params *params = work->ctx;
- int ret;
-
- if (deinit) {
- if (!work->started) {
- wpa_scan_free_params(params);
- return;
- }
-
- wpa_s->p2p_scan_work = NULL;
- return;
- }
-
- if (wpa_s->clear_driver_scan_cache) {
- wpa_printf(MSG_DEBUG,
- "Request driver to clear scan cache due to local BSS flush");
- params->only_new_results = 1;
- }
-
- if (!params->p2p_include_6ghz && !params->freqs) {
- wpa_printf(MSG_DEBUG,
- "P2P: Exclude 6 GHz channels - update the scan frequency list");
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
- 0);
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
- 0);
- }
- ret = wpa_drv_scan(wpa_s, params);
- if (ret == 0)
- wpa_s->curr_scan_cookie = params->scan_cookie;
- wpa_scan_free_params(params);
- work->ctx = NULL;
- if (ret) {
- radio_work_done(work);
- p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
- return;
- }
-
- p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
- os_get_reltime(&wpa_s->scan_trigger_time);
- wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
- wpa_s->scan_res_fail_handler = wpas_p2p_scan_res_fail_handler;
- wpa_s->own_scan_requested = 1;
- wpa_s->clear_driver_scan_cache = 0;
- wpa_s->p2p_scan_work = work;
-}
-
-
-static int wpas_p2p_search_social_channel(struct wpa_supplicant *wpa_s,
- int freq)
-{
- if (wpa_s->global->p2p_24ghz_social_channels &&
- (freq == 2412 || freq == 2437 || freq == 2462)) {
- /*
- * Search all social channels regardless of whether these have
- * been disabled for P2P operating channel use to avoid missing
- * peers.
- */
- return 1;
- }
- return p2p_supported_freq(wpa_s->global->p2p, freq);
-}
-
-
-static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
- unsigned int num_req_dev_types,
- const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
- bool include_6ghz)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_driver_scan_params *params = NULL;
- struct wpabuf *wps_ie, *ies;
- unsigned int num_channels = 0;
- int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
- size_t ielen;
- u8 *n, i;
- unsigned int bands;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- if (wpa_s->p2p_scan_work) {
- wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
- return -1;
- }
-
- params = os_zalloc(sizeof(*params));
- if (params == NULL)
- return -1;
-
- /* P2P Wildcard SSID */
- params->num_ssids = 1;
- n = os_malloc(P2P_WILDCARD_SSID_LEN);
- if (n == NULL)
- goto fail;
- os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
- params->ssids[0].ssid = n;
- params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
-
- wpa_s->wps->dev.p2p = 1;
- wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
- wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
- num_req_dev_types, req_dev_types);
- if (wps_ie == NULL)
- goto fail;
- if (!wpa_s->conf->p2p_6ghz_disable)
- params->p2p_include_6ghz = include_6ghz;
- switch (type) {
- case P2P_SCAN_SOCIAL:
- params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
- sizeof(int));
- if (params->freqs == NULL)
- goto fail;
- for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
- if (wpas_p2p_search_social_channel(
- wpa_s, social_channels_freq[i]))
- params->freqs[num_channels++] =
- social_channels_freq[i];
- }
- params->freqs[num_channels++] = 0;
- break;
- case P2P_SCAN_FULL:
- break;
- case P2P_SCAN_SPECIFIC:
- params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs == NULL)
- goto fail;
- params->freqs[0] = freq;
- params->freqs[1] = 0;
- break;
- case P2P_SCAN_SOCIAL_PLUS_ONE:
- params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
- sizeof(int));
- if (params->freqs == NULL)
- goto fail;
- for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
- if (wpas_p2p_search_social_channel(
- wpa_s, social_channels_freq[i]))
- params->freqs[num_channels++] =
- social_channels_freq[i];
- }
- if (p2p_supported_freq(wpa_s->global->p2p, freq))
- params->freqs[num_channels++] = freq;
- params->freqs[num_channels++] = 0;
- break;
- }
-
- ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
- if (ies == NULL) {
- wpabuf_free(wps_ie);
- goto fail;
- }
- wpabuf_put_buf(ies, wps_ie);
- wpabuf_free(wps_ie);
-
- bands = wpas_get_bands(wpa_s, params->freqs);
- p2p_scan_ie(wpa_s->global->p2p, ies, dev_id, bands);
-
- params->p2p_probe = 1;
- n = os_malloc(wpabuf_len(ies));
- if (n == NULL) {
- wpabuf_free(ies);
- goto fail;
- }
- os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
- params->extra_ies = n;
- params->extra_ies_len = wpabuf_len(ies);
- wpabuf_free(ies);
-
- radio_remove_works(wpa_s, "p2p-scan", 0);
- if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
- params) < 0)
- goto fail;
- return 0;
-
-fail:
- wpa_scan_free_params(params);
- return -1;
-}
-
-
-static enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
-{
- switch (p2p_group_interface) {
- case P2P_GROUP_INTERFACE_PENDING:
- return WPA_IF_P2P_GROUP;
- case P2P_GROUP_INTERFACE_GO:
- return WPA_IF_P2P_GO;
- case P2P_GROUP_INTERFACE_CLIENT:
- return WPA_IF_P2P_CLIENT;
- }
-
- return WPA_IF_P2P_GROUP;
-}
-
-
-static struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
- const u8 *ssid,
- size_t ssid_len, int *go)
-{
- struct wpa_ssid *s;
-
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled != 0 || !s->p2p_group ||
- s->ssid_len != ssid_len ||
- os_memcmp(ssid, s->ssid, ssid_len) != 0)
- continue;
- if (s->mode == WPAS_MODE_P2P_GO &&
- s != wpa_s->current_ssid)
- continue;
- if (go)
- *go = s->mode == WPAS_MODE_P2P_GO;
- return wpa_s;
- }
- }
-
- return NULL;
-}
-
-
-static void run_wpas_p2p_disconnect(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpa_printf(MSG_DEBUG,
- "P2P: Complete previously requested removal of %s",
- wpa_s->ifname);
- wpas_p2p_disconnect(wpa_s);
-}
-
-
-static int wpas_p2p_disconnect_safely(struct wpa_supplicant *wpa_s,
- struct wpa_supplicant *calling_wpa_s)
-{
- if (calling_wpa_s == wpa_s && wpa_s &&
- wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
- /*
- * The calling wpa_s instance is going to be removed. Do that
- * from an eloop callback to keep the instance available until
- * the caller has returned. This may be needed, e.g., to provide
- * control interface responses on the per-interface socket.
- */
- if (eloop_register_timeout(0, 0, run_wpas_p2p_disconnect,
- wpa_s, NULL) < 0)
- return -1;
- return 0;
- }
-
- return wpas_p2p_disconnect(wpa_s);
-}
-
-
-/* Determine total number of clients in active groups where we are the GO */
-static unsigned int p2p_group_go_member_count(struct wpa_supplicant *wpa_s)
-{
- unsigned int count = 0;
- struct wpa_ssid *s;
-
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- wpa_printf(MSG_DEBUG,
- "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d",
- wpa_s, s, s->disabled, s->p2p_group,
- s->mode);
- if (!s->disabled && s->p2p_group &&
- s->mode == WPAS_MODE_P2P_GO) {
- count += p2p_get_group_num_members(
- wpa_s->p2p_group);
- }
- }
- }
-
- return count;
-}
-
-
-static unsigned int p2p_is_active_persistent_group(struct wpa_supplicant *wpa_s)
-{
- return !wpa_s->p2p_mgmt && wpa_s->current_ssid &&
- !wpa_s->current_ssid->disabled &&
- wpa_s->current_ssid->p2p_group &&
- wpa_s->current_ssid->p2p_persistent_group;
-}
-
-
-static unsigned int p2p_is_active_persistent_go(struct wpa_supplicant *wpa_s)
-{
- return p2p_is_active_persistent_group(wpa_s) &&
- wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO;
-}
-
-
-/* Find an interface for a P2P group where we are the GO */
-static struct wpa_supplicant *
-wpas_p2p_get_go_group(struct wpa_supplicant *wpa_s)
-{
- struct wpa_supplicant *save = NULL;
-
- if (!wpa_s)
- return NULL;
-
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (!p2p_is_active_persistent_go(wpa_s))
- continue;
-
- /* Prefer a group with connected clients */
- if (p2p_get_group_num_members(wpa_s->p2p_group))
- return wpa_s;
- save = wpa_s;
- }
-
- /* No group with connected clients, so pick the one without (if any) */
- return save;
-}
-
-
-static unsigned int p2p_is_active_persistent_cli(struct wpa_supplicant *wpa_s)
-{
- return p2p_is_active_persistent_group(wpa_s) &&
- wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
-}
-
-
-/* Find an interface for a P2P group where we are the P2P Client */
-static struct wpa_supplicant *
-wpas_p2p_get_cli_group(struct wpa_supplicant *wpa_s)
-{
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (p2p_is_active_persistent_cli(wpa_s))
- return wpa_s;
- }
-
- return NULL;
-}
-
-
-/* Find a persistent group where we are the GO */
-static struct wpa_ssid *
-wpas_p2p_get_persistent_go(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *s;
-
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled == 2 && s->mode == WPAS_MODE_P2P_GO)
- return s;
- }
-
- return NULL;
-}
-
-
-static u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role,
- unsigned int *force_freq,
- unsigned int *pref_freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *s;
- u8 conncap = P2PS_SETUP_NONE;
- unsigned int owned_members = 0;
- struct wpa_supplicant *go_wpa_s, *cli_wpa_s;
- struct wpa_ssid *persistent_go;
- int p2p_no_group_iface;
- unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
-
- wpa_printf(MSG_DEBUG, "P2P: Conncap - in:%d role:%d", incoming, role);
-
- if (force_freq)
- *force_freq = 0;
- if (pref_freq)
- *pref_freq = 0;
-
- size = P2P_MAX_PREF_CHANNELS;
- if (force_freq && pref_freq &&
- !wpas_p2p_setup_freqs(wpa_s, 0, (int *) force_freq,
- (int *) pref_freq, 0, pref_freq_list, &size))
- wpas_p2p_set_own_freq_preference(wpa_s,
- *force_freq ? *force_freq :
- *pref_freq);
-
- /*
- * For non-concurrent capable devices:
- * If persistent_go, then no new.
- * If GO, then no client.
- * If client, then no GO.
- */
- go_wpa_s = wpas_p2p_get_go_group(wpa_s);
- if (go_wpa_s)
- owned_members = p2p_get_group_num_members(go_wpa_s->p2p_group);
- persistent_go = wpas_p2p_get_persistent_go(wpa_s);
- p2p_no_group_iface = !wpas_p2p_create_iface(wpa_s);
- cli_wpa_s = wpas_p2p_get_cli_group(wpa_s);
-
- wpa_printf(MSG_DEBUG,
- "P2P: GO(iface)=%p members=%u CLI(iface)=%p persistent(ssid)=%p",
- go_wpa_s, owned_members, cli_wpa_s, persistent_go);
-
- /* If not concurrent, restrict our choices */
- if (p2p_no_group_iface) {
- wpa_printf(MSG_DEBUG, "P2P: p2p_no_group_iface");
-
- if (cli_wpa_s)
- return P2PS_SETUP_NONE;
-
- if (go_wpa_s) {
- if (role == P2PS_SETUP_CLIENT ||
- incoming == P2PS_SETUP_GROUP_OWNER ||
- p2p_client_limit_reached(go_wpa_s->p2p_group))
- return P2PS_SETUP_NONE;
-
- return P2PS_SETUP_GROUP_OWNER;
- }
-
- if (persistent_go) {
- if (role == P2PS_SETUP_NONE || role == P2PS_SETUP_NEW) {
- if (!incoming)
- return P2PS_SETUP_GROUP_OWNER |
- P2PS_SETUP_CLIENT;
- if (incoming == P2PS_SETUP_NEW) {
- u8 r;
-
- if (os_get_random(&r, sizeof(r)) < 0 ||
- (r & 1))
- return P2PS_SETUP_CLIENT;
- return P2PS_SETUP_GROUP_OWNER;
- }
- }
- }
- }
-
- /* If a required role has been specified, handle it here */
- if (role && role != P2PS_SETUP_NEW) {
- switch (incoming) {
- case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
- case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
- /*
- * Peer has an active GO, so if the role allows it and
- * we do not have any active roles, become client.
- */
- if ((role & P2PS_SETUP_CLIENT) && !go_wpa_s &&
- !cli_wpa_s)
- return P2PS_SETUP_CLIENT;
-
- /* fall through */
-
- case P2PS_SETUP_NONE:
- case P2PS_SETUP_NEW:
- conncap = role;
- goto grp_owner;
-
- case P2PS_SETUP_GROUP_OWNER:
- /*
- * Must be a complimentary role - cannot be a client to
- * more than one peer.
- */
- if (incoming == role || cli_wpa_s)
- return P2PS_SETUP_NONE;
-
- return P2PS_SETUP_CLIENT;
-
- case P2PS_SETUP_CLIENT:
- /* Must be a complimentary role */
- if (incoming != role) {
- conncap = P2PS_SETUP_GROUP_OWNER;
- goto grp_owner;
- }
- /* fall through */
-
- default:
- return P2PS_SETUP_NONE;
- }
- }
-
- /*
- * For now, we only will support ownership of one group, and being a
- * client of one group. Therefore, if we have either an existing GO
- * group, or an existing client group, we will not do a new GO
- * negotiation, but rather try to re-use the existing groups.
- */
- switch (incoming) {
- case P2PS_SETUP_NONE:
- case P2PS_SETUP_NEW:
- if (cli_wpa_s)
- conncap = P2PS_SETUP_GROUP_OWNER;
- else if (!owned_members)
- conncap = P2PS_SETUP_NEW;
- else if (incoming == P2PS_SETUP_NONE)
- conncap = P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT;
- else
- conncap = P2PS_SETUP_CLIENT;
- break;
-
- case P2PS_SETUP_CLIENT:
- conncap = P2PS_SETUP_GROUP_OWNER;
- break;
-
- case P2PS_SETUP_GROUP_OWNER:
- if (!cli_wpa_s)
- conncap = P2PS_SETUP_CLIENT;
- break;
-
- case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW:
- case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT:
- if (cli_wpa_s)
- conncap = P2PS_SETUP_GROUP_OWNER;
- else {
- u8 r;
-
- if (os_get_random(&r, sizeof(r)) < 0 ||
- (r & 1))
- conncap = P2PS_SETUP_CLIENT;
- else
- conncap = P2PS_SETUP_GROUP_OWNER;
- }
- break;
-
- default:
- return P2PS_SETUP_NONE;
- }
-
-grp_owner:
- if ((conncap & P2PS_SETUP_GROUP_OWNER) ||
- (!incoming && (conncap & P2PS_SETUP_NEW))) {
- if (go_wpa_s && p2p_client_limit_reached(go_wpa_s->p2p_group))
- conncap &= ~P2PS_SETUP_GROUP_OWNER;
-
- s = wpas_p2p_get_persistent_go(wpa_s);
- if (!s && !go_wpa_s && p2p_no_group_iface) {
- p2p_set_intended_addr(wpa_s->global->p2p,
- wpa_s->p2p_mgmt ?
- wpa_s->parent->own_addr :
- wpa_s->own_addr);
- } else if (!s && !go_wpa_s) {
- if (wpas_p2p_add_group_interface(wpa_s,
- WPA_IF_P2P_GROUP) < 0) {
- wpa_printf(MSG_ERROR,
- "P2P: Failed to allocate a new interface for the group");
- return P2PS_SETUP_NONE;
- }
- wpa_s->global->pending_group_iface_for_p2ps = 1;
- p2p_set_intended_addr(wpa_s->global->p2p,
- wpa_s->pending_interface_addr);
- }
- }
-
- return conncap;
-}
-
-
-static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
- enum p2p_group_removal_reason removal_reason)
-{
- struct wpa_ssid *ssid;
- char *gtype;
- const char *reason;
-
- ssid = wpa_s->current_ssid;
- if (ssid == NULL) {
- /*
- * The current SSID was not known, but there may still be a
- * pending P2P group interface waiting for provisioning or a
- * P2P group that is trying to reconnect.
- */
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- if (ssid->p2p_group && ssid->disabled != 2)
- break;
- ssid = ssid->next;
- }
- if (ssid == NULL &&
- wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)
- {
- wpa_printf(MSG_ERROR, "P2P: P2P group interface "
- "not found");
- return -1;
- }
- }
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO)
- gtype = "GO";
- else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
- (ssid && ssid->mode == WPAS_MODE_INFRA)) {
- wpa_s->reassociate = 0;
- wpa_s->disconnected = 1;
- gtype = "client";
- } else
- gtype = "GO";
-
- if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid)
- wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);
-
- if (os_strcmp(gtype, "client") == 0) {
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- if (eloop_is_timeout_registered(wpas_p2p_psk_failure_removal,
- wpa_s, NULL)) {
- wpa_printf(MSG_DEBUG,
- "P2P: PSK failure removal was scheduled, so use PSK failure as reason for group removal");
- removal_reason = P2P_GROUP_REMOVAL_PSK_FAILURE;
- eloop_cancel_timeout(wpas_p2p_psk_failure_removal,
- wpa_s, NULL);
- }
- }
-
- if (wpa_s->cross_connect_in_use) {
- wpa_s->cross_connect_in_use = 0;
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
- wpa_s->ifname, wpa_s->cross_connect_uplink);
- }
- switch (removal_reason) {
- case P2P_GROUP_REMOVAL_REQUESTED:
- reason = " reason=REQUESTED";
- break;
- case P2P_GROUP_REMOVAL_FORMATION_FAILED:
- reason = " reason=FORMATION_FAILED";
- break;
- case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
- reason = " reason=IDLE";
- break;
- case P2P_GROUP_REMOVAL_UNAVAILABLE:
- reason = " reason=UNAVAILABLE";
- break;
- case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
- reason = " reason=GO_ENDING_SESSION";
- break;
- case P2P_GROUP_REMOVAL_PSK_FAILURE:
- reason = " reason=PSK_FAILURE";
- break;
- case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
- reason = " reason=FREQ_CONFLICT";
- break;
- default:
- reason = "";
- break;
- }
- if (removal_reason != P2P_GROUP_REMOVAL_SILENT) {
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_REMOVED "%s %s%s",
- wpa_s->ifname, gtype, reason);
- }
-
- if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0)
- wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout");
- if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
- wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
- if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL) > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation "
- "timeout");
- wpa_s->p2p_in_provisioning = 0;
- wpas_p2p_group_formation_failed(wpa_s, 1);
- }
-
- wpa_s->p2p_in_invitation = 0;
- eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL);
-
- /*
- * Make sure wait for the first client does not remain active after the
- * group has been removed.
- */
- wpa_s->global->p2p_go_wait_client.sec = 0;
-
- if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
- struct wpa_global *global;
- char *ifname;
- enum wpa_driver_if_type type;
- wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s",
- wpa_s->ifname);
- global = wpa_s->global;
- ifname = os_strdup(wpa_s->ifname);
- type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
- eloop_cancel_timeout(run_wpas_p2p_disconnect, wpa_s, NULL);
- wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
- wpa_s = global->ifaces;
- if (wpa_s && ifname)
- wpa_drv_if_remove(wpa_s, type, ifname);
- os_free(ifname);
- return 1;
- }
-
- /*
- * The primary interface was used for P2P group operations, so
- * need to reset its p2pdev.
- */
- wpa_s->p2pdev = wpa_s->parent;
-
- if (!wpa_s->p2p_go_group_formation_completed) {
- wpa_s->global->p2p_group_formation = NULL;
- wpa_s->p2p_in_provisioning = 0;
- }
-
- wpa_s->show_group_started = 0;
- os_free(wpa_s->go_params);
- wpa_s->go_params = NULL;
-
- os_free(wpa_s->p2p_group_common_freqs);
- wpa_s->p2p_group_common_freqs = NULL;
- wpa_s->p2p_group_common_freqs_num = 0;
- wpa_s->p2p_go_do_acs = 0;
- wpa_s->p2p_go_allow_dfs = 0;
-
- wpa_s->waiting_presence_resp = 0;
-
- wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network");
- if (ssid && (ssid->p2p_group ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
- (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
- int id = ssid->id;
- if (ssid == wpa_s->current_ssid) {
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_s->current_ssid = NULL;
- }
- /*
- * Networks objects created during any P2P activities are not
- * exposed out as they might/will confuse certain non-P2P aware
- * applications since these network objects won't behave like
- * regular ones.
- *
- * Likewise, we don't send out network removed signals for such
- * network objects.
- */
- wpa_config_remove_network(wpa_s->conf, id);
- wpa_supplicant_clear_status(wpa_s);
- wpa_supplicant_cancel_sched_scan(wpa_s);
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
- "found");
- }
- if (wpa_s->ap_iface)
- wpa_supplicant_ap_deinit(wpa_s);
- else
- wpa_drv_deinit_p2p_cli(wpa_s);
-
- os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
-
- return 0;
-}
-
-
-static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
- u8 *go_dev_addr,
- const u8 *ssid, size_t ssid_len)
-{
- struct wpa_bss *bss;
- const u8 *bssid;
- struct wpabuf *p2p;
- u8 group_capab;
- const u8 *addr;
-
- if (wpa_s->go_params)
- bssid = wpa_s->go_params->peer_interface_addr;
- else
- bssid = wpa_s->bssid;
-
- bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
- if (bss == NULL && wpa_s->go_params &&
- !is_zero_ether_addr(wpa_s->go_params->peer_device_addr))
- bss = wpa_bss_get_p2p_dev_addr(
- wpa_s, wpa_s->go_params->peer_device_addr);
- if (bss == NULL) {
- u8 iface_addr[ETH_ALEN];
- if (p2p_get_interface_addr(wpa_s->global->p2p, bssid,
- iface_addr) == 0)
- bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len);
- }
- if (bss == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
- "group is persistent - BSS " MACSTR " not found",
- MAC2STR(bssid));
- return 0;
- }
-
- p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
- if (p2p == NULL)
- p2p = wpa_bss_get_vendor_ie_multi_beacon(bss,
- P2P_IE_VENDOR_TYPE);
- if (p2p == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
- "group is persistent - BSS " MACSTR
- " did not include P2P IE", MAC2STR(bssid));
- wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs",
- wpa_bss_ie_ptr(bss), bss->ie_len);
- wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs",
- wpa_bss_ie_ptr(bss) + bss->ie_len,
- bss->beacon_ie_len);
- return 0;
- }
-
- group_capab = p2p_get_group_capab(p2p);
- addr = p2p_get_go_dev_addr(p2p);
- wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: "
- "group_capab=0x%x", group_capab);
- if (addr) {
- os_memcpy(go_dev_addr, addr, ETH_ALEN);
- wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR,
- MAC2STR(addr));
- } else
- os_memset(go_dev_addr, 0, ETH_ALEN);
- wpabuf_free(p2p);
-
- wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x "
- "go_dev_addr=" MACSTR,
- MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
-
- return !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
-}
-
-
-static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const u8 *go_dev_addr)
-{
- struct wpa_ssid *s;
- int changed = 0;
-
- wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent "
- "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr));
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled == 2 &&
- os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 &&
- s->ssid_len == ssid->ssid_len &&
- os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0)
- break;
- }
-
- if (s) {
- wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group "
- "entry");
- if (ssid->passphrase && !s->passphrase)
- changed = 1;
- else if (ssid->passphrase && s->passphrase &&
- os_strcmp(ssid->passphrase, s->passphrase) != 0)
- changed = 1;
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group "
- "entry");
- changed = 1;
- s = wpa_config_add_network(wpa_s->conf);
- if (s == NULL)
- return -1;
-
- /*
- * Instead of network_added we emit persistent_group_added
- * notification. Also to keep the defense checks in
- * persistent_group obj registration method, we set the
- * relevant flags in s to designate it as a persistent group.
- */
- s->p2p_group = 1;
- s->p2p_persistent_group = 1;
- wpas_notify_persistent_group_added(wpa_s, s);
- wpa_config_set_network_defaults(s);
- }
-
- s->p2p_group = 1;
- s->p2p_persistent_group = 1;
- s->disabled = 2;
- s->bssid_set = 1;
- os_memcpy(s->bssid, go_dev_addr, ETH_ALEN);
- s->mode = ssid->mode;
- s->auth_alg = WPA_AUTH_ALG_OPEN;
- s->key_mgmt = WPA_KEY_MGMT_PSK;
- s->proto = WPA_PROTO_RSN;
- s->pbss = ssid->pbss;
- s->pairwise_cipher = ssid->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
- s->export_keys = 1;
- if (ssid->passphrase) {
- os_free(s->passphrase);
- s->passphrase = os_strdup(ssid->passphrase);
- }
- if (ssid->psk_set) {
- s->psk_set = 1;
- os_memcpy(s->psk, ssid->psk, 32);
- }
- if (s->passphrase && !s->psk_set)
- wpa_config_update_psk(s);
- if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) {
- os_free(s->ssid);
- s->ssid = os_malloc(ssid->ssid_len);
- }
- if (s->ssid) {
- s->ssid_len = ssid->ssid_len;
- os_memcpy(s->ssid, ssid->ssid, s->ssid_len);
- }
- if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) {
- dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list);
- wpa_s->global->add_psk = NULL;
- changed = 1;
- }
-
- if (changed && wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf)) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
- }
-
- return s->id;
-}
-
-
-static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- struct wpa_ssid *ssid, *s;
- u8 *n;
- size_t i;
- int found = 0;
- struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- ssid = wpa_s->current_ssid;
- if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
- !ssid->p2p_persistent_group)
- return;
-
- for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
- continue;
-
- if (s->ssid_len == ssid->ssid_len &&
- os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
- break;
- }
-
- if (s == NULL)
- return;
-
- for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
- if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr,
- ETH_ALEN) != 0)
- continue;
-
- if (i == s->num_p2p_clients - 1)
- return; /* already the most recent entry */
-
- /* move the entry to mark it most recent */
- os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
- s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
- (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
- os_memcpy(s->p2p_client_list +
- (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr,
- ETH_ALEN);
- os_memset(s->p2p_client_list +
- (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
- 0xff, ETH_ALEN);
- found = 1;
- break;
- }
-
- if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
- n = os_realloc_array(s->p2p_client_list,
- s->num_p2p_clients + 1, 2 * ETH_ALEN);
- if (n == NULL)
- return;
- os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr,
- ETH_ALEN);
- os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN,
- 0xff, ETH_ALEN);
- s->p2p_client_list = n;
- s->num_p2p_clients++;
- } else if (!found && s->p2p_client_list) {
- /* Not enough room for an additional entry - drop the oldest
- * entry */
- os_memmove(s->p2p_client_list,
- s->p2p_client_list + 2 * ETH_ALEN,
- (s->num_p2p_clients - 1) * 2 * ETH_ALEN);
- os_memcpy(s->p2p_client_list +
- (s->num_p2p_clients - 1) * 2 * ETH_ALEN,
- addr, ETH_ALEN);
- os_memset(s->p2p_client_list +
- (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
- 0xff, ETH_ALEN);
- }
-
- if (p2p_wpa_s->conf->update_config &&
- wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
- wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
-}
-
-
-static void wpas_p2p_group_started(struct wpa_supplicant *wpa_s,
- int go, struct wpa_ssid *ssid, int freq,
- const u8 *psk, const char *passphrase,
- const u8 *go_dev_addr, int persistent,
- const char *extra)
-{
- const char *ssid_txt;
- char psk_txt[65];
-
- if (psk)
- wpa_snprintf_hex(psk_txt, sizeof(psk_txt), psk, 32);
- else
- psk_txt[0] = '\0';
-
- if (ssid)
- ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
- else
- ssid_txt = "";
-
- if (passphrase && passphrase[0] == '\0')
- passphrase = NULL;
-
- /*
- * Include PSK/passphrase only in the control interface message and
- * leave it out from the debug log entry.
- */
- wpa_msg_global_ctrl(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_STARTED
- "%s %s ssid=\"%s\" freq=%d%s%s%s%s%s go_dev_addr="
- MACSTR "%s%s",
- wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
- psk ? " psk=" : "", psk_txt,
- passphrase ? " passphrase=\"" : "",
- passphrase ? passphrase : "",
- passphrase ? "\"" : "",
- MAC2STR(go_dev_addr),
- persistent ? " [PERSISTENT]" : "", extra);
- wpa_printf(MSG_INFO, P2P_EVENT_GROUP_STARTED
- "%s %s ssid=\"%s\" freq=%d go_dev_addr=" MACSTR "%s%s",
- wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq,
- MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : "",
- extra);
-}
-
-
-static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
- int success, int already_deleted)
-{
- struct wpa_ssid *ssid;
- int client;
- int persistent;
- u8 go_dev_addr[ETH_ALEN];
-
- /*
- * This callback is likely called for the main interface. Update wpa_s
- * to use the group interface if a new interface was created for the
- * group.
- */
- if (wpa_s->global->p2p_group_formation)
- wpa_s = wpa_s->global->p2p_group_formation;
- if (wpa_s->p2p_go_group_formation_completed) {
- wpa_s->global->p2p_group_formation = NULL;
- wpa_s->p2p_in_provisioning = 0;
- } else if (wpa_s->p2p_in_provisioning && !success) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "P2P: Stop provisioning state due to failure");
- wpa_s->p2p_in_provisioning = 0;
- }
- wpa_s->p2p_in_invitation = 0;
- wpa_s->group_formation_reported = 1;
-
- if (!success) {
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_FORMATION_FAILURE);
- wpas_notify_p2p_group_formation_failure(wpa_s, "");
- if (already_deleted)
- return;
- wpas_p2p_group_delete(wpa_s,
- P2P_GROUP_REMOVAL_FORMATION_FAILED);
- return;
- }
-
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_FORMATION_SUCCESS);
-
- ssid = wpa_s->current_ssid;
- if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
- ssid->mode = WPAS_MODE_P2P_GO;
- p2p_group_notif_formation_done(wpa_s->p2p_group);
- wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL);
- }
-
- persistent = 0;
- if (ssid) {
- client = ssid->mode == WPAS_MODE_INFRA;
- if (ssid->mode == WPAS_MODE_P2P_GO) {
- persistent = ssid->p2p_persistent_group;
- os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
- ETH_ALEN);
- } else
- persistent = wpas_p2p_persistent_group(wpa_s,
- go_dev_addr,
- ssid->ssid,
- ssid->ssid_len);
- } else {
- client = wpa_s->p2p_group_interface ==
- P2P_GROUP_INTERFACE_CLIENT;
- os_memset(go_dev_addr, 0, ETH_ALEN);
- }
-
- wpa_s->show_group_started = 0;
- if (client) {
- /*
- * Indicate event only after successfully completed 4-way
- * handshake, i.e., when the interface is ready for data
- * packets.
- */
- wpa_s->show_group_started = 1;
- } else {
- wpas_p2p_group_started(wpa_s, 1, ssid,
- ssid ? ssid->frequency : 0,
- ssid && ssid->passphrase == NULL &&
- ssid->psk_set ? ssid->psk : NULL,
- ssid ? ssid->passphrase : NULL,
- go_dev_addr, persistent, "");
- wpas_p2p_cross_connect_setup(wpa_s);
- wpas_p2p_set_group_idle_timeout(wpa_s);
- }
-
- if (persistent)
- wpas_p2p_store_persistent_group(wpa_s->p2pdev,
- ssid, go_dev_addr);
- else {
- os_free(wpa_s->global->add_psk);
- wpa_s->global->add_psk = NULL;
- }
-
- if (!client) {
- wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 0, NULL);
- os_get_reltime(&wpa_s->global->p2p_go_wait_client);
- }
-}
-
-
-struct send_action_work {
- unsigned int freq;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- size_t len;
- unsigned int wait_time;
- u8 buf[0];
-};
-
-
-static void wpas_p2p_free_send_action_work(struct wpa_supplicant *wpa_s)
-{
- struct send_action_work *awork = wpa_s->p2p_send_action_work->ctx;
-
- wpa_printf(MSG_DEBUG,
- "P2P: Free Action frame radio work @%p (freq=%u dst="
- MACSTR " src=" MACSTR " bssid=" MACSTR " wait_time=%u)",
- wpa_s->p2p_send_action_work, awork->freq,
- MAC2STR(awork->dst), MAC2STR(awork->src),
- MAC2STR(awork->bssid), awork->wait_time);
- wpa_hexdump(MSG_DEBUG, "P2P: Freeing pending Action frame",
- awork->buf, awork->len);
- os_free(awork);
- wpa_s->p2p_send_action_work->ctx = NULL;
- radio_work_done(wpa_s->p2p_send_action_work);
- wpa_s->p2p_send_action_work = NULL;
-}
-
-
-static void wpas_p2p_send_action_work_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (!wpa_s->p2p_send_action_work)
- return;
-
- wpa_printf(MSG_DEBUG, "P2P: Send Action frame radio work timed out");
- wpas_p2p_free_send_action_work(wpa_s);
-}
-
-
-static void wpas_p2p_action_tx_clear(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_send_action_work) {
- struct send_action_work *awork;
-
- awork = wpa_s->p2p_send_action_work->ctx;
- wpa_printf(MSG_DEBUG,
- "P2P: Clear Action TX work @%p (wait_time=%u)",
- wpa_s->p2p_send_action_work, awork->wait_time);
- if (awork->wait_time == 0) {
- wpas_p2p_free_send_action_work(wpa_s);
- } else {
- /*
- * In theory, this should not be needed, but number of
- * places in the P2P code is still using non-zero wait
- * time for the last Action frame in the sequence and
- * some of these do not call send_action_done().
- */
- eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
- wpa_s, NULL);
- eloop_register_timeout(
- 0, awork->wait_time * 1000,
- wpas_p2p_send_action_work_timeout,
- wpa_s, NULL);
- }
- }
-}
-
-
-static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- const u8 *dst, const u8 *src,
- const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result
- result)
-{
- enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;
-
- wpas_p2p_action_tx_clear(wpa_s);
-
- if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
- return;
-
- switch (result) {
- case OFFCHANNEL_SEND_ACTION_SUCCESS:
- res = P2P_SEND_ACTION_SUCCESS;
- break;
- case OFFCHANNEL_SEND_ACTION_NO_ACK:
- res = P2P_SEND_ACTION_NO_ACK;
- break;
- case OFFCHANNEL_SEND_ACTION_FAILED:
- res = P2P_SEND_ACTION_FAILED;
- break;
- }
-
- p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
-
- if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
- wpa_s->pending_pd_before_join &&
- (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
- os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) &&
- wpa_s->p2p_fallback_to_go_neg) {
- wpa_s->pending_pd_before_join = 0;
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req "
- "during p2p_connect-auto");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=no-ACK-to-PD-Req");
- wpas_p2p_fallback_to_go_neg(wpa_s, 0);
- return;
- }
-}
-
-
-static void wpas_send_action_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct send_action_work *awork = work->ctx;
-
- if (deinit) {
- if (work->started) {
- eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
- wpa_s, NULL);
- wpa_s->p2p_send_action_work = NULL;
- offchannel_send_action_done(wpa_s);
- }
- os_free(awork);
- return;
- }
-
- if (offchannel_send_action(wpa_s, awork->freq, awork->dst, awork->src,
- awork->bssid, awork->buf, awork->len,
- awork->wait_time,
- wpas_p2p_send_action_tx_status, 1) < 0) {
- os_free(awork);
- radio_work_done(work);
- return;
- }
- wpa_s->p2p_send_action_work = work;
-}
-
-
-static int wpas_send_action_work(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time)
-{
- struct send_action_work *awork;
-
- if (radio_work_pending(wpa_s, "p2p-send-action")) {
- wpa_printf(MSG_DEBUG, "P2P: Cannot schedule new p2p-send-action work since one is already pending");
- return -1;
- }
-
- awork = os_zalloc(sizeof(*awork) + len);
- if (awork == NULL)
- return -1;
-
- awork->freq = freq;
- os_memcpy(awork->dst, dst, ETH_ALEN);
- os_memcpy(awork->src, src, ETH_ALEN);
- os_memcpy(awork->bssid, bssid, ETH_ALEN);
- awork->len = len;
- awork->wait_time = wait_time;
- os_memcpy(awork->buf, buf, len);
-
- if (radio_add_work(wpa_s, freq, "p2p-send-action", 1,
- wpas_send_action_cb, awork) < 0) {
- os_free(awork);
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time, int *scheduled)
-{
- struct wpa_supplicant *wpa_s = ctx;
- int listen_freq = -1, send_freq = -1;
-
- if (scheduled)
- *scheduled = 0;
- if (wpa_s->p2p_listen_work)
- listen_freq = wpa_s->p2p_listen_work->freq;
- if (wpa_s->p2p_send_action_work)
- send_freq = wpa_s->p2p_send_action_work->freq;
- if (listen_freq != (int) freq && send_freq != (int) freq) {
- int res;
-
- wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d freq=%u)",
- listen_freq, send_freq, freq);
- res = wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
- len, wait_time);
- if (res == 0 && scheduled)
- *scheduled = 1;
- return res;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
- return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
- wait_time,
- wpas_p2p_send_action_tx_status, 1);
-}
-
-
-static void wpas_send_action_done(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->p2p_send_action_work) {
- eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
- wpa_s, NULL);
- os_free(wpa_s->p2p_send_action_work->ctx);
- radio_work_done(wpa_s->p2p_send_action_work);
- wpa_s->p2p_send_action_work = NULL;
- }
-
- offchannel_send_action_done(wpa_s);
-}
-
-
-static int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params)
-{
- if (wpa_s->go_params == NULL) {
- wpa_s->go_params = os_malloc(sizeof(*params));
- if (wpa_s->go_params == NULL)
- return -1;
- }
- os_memcpy(wpa_s->go_params, params, sizeof(*params));
- return 0;
-}
-
-
-static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *res)
-{
- wpa_s->group_formation_reported = 0;
- wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR
- " dev_addr " MACSTR " wps_method %d",
- MAC2STR(res->peer_interface_addr),
- MAC2STR(res->peer_device_addr), res->wps_method);
- wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID",
- res->ssid, res->ssid_len);
- wpa_supplicant_ap_deinit(wpa_s);
- wpas_copy_go_neg_results(wpa_s, res);
- if (res->wps_method == WPS_PBC) {
- wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
-#ifdef CONFIG_WPS_NFC
- } else if (res->wps_method == WPS_NFC) {
- wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
- res->peer_interface_addr,
- wpa_s->p2pdev->p2p_oob_dev_pw,
- wpa_s->p2pdev->p2p_oob_dev_pw_id, 1,
- wpa_s->p2pdev->p2p_oob_dev_pw_id ==
- DEV_PW_NFC_CONNECTION_HANDOVER ?
- wpa_s->p2pdev->p2p_peer_oob_pubkey_hash :
- NULL,
- NULL, 0, 0);
-#endif /* CONFIG_WPS_NFC */
- } else {
- u16 dev_pw_id = DEV_PW_DEFAULT;
- if (wpa_s->p2p_wps_method == WPS_P2PS)
- dev_pw_id = DEV_PW_P2PS_DEFAULT;
- if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD)
- dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED;
- wpas_wps_start_pin(wpa_s, res->peer_interface_addr,
- wpa_s->p2p_pin, 1, dev_pw_id);
- }
-}
-
-
-static void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpa_ssid *persistent;
- struct psk_list_entry *psk;
- struct hostapd_data *hapd;
-
- if (!wpa_s->ap_iface)
- return;
-
- persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, NULL, ssid->ssid,
- ssid->ssid_len);
- if (persistent == NULL)
- return;
-
- hapd = wpa_s->ap_iface->bss[0];
-
- dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry,
- list) {
- struct hostapd_wpa_psk *hpsk;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for "
- MACSTR " psk=%d",
- MAC2STR(psk->addr), psk->p2p);
- hpsk = os_zalloc(sizeof(*hpsk));
- if (hpsk == NULL)
- break;
- os_memcpy(hpsk->psk, psk->psk, PMK_LEN);
- if (psk->p2p)
- os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN);
- else
- os_memcpy(hpsk->addr, psk->addr, ETH_ALEN);
- hpsk->next = hapd->conf->ssid.wpa_psk;
- hapd->conf->ssid.wpa_psk = hpsk;
- }
-}
-
-
-static void p2p_go_dump_common_freqs(struct wpa_supplicant *wpa_s)
-{
- char buf[20 + P2P_MAX_CHANNELS * 6];
- char *pos, *end;
- unsigned int i;
- int res;
-
- pos = buf;
- end = pos + sizeof(buf);
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- res = os_snprintf(pos, end - pos, " %d",
- wpa_s->p2p_group_common_freqs[i]);
- if (os_snprintf_error(end - pos, res))
- break;
- pos += res;
- }
- *pos = '\0';
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Common group frequencies:%s", buf);
-}
-
-
-static void p2p_go_save_group_common_freqs(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params)
-{
- unsigned int i, len = int_array_len(wpa_s->go_params->freq_list);
-
- wpa_s->p2p_group_common_freqs_num = 0;
- os_free(wpa_s->p2p_group_common_freqs);
- wpa_s->p2p_group_common_freqs = os_calloc(len, sizeof(int));
- if (!wpa_s->p2p_group_common_freqs)
- return;
-
- for (i = 0; i < len; i++) {
- if (!wpa_s->go_params->freq_list[i])
- break;
- wpa_s->p2p_group_common_freqs[i] =
- wpa_s->go_params->freq_list[i];
- }
- wpa_s->p2p_group_common_freqs_num = i;
-}
-
-
-static void p2p_config_write(struct wpa_supplicant *wpa_s)
-{
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (wpa_s->p2pdev->conf->update_config &&
- wpa_config_write(wpa_s->p2pdev->confname, wpa_s->p2pdev->conf))
- wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
-#endif /* CONFIG_NO_CONFIG_WRITE */
-}
-
-
-static void p2p_go_configured(void *ctx, void *data)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct p2p_go_neg_results *params = data;
- struct wpa_ssid *ssid;
-
- wpa_s->ap_configured_cb = NULL;
- wpa_s->ap_configured_cb_ctx = NULL;
- wpa_s->ap_configured_cb_data = NULL;
- if (!wpa_s->go_params) {
- wpa_printf(MSG_ERROR,
- "P2P: p2p_go_configured() called with wpa_s->go_params == NULL");
- return;
- }
-
- p2p_go_save_group_common_freqs(wpa_s, params);
- p2p_go_dump_common_freqs(wpa_s);
-
- ssid = wpa_s->current_ssid;
- if (ssid && ssid->mode == WPAS_MODE_P2P_GO) {
- wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
- if (wpa_s->global->p2p_group_formation == wpa_s)
- wpa_s->global->p2p_group_formation = NULL;
- wpas_p2p_group_started(wpa_s, 1, ssid, ssid->frequency,
- params->passphrase[0] == '\0' ?
- params->psk : NULL,
- params->passphrase,
- wpa_s->global->p2p_dev_addr,
- params->persistent_group, "");
- wpa_s->group_formation_reported = 1;
-
- if (wpa_s->p2pdev->p2ps_method_config_any) {
- if (is_zero_ether_addr(wpa_s->p2pdev->p2ps_join_addr)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2PS: Setting default PIN for ANY");
- wpa_supplicant_ap_wps_pin(wpa_s, NULL,
- "12345670", NULL, 0,
- 0);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2PS: Setting default PIN for " MACSTR,
- MAC2STR(wpa_s->p2pdev->p2ps_join_addr));
- wpa_supplicant_ap_wps_pin(
- wpa_s, wpa_s->p2pdev->p2ps_join_addr,
- "12345670", NULL, 0, 0);
- }
- wpa_s->p2pdev->p2ps_method_config_any = 0;
- }
-
- os_get_reltime(&wpa_s->global->p2p_go_wait_client);
- if (params->persistent_group) {
- wpas_p2p_store_persistent_group(
- wpa_s->p2pdev, ssid,
- wpa_s->global->p2p_dev_addr);
- wpas_p2p_add_psk_list(wpa_s, ssid);
- }
-
- wpas_notify_p2p_group_started(wpa_s, ssid,
- params->persistent_group, 0,
- NULL);
- wpas_p2p_cross_connect_setup(wpa_s);
- wpas_p2p_set_group_idle_timeout(wpa_s);
-
- if (wpa_s->p2p_first_connection_timeout) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Start group formation timeout of %d seconds until first data connection on GO",
- wpa_s->p2p_first_connection_timeout);
- wpa_s->p2p_go_group_formation_completed = 0;
- wpa_s->global->p2p_group_formation = wpa_s;
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- eloop_register_timeout(
- wpa_s->p2p_first_connection_timeout, 0,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- }
-
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning");
- if (wpa_supplicant_ap_mac_addr_filter(wpa_s,
- params->peer_interface_addr)) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address "
- "filtering");
- return;
- }
- if (params->wps_method == WPS_PBC) {
- wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
- params->peer_device_addr);
-#ifdef CONFIG_WPS_NFC
- } else if (params->wps_method == WPS_NFC) {
- if (wpa_s->p2pdev->p2p_oob_dev_pw_id !=
- DEV_PW_NFC_CONNECTION_HANDOVER &&
- !wpa_s->p2pdev->p2p_oob_dev_pw) {
- wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
- return;
- }
- wpas_ap_wps_add_nfc_pw(
- wpa_s, wpa_s->p2pdev->p2p_oob_dev_pw_id,
- wpa_s->p2pdev->p2p_oob_dev_pw,
- wpa_s->p2pdev->p2p_peer_oob_pk_hash_known ?
- wpa_s->p2pdev->p2p_peer_oob_pubkey_hash : NULL);
-#endif /* CONFIG_WPS_NFC */
- } else if (wpa_s->p2p_pin[0])
- wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
- wpa_s->p2p_pin, NULL, 0, 0);
- os_free(wpa_s->go_params);
- wpa_s->go_params = NULL;
-}
-
-
-/**
- * wpas_p2p_freq_to_edmg_channel - Convert frequency into EDMG channel
- * @freq: Frequency (MHz) to convert
- * @op_class: Buffer for returning operating class
- * @op_edmg_channel: Buffer for returning channel number
- * Returns: 0 on success, -1 on failure
- *
- * This can be used to find the highest channel bonding which includes the
- * specified frequency.
- */
-static int wpas_p2p_freq_to_edmg_channel(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- u8 *op_class, u8 *op_edmg_channel)
-{
- struct hostapd_hw_modes *hwmode;
- struct ieee80211_edmg_config edmg;
- unsigned int i;
- enum chan_width chanwidth[] = {
- CHAN_WIDTH_8640,
- CHAN_WIDTH_6480,
- CHAN_WIDTH_4320,
- };
-
- if (!wpa_s->hw.modes)
- return -1;
-
- hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211AD, false);
- if (!hwmode) {
- wpa_printf(MSG_ERROR,
- "Unsupported AP mode: HOSTAPD_MODE_IEEE80211AD");
- return -1;
- }
-
- /* Find the highest EDMG channel bandwidth to start the P2P GO */
- for (i = 0; i < ARRAY_SIZE(chanwidth); i++) {
- if (ieee80211_chaninfo_to_channel(freq, chanwidth[i], 0,
- op_class,
- op_edmg_channel) < 0)
- continue;
-
- hostapd_encode_edmg_chan(1, *op_edmg_channel, 0, &edmg);
- if (edmg.channels &&
- ieee802_edmg_is_allowed(hwmode->edmg, edmg)) {
- wpa_printf(MSG_DEBUG,
- "Freq %u to EDMG channel %u at opclass %u",
- freq, *op_edmg_channel, *op_class);
- return 0;
- }
- }
-
- return -1;
-}
-
-
-int wpas_p2p_try_edmg_channel(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params)
-{
- u8 op_channel, op_class;
- int freq;
-
- /* Try social channel as primary channel frequency */
- freq = (!params->freq) ? 58320 + 1 * 2160 : params->freq;
-
- if (wpas_p2p_freq_to_edmg_channel(wpa_s, freq, &op_class,
- &op_channel) == 0) {
- wpa_printf(MSG_DEBUG,
- "Freq %d will be used to set an EDMG connection (channel=%u opclass=%u)",
- freq, op_channel, op_class);
- params->freq = freq;
- return 0;
- }
-
- return -1;
-}
-
-
-static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params,
- int group_formation)
-{
- struct wpa_ssid *ssid;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO");
- if (wpas_copy_go_neg_results(wpa_s, params) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation "
- "results");
- return;
- }
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO");
- return;
- }
-
- wpa_s->show_group_started = 0;
- wpa_s->p2p_go_group_formation_completed = 0;
- wpa_s->group_formation_reported = 0;
- os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
-
- wpa_config_set_network_defaults(ssid);
- ssid->temporary = 1;
- ssid->p2p_group = 1;
- ssid->p2p_persistent_group = !!params->persistent_group;
- ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
- WPAS_MODE_P2P_GO;
- ssid->frequency = params->freq;
- ssid->ht40 = params->ht40;
- ssid->vht = params->vht;
- ssid->max_oper_chwidth = params->max_oper_chwidth;
- ssid->vht_center_freq2 = params->vht_center_freq2;
- ssid->he = params->he;
- if (params->edmg) {
- u8 op_channel, op_class;
-
- if (!wpas_p2p_freq_to_edmg_channel(wpa_s, params->freq,
- &op_class, &op_channel)) {
- ssid->edmg_channel = op_channel;
- ssid->enable_edmg = params->edmg;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Could not match EDMG channel, freq %d, for GO",
- params->freq);
- }
- }
-
- ssid->ssid = os_zalloc(params->ssid_len + 1);
- if (ssid->ssid) {
- os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
- ssid->ssid_len = params->ssid_len;
- }
- ssid->auth_alg = WPA_AUTH_ALG_OPEN;
- ssid->key_mgmt = WPA_KEY_MGMT_PSK;
- if (is_6ghz_freq(ssid->frequency) &&
- is_p2p_6ghz_capable(wpa_s->global->p2p)) {
- ssid->auth_alg |= WPA_AUTH_ALG_SAE;
- ssid->key_mgmt = WPA_KEY_MGMT_SAE;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
- ssid->sae_pwe = 1;
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use SAE auth_alg and key_mgmt");
- } else {
- p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
- }
- ssid->proto = WPA_PROTO_RSN;
- ssid->pairwise_cipher = WPA_CIPHER_CCMP;
- ssid->group_cipher = WPA_CIPHER_CCMP;
- if (params->freq > 56160) {
- /*
- * Enable GCMP instead of CCMP as pairwise_cipher and
- * group_cipher in 60 GHz.
- */
- ssid->pairwise_cipher = WPA_CIPHER_GCMP;
- ssid->group_cipher = WPA_CIPHER_GCMP;
- /* P2P GO in 60 GHz is always a PCP (PBSS) */
- ssid->pbss = 1;
- }
- if (os_strlen(params->passphrase) > 0) {
- ssid->passphrase = os_strdup(params->passphrase);
- if (ssid->passphrase == NULL) {
- wpa_msg_global(wpa_s, MSG_ERROR,
- "P2P: Failed to copy passphrase for GO");
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return;
- }
- } else
- ssid->passphrase = NULL;
- ssid->psk_set = params->psk_set;
- if (ssid->psk_set)
- os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
- else if (ssid->passphrase)
- wpa_config_update_psk(ssid);
- ssid->ap_max_inactivity = wpa_s->p2pdev->conf->p2p_go_max_inactivity;
-
- wpa_s->ap_configured_cb = p2p_go_configured;
- wpa_s->ap_configured_cb_ctx = wpa_s;
- wpa_s->ap_configured_cb_data = wpa_s->go_params;
- wpa_s->scan_req = NORMAL_SCAN_REQ;
- wpa_s->connect_without_scan = ssid;
- wpa_s->reassociate = 1;
- wpa_s->disconnected = 0;
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to "
- "start GO)");
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
- const struct wpa_supplicant *src)
-{
- struct wpa_config *d;
- const struct wpa_config *s;
-
- d = dst->conf;
- s = src->conf;
-
-#define C(n) \
-do { \
- if (s->n && !d->n) \
- d->n = os_strdup(s->n); \
-} while (0)
-
- C(device_name);
- C(manufacturer);
- C(model_name);
- C(model_number);
- C(serial_number);
- C(config_methods);
-#undef C
-
- os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
- os_memcpy(d->sec_device_type, s->sec_device_type,
- sizeof(d->sec_device_type));
- d->num_sec_device_types = s->num_sec_device_types;
-
- d->p2p_group_idle = s->p2p_group_idle;
- d->p2p_go_freq_change_policy = s->p2p_go_freq_change_policy;
- d->p2p_intra_bss = s->p2p_intra_bss;
- d->persistent_reconnect = s->persistent_reconnect;
- d->max_num_sta = s->max_num_sta;
- d->pbc_in_m1 = s->pbc_in_m1;
- d->ignore_old_scan_res = s->ignore_old_scan_res;
- d->beacon_int = s->beacon_int;
- d->dtim_period = s->dtim_period;
- d->p2p_go_ctwindow = s->p2p_go_ctwindow;
- d->disassoc_low_ack = s->disassoc_low_ack;
- d->disable_scan_offload = s->disable_scan_offload;
- d->passive_scan = s->passive_scan;
- d->pmf = s->pmf;
- d->p2p_6ghz_disable = s->p2p_6ghz_disable;
-
- if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey &&
- !d->wps_nfc_pw_from_config) {
- wpabuf_free(d->wps_nfc_dh_privkey);
- wpabuf_free(d->wps_nfc_dh_pubkey);
- d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
- d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
- }
- d->p2p_cli_probe = s->p2p_cli_probe;
- d->go_interworking = s->go_interworking;
- d->go_access_network_type = s->go_access_network_type;
- d->go_internet = s->go_internet;
- d->go_venue_group = s->go_venue_group;
- d->go_venue_type = s->go_venue_type;
- d->p2p_add_cli_chan = s->p2p_add_cli_chan;
-}
-
-
-static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
- char *ifname, size_t len)
-{
- char *ifname_ptr = wpa_s->ifname;
-
- if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
- os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
- ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
- }
-
- os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
- if (os_strlen(ifname) >= IFNAMSIZ &&
- os_strlen(wpa_s->ifname) < IFNAMSIZ) {
- int res;
-
- /* Try to avoid going over the IFNAMSIZ length limit */
- res = os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx);
- if (os_snprintf_error(len, res) && len)
- ifname[len - 1] = '\0';
- }
-}
-
-
-static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type type)
-{
- char ifname[120], force_ifname[120];
-
- if (wpa_s->pending_interface_name[0]) {
- wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists "
- "- skip creation of a new one");
- if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
- wpa_printf(MSG_DEBUG, "P2P: Pending virtual address "
- "unknown?! ifname='%s'",
- wpa_s->pending_interface_name);
- return -1;
- }
- return 0;
- }
-
- wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
- force_ifname[0] = '\0';
-
- wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
- ifname);
- wpa_s->p2p_group_idx++;
-
- wpa_s->pending_interface_type = type;
- if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname,
- wpa_s->pending_interface_addr, NULL) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Failed to create new group "
- "interface");
- return -1;
- }
-
- if (wpa_s->conf->p2p_interface_random_mac_addr) {
- random_mac_addr(wpa_s->pending_interface_addr);
- wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR
- " for the group",
- MAC2STR(wpa_s->pending_interface_addr));
- }
-
- if (force_ifname[0]) {
- wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
- force_ifname);
- os_strlcpy(wpa_s->pending_interface_name, force_ifname,
- sizeof(wpa_s->pending_interface_name));
- } else
- os_strlcpy(wpa_s->pending_interface_name, ifname,
- sizeof(wpa_s->pending_interface_name));
- wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr "
- MACSTR, wpa_s->pending_interface_name,
- MAC2STR(wpa_s->pending_interface_addr));
-
- return 0;
-}
-
-
-static void wpas_p2p_remove_pending_group_interface(
- struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->pending_interface_name[0] ||
- is_zero_ether_addr(wpa_s->pending_interface_addr))
- return; /* No pending virtual interface */
-
- wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s",
- wpa_s->pending_interface_name);
- wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type,
- wpa_s->pending_interface_name);
- os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
- wpa_s->pending_interface_name[0] = '\0';
- wpa_s->global->pending_group_iface_for_p2ps = 0;
-}
-
-
-static struct wpa_supplicant *
-wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go)
-{
- struct wpa_interface iface;
- struct wpa_supplicant *group_wpa_s;
-
- if (!wpa_s->pending_interface_name[0]) {
- wpa_printf(MSG_ERROR, "P2P: No pending group interface");
- if (!wpas_p2p_create_iface(wpa_s))
- return NULL;
- /*
- * Something has forced us to remove the pending interface; try
- * to create a new one and hope for the best that we will get
- * the same local address.
- */
- if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
- WPA_IF_P2P_CLIENT) < 0)
- return NULL;
- }
-
- os_memset(&iface, 0, sizeof(iface));
- iface.ifname = wpa_s->pending_interface_name;
- iface.driver = wpa_s->driver->name;
- if (wpa_s->conf->ctrl_interface == NULL &&
- wpa_s->parent != wpa_s &&
- wpa_s->p2p_mgmt &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
- iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
- else
- iface.ctrl_interface = wpa_s->conf->ctrl_interface;
- iface.driver_param = wpa_s->conf->driver_param;
- group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
- if (group_wpa_s == NULL) {
- wpa_printf(MSG_ERROR, "P2P: Failed to create new "
- "wpa_supplicant interface");
- return NULL;
- }
- wpa_s->pending_interface_name[0] = '\0';
- group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO :
- P2P_GROUP_INTERFACE_CLIENT;
- wpa_s->global->p2p_group_formation = group_wpa_s;
- wpa_s->global->pending_group_iface_for_p2ps = 0;
-
- wpas_p2p_clone_config(group_wpa_s, wpa_s);
-
- if (wpa_s->conf->p2p_interface_random_mac_addr) {
- if (wpa_drv_set_mac_addr(group_wpa_s,
- wpa_s->pending_interface_addr) < 0) {
- wpa_msg(group_wpa_s, MSG_INFO,
- "Failed to set random MAC address");
- wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s,
- 0);
- return NULL;
- }
-
- if (wpa_supplicant_update_mac_addr(group_wpa_s) < 0) {
- wpa_msg(group_wpa_s, MSG_INFO,
- "Could not update MAC address information");
- wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s,
- 0);
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Using random MAC address " MACSTR
- " for the group",
- MAC2STR(wpa_s->pending_interface_addr));
- }
-
- return group_wpa_s;
-}
-
-
-static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
- void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
- wpas_p2p_group_formation_failed(wpa_s, 0);
-}
-
-
-static void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s,
- int already_deleted)
-{
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- if (wpa_s->global->p2p)
- p2p_group_formation_failed(wpa_s->global->p2p);
- wpas_group_formation_completed(wpa_s, 0, already_deleted);
-}
-
-
-static void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure");
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- wpa_s->global->p2p_fail_on_wps_complete = 0;
-}
-
-
-void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->global->p2p_group_formation != wpa_s)
- return;
- /* Speed up group formation timeout since this cannot succeed */
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
-}
-
-
-static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_supplicant *group_wpa_s;
-
- if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = 0;
- }
-
- if (res->status) {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_GO_NEG_FAILURE "status=%d",
- res->status);
- wpas_notify_p2p_go_neg_completed(wpa_s, res);
- wpas_p2p_remove_pending_group_interface(wpa_s);
- return;
- }
-
- if (!res->role_go) {
- /* Inform driver of the operating channel of GO. */
- wpa_drv_set_prob_oper_freq(wpa_s, res->freq);
- }
-
- if (wpa_s->p2p_go_ht40)
- res->ht40 = 1;
- if (wpa_s->p2p_go_vht)
- res->vht = 1;
- if (wpa_s->p2p_go_he)
- res->he = 1;
- if (wpa_s->p2p_go_edmg)
- res->edmg = 1;
- res->max_oper_chwidth = wpa_s->p2p_go_max_oper_chwidth;
- res->vht_center_freq2 = wpa_s->p2p_go_vht_center_freq2;
-
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
- "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
- " wps_method=%s",
- res->role_go ? "GO" : "client", res->freq, res->ht40,
- MAC2STR(res->peer_device_addr),
- MAC2STR(res->peer_interface_addr),
- p2p_wps_method_text(res->wps_method));
- wpas_notify_p2p_go_neg_completed(wpa_s, res);
-
- if (res->role_go && wpa_s->p2p_persistent_id >= 0) {
- struct wpa_ssid *ssid;
- ssid = wpa_config_get_network(wpa_s->conf,
- wpa_s->p2p_persistent_id);
- if (ssid && ssid->disabled == 2 &&
- ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) {
- size_t len = os_strlen(ssid->passphrase);
- wpa_printf(MSG_DEBUG, "P2P: Override passphrase based "
- "on requested persistent group");
- os_memcpy(res->passphrase, ssid->passphrase, len);
- res->passphrase[len] = '\0';
- }
- }
-
- if (wpa_s->create_p2p_iface) {
- group_wpa_s =
- wpas_p2p_init_group_interface(wpa_s, res->role_go);
- if (group_wpa_s == NULL) {
- wpas_p2p_remove_pending_group_interface(wpa_s);
- eloop_cancel_timeout(wpas_p2p_long_listen_timeout,
- wpa_s, NULL);
- wpas_p2p_group_formation_failed(wpa_s, 1);
- return;
- }
- os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
- wpa_s->pending_interface_name[0] = '\0';
- } else {
- group_wpa_s = wpa_s->parent;
- wpa_s->global->p2p_group_formation = group_wpa_s;
- if (group_wpa_s != wpa_s)
- wpas_p2p_clone_config(group_wpa_s, wpa_s);
- }
-
- group_wpa_s->p2p_in_provisioning = 1;
- group_wpa_s->p2pdev = wpa_s;
- if (group_wpa_s != wpa_s) {
- os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin,
- sizeof(group_wpa_s->p2p_pin));
- group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method;
- }
- if (res->role_go) {
- wpas_start_wps_go(group_wpa_s, res, 1);
- } else {
- os_get_reltime(&group_wpa_s->scan_min_time);
- wpas_start_wps_enrollee(group_wpa_s, res);
- }
-
- wpa_s->global->p2p_long_listen = 0;
- eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
-
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
- eloop_register_timeout(15 + res->peer_config_timeout / 100,
- (res->peer_config_timeout % 100) * 10000,
- wpas_p2p_group_formation_timeout, wpa_s, NULL);
-}
-
-
-static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id,
- u8 go_intent)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
- " dev_passwd_id=%u go_intent=%u", MAC2STR(src),
- dev_passwd_id, go_intent);
-
- wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
-}
-
-
-static void wpas_dev_found(void *ctx, const u8 *addr,
- const struct p2p_peer_info *info,
- int new_device)
-{
-#ifndef CONFIG_NO_STDOUT_DEBUG
- struct wpa_supplicant *wpa_s = ctx;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
- char *wfd_dev_info_hex = NULL;
-
-#ifdef CONFIG_WIFI_DISPLAY
- wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
- WFD_SUBELEM_DEVICE_INFO);
-#endif /* CONFIG_WIFI_DISPLAY */
-
- if (info->p2ps_instance) {
- char str[256];
- const u8 *buf = wpabuf_head(info->p2ps_instance);
- size_t len = wpabuf_len(info->p2ps_instance);
-
- while (len) {
- u32 id;
- u16 methods;
- u8 str_len;
-
- if (len < 4 + 2 + 1)
- break;
- id = WPA_GET_LE32(buf);
- buf += sizeof(u32);
- methods = WPA_GET_BE16(buf);
- buf += sizeof(u16);
- str_len = *buf++;
- if (str_len > len - 4 - 2 - 1)
- break;
- os_memcpy(str, buf, str_len);
- str[str_len] = '\0';
- buf += str_len;
- len -= str_len + sizeof(u32) + sizeof(u16) + sizeof(u8);
-
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_DEVICE_FOUND MACSTR
- " p2p_dev_addr=" MACSTR
- " pri_dev_type=%s name='%s'"
- " config_methods=0x%x"
- " dev_capab=0x%x"
- " group_capab=0x%x"
- " adv_id=%x asp_svc=%s%s",
- MAC2STR(addr),
- MAC2STR(info->p2p_device_addr),
- wps_dev_type_bin2str(
- info->pri_dev_type,
- devtype, sizeof(devtype)),
- info->device_name, methods,
- info->dev_capab, info->group_capab,
- id, str,
- info->vendor_elems ?
- " vendor_elems=1" : "");
- }
- goto done;
- }
-
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
- " p2p_dev_addr=" MACSTR
- " pri_dev_type=%s name='%s' config_methods=0x%x "
- "dev_capab=0x%x group_capab=0x%x%s%s%s new=%d",
- MAC2STR(addr), MAC2STR(info->p2p_device_addr),
- wps_dev_type_bin2str(info->pri_dev_type, devtype,
- sizeof(devtype)),
- info->device_name, info->config_methods,
- info->dev_capab, info->group_capab,
- wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
- wfd_dev_info_hex ? wfd_dev_info_hex : "",
- info->vendor_elems ? " vendor_elems=1" : "",
- new_device);
-
-done:
- os_free(wfd_dev_info_hex);
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
- wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
-}
-
-
-static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
- "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
-
- wpas_notify_p2p_device_lost(wpa_s, dev_addr);
-}
-
-
-static void wpas_find_stopped(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->p2p_scan_work && wpas_abort_ongoing_scan(wpa_s) < 0)
- wpa_printf(MSG_DEBUG, "P2P: Abort ongoing scan failed");
-
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
- wpas_notify_p2p_find_stopped(wpa_s);
-}
-
-
-struct wpas_p2p_listen_work {
- unsigned int freq;
- unsigned int duration;
- struct wpabuf *probe_resp_ie;
-};
-
-
-static void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork)
-{
- if (lwork == NULL)
- return;
- wpabuf_free(lwork->probe_resp_ie);
- os_free(lwork);
-}
-
-
-static void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s)
-{
- struct wpas_p2p_listen_work *lwork;
-
- if (!wpa_s->p2p_listen_work)
- return;
-
- lwork = wpa_s->p2p_listen_work->ctx;
- wpas_p2p_listen_work_free(lwork);
- radio_work_done(wpa_s->p2p_listen_work);
- wpa_s->p2p_listen_work = NULL;
-}
-
-
-static void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpas_p2p_listen_work *lwork = work->ctx;
- unsigned int duration;
-
- if (deinit) {
- if (work->started) {
- wpa_s->p2p_listen_work = NULL;
- wpas_stop_listen(wpa_s);
- }
- wpas_p2p_listen_work_free(lwork);
- return;
- }
-
- wpa_s->p2p_listen_work = work;
-
- wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL);
-
- if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
- "report received Probe Request frames");
- wpas_p2p_listen_work_done(wpa_s);
- return;
- }
-
- wpa_s->pending_listen_freq = lwork->freq;
- wpa_s->pending_listen_duration = lwork->duration;
-
- duration = lwork->duration;
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->extra_roc_dur) {
- wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u",
- duration, duration + wpa_s->extra_roc_dur);
- duration += wpa_s->extra_roc_dur;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver "
- "to remain on channel (%u MHz) for Listen "
- "state", lwork->freq);
- wpas_p2p_listen_work_done(wpa_s);
- wpa_s->pending_listen_freq = 0;
- return;
- }
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = lwork->freq;
-}
-
-
-static int wpas_start_listen(void *ctx, unsigned int freq,
- unsigned int duration,
- const struct wpabuf *probe_resp_ie)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpas_p2p_listen_work *lwork;
-
- if (wpa_s->p2p_listen_work) {
- wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists");
- return -1;
- }
-
- lwork = os_zalloc(sizeof(*lwork));
- if (lwork == NULL)
- return -1;
- lwork->freq = freq;
- lwork->duration = duration;
- if (probe_resp_ie) {
- lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie);
- if (lwork->probe_resp_ie == NULL) {
- wpas_p2p_listen_work_free(lwork);
- return -1;
- }
- }
-
- if (radio_add_work(wpa_s, freq, "p2p-listen", 0, wpas_start_listen_cb,
- lwork) < 0) {
- wpas_p2p_listen_work_free(lwork);
- return -1;
- }
-
- return 0;
-}
-
-
-static void wpas_stop_listen(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = 0;
- }
- wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL);
-
- /*
- * Don't cancel Probe Request RX reporting for a connected P2P Client
- * handling Probe Request frames.
- */
- if (!wpa_s->p2p_cli_probe)
- wpa_drv_probe_req_report(wpa_s, 0);
-
- wpas_p2p_listen_work_done(wpa_s);
-}
-
-
-static int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf,
- unsigned int freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
- freq, 0);
-}
-
-
-static void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s,
- const u8 *peer, const char *params,
- unsigned int generated_pin)
-{
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR
- " %08d%s", MAC2STR(peer), generated_pin, params);
-}
-
-
-static void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
- const u8 *peer, const char *params)
-{
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR
- "%s", MAC2STR(peer), params);
-}
-
-
-static void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
- const u8 *dev_addr, const u8 *pri_dev_type,
- const char *dev_name, u16 supp_config_methods,
- u8 dev_capab, u8 group_capab, const u8 *group_id,
- size_t group_id_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
- char params[300];
- u8 empty_dev_type[8];
- unsigned int generated_pin = 0;
- struct wpa_supplicant *group = NULL;
- int res;
-
- if (group_id) {
- for (group = wpa_s->global->ifaces; group; group = group->next)
- {
- struct wpa_ssid *s = group->current_ssid;
- if (s != NULL &&
- s->mode == WPAS_MODE_P2P_GO &&
- group_id_len - ETH_ALEN == s->ssid_len &&
- os_memcmp(group_id + ETH_ALEN, s->ssid,
- s->ssid_len) == 0)
- break;
- }
- }
-
- if (pri_dev_type == NULL) {
- os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
- pri_dev_type = empty_dev_type;
- }
- res = os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
- " pri_dev_type=%s name='%s' config_methods=0x%x "
- "dev_capab=0x%x group_capab=0x%x%s%s",
- MAC2STR(dev_addr),
- wps_dev_type_bin2str(pri_dev_type, devtype,
- sizeof(devtype)),
- dev_name, supp_config_methods, dev_capab, group_capab,
- group ? " group=" : "",
- group ? group->ifname : "");
- if (os_snprintf_error(sizeof(params), res))
- wpa_printf(MSG_DEBUG, "P2P: PD Request event truncated");
- params[sizeof(params) - 1] = '\0';
-
- if (config_methods & WPS_CONFIG_DISPLAY) {
- if (wps_generate_pin(&generated_pin) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Could not generate PIN");
- wpas_notify_p2p_provision_discovery(
- wpa_s, peer, 0 /* response */,
- P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
- return;
- }
- wpas_prov_disc_local_display(wpa_s, peer, params,
- generated_pin);
- } else if (config_methods & WPS_CONFIG_KEYPAD)
- wpas_prov_disc_local_keypad(wpa_s, peer, params);
- else if (config_methods & WPS_CONFIG_PUSHBUTTON)
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ
- MACSTR "%s", MAC2STR(peer), params);
-
- wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */,
- P2P_PROV_DISC_SUCCESS,
- config_methods, generated_pin);
-}
-
-
-static void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
-{
- struct wpa_supplicant *wpa_s = ctx;
- unsigned int generated_pin = 0;
- char params[20];
-
- if (wpa_s->pending_pd_before_join &&
- (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
- os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
- wpa_s->pending_pd_before_join = 0;
- wpa_printf(MSG_DEBUG, "P2P: Starting pending "
- "join-existing-group operation");
- wpas_p2p_join_start(wpa_s, 0, NULL, 0);
- return;
- }
-
- if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
- wpa_s->pending_pd_use == AUTO_PD_GO_NEG) {
- int res;
-
- res = os_snprintf(params, sizeof(params), " peer_go=%d",
- wpa_s->pending_pd_use == AUTO_PD_JOIN);
- if (os_snprintf_error(sizeof(params), res))
- params[sizeof(params) - 1] = '\0';
- } else
- params[0] = '\0';
-
- if (config_methods & WPS_CONFIG_DISPLAY)
- wpas_prov_disc_local_keypad(wpa_s, peer, params);
- else if (config_methods & WPS_CONFIG_KEYPAD) {
- if (wps_generate_pin(&generated_pin) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Could not generate PIN");
- wpas_notify_p2p_provision_discovery(
- wpa_s, peer, 0 /* response */,
- P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
- return;
- }
- wpas_prov_disc_local_display(wpa_s, peer, params,
- generated_pin);
- } else if (config_methods & WPS_CONFIG_PUSHBUTTON)
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP
- MACSTR "%s", MAC2STR(peer), params);
-
- wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
- P2P_PROV_DISC_SUCCESS,
- config_methods, generated_pin);
-}
-
-
-static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
- enum p2p_prov_disc_status status,
- u32 adv_id, const u8 *adv_mac,
- const char *deferred_session_resp)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->p2p_fallback_to_go_neg) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto "
- "failed - fall back to GO Negotiation");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=PD-failed");
- wpas_p2p_fallback_to_go_neg(wpa_s, 0);
- return;
- }
-
- if (status == P2P_PROV_DISC_TIMEOUT_JOIN) {
- wpa_s->pending_pd_before_join = 0;
- wpa_printf(MSG_DEBUG, "P2P: Starting pending "
- "join-existing-group operation (no ACK for PD "
- "Req attempts)");
- wpas_p2p_join_start(wpa_s, 0, NULL, 0);
- return;
- }
-
- if (adv_id && adv_mac && deferred_session_resp) {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
- " p2p_dev_addr=" MACSTR " status=%d adv_id=%x"
- " deferred_session_resp='%s'",
- MAC2STR(peer), status, adv_id,
- deferred_session_resp);
- } else if (adv_id && adv_mac) {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
- " p2p_dev_addr=" MACSTR " status=%d adv_id=%x",
- MAC2STR(peer), status, adv_id);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
- " p2p_dev_addr=" MACSTR " status=%d",
- MAC2STR(peer), status);
- }
-
- wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
- status, 0, 0);
-}
-
-
-static int freq_included(struct wpa_supplicant *wpa_s,
- const struct p2p_channels *channels,
- unsigned int freq)
-{
- if ((channels == NULL || p2p_channels_includes_freq(channels, freq)) &&
- wpas_p2p_go_is_peer_freq(wpa_s, freq))
- return 1;
- return 0;
-}
-
-
-static void wpas_p2p_go_update_common_freqs(struct wpa_supplicant *wpa_s)
-{
- unsigned int num = P2P_MAX_CHANNELS;
- int *common_freqs;
- int ret;
-
- p2p_go_dump_common_freqs(wpa_s);
- common_freqs = os_calloc(num, sizeof(int));
- if (!common_freqs)
- return;
-
- ret = p2p_group_get_common_freqs(wpa_s->p2p_group, common_freqs, &num);
- if (ret < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Failed to get group common freqs");
- os_free(common_freqs);
- return;
- }
-
- os_free(wpa_s->p2p_group_common_freqs);
- wpa_s->p2p_group_common_freqs = common_freqs;
- wpa_s->p2p_group_common_freqs_num = num;
- p2p_go_dump_common_freqs(wpa_s);
-}
-
-
-/*
- * Check if the given frequency is one of the possible operating frequencies
- * set after the completion of the GO Negotiation.
- */
-static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq)
-{
- unsigned int i;
-
- p2p_go_dump_common_freqs(wpa_s);
-
- /* assume no restrictions */
- if (!wpa_s->p2p_group_common_freqs_num)
- return 1;
-
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- if (wpa_s->p2p_group_common_freqs[i] == freq)
- return 1;
- }
- return 0;
-}
-
-
-static int wpas_sta_check_ecsa(struct hostapd_data *hapd,
- struct sta_info *sta, void *ctx)
-{
- int *ecsa_support = ctx;
-
- *ecsa_support &= sta->ecsa_supported;
-
- return 0;
-}
-
-
-/* Check if all the peers support eCSA */
-static int wpas_p2p_go_clients_support_ecsa(struct wpa_supplicant *wpa_s)
-{
- int ecsa_support = 1;
-
- ap_for_each_sta(wpa_s->ap_iface->bss[0], wpas_sta_check_ecsa,
- &ecsa_support);
-
- return ecsa_support;
-}
-
-
-/**
- * Pick the best frequency to use from all the currently used frequencies.
- */
-static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs,
- unsigned int num)
-{
- unsigned int i, c;
-
- /* find a candidate freq that is supported by P2P */
- for (c = 0; c < num; c++)
- if (p2p_supported_freq(wpa_s->global->p2p, freqs[c].freq))
- break;
-
- if (c == num)
- return 0;
-
- /* once we have a candidate, try to find a 'better' one */
- for (i = c + 1; i < num; i++) {
- if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
- continue;
-
- /*
- * 1. Infrastructure station interfaces have higher preference.
- * 2. P2P Clients have higher preference.
- * 3. All others.
- */
- if (freqs[i].flags & WPA_FREQ_USED_BY_INFRA_STATION) {
- c = i;
- break;
- }
-
- if ((freqs[i].flags & WPA_FREQ_USED_BY_P2P_CLIENT))
- c = i;
- }
- return freqs[c].freq;
-}
-
-
-static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
- const u8 *go_dev_addr, const u8 *ssid,
- size_t ssid_len, int *go, u8 *group_bssid,
- int *force_freq, int persistent_group,
- const struct p2p_channels *channels,
- int dev_pw_id)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *s;
- struct wpa_used_freq_data *freqs;
- struct wpa_supplicant *grp;
- int best_freq;
-
- if (!persistent_group) {
- wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
- " to join an active group (SSID: %s)",
- MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len));
- if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
- (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
- == 0 ||
- os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) {
- wpa_printf(MSG_DEBUG, "P2P: Accept previously "
- "authorized invitation");
- goto accept_inv;
- }
-
-#ifdef CONFIG_WPS_NFC
- if (dev_pw_id >= 0 && wpa_s->p2p_nfc_tag_enabled &&
- dev_pw_id == wpa_s->p2p_oob_dev_pw_id) {
- wpa_printf(MSG_DEBUG, "P2P: Accept invitation based on local enabled NFC Tag");
- wpa_s->p2p_wps_method = WPS_NFC;
- wpa_s->pending_join_wps_method = WPS_NFC;
- os_memcpy(wpa_s->pending_join_dev_addr,
- go_dev_addr, ETH_ALEN);
- os_memcpy(wpa_s->pending_join_iface_addr,
- bssid, ETH_ALEN);
- goto accept_inv;
- }
-#endif /* CONFIG_WPS_NFC */
-
- /*
- * Do not accept the invitation automatically; notify user and
- * request approval.
- */
- return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
- }
-
- grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go);
- if (grp) {
- wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already "
- "running persistent group");
- if (*go)
- os_memcpy(group_bssid, grp->own_addr, ETH_ALEN);
- goto accept_inv;
- }
-
- if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
- os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated "
- "invitation to re-invoke a persistent group");
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
- } else if (!wpa_s->conf->persistent_reconnect)
- return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
-
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled == 2 &&
- os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 &&
- s->ssid_len == ssid_len &&
- os_memcmp(ssid, s->ssid, ssid_len) == 0)
- break;
- }
-
- if (!s) {
- wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
- " requested reinvocation of an unknown group",
- MAC2STR(sa));
- return P2P_SC_FAIL_UNKNOWN_GROUP;
- }
-
- if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) {
- *go = 1;
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- wpa_printf(MSG_DEBUG, "P2P: The only available "
- "interface is already in use - reject "
- "invitation");
- return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
- }
- if (wpa_s->p2p_mgmt)
- os_memcpy(group_bssid, wpa_s->parent->own_addr,
- ETH_ALEN);
- else
- os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN);
- } else if (s->mode == WPAS_MODE_P2P_GO) {
- *go = 1;
- if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0)
- {
- wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
- "interface address for the group");
- return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
- }
- os_memcpy(group_bssid, wpa_s->pending_interface_addr,
- ETH_ALEN);
- }
-
-accept_inv:
- wpas_p2p_set_own_freq_preference(wpa_s, 0);
-
- best_freq = 0;
- freqs = os_calloc(wpa_s->num_multichan_concurrent,
- sizeof(struct wpa_used_freq_data));
- if (freqs) {
- int num_channels = wpa_s->num_multichan_concurrent;
- int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, num_channels);
- best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
- os_free(freqs);
- }
-
- /* Get one of the frequencies currently in use */
- if (best_freq > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
- wpas_p2p_set_own_freq_preference(wpa_s, best_freq);
-
- if (wpa_s->num_multichan_concurrent < 2 ||
- wpas_p2p_num_unused_channels(wpa_s) < 1) {
- wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
- *force_freq = best_freq;
- }
- }
-
- if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
- wpas_p2p_num_unused_channels(wpa_s) > 0) {
- if (*go == 0) {
- /* We are the client */
- wpa_printf(MSG_DEBUG, "P2P: Peer was found to be "
- "running a GO but we are capable of MCC, "
- "figure out the best channel to use");
- *force_freq = 0;
- } else if (!freq_included(wpa_s, channels, *force_freq)) {
- /* We are the GO, and *force_freq is not in the
- * intersection */
- wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
- "in intersection but we are capable of MCC, "
- "figure out the best channel to use",
- *force_freq);
- *force_freq = 0;
- }
- }
-
- return P2P_SC_SUCCESS;
-}
-
-
-static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
- const u8 *ssid, size_t ssid_len,
- const u8 *go_dev_addr, u8 status,
- int op_freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *s;
-
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled == 2 &&
- s->ssid_len == ssid_len &&
- os_memcmp(ssid, s->ssid, ssid_len) == 0)
- break;
- }
-
- if (status == P2P_SC_SUCCESS) {
- wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
- " was accepted; op_freq=%d MHz, SSID=%s",
- MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
- if (s) {
- int go = s->mode == WPAS_MODE_P2P_GO;
- if (go) {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_INVITATION_ACCEPTED
- "sa=" MACSTR
- " persistent=%d freq=%d",
- MAC2STR(sa), s->id, op_freq);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_INVITATION_ACCEPTED
- "sa=" MACSTR
- " persistent=%d",
- MAC2STR(sa), s->id);
- }
- wpas_p2p_group_add_persistent(
- wpa_s, s, go, 0, op_freq, 0,
- wpa_s->conf->p2p_go_ht40,
- wpa_s->conf->p2p_go_vht,
- 0,
- wpa_s->conf->p2p_go_he,
- wpa_s->conf->p2p_go_edmg, NULL,
- go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
- 1, is_p2p_allow_6ghz(wpa_s->global->p2p));
- } else if (bssid) {
- wpa_s->user_initiated_pd = 0;
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_INVITATION_ACCEPTED
- "sa=" MACSTR " go_dev_addr=" MACSTR
- " bssid=" MACSTR " unknown-network",
- MAC2STR(sa), MAC2STR(go_dev_addr),
- MAC2STR(bssid));
- wpas_p2p_join(wpa_s, bssid, go_dev_addr,
- wpa_s->p2p_wps_method, 0, op_freq,
- ssid, ssid_len);
- }
- return;
- }
-
- if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
- wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
- " was rejected (status %u)", MAC2STR(sa), status);
- return;
- }
-
- if (!s) {
- if (bssid) {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_INVITATION_RECEIVED
- "sa=" MACSTR " go_dev_addr=" MACSTR
- " bssid=" MACSTR " unknown-network",
- MAC2STR(sa), MAC2STR(go_dev_addr),
- MAC2STR(bssid));
- } else {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_INVITATION_RECEIVED
- "sa=" MACSTR " go_dev_addr=" MACSTR
- " unknown-network",
- MAC2STR(sa), MAC2STR(go_dev_addr));
- }
- wpas_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr,
- bssid, 0, op_freq);
- return;
- }
-
- if (s->mode == WPAS_MODE_P2P_GO && op_freq) {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
- "sa=" MACSTR " persistent=%d freq=%d",
- MAC2STR(sa), s->id, op_freq);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
- "sa=" MACSTR " persistent=%d",
- MAC2STR(sa), s->id);
- }
- wpas_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
- s->id, op_freq);
-}
-
-
-static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const u8 *peer, int inv)
-{
- size_t i;
- struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- if (ssid == NULL)
- return;
-
- for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
- if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer,
- ETH_ALEN) == 0)
- break;
- }
- if (i >= ssid->num_p2p_clients || !ssid->p2p_client_list) {
- if (ssid->mode != WPAS_MODE_P2P_GO &&
- os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
- "due to invitation result", ssid->id);
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return;
- }
- return; /* Peer not found in client list */
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
- "group %d client list%s",
- MAC2STR(peer), ssid->id,
- inv ? " due to invitation result" : "");
- os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN,
- ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
- (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
- ssid->num_p2p_clients--;
- if (p2p_wpa_s->conf->update_config &&
- wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf))
- wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
-}
-
-
-static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
- const u8 *peer)
-{
- struct wpa_ssid *ssid;
-
- wpa_s = wpa_s->global->p2p_invite_group;
- if (wpa_s == NULL)
- return; /* No known invitation group */
- ssid = wpa_s->current_ssid;
- if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
- !ssid->p2p_persistent_group)
- return; /* Not operating as a GO in persistent group */
- ssid = wpas_p2p_get_persistent(wpa_s->p2pdev, peer,
- ssid->ssid, ssid->ssid_len);
- wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
-}
-
-
-static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
- const struct p2p_channels *channels,
- const u8 *peer, int neg_freq,
- int peer_oper_freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *ssid;
- int freq;
-
- if (bssid) {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
- "status=%d " MACSTR,
- status, MAC2STR(bssid));
- } else {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
- "status=%d ", status);
- }
- wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
-
- wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
- status, MAC2STR(peer));
- if (wpa_s->pending_invite_ssid_id == -1) {
- struct wpa_supplicant *group_if =
- wpa_s->global->p2p_invite_group;
-
- if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
- wpas_remove_persistent_client(wpa_s, peer);
-
- /*
- * Invitation to an active group. If this is successful and we
- * are the GO, set the client wait to postpone some concurrent
- * operations and to allow provisioning and connection to happen
- * more quickly.
- */
- if (status == P2P_SC_SUCCESS &&
- group_if && group_if->current_ssid &&
- group_if->current_ssid->mode == WPAS_MODE_P2P_GO) {
- os_get_reltime(&wpa_s->global->p2p_go_wait_client);
-#ifdef CONFIG_TESTING_OPTIONS
- if (group_if->p2p_go_csa_on_inv) {
- wpa_printf(MSG_DEBUG,
- "Testing: force P2P GO CSA after invitation");
- eloop_cancel_timeout(
- wpas_p2p_reconsider_moving_go,
- wpa_s, NULL);
- eloop_register_timeout(
- 0, 50000,
- wpas_p2p_reconsider_moving_go,
- wpa_s, NULL);
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- }
- return;
- }
-
- if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
- wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
- "invitation exchange to indicate readiness for "
- "re-invocation");
- }
-
- if (status != P2P_SC_SUCCESS) {
- if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
- ssid = wpa_config_get_network(
- wpa_s->conf, wpa_s->pending_invite_ssid_id);
- wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
- }
- wpas_p2p_remove_pending_group_interface(wpa_s);
- return;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf,
- wpa_s->pending_invite_ssid_id);
- if (ssid == NULL) {
- wpa_printf(MSG_ERROR, "P2P: Could not find persistent group "
- "data matching with invitation");
- return;
- }
-
- /*
- * The peer could have missed our ctrl::ack frame for Invitation
- * Response and continue retransmitting the frame. To reduce the
- * likelihood of the peer not getting successful TX status for the
- * Invitation Response frame, wait a short time here before starting
- * the persistent group so that we will remain on the current channel to
- * acknowledge any possible retransmission from the peer.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before "
- "starting persistent group");
- os_sleep(0, 50000);
-
- if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
- freq_included(wpa_s, channels, neg_freq))
- freq = neg_freq;
- else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
- freq_included(wpa_s, channels, peer_oper_freq))
- freq = peer_oper_freq;
- else
- freq = 0;
-
- wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s",
- freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- wpas_p2p_group_add_persistent(wpa_s, ssid,
- ssid->mode == WPAS_MODE_P2P_GO,
- wpa_s->p2p_persistent_go_freq,
- freq,
- wpa_s->p2p_go_vht_center_freq2,
- wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
- wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he,
- wpa_s->p2p_go_edmg,
- channels,
- ssid->mode == WPAS_MODE_P2P_GO ?
- P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
- 0, 1,
- is_p2p_allow_6ghz(wpa_s->global->p2p));
-}
-
-
-static int wpas_p2p_disallowed_freq(struct wpa_global *global,
- unsigned int freq)
-{
- if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq))
- return 1;
- return freq_range_list_includes(&global->p2p_disallow_freq, freq);
-}
-
-
-static void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
-{
- reg->channel[reg->channels] = chan;
- reg->channels++;
-}
-
-
-static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
- struct p2p_channels *chan,
- struct p2p_channels *cli_chan)
-{
- int i, cla = 0;
-
- wpa_s->global->p2p_24ghz_social_channels = 1;
-
- os_memset(cli_chan, 0, sizeof(*cli_chan));
-
- wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
- "band");
-
- /* Operating class 81 - 2.4 GHz band channels 1..13 */
- chan->reg_class[cla].reg_class = 81;
- chan->reg_class[cla].channels = 0;
- for (i = 0; i < 11; i++) {
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
- }
- if (chan->reg_class[cla].channels)
- cla++;
-
- wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
- "band");
-
- /* Operating class 115 - 5 GHz, channels 36-48 */
- chan->reg_class[cla].reg_class = 115;
- chan->reg_class[cla].channels = 0;
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 36);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 40);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 44);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 48);
- if (chan->reg_class[cla].channels)
- cla++;
-
- wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
- "band");
-
- /* Operating class 124 - 5 GHz, channels 149,153,157,161 */
- chan->reg_class[cla].reg_class = 124;
- chan->reg_class[cla].channels = 0;
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 149);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 153);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 157);
- if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
- wpas_p2p_add_chan(&chan->reg_class[cla], 161);
- if (chan->reg_class[cla].channels)
- cla++;
-
- chan->reg_classes = cla;
- return 0;
-}
-
-
-static enum chan_allowed has_channel(struct wpa_global *global,
- struct hostapd_hw_modes *mode, u8 op_class,
- u8 chan, int *flags)
-{
- int i;
- unsigned int freq;
-
- freq = ieee80211_chan_to_freq(NULL, op_class, chan);
- if (wpas_p2p_disallowed_freq(global, freq))
- return NOT_ALLOWED;
-
- for (i = 0; i < mode->num_channels; i++) {
- if ((unsigned int) mode->channels[i].freq == freq) {
- if (flags)
- *flags = mode->channels[i].flag;
- if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
- return NOT_ALLOWED;
- if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
- return NO_IR;
- if (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)
- return RADAR;
- return ALLOWED;
- }
- }
-
- return NOT_ALLOWED;
-}
-
-
-static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 channel, const u8 *center_channels,
- size_t num_chan)
-{
- size_t i;
-
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return 0;
-
- for (i = 0; i < num_chan; i++)
- /*
- * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
- * so the center channel is 6 channels away from the start/end.
- */
- if (channel >= center_channels[i] - 6 &&
- channel <= center_channels[i] + 6)
- return center_channels[i];
-
- return 0;
-}
-
-
-static const u8 center_channels_5ghz_80mhz[] = { 42, 58, 106, 122, 138,
- 155, 171 };
-static const u8 center_channels_6ghz_80mhz[] = { 7, 23, 39, 55, 71, 87, 103,
- 119, 135, 151, 167, 183, 199,
- 215 };
-
-static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 op_class, u8 channel, u8 bw)
-{
- u8 center_chan;
- int i, flags;
- enum chan_allowed res, ret = ALLOWED;
- const u8 *chans;
- size_t num_chans;
- bool is_6ghz = is_6ghz_op_class(op_class);
-
- if (is_6ghz) {
- chans = center_channels_6ghz_80mhz;
- num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
- } else {
- chans = center_channels_5ghz_80mhz;
- num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
- }
- center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
- chans, num_chans);
- if (!center_chan)
- return NOT_ALLOWED;
- if (!wpa_s->p2p_go_allow_dfs &&
- !is_6ghz && center_chan >= 58 && center_chan <= 138)
- return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
-
- /* check all the channels are available */
- for (i = 0; i < 4; i++) {
- int adj_chan = center_chan - 6 + i * 4;
-
- res = has_channel(wpa_s->global, mode, op_class, adj_chan,
- &flags);
- if (res == NOT_ALLOWED)
- return NOT_ALLOWED;
- if (res == RADAR)
- ret = RADAR;
- if (res == NO_IR)
- ret = NO_IR;
- if (!is_6ghz) {
- if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
- return NOT_ALLOWED;
- if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
- return NOT_ALLOWED;
- if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
- return NOT_ALLOWED;
- if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
- return NOT_ALLOWED;
- } else if (is_6ghz &&
- (!(wpas_get_6ghz_he_chwidth_capab(mode) &
- HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G))) {
- return NOT_ALLOWED;
- }
- }
-
- return ret;
-}
-
-
-static int wpas_p2p_get_center_160mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 channel, const u8 *center_channels,
- size_t num_chan)
-{
- unsigned int i;
-
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return 0;
-
- for (i = 0; i < num_chan; i++)
- /*
- * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
- * so the center channel is 14 channels away from the start/end.
- */
- if (channel >= center_channels[i] - 14 &&
- channel <= center_channels[i] + 14)
- return center_channels[i];
-
- return 0;
-}
-
-
-static const u8 center_channels_5ghz_160mhz[] = { 50, 114, 163 };
-static const u8 center_channels_6ghz_160mhz[] = { 15, 47, 79, 111, 143, 175,
- 207 };
-
-static enum chan_allowed wpas_p2p_verify_160mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 op_class, u8 channel, u8 bw)
-{
- u8 center_chan;
- int i, flags;
- enum chan_allowed res, ret = ALLOWED;
- const u8 *chans;
- size_t num_chans;
-
- if (is_6ghz_op_class(op_class)) {
- chans = center_channels_6ghz_160mhz;
- num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
- } else {
- chans = center_channels_5ghz_160mhz;
- num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
- }
- center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
- chans, num_chans);
- if (!center_chan)
- return NOT_ALLOWED;
- /* VHT 160 MHz uses DFS channels in most countries. */
-
- /* Check all the channels are available */
- for (i = 0; i < 8; i++) {
- int adj_chan = center_chan - 14 + i * 4;
-
- res = has_channel(wpa_s->global, mode, op_class, adj_chan,
- &flags);
- if (res == NOT_ALLOWED)
- return NOT_ALLOWED;
-
- if (res == RADAR)
- ret = RADAR;
- if (res == NO_IR)
- ret = NO_IR;
-
- if (!is_6ghz_op_class(op_class)) {
- if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150))
- return NOT_ALLOWED;
- if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130))
- return NOT_ALLOWED;
- if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110))
- return NOT_ALLOWED;
- if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90))
- return NOT_ALLOWED;
- if (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70))
- return NOT_ALLOWED;
- if (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50))
- return NOT_ALLOWED;
- if (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30))
- return NOT_ALLOWED;
- if (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10))
- return NOT_ALLOWED;
- } else if (is_6ghz_op_class(op_class) &&
- (!(wpas_get_6ghz_he_chwidth_capab(mode) &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))) {
- return NOT_ALLOWED;
- }
- }
-
- return ret;
-}
-
-
-static enum chan_allowed wpas_p2p_verify_edmg(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 channel)
-{
- struct ieee80211_edmg_config edmg;
-
- hostapd_encode_edmg_chan(1, channel, 0, &edmg);
- if (edmg.channels && ieee802_edmg_is_allowed(mode->edmg, edmg))
- return ALLOWED;
-
- return NOT_ALLOWED;
-}
-
-
-static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 op_class, u8 channel, u8 bw)
-{
- int flag = 0;
- enum chan_allowed res, res2;
-
- res2 = res = has_channel(wpa_s->global, mode, op_class, channel, &flag);
- if (bw == BW40MINUS) {
- if (!(flag & HOSTAPD_CHAN_HT40MINUS))
- return NOT_ALLOWED;
- res2 = has_channel(wpa_s->global, mode, op_class, channel - 4,
- NULL);
- } else if (bw == BW40PLUS) {
- if (!(flag & HOSTAPD_CHAN_HT40PLUS))
- return NOT_ALLOWED;
- res2 = has_channel(wpa_s->global, mode, op_class, channel + 4,
- NULL);
- } else if (is_6ghz_op_class(op_class) && bw == BW40) {
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return NOT_ALLOWED;
- if (get_6ghz_sec_channel(channel) < 0)
- res2 = has_channel(wpa_s->global, mode, op_class,
- channel - 4, NULL);
- else
- res2 = has_channel(wpa_s->global, mode, op_class,
- channel + 4, NULL);
- } else if (bw == BW80) {
- res2 = wpas_p2p_verify_80mhz(wpa_s, mode, op_class, channel,
- bw);
- } else if (bw == BW160) {
- res2 = wpas_p2p_verify_160mhz(wpa_s, mode, op_class, channel,
- bw);
- } else if (bw == BW4320 || bw == BW6480 || bw == BW8640) {
- return wpas_p2p_verify_edmg(wpa_s, mode, channel);
- }
-
- if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
- return NOT_ALLOWED;
- if (res == NO_IR || res2 == NO_IR)
- return NO_IR;
- if (res == RADAR || res2 == RADAR)
- return RADAR;
- return res;
-}
-
-
-static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
- struct p2p_channels *chan,
- struct p2p_channels *cli_chan,
- bool p2p_disable_6ghz)
-{
- struct hostapd_hw_modes *mode;
- int cla, op, cli_cla;
-
- if (wpa_s->hw.modes == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
- "of all supported channels; assume dualband "
- "support");
- return wpas_p2p_default_channels(wpa_s, chan, cli_chan);
- }
-
- cla = cli_cla = 0;
-
- for (op = 0; global_op_class[op].op_class; op++) {
- const struct oper_class_map *o = &global_op_class[op];
- unsigned int ch;
- struct p2p_reg_class *reg = NULL, *cli_reg = NULL;
-
- if (o->p2p == NO_P2P_SUPP ||
- (is_6ghz_op_class(o->op_class) && p2p_disable_6ghz))
- continue;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode,
- is_6ghz_op_class(o->op_class));
- if (mode == NULL)
- continue;
- if (mode->mode == HOSTAPD_MODE_IEEE80211G)
- wpa_s->global->p2p_24ghz_social_channels = 1;
- for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
- enum chan_allowed res;
-
- /* Check for non-continuous jump in channel index
- * incrementation */
- if ((o->op_class >= 128 && o->op_class <= 130) &&
- ch < 149 && ch + o->inc > 149)
- ch = 149;
-
- res = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
- ch, o->bw);
- if (res == ALLOWED) {
- if (reg == NULL) {
- if (cla == P2P_MAX_REG_CLASSES)
- continue;
- wpa_printf(MSG_DEBUG, "P2P: Add operating class %u",
- o->op_class);
- reg = &chan->reg_class[cla];
- cla++;
- reg->reg_class = o->op_class;
- }
- if (reg->channels == P2P_MAX_REG_CLASS_CHANNELS)
- continue;
- reg->channel[reg->channels] = ch;
- reg->channels++;
- } else if (res == NO_IR &&
- wpa_s->conf->p2p_add_cli_chan) {
- if (cli_reg == NULL) {
- if (cli_cla == P2P_MAX_REG_CLASSES)
- continue;
- wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)",
- o->op_class);
- cli_reg = &cli_chan->reg_class[cli_cla];
- cli_cla++;
- cli_reg->reg_class = o->op_class;
- }
- if (cli_reg->channels ==
- P2P_MAX_REG_CLASS_CHANNELS)
- continue;
- cli_reg->channel[cli_reg->channels] = ch;
- cli_reg->channels++;
- }
- }
- if (reg) {
- wpa_hexdump(MSG_DEBUG, "P2P: Channels",
- reg->channel, reg->channels);
- }
- if (cli_reg) {
- wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)",
- cli_reg->channel, cli_reg->channels);
- }
- }
-
- chan->reg_classes = cla;
- cli_chan->reg_classes = cli_cla;
-
- return 0;
-}
-
-
-int wpas_p2p_get_sec_channel_offset_40mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 channel)
-{
- int op;
- enum chan_allowed ret;
-
- for (op = 0; global_op_class[op].op_class; op++) {
- const struct oper_class_map *o = &global_op_class[op];
- u16 ch;
- int chan = channel;
-
- /* Allow DFS channels marked as NO_P2P_SUPP to be used with
- * driver offloaded DFS. */
- if ((o->p2p == NO_P2P_SUPP &&
- (!is_dfs_global_op_class(o->op_class) ||
- !wpa_s->p2p_go_allow_dfs)) ||
- (is_6ghz_op_class(o->op_class) &&
- wpa_s->conf->p2p_6ghz_disable))
- continue;
-
- if (is_6ghz_op_class(o->op_class) && o->bw == BW40 &&
- get_6ghz_sec_channel(channel) < 0)
- chan = channel - 4;
-
- for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
- if (o->mode != HOSTAPD_MODE_IEEE80211A ||
- (o->bw != BW40PLUS && o->bw != BW40MINUS &&
- o->bw != BW40) ||
- ch != chan)
- continue;
- ret = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
- ch, o->bw);
- if (ret == ALLOWED) {
- if (is_6ghz_op_class(o->op_class) &&
- o->bw == BW40)
- return get_6ghz_sec_channel(channel);
- return (o->bw == BW40MINUS) ? -1 : 1;
- }
- if (ret == RADAR && wpa_s->p2p_go_allow_dfs) {
- /* Allow RADAR channels used for driver
- * offloaded DFS */
- return (o->bw == BW40MINUS) ? -1 : 1;
- }
- }
- }
- return 0;
-}
-
-
-int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode, u8 channel,
- u8 op_class)
-{
- const u8 *chans;
- size_t num_chans;
- enum chan_allowed ret;
-
- ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW80);
- if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
- return 0;
-
- if (is_6ghz_op_class(op_class)) {
- chans = center_channels_6ghz_80mhz;
- num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
- } else {
- chans = center_channels_5ghz_80mhz;
- num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
- }
- return wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
- chans, num_chans);
-}
-
-
-int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode, u8 channel,
- u8 op_class)
-{
- const u8 *chans;
- size_t num_chans;
- enum chan_allowed ret;
-
- ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW160);
- if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
- return 0;
- if (is_6ghz_op_class(op_class)) {
- chans = center_channels_6ghz_160mhz;
- num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
- } else {
- chans = center_channels_5ghz_160mhz;
- num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
- }
- return wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
- chans, num_chans);
-}
-
-
-static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
- size_t buf_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0)
- break;
- }
- if (wpa_s == NULL)
- return -1;
-
- return wpa_drv_get_noa(wpa_s, buf, buf_len);
-}
-
-
-struct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
- const u8 *ssid, size_t ssid_len)
-{
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- struct wpa_ssid *s = wpa_s->current_ssid;
- if (s == NULL)
- continue;
- if (s->mode != WPAS_MODE_P2P_GO &&
- s->mode != WPAS_MODE_AP &&
- s->mode != WPAS_MODE_P2P_GROUP_FORMATION)
- continue;
- if (s->ssid_len != ssid_len ||
- os_memcmp(ssid, s->ssid, ssid_len) != 0)
- continue;
- return wpa_s;
- }
-
- return NULL;
-
-}
-
-
-struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
- const u8 *peer_dev_addr)
-{
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- if (ssid && (ssid->mode != WPAS_MODE_INFRA || !ssid->p2p_group))
- continue;
- if (os_memcmp(wpa_s->go_dev_addr, peer_dev_addr, ETH_ALEN) == 0)
- return wpa_s;
- }
-
- return NULL;
-}
-
-
-static int wpas_go_connected(void *ctx, const u8 *dev_addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- return wpas_get_p2p_client_iface(wpa_s, dev_addr) != NULL;
-}
-
-
-static int wpas_is_concurrent_session_active(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_supplicant *ifs;
-
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if (ifs == wpa_s)
- continue;
- if (ifs->wpa_state > WPA_ASSOCIATED)
- return 1;
- }
- return 0;
-}
-
-
-static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_msg_global(wpa_s, level, "P2P: %s", msg);
-}
-
-
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
- const char *conf_p2p_dev)
-{
- struct wpa_interface iface;
- struct wpa_supplicant *p2pdev_wpa_s;
- char ifname[100];
- char force_name[100];
- int ret;
- const u8 *if_addr = NULL;
-
- ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
- wpa_s->ifname);
- if (os_snprintf_error(sizeof(ifname), ret))
- return -1;
- /* Cut length at the maximum size. Note that we don't need to ensure
- * collision free names here as the created interface is not a netdev.
- */
- ifname[IFNAMSIZ - 1] = '\0';
- force_name[0] = '\0';
- wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
-
- if (wpa_s->conf->p2p_device_random_mac_addr == 2 &&
- !is_zero_ether_addr(wpa_s->conf->p2p_device_persistent_mac_addr))
- if_addr = wpa_s->conf->p2p_device_persistent_mac_addr;
-
- ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, if_addr, NULL,
- force_name, wpa_s->pending_interface_addr, NULL);
- if (ret < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
- return ret;
- }
- os_strlcpy(wpa_s->pending_interface_name, ifname,
- sizeof(wpa_s->pending_interface_name));
-
- os_memset(&iface, 0, sizeof(iface));
- iface.p2p_mgmt = 1;
- iface.ifname = wpa_s->pending_interface_name;
- iface.driver = wpa_s->driver->name;
- iface.driver_param = wpa_s->conf->driver_param;
-
- /*
- * If a P2P Device configuration file was given, use it as the interface
- * configuration file (instead of using parent's configuration file.
- */
- if (conf_p2p_dev) {
- iface.confname = conf_p2p_dev;
- iface.ctrl_interface = NULL;
- } else {
- iface.confname = wpa_s->confname;
- iface.ctrl_interface = wpa_s->conf->ctrl_interface;
- }
-
- p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s);
- if (!p2pdev_wpa_s) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
- return -1;
- }
-
- p2pdev_wpa_s->p2pdev = p2pdev_wpa_s;
- wpa_s->pending_interface_name[0] = '\0';
- return 0;
-}
-
-
-static void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
- const u8 *noa, size_t noa_len)
-{
- struct wpa_supplicant *wpa_s, *intf = ctx;
- char hex[100];
-
- for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->waiting_presence_resp)
- break;
- }
- if (!wpa_s) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response");
- return;
- }
- wpa_s->waiting_presence_resp = 0;
-
- wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len);
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR
- " status=%u noa=%s", MAC2STR(src), status, hex);
-}
-
-
-static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid,
- size_t ssid_len, u8 *go_dev_addr,
- u8 *ret_ssid, size_t *ret_ssid_len,
- u8 *intended_iface_addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *s;
-
- s = wpas_p2p_get_persistent(wpa_s, addr, ssid, ssid_len);
- if (s) {
- os_memcpy(ret_ssid, s->ssid, s->ssid_len);
- *ret_ssid_len = s->ssid_len;
- os_memcpy(go_dev_addr, s->bssid, ETH_ALEN);
-
- if (s->mode != WPAS_MODE_P2P_GO) {
- os_memset(intended_iface_addr, 0, ETH_ALEN);
- } else if (wpas_p2p_create_iface(wpa_s)) {
- if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO))
- return 0;
-
- os_memcpy(intended_iface_addr,
- wpa_s->pending_interface_addr, ETH_ALEN);
- } else {
- os_memcpy(intended_iface_addr, wpa_s->own_addr,
- ETH_ALEN);
- }
- return 1;
- }
-
- return 0;
-}
-
-
-static int wpas_get_go_info(void *ctx, u8 *intended_addr,
- u8 *ssid, size_t *ssid_len, int *group_iface,
- unsigned int *freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_supplicant *go;
- struct wpa_ssid *s;
-
- /*
- * group_iface will be set to 1 only if a dedicated interface for P2P
- * role is required. First, we try to reuse an active GO. However,
- * if it is not present, we will try to reactivate an existing
- * persistent group and set group_iface to 1, so the caller will know
- * that the pending interface should be used.
- */
- *group_iface = 0;
-
- if (freq)
- *freq = 0;
-
- go = wpas_p2p_get_go_group(wpa_s);
- if (!go) {
- s = wpas_p2p_get_persistent_go(wpa_s);
- *group_iface = wpas_p2p_create_iface(wpa_s);
- if (s)
- os_memcpy(intended_addr, s->bssid, ETH_ALEN);
- else
- return 0;
- } else {
- s = go->current_ssid;
- os_memcpy(intended_addr, go->own_addr, ETH_ALEN);
- if (freq)
- *freq = go->assoc_freq;
- }
-
- os_memcpy(ssid, s->ssid, s->ssid_len);
- *ssid_len = s->ssid_len;
-
- return 1;
-}
-
-
-static int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go,
- const u8 *ssid, size_t ssid_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *s;
- int save_config = 0;
- size_t i;
-
- /* Start with our first choice of Persistent Groups */
- while ((s = wpas_p2p_get_persistent(wpa_s, peer, NULL, 0))) {
- if (go && ssid && ssid_len &&
- s->ssid_len == ssid_len &&
- os_memcmp(go, s->bssid, ETH_ALEN) == 0 &&
- os_memcmp(ssid, s->ssid, ssid_len) == 0)
- break;
-
- /* Remove stale persistent group */
- if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove stale persistent group id=%d",
- s->id);
- wpas_notify_persistent_group_removed(wpa_s, s);
- wpa_config_remove_network(wpa_s->conf, s->id);
- save_config = 1;
- continue;
- }
-
- for (i = 0; i < s->num_p2p_clients; i++) {
- if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
- peer, ETH_ALEN) != 0)
- continue;
-
- os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
- s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
- (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
- break;
- }
- s->num_p2p_clients--;
- save_config = 1;
- }
-
- if (save_config)
- p2p_config_write(wpa_s);
-
- /* Return TRUE if valid SSID remains */
- return s != NULL;
-}
-
-
-static void wpas_p2ps_get_feat_cap_str(char *buf, size_t buf_len,
- const u8 *feat_cap, size_t feat_cap_len)
-{
- static const char pref[] = " feature_cap=";
- int ret;
-
- buf[0] = '\0';
-
- /*
- * We expect a feature capability to contain at least one byte to be
- * reported. The string buffer provided by the caller function is
- * expected to be big enough to contain all bytes of the attribute for
- * known specifications. This function truncates the reported bytes if
- * the feature capability data exceeds the string buffer size.
- */
- if (!feat_cap || !feat_cap_len || buf_len < sizeof(pref) + 2)
- return;
-
- os_memcpy(buf, pref, sizeof(pref));
- ret = wpa_snprintf_hex(&buf[sizeof(pref) - 1],
- buf_len - sizeof(pref) + 1,
- feat_cap, feat_cap_len);
-
- if (ret != (2 * (int) feat_cap_len))
- wpa_printf(MSG_WARNING, "P2PS feature_cap bytes truncated");
-}
-
-
-static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
- const u8 *adv_mac, const u8 *ses_mac,
- const u8 *grp_mac, u32 adv_id, u32 ses_id,
- u8 conncap, int passwd_id,
- const u8 *persist_ssid,
- size_t persist_ssid_size, int response_done,
- int prov_start, const char *session_info,
- const u8 *feat_cap, size_t feat_cap_len,
- unsigned int freq,
- const u8 *group_ssid, size_t group_ssid_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- u8 mac[ETH_ALEN];
- struct wpa_ssid *persistent_go, *stale, *s = NULL;
- int save_config = 0;
- struct wpa_supplicant *go_wpa_s;
- char feat_cap_str[256];
-
- if (!dev)
- return;
-
- os_memset(mac, 0, ETH_ALEN);
- if (!adv_mac)
- adv_mac = mac;
- if (!ses_mac)
- ses_mac = mac;
- if (!grp_mac)
- grp_mac = mac;
-
- wpas_p2ps_get_feat_cap_str(feat_cap_str, sizeof(feat_cap_str),
- feat_cap, feat_cap_len);
-
- if (prov_start) {
- if (session_info == NULL) {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_START MACSTR
- " adv_id=%x conncap=%x"
- " adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " dev_passwd_id=%d%s",
- MAC2STR(dev), adv_id, conncap,
- MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac),
- passwd_id, feat_cap_str);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_START MACSTR
- " adv_id=%x conncap=%x"
- " adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " dev_passwd_id=%d info='%s'%s",
- MAC2STR(dev), adv_id, conncap,
- MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac),
- passwd_id, session_info, feat_cap_str);
- }
- return;
- }
-
- go_wpa_s = wpas_p2p_get_go_group(wpa_s);
- persistent_go = wpas_p2p_get_persistent_go(wpa_s);
-
- if (status && status != P2P_SC_SUCCESS_DEFERRED) {
- if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
- wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
-
- if (persistent_go && !persistent_go->num_p2p_clients) {
- /* remove empty persistent GO */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove empty persistent group id=%d",
- persistent_go->id);
- wpas_notify_persistent_group_removed(wpa_s,
- persistent_go);
- wpa_config_remove_network(wpa_s->conf,
- persistent_go->id);
- }
-
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_DONE MACSTR
- " status=%d"
- " adv_id=%x adv_mac=" MACSTR
- " session=%x mac=" MACSTR "%s",
- MAC2STR(dev), status,
- adv_id, MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac), feat_cap_str);
- return;
- }
-
- /* Clean up stale persistent groups with this device */
- if (persist_ssid && persist_ssid_size)
- s = wpas_p2p_get_persistent(wpa_s, dev, persist_ssid,
- persist_ssid_size);
-
- if (persist_ssid && s && s->mode != WPAS_MODE_P2P_GO &&
- is_zero_ether_addr(grp_mac)) {
- wpa_dbg(wpa_s, MSG_ERROR,
- "P2P: Peer device is a GO in a persistent group, but it did not provide the intended MAC address");
- return;
- }
-
- for (;;) {
- stale = wpas_p2p_get_persistent(wpa_s, dev, NULL, 0);
- if (!stale)
- break;
-
- if (s && s->ssid_len == stale->ssid_len &&
- os_memcmp(stale->bssid, s->bssid, ETH_ALEN) == 0 &&
- os_memcmp(stale->ssid, s->ssid, s->ssid_len) == 0)
- break;
-
- /* Remove stale persistent group */
- if (stale->mode != WPAS_MODE_P2P_GO ||
- stale->num_p2p_clients <= 1) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove stale persistent group id=%d",
- stale->id);
- wpas_notify_persistent_group_removed(wpa_s, stale);
- wpa_config_remove_network(wpa_s->conf, stale->id);
- } else {
- size_t i;
-
- for (i = 0; i < stale->num_p2p_clients; i++) {
- if (os_memcmp(stale->p2p_client_list +
- i * ETH_ALEN,
- dev, ETH_ALEN) == 0) {
- os_memmove(stale->p2p_client_list +
- i * ETH_ALEN,
- stale->p2p_client_list +
- (i + 1) * ETH_ALEN,
- (stale->num_p2p_clients -
- i - 1) * ETH_ALEN);
- break;
- }
- }
- stale->num_p2p_clients--;
- }
- save_config = 1;
- }
-
- if (save_config)
- p2p_config_write(wpa_s);
-
- if (s) {
- if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
- wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
-
- if (persistent_go && s != persistent_go &&
- !persistent_go->num_p2p_clients) {
- /* remove empty persistent GO */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove empty persistent group id=%d",
- persistent_go->id);
- wpas_notify_persistent_group_removed(wpa_s,
- persistent_go);
- wpa_config_remove_network(wpa_s->conf,
- persistent_go->id);
- /* Save config */
- }
-
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_DONE MACSTR
- " status=%d"
- " adv_id=%x adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " persist=%d%s",
- MAC2STR(dev), status,
- adv_id, MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac), s->id, feat_cap_str);
- return;
- }
-
- wpa_s->global->pending_p2ps_group = 0;
- wpa_s->global->pending_p2ps_group_freq = 0;
-
- if (conncap == P2PS_SETUP_GROUP_OWNER) {
- /*
- * We need to copy the interface name. Simply saving a
- * pointer isn't enough, since if we use pending_interface_name
- * it will be overwritten when the group is added.
- */
- char go_ifname[100];
-
- go_ifname[0] = '\0';
- if (!go_wpa_s) {
- if (!response_done) {
- wpa_s->global->pending_p2ps_group = 1;
- wpa_s->global->pending_p2ps_group_freq = freq;
- }
-
- if (!wpas_p2p_create_iface(wpa_s))
- os_memcpy(go_ifname, wpa_s->ifname,
- sizeof(go_ifname));
- else if (wpa_s->pending_interface_name[0])
- os_memcpy(go_ifname,
- wpa_s->pending_interface_name,
- sizeof(go_ifname));
-
- if (!go_ifname[0]) {
- wpas_p2ps_prov_complete(
- wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
- dev, adv_mac, ses_mac,
- grp_mac, adv_id, ses_id, 0, 0,
- NULL, 0, 0, 0, NULL, NULL, 0, 0,
- NULL, 0);
- return;
- }
-
- /* If PD Resp complete, start up the GO */
- if (response_done && persistent_go) {
- wpas_p2p_group_add_persistent(
- wpa_s, persistent_go,
- 0, 0, freq, 0, 0, 0, 0, 0, 0, NULL,
- persistent_go->mode ==
- WPAS_MODE_P2P_GO ?
- P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
- 0, 0, false);
- } else if (response_done) {
- wpas_p2p_group_add(wpa_s, 1, freq,
- 0, 0, 0, 0, 0, 0, false);
- }
-
- if (passwd_id == DEV_PW_P2PS_DEFAULT) {
- os_memcpy(wpa_s->p2ps_join_addr, grp_mac,
- ETH_ALEN);
- wpa_s->p2ps_method_config_any = 1;
- }
- } else if (passwd_id == DEV_PW_P2PS_DEFAULT) {
- os_memcpy(go_ifname, go_wpa_s->ifname,
- sizeof(go_ifname));
-
- if (is_zero_ether_addr(grp_mac)) {
- wpa_dbg(go_wpa_s, MSG_DEBUG,
- "P2P: Setting PIN-1 for ANY");
- wpa_supplicant_ap_wps_pin(go_wpa_s, NULL,
- "12345670", NULL, 0,
- 0);
- } else {
- wpa_dbg(go_wpa_s, MSG_DEBUG,
- "P2P: Setting PIN-1 for " MACSTR,
- MAC2STR(grp_mac));
- wpa_supplicant_ap_wps_pin(go_wpa_s, grp_mac,
- "12345670", NULL, 0,
- 0);
- }
-
- os_memcpy(wpa_s->p2ps_join_addr, grp_mac, ETH_ALEN);
- wpa_s->p2ps_method_config_any = 1;
- }
-
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_DONE MACSTR
- " status=%d conncap=%x"
- " adv_id=%x adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " dev_passwd_id=%d go=%s%s",
- MAC2STR(dev), status, conncap,
- adv_id, MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac),
- passwd_id, go_ifname, feat_cap_str);
- return;
- }
-
- if (go_wpa_s && !p2p_group_go_member_count(wpa_s))
- wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname);
-
- if (persistent_go && !persistent_go->num_p2p_clients) {
- /* remove empty persistent GO */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove empty persistent group id=%d",
- persistent_go->id);
- wpas_notify_persistent_group_removed(wpa_s, persistent_go);
- wpa_config_remove_network(wpa_s->conf, persistent_go->id);
- }
-
- if (conncap == P2PS_SETUP_CLIENT) {
- char ssid_hex[32 * 2 + 1];
-
- if (group_ssid)
- wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
- group_ssid, group_ssid_len);
- else
- ssid_hex[0] = '\0';
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_DONE MACSTR
- " status=%d conncap=%x"
- " adv_id=%x adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " dev_passwd_id=%d join=" MACSTR "%s%s%s",
- MAC2STR(dev), status, conncap,
- adv_id, MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac),
- passwd_id, MAC2STR(grp_mac), feat_cap_str,
- group_ssid ? " group_ssid=" : "", ssid_hex);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_P2PS_PROVISION_DONE MACSTR
- " status=%d conncap=%x"
- " adv_id=%x adv_mac=" MACSTR
- " session=%x mac=" MACSTR
- " dev_passwd_id=%d%s",
- MAC2STR(dev), status, conncap,
- adv_id, MAC2STR(adv_mac),
- ses_id, MAC2STR(ses_mac),
- passwd_id, feat_cap_str);
- }
-}
-
-
-static int _wpas_p2p_in_progress(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpas_p2p_in_progress(wpa_s);
-}
-
-
-static int wpas_prov_disc_resp_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *persistent_go;
- unsigned int freq;
-
- if (!wpa_s->global->pending_p2ps_group)
- return 0;
-
- freq = wpa_s->global->pending_p2ps_group_freq;
- wpa_s->global->pending_p2ps_group_freq = 0;
- wpa_s->global->pending_p2ps_group = 0;
-
- if (wpas_p2p_get_go_group(wpa_s))
- return 0;
- persistent_go = wpas_p2p_get_persistent_go(wpa_s);
-
- if (persistent_go) {
- wpas_p2p_group_add_persistent(
- wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- NULL,
- persistent_go->mode == WPAS_MODE_P2P_GO ?
- P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p));
- } else {
- wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p));
- }
-
- return 1;
-}
-
-
-static int wpas_p2p_get_pref_freq_list(void *ctx, int go,
- unsigned int *len,
- unsigned int *freq_list)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- return wpa_drv_get_pref_freq_list(wpa_s, go ? WPA_IF_P2P_GO :
- WPA_IF_P2P_CLIENT, len, freq_list);
-}
-
-
-int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
-{
- u8 addr[ETH_ALEN] = {0};
-
- if (wpa_s->conf->p2p_device_random_mac_addr == 0)
- return 0;
-
- if (wpa_s->conf->p2p_device_random_mac_addr == 2) {
- if (is_zero_ether_addr(
- wpa_s->conf->p2p_device_persistent_mac_addr) &&
- !is_zero_ether_addr(wpa_s->own_addr)) {
- os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr,
- wpa_s->own_addr, ETH_ALEN);
- }
- return 0;
- }
-
- if (!wpa_s->conf->ssid) {
- if (random_mac_addr(addr) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to generate random MAC address");
- return -EINVAL;
- }
-
- /* Store generated MAC address. */
- os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, addr,
- ETH_ALEN);
- } else {
- /* If there are existing saved groups, restore last MAC address.
- * if there is no last used MAC address, the last one is
- * factory MAC. */
- if (is_zero_ether_addr(
- wpa_s->conf->p2p_device_persistent_mac_addr))
- return 0;
- os_memcpy(addr, wpa_s->conf->p2p_device_persistent_mac_addr,
- ETH_ALEN);
- wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address.");
- }
-
- if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to set random MAC address");
- return -EINVAL;
- }
-
- if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Could not update MAC address information");
- return -EINVAL;
- }
-
- wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
- MAC2STR(addr));
-
- return 0;
-}
-
-
-/**
- * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
- * @global: Pointer to global data from wpa_supplicant_init()
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * Returns: 0 on success, -1 on failure
- */
-int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
-{
- struct p2p_config p2p;
- int i;
-
- if (wpa_s->conf->p2p_disabled)
- return 0;
-
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
- return 0;
-
- if (global->p2p)
- return 0;
-
- if (wpas_p2p_mac_setup(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Failed to initialize P2P random MAC address.");
- return -1;
- }
-
- os_memset(&p2p, 0, sizeof(p2p));
- p2p.cb_ctx = wpa_s;
- p2p.debug_print = wpas_p2p_debug_print;
- p2p.p2p_scan = wpas_p2p_scan;
- p2p.send_action = wpas_send_action;
- p2p.send_action_done = wpas_send_action_done;
- p2p.go_neg_completed = wpas_go_neg_completed;
- p2p.go_neg_req_rx = wpas_go_neg_req_rx;
- p2p.dev_found = wpas_dev_found;
- p2p.dev_lost = wpas_dev_lost;
- p2p.find_stopped = wpas_find_stopped;
- p2p.start_listen = wpas_start_listen;
- p2p.stop_listen = wpas_stop_listen;
- p2p.send_probe_resp = wpas_send_probe_resp;
- p2p.sd_request = wpas_sd_request;
- p2p.sd_response = wpas_sd_response;
- p2p.prov_disc_req = wpas_prov_disc_req;
- p2p.prov_disc_resp = wpas_prov_disc_resp;
- p2p.prov_disc_fail = wpas_prov_disc_fail;
- p2p.invitation_process = wpas_invitation_process;
- p2p.invitation_received = wpas_invitation_received;
- p2p.invitation_result = wpas_invitation_result;
- p2p.get_noa = wpas_get_noa;
- p2p.go_connected = wpas_go_connected;
- p2p.presence_resp = wpas_presence_resp;
- p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;
- p2p.is_p2p_in_progress = _wpas_p2p_in_progress;
- p2p.get_persistent_group = wpas_get_persistent_group;
- p2p.get_go_info = wpas_get_go_info;
- p2p.remove_stale_groups = wpas_remove_stale_groups;
- p2p.p2ps_prov_complete = wpas_p2ps_prov_complete;
- p2p.prov_disc_resp_cb = wpas_prov_disc_resp_cb;
- p2p.p2ps_group_capability = p2ps_group_capability;
- p2p.get_pref_freq_list = wpas_p2p_get_pref_freq_list;
- p2p.p2p_6ghz_disable = wpa_s->conf->p2p_6ghz_disable;
-
- os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
- p2p.dev_name = wpa_s->conf->device_name;
- p2p.manufacturer = wpa_s->conf->manufacturer;
- p2p.model_name = wpa_s->conf->model_name;
- p2p.model_number = wpa_s->conf->model_number;
- p2p.serial_number = wpa_s->conf->serial_number;
- if (wpa_s->wps) {
- os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
- p2p.config_methods = wpa_s->wps->config_methods;
- }
-
- if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels,
- p2p.p2p_6ghz_disable)) {
- wpa_printf(MSG_ERROR,
- "P2P: Failed to configure supported channel list");
- return -1;
- }
-
- if (wpa_s->conf->p2p_listen_reg_class &&
- wpa_s->conf->p2p_listen_channel) {
- p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
- p2p.channel = wpa_s->conf->p2p_listen_channel;
- p2p.channel_forced = 1;
- } else {
- /*
- * Pick one of the social channels randomly as the listen
- * channel.
- */
- if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
- &p2p.channel,
- &global->p2p_go_avoid_freq,
- &global->p2p_disallow_freq) !=
- 0) {
- wpa_printf(MSG_INFO,
- "P2P: No social channels supported by the driver - do not enable P2P");
- return 0;
- }
- p2p.channel_forced = 0;
- }
- wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
- p2p.reg_class, p2p.channel);
-
- if (wpa_s->conf->p2p_oper_reg_class &&
- wpa_s->conf->p2p_oper_channel) {
- p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
- p2p.op_channel = wpa_s->conf->p2p_oper_channel;
- p2p.cfg_op_channel = 1;
- wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
- "%d:%d", p2p.op_reg_class, p2p.op_channel);
-
- } else {
- /*
- * Use random operation channel from 2.4 GHz band social
- * channels (1, 6, 11) or band 60 GHz social channel (2) if no
- * other preference is indicated.
- */
- if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
- &p2p.op_channel, NULL,
- NULL) != 0) {
- wpa_printf(MSG_INFO,
- "P2P: Failed to select random social channel as operation channel");
- p2p.op_reg_class = 0;
- p2p.op_channel = 0;
- /* This will be overridden during group setup in
- * p2p_prepare_channel(), so allow setup to continue. */
- }
- p2p.cfg_op_channel = 0;
- wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
- "%d:%d", p2p.op_reg_class, p2p.op_channel);
- }
-
- if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
- p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
- p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
- }
-
- if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
- os_memcpy(p2p.country, wpa_s->conf->country, 2);
- p2p.country[2] = 0x04;
- } else
- os_memcpy(p2p.country, "XX\x04", 3);
-
- os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN);
-
- p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
- os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
- p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
-
- p2p.concurrent_operations = !!(wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_P2P_CONCURRENT);
-
- p2p.max_peers = 100;
-
- if (wpa_s->conf->p2p_ssid_postfix) {
- p2p.ssid_postfix_len =
- os_strlen(wpa_s->conf->p2p_ssid_postfix);
- if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
- p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
- os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
- p2p.ssid_postfix_len);
- }
-
- p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
-
- p2p.max_listen = wpa_s->max_remain_on_chan;
-
- if (wpa_s->conf->p2p_passphrase_len >= 8 &&
- wpa_s->conf->p2p_passphrase_len <= 63)
- p2p.passphrase_len = wpa_s->conf->p2p_passphrase_len;
- else
- p2p.passphrase_len = 8;
-
- global->p2p = p2p_init(&p2p);
- if (global->p2p == NULL)
- return -1;
- global->p2p_init_wpa_s = wpa_s;
-
- for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
- if (wpa_s->conf->wps_vendor_ext[i] == NULL)
- continue;
- p2p_add_wps_vendor_extension(
- global->p2p, wpa_s->conf->wps_vendor_ext[i]);
- }
-
- p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq);
-
- return 0;
-}
-
-
-/**
- * wpas_p2p_deinit - Deinitialize per-interface P2P data
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- *
- * This function deinitialize per-interface P2P data.
- */
-void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->driver && wpa_s->drv_priv)
- wpa_drv_probe_req_report(wpa_s, 0);
-
- if (wpa_s->go_params) {
- /* Clear any stored provisioning info */
- p2p_clear_provisioning_info(
- wpa_s->global->p2p,
- wpa_s->go_params->peer_device_addr);
- }
-
- os_free(wpa_s->go_params);
- wpa_s->go_params = NULL;
- eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
- wpa_s->global->p2p_long_listen = 0;
- eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
- wpas_p2p_remove_pending_group_interface(wpa_s);
- eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL);
- wpas_p2p_listen_work_done(wpa_s);
- if (wpa_s->p2p_send_action_work) {
- os_free(wpa_s->p2p_send_action_work->ctx);
- radio_work_done(wpa_s->p2p_send_action_work);
- wpa_s->p2p_send_action_work = NULL;
- }
- eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, wpa_s, NULL);
-
- wpabuf_free(wpa_s->p2p_oob_dev_pw);
- wpa_s->p2p_oob_dev_pw = NULL;
-
- os_free(wpa_s->p2p_group_common_freqs);
- wpa_s->p2p_group_common_freqs = NULL;
- wpa_s->p2p_group_common_freqs_num = 0;
-
- /* TODO: remove group interface from the driver if this wpa_s instance
- * is on top of a P2P group interface */
-}
-
-
-/**
- * wpas_p2p_deinit_global - Deinitialize global P2P module
- * @global: Pointer to global data from wpa_supplicant_init()
- *
- * This function deinitializes the global (per device) P2P module.
- */
-static void wpas_p2p_deinit_global(struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s, *tmp;
-
- wpa_s = global->ifaces;
-
- wpas_p2p_service_flush(global->p2p_init_wpa_s);
-
- /* Remove remaining P2P group interfaces */
- while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
- wpa_s = wpa_s->next;
- while (wpa_s) {
- tmp = global->ifaces;
- while (tmp &&
- (tmp == wpa_s ||
- tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) {
- tmp = tmp->next;
- }
- if (tmp == NULL)
- break;
- /* Disconnect from the P2P group and deinit the interface */
- wpas_p2p_disconnect(tmp);
- }
-
- /*
- * Deinit GO data on any possibly remaining interface (if main
- * interface is used as GO).
- */
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s->ap_iface)
- wpas_p2p_group_deinit(wpa_s);
- }
-
- p2p_deinit(global->p2p);
- global->p2p = NULL;
- global->p2p_init_wpa_s = NULL;
-}
-
-
-static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->conf->p2p_no_group_iface)
- return 0; /* separate interface disabled per configuration */
- if (wpa_s->drv_flags &
- (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
- WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P))
- return 1; /* P2P group requires a new interface in every case
- */
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT))
- return 0; /* driver does not support concurrent operations */
- if (wpa_s->global->ifaces->next)
- return 1; /* more that one interface already in use */
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- return 1; /* this interface is already in use */
- return 0;
-}
-
-
-static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr,
- enum p2p_wps_method wps_method,
- int go_intent, const u8 *own_interface_addr,
- unsigned int force_freq, int persistent_group,
- struct wpa_ssid *ssid, unsigned int pref_freq)
-{
- if (persistent_group && wpa_s->conf->persistent_reconnect)
- persistent_group = 2;
-
- /*
- * Increase GO config timeout if HT40 is used since it takes some time
- * to scan channels for coex purposes before the BSS can be started.
- */
- p2p_set_config_timeout(wpa_s->global->p2p,
- wpa_s->p2p_go_ht40 ? 255 : 100, 20);
-
- return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
- go_intent, own_interface_addr, force_freq,
- persistent_group, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0,
- wpa_s->p2p_pd_before_go_neg, pref_freq,
- wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
- 0);
-}
-
-
-static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr,
- enum p2p_wps_method wps_method,
- int go_intent, const u8 *own_interface_addr,
- unsigned int force_freq, int persistent_group,
- struct wpa_ssid *ssid, unsigned int pref_freq)
-{
- if (persistent_group && wpa_s->conf->persistent_reconnect)
- persistent_group = 2;
-
- return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method,
- go_intent, own_interface_addr, force_freq,
- persistent_group, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0, pref_freq,
- wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
- 0);
-}
-
-
-static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
-{
- wpa_s->p2p_join_scan_count++;
- wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d",
- wpa_s->p2p_join_scan_count);
- if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR
- " for join operationg - stop join attempt",
- MAC2STR(wpa_s->pending_join_iface_addr));
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
- if (wpa_s->p2p_auto_pd) {
- wpa_s->p2p_auto_pd = 0;
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_PROV_DISC_FAILURE
- " p2p_dev_addr=" MACSTR " status=N/A",
- MAC2STR(wpa_s->pending_join_dev_addr));
- return;
- }
- if (wpa_s->p2p_fallback_to_go_neg) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Join operation failed - fall back to GO Negotiation");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=join-failed");
- wpas_p2p_fallback_to_go_neg(wpa_s, 0);
- return;
- }
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_FORMATION_FAILURE);
- wpas_notify_p2p_group_formation_failure(wpa_s, "");
- }
-}
-
-
-static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
-{
- int res;
- unsigned int num, i;
- struct wpa_used_freq_data *freqs;
-
- if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
- /* Multiple channels are supported and not all are in use */
- return 0;
- }
-
- freqs = os_calloc(wpa_s->num_multichan_concurrent,
- sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return 1;
-
- num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
- wpa_s->num_multichan_concurrent);
-
- for (i = 0; i < num; i++) {
- if (freqs[i].freq == freq) {
- wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
- freq);
- res = 0;
- goto exit_free;
- }
- }
-
- wpa_printf(MSG_DEBUG, "P2P: No valid operating frequencies");
- res = 1;
-
-exit_free:
- os_free(freqs);
- return res;
-}
-
-
-static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s,
- const u8 *peer_dev_addr)
-{
- struct wpa_bss *bss;
- int updated;
-
- bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr);
- if (bss == NULL)
- return -1;
- if (bss->last_update_idx < wpa_s->bss_update_idx) {
- wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the "
- "last scan");
- return 0;
- }
-
- updated = os_reltime_before(&wpa_s->p2p_auto_started,
- &bss->last_update);
- wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at "
- "%ld.%06ld (%supdated in last scan)",
- bss->last_update.sec, bss->last_update.usec,
- updated ? "": "not ");
-
- return updated;
-}
-
-
-static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- struct wpa_bss *bss = NULL;
- int freq;
- u8 iface_addr[ETH_ALEN];
-
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
-
- if (wpa_s->global->p2p_disabled)
- return;
-
- wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin",
- scan_res ? (int) scan_res->num : -1,
- wpa_s->p2p_auto_join ? "auto_" : "");
-
- if (scan_res)
- wpas_p2p_scan_res_handler(wpa_s, scan_res);
-
- if (wpa_s->p2p_auto_pd) {
- int join = wpas_p2p_peer_go(wpa_s,
- wpa_s->pending_join_dev_addr);
- if (join == 0 &&
- wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) {
- wpa_s->auto_pd_scan_retry++;
- bss = wpa_bss_get_bssid_latest(
- wpa_s, wpa_s->pending_join_dev_addr);
- if (bss) {
- freq = bss->freq;
- wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for "
- "the peer " MACSTR " at %d MHz",
- wpa_s->auto_pd_scan_retry,
- MAC2STR(wpa_s->
- pending_join_dev_addr),
- freq);
- wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0);
- return;
- }
- }
-
- if (join < 0)
- join = 0;
-
- wpa_s->p2p_auto_pd = 0;
- wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
- wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
- MAC2STR(wpa_s->pending_join_dev_addr), join);
- if (p2p_prov_disc_req(wpa_s->global->p2p,
- wpa_s->pending_join_dev_addr, NULL,
- wpa_s->pending_pd_config_methods, join,
- 0, wpa_s->user_initiated_pd) < 0) {
- wpa_s->p2p_auto_pd = 0;
- wpa_msg_global(wpa_s, MSG_INFO,
- P2P_EVENT_PROV_DISC_FAILURE
- " p2p_dev_addr=" MACSTR " status=N/A",
- MAC2STR(wpa_s->pending_join_dev_addr));
- }
- return;
- }
-
- if (wpa_s->p2p_auto_join) {
- int join = wpas_p2p_peer_go(wpa_s,
- wpa_s->pending_join_dev_addr);
- if (join < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
- "running a GO -> use GO Negotiation");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=peer-not-running-GO");
- wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
- wpa_s->p2p_pin, wpa_s->p2p_wps_method,
- wpa_s->p2p_persistent_group, 0, 0, 0,
- wpa_s->p2p_go_intent,
- wpa_s->p2p_connect_freq,
- wpa_s->p2p_go_vht_center_freq2,
- wpa_s->p2p_persistent_id,
- wpa_s->p2p_pd_before_go_neg,
- wpa_s->p2p_go_ht40,
- wpa_s->p2p_go_vht,
- wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he,
- wpa_s->p2p_go_edmg,
- NULL, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p));
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> "
- "try to join the group", join ? "" :
- " in older scan");
- if (!join) {
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED);
- wpa_s->p2p_fallback_to_go_neg = 1;
- }
- }
-
- freq = p2p_get_oper_freq(wpa_s->global->p2p,
- wpa_s->pending_join_iface_addr);
- if (freq < 0 &&
- p2p_get_interface_addr(wpa_s->global->p2p,
- wpa_s->pending_join_dev_addr,
- iface_addr) == 0 &&
- os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0
- && !wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr)) {
- wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface "
- "address for join from " MACSTR " to " MACSTR
- " based on newly discovered P2P peer entry",
- MAC2STR(wpa_s->pending_join_iface_addr),
- MAC2STR(iface_addr));
- os_memcpy(wpa_s->pending_join_iface_addr, iface_addr,
- ETH_ALEN);
-
- freq = p2p_get_oper_freq(wpa_s->global->p2p,
- wpa_s->pending_join_iface_addr);
- }
- if (freq >= 0) {
- wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
- "from P2P peer table: %d MHz", freq);
- }
- if (wpa_s->p2p_join_ssid_len) {
- wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
- MACSTR " and SSID %s",
- MAC2STR(wpa_s->pending_join_iface_addr),
- wpa_ssid_txt(wpa_s->p2p_join_ssid,
- wpa_s->p2p_join_ssid_len));
- bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
- wpa_s->p2p_join_ssid,
- wpa_s->p2p_join_ssid_len);
- } else if (!bss) {
- wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
- MACSTR, MAC2STR(wpa_s->pending_join_iface_addr));
- bss = wpa_bss_get_bssid_latest(wpa_s,
- wpa_s->pending_join_iface_addr);
- }
- if (bss) {
- u8 dev_addr[ETH_ALEN];
-
- freq = bss->freq;
- wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
- "from BSS table: %d MHz (SSID %s)", freq,
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- if (p2p_parse_dev_addr(wpa_bss_ie_ptr(bss), bss->ie_len,
- dev_addr) == 0 &&
- os_memcmp(wpa_s->pending_join_dev_addr,
- wpa_s->pending_join_iface_addr, ETH_ALEN) == 0 &&
- os_memcmp(dev_addr, wpa_s->pending_join_dev_addr,
- ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG,
- "P2P: Update target GO device address based on BSS entry: " MACSTR " (was " MACSTR ")",
- MAC2STR(dev_addr),
- MAC2STR(wpa_s->pending_join_dev_addr));
- os_memcpy(wpa_s->pending_join_dev_addr, dev_addr,
- ETH_ALEN);
- }
- }
- if (freq > 0) {
- u16 method;
-
- if (wpas_check_freq_conflict(wpa_s, freq) > 0) {
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_GROUP_FORMATION_FAILURE
- "reason=FREQ_CONFLICT");
- wpas_notify_p2p_group_formation_failure(
- wpa_s, "FREQ_CONFLICT");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request "
- "prior to joining an existing group (GO " MACSTR
- " freq=%u MHz)",
- MAC2STR(wpa_s->pending_join_dev_addr), freq);
- wpa_s->pending_pd_before_join = 1;
-
- switch (wpa_s->pending_join_wps_method) {
- case WPS_PIN_DISPLAY:
- method = WPS_CONFIG_KEYPAD;
- break;
- case WPS_PIN_KEYPAD:
- method = WPS_CONFIG_DISPLAY;
- break;
- case WPS_PBC:
- method = WPS_CONFIG_PUSHBUTTON;
- break;
- case WPS_P2PS:
- method = WPS_CONFIG_P2PS;
- break;
- default:
- method = 0;
- break;
- }
-
- if ((p2p_get_provisioning_info(wpa_s->global->p2p,
- wpa_s->pending_join_dev_addr) ==
- method)) {
- /*
- * We have already performed provision discovery for
- * joining the group. Proceed directly to join
- * operation without duplicated provision discovery. */
- wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
- "with " MACSTR " already done - proceed to "
- "join",
- MAC2STR(wpa_s->pending_join_dev_addr));
- wpa_s->pending_pd_before_join = 0;
- goto start;
- }
-
- if (p2p_prov_disc_req(wpa_s->global->p2p,
- wpa_s->pending_join_dev_addr,
- NULL, method, 1,
- freq, wpa_s->user_initiated_pd) < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
- "Discovery Request before joining an "
- "existing group");
- wpa_s->pending_pd_before_join = 0;
- goto start;
- }
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later");
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
- eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
- wpas_p2p_check_join_scan_limit(wpa_s);
- return;
-
-start:
- /* Start join operation immediately */
- wpas_p2p_join_start(wpa_s, 0, wpa_s->p2p_join_ssid,
- wpa_s->p2p_join_ssid_len);
-}
-
-
-static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
- const u8 *ssid, size_t ssid_len)
-{
- int ret;
- struct wpa_driver_scan_params params;
- struct wpabuf *wps_ie, *ies;
- size_t ielen;
- int freqs[2] = { 0, 0 };
- unsigned int bands;
-
- os_memset(&params, 0, sizeof(params));
-
- /* P2P Wildcard SSID */
- params.num_ssids = 1;
- if (ssid && ssid_len) {
- params.ssids[0].ssid = ssid;
- params.ssids[0].ssid_len = ssid_len;
- os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len);
- wpa_s->p2p_join_ssid_len = ssid_len;
- } else {
- params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
- params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
- wpa_s->p2p_join_ssid_len = 0;
- }
-
- wpa_s->wps->dev.p2p = 1;
- wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
- wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
- NULL);
- if (wps_ie == NULL) {
- wpas_p2p_scan_res_join(wpa_s, NULL);
- return;
- }
-
- if (!freq) {
- int oper_freq;
- /*
- * If freq is not provided, check the operating freq of the GO
- * and use a single channel scan on if possible.
- */
- oper_freq = p2p_get_oper_freq(wpa_s->global->p2p,
- wpa_s->pending_join_iface_addr);
- if (oper_freq > 0)
- freq = oper_freq;
- }
- if (freq > 0) {
- freqs[0] = freq;
- params.freqs = freqs;
- } else if (wpa_s->conf->p2p_6ghz_disable ||
- !is_p2p_allow_6ghz(wpa_s->global->p2p)) {
- wpa_printf(MSG_DEBUG,
- "P2P: 6 GHz disabled - update the scan frequency list");
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
- 0);
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, &params,
- 0);
- }
-
- ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
- if (ies == NULL) {
- wpabuf_free(wps_ie);
- wpas_p2p_scan_res_join(wpa_s, NULL);
- return;
- }
- wpabuf_put_buf(ies, wps_ie);
- wpabuf_free(wps_ie);
-
- bands = wpas_get_bands(wpa_s, freqs);
- p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
-
- params.p2p_probe = 1;
- params.extra_ies = wpabuf_head(ies);
- params.extra_ies_len = wpabuf_len(ies);
-
- if (wpa_s->clear_driver_scan_cache) {
- wpa_printf(MSG_DEBUG,
- "Request driver to clear scan cache due to local BSS flush");
- params.only_new_results = 1;
- }
-
- /*
- * Run a scan to update BSS table and start Provision Discovery once
- * the new scan results become available.
- */
- ret = wpa_drv_scan(wpa_s, &params);
- if (params.freqs != freqs)
- os_free(params.freqs);
- if (!ret) {
- os_get_reltime(&wpa_s->scan_trigger_time);
- wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
- wpa_s->own_scan_requested = 1;
- wpa_s->clear_driver_scan_cache = 0;
- }
-
- wpabuf_free(ies);
-
- if (ret) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - "
- "try again later");
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
- eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
- wpas_p2p_check_join_scan_limit(wpa_s);
- }
-}
-
-
-static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0);
-}
-
-
-static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
- const u8 *dev_addr, enum p2p_wps_method wps_method,
- int auto_join, int op_freq,
- const u8 *ssid, size_t ssid_len)
-{
- wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
- MACSTR " dev " MACSTR " op_freq=%d)%s",
- MAC2STR(iface_addr), MAC2STR(dev_addr), op_freq,
- auto_join ? " (auto_join)" : "");
- if (ssid && ssid_len) {
- wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s",
- wpa_ssid_txt(ssid, ssid_len));
- }
-
- wpa_s->p2p_auto_pd = 0;
- wpa_s->p2p_auto_join = !!auto_join;
- os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
- os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
- wpa_s->pending_join_wps_method = wps_method;
-
- /* Make sure we are not running find during connection establishment */
- wpas_p2p_stop_find(wpa_s);
-
- wpa_s->p2p_join_scan_count = 0;
- wpas_p2p_join_scan_req(wpa_s, op_freq, ssid, ssid_len);
- return 0;
-}
-
-
-static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
- const u8 *ssid, size_t ssid_len)
-{
- struct wpa_supplicant *group;
- struct p2p_go_neg_results res;
- struct wpa_bss *bss;
-
- group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
- if (group == NULL)
- return -1;
- if (group != wpa_s) {
- os_memcpy(group->p2p_pin, wpa_s->p2p_pin,
- sizeof(group->p2p_pin));
- group->p2p_wps_method = wpa_s->p2p_wps_method;
- }
-
- /*
- * Need to mark the current interface for p2p_group_formation
- * when a separate group interface is not used. This is needed
- * to allow p2p_cancel stop a pending p2p_connect-join.
- * wpas_p2p_init_group_interface() addresses this for the case
- * where a separate group interface is used.
- */
- if (group == wpa_s->parent)
- wpa_s->global->p2p_group_formation = group;
-
- group->p2p_in_provisioning = 1;
- group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg;
-
- os_memset(&res, 0, sizeof(res));
- os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN);
- os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
- ETH_ALEN);
- res.wps_method = wpa_s->pending_join_wps_method;
- if (freq && ssid && ssid_len) {
- res.freq = freq;
- res.ssid_len = ssid_len;
- os_memcpy(res.ssid, ssid, ssid_len);
- } else {
- if (ssid && ssid_len) {
- bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
- ssid, ssid_len);
- } else {
- bss = wpa_bss_get_bssid_latest(
- wpa_s, wpa_s->pending_join_iface_addr);
- }
- if (bss) {
- res.freq = bss->freq;
- res.ssid_len = bss->ssid_len;
- os_memcpy(res.ssid, bss->ssid, bss->ssid_len);
- wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)",
- bss->freq,
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- } else if (ssid && ssid_len) {
- res.ssid_len = ssid_len;
- os_memcpy(res.ssid, ssid, ssid_len);
- wpa_printf(MSG_DEBUG, "P2P: Join target GO (SSID %s)",
- wpa_ssid_txt(ssid, ssid_len));
- }
- }
-
- if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
- wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to "
- "starting client");
- wpa_drv_cancel_remain_on_channel(wpa_s);
- wpa_s->off_channel_freq = 0;
- wpa_s->roc_waiting_drv_freq = 0;
- }
- wpas_start_wps_enrollee(group, &res);
-
- /*
- * Allow a longer timeout for join-a-running-group than normal 15
- * second group formation timeout since the GO may not have authorized
- * our connection yet.
- */
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
- eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout,
- wpa_s, NULL);
-
- return 0;
-}
-
-
-static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
- int *force_freq, int *pref_freq, int go,
- unsigned int *pref_freq_list,
- unsigned int *num_pref_freq)
-{
- struct wpa_used_freq_data *freqs;
- int res, best_freq, num_unused;
- unsigned int freq_in_use = 0, num, i, max_pref_freq;
-
- max_pref_freq = *num_pref_freq;
- *num_pref_freq = 0;
-
- freqs = os_calloc(wpa_s->num_multichan_concurrent,
- sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return -1;
-
- num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
- wpa_s->num_multichan_concurrent);
-
- /*
- * It is possible that the total number of used frequencies is bigger
- * than the number of frequencies used for P2P, so get the system wide
- * number of unused frequencies.
- */
- num_unused = wpas_p2p_num_unused_channels(wpa_s);
-
- wpa_printf(MSG_DEBUG,
- "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u num_unused=%d",
- freq, wpa_s->num_multichan_concurrent, num, num_unused);
-
- if (freq > 0) {
- int ret;
- if (go)
- ret = p2p_supported_freq(wpa_s->global->p2p, freq);
- else
- ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq);
- if (!ret) {
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
- ieee80211_is_dfs(freq, wpa_s->hw.modes,
- wpa_s->hw.num_modes)) {
- /*
- * If freq is a DFS channel and DFS is offloaded
- * to the driver, allow P2P GO to use it.
- */
- wpa_printf(MSG_DEBUG,
- "P2P: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to the driver",
- freq);
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: The forced channel (%u MHz) is not supported for P2P uses",
- freq);
- res = -3;
- goto exit_free;
- }
- }
-
- for (i = 0; i < num; i++) {
- if (freqs[i].freq == freq)
- freq_in_use = 1;
- }
-
- if (num_unused <= 0 && !freq_in_use) {
- wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
- freq);
- res = -2;
- goto exit_free;
- }
- wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
- "requested channel (%u MHz)", freq);
- *force_freq = freq;
- goto exit_ok;
- }
-
- best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
-
- if (!wpa_s->conf->num_p2p_pref_chan && *pref_freq == 0) {
- enum wpa_driver_if_type iface_type;
-
- if (go)
- iface_type = WPA_IF_P2P_GO;
- else
- iface_type = WPA_IF_P2P_CLIENT;
-
- wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
- best_freq, go);
-
- res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
- &max_pref_freq,
- pref_freq_list);
- if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
- max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list,
- max_pref_freq);
-
- if (!res && max_pref_freq > 0) {
- *num_pref_freq = max_pref_freq;
- i = 0;
- while (i < *num_pref_freq &&
- (!p2p_supported_freq(wpa_s->global->p2p,
- pref_freq_list[i]) ||
- wpas_p2p_disallowed_freq(wpa_s->global,
- pref_freq_list[i]))) {
- wpa_printf(MSG_DEBUG,
- "P2P: preferred_freq_list[%d]=%d is disallowed",
- i, pref_freq_list[i]);
- i++;
- }
- if (i != *num_pref_freq) {
- best_freq = pref_freq_list[i];
- wpa_printf(MSG_DEBUG,
- "P2P: Using preferred_freq_list[%d]=%d",
- i, best_freq);
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: All driver preferred frequencies are disallowed for P2P use");
- *num_pref_freq = 0;
- }
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: No preferred frequency list available");
- }
- }
-
- /* We have a candidate frequency to use */
- if (best_freq > 0) {
- if (*pref_freq == 0 && num_unused > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
- best_freq);
- *pref_freq = best_freq;
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
- best_freq);
- *force_freq = best_freq;
- }
- } else if (num_unused > 0) {
- wpa_printf(MSG_DEBUG,
- "P2P: Current operating channels are not available for P2P. Try to use another channel");
- *force_freq = 0;
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
- res = -2;
- goto exit_free;
- }
-
-exit_ok:
- res = 0;
-exit_free:
- os_free(freqs);
- return res;
-}
-
-
-static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- if (wpa_s->conf->p2p_6ghz_disable ||
- !get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211A, true))
- return false;
-
- if (!p2p_wfd_enabled(wpa_s->global->p2p))
- return false;
- if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr))
- return false;
-
- return true;
-}
-
-
-static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, bool allow_6ghz, int freq)
-{
- if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Allow connection on 6 GHz channels");
- p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true);
- } else {
- if (is_6ghz_freq(freq))
- return -2;
- p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
- }
-
- return 0;
-}
-
-
-/**
- * wpas_p2p_connect - Request P2P Group Formation to be started
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * @peer_addr: Address of the peer P2P Device
- * @pin: PIN to use during provisioning or %NULL to indicate PBC mode
- * @persistent_group: Whether to create a persistent group
- * @auto_join: Whether to select join vs. GO Negotiation automatically
- * @join: Whether to join an existing group (as a client) instead of starting
- * Group Owner negotiation; @peer_addr is BSSID in that case
- * @auth: Whether to only authorize the connection instead of doing that and
- * initiating Group Owner negotiation
- * @go_intent: GO Intent or -1 to use default
- * @freq: Frequency for the group or 0 for auto-selection
- * @freq2: Center frequency of segment 1 for the GO operating in VHT 80P80 mode
- * @persistent_id: Persistent group credentials to use for forcing GO
- * parameters or -1 to generate new values (SSID/passphrase)
- * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
- * interoperability workaround when initiating group formation
- * @ht40: Start GO with 40 MHz channel width
- * @vht: Start GO with VHT support
- * @vht_chwidth: Channel width supported by GO operating with VHT support
- * (CHANWIDTH_*).
- * @group_ssid: Specific Group SSID for join or %NULL if not set
- * @group_ssid_len: Length of @group_ssid in octets
- * @allow_6ghz: Allow P2P connection on 6 GHz channels
- * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
- * failure, -2 on failure due to channel not currently available,
- * -3 if forced channel is not supported
- */
-int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *pin, enum p2p_wps_method wps_method,
- int persistent_group, int auto_join, int join, int auth,
- int go_intent, int freq, unsigned int vht_center_freq2,
- int persistent_id, int pd, int ht40, int vht,
- unsigned int vht_chwidth, int he, int edmg,
- const u8 *group_ssid, size_t group_ssid_len,
- bool allow_6ghz)
-{
- int force_freq = 0, pref_freq = 0;
- int ret = 0, res;
- enum wpa_driver_if_type iftype;
- const u8 *if_addr;
- struct wpa_ssid *ssid = NULL;
- unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- if (persistent_id >= 0) {
- ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
- if (ssid == NULL || ssid->disabled != 2 ||
- ssid->mode != WPAS_MODE_P2P_GO)
- return -1;
- }
-
- if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
- return -2;
-
- os_free(wpa_s->global->add_psk);
- wpa_s->global->add_psk = NULL;
-
- wpa_s->global->p2p_fail_on_wps_complete = 0;
- wpa_s->global->pending_p2ps_group = 0;
- wpa_s->global->pending_p2ps_group_freq = 0;
- wpa_s->p2ps_method_config_any = 0;
-
- if (go_intent < 0)
- go_intent = wpa_s->conf->p2p_go_intent;
-
- if (!auth)
- wpa_s->global->p2p_long_listen = 0;
-
- wpa_s->p2p_wps_method = wps_method;
- wpa_s->p2p_persistent_group = !!persistent_group;
- wpa_s->p2p_persistent_id = persistent_id;
- wpa_s->p2p_go_intent = go_intent;
- wpa_s->p2p_connect_freq = freq;
- wpa_s->p2p_fallback_to_go_neg = 0;
- wpa_s->p2p_pd_before_go_neg = !!pd;
- wpa_s->p2p_go_ht40 = !!ht40;
- wpa_s->p2p_go_vht = !!vht;
- wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
- wpa_s->p2p_go_max_oper_chwidth = vht_chwidth;
- wpa_s->p2p_go_he = !!he;
- wpa_s->p2p_go_edmg = !!edmg;
-
- if (pin)
- os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
- else if (wps_method == WPS_PIN_DISPLAY) {
- if (wps_generate_pin((unsigned int *) &ret) < 0)
- return -1;
- res = os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin),
- "%08d", ret);
- if (os_snprintf_error(sizeof(wpa_s->p2p_pin), res))
- wpa_s->p2p_pin[sizeof(wpa_s->p2p_pin) - 1] = '\0';
- wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
- wpa_s->p2p_pin);
- } else if (wps_method == WPS_P2PS) {
- /* Force the P2Ps default PIN to be used */
- os_strlcpy(wpa_s->p2p_pin, "12345670", sizeof(wpa_s->p2p_pin));
- } else
- wpa_s->p2p_pin[0] = '\0';
-
- if (join || auto_join) {
- u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
- if (auth) {
- wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
- "connect a running group from " MACSTR,
- MAC2STR(peer_addr));
- os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
- return ret;
- }
- os_memcpy(dev_addr, peer_addr, ETH_ALEN);
- if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
- iface_addr) < 0) {
- os_memcpy(iface_addr, peer_addr, ETH_ALEN);
- p2p_get_dev_addr(wpa_s->global->p2p, peer_addr,
- dev_addr);
- }
- if (auto_join) {
- os_get_reltime(&wpa_s->p2p_auto_started);
- wpa_printf(MSG_DEBUG, "P2P: Auto join started at "
- "%ld.%06ld",
- wpa_s->p2p_auto_started.sec,
- wpa_s->p2p_auto_started.usec);
- }
- wpa_s->user_initiated_pd = 1;
- if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
- auto_join, freq,
- group_ssid, group_ssid_len) < 0)
- return -1;
- return ret;
- }
-
- size = P2P_MAX_PREF_CHANNELS;
- res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- go_intent == 15, pref_freq_list, &size);
- if (res)
- return res;
- wpas_p2p_set_own_freq_preference(wpa_s,
- force_freq ? force_freq : pref_freq);
-
- p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);
-
- wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
-
- if (wpa_s->create_p2p_iface) {
- /* Prepare to add a new interface for the group */
- iftype = WPA_IF_P2P_GROUP;
- if (go_intent == 15)
- iftype = WPA_IF_P2P_GO;
- if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
- "interface for the group");
- return -1;
- }
-
- if_addr = wpa_s->pending_interface_addr;
- } else {
- if (wpa_s->p2p_mgmt)
- if_addr = wpa_s->parent->own_addr;
- else
- if_addr = wpa_s->own_addr;
- os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
- }
-
- if (auth) {
- if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
- go_intent, if_addr,
- force_freq, persistent_group, ssid,
- pref_freq) < 0)
- return -1;
- return ret;
- }
-
- if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
- go_intent, if_addr, force_freq,
- persistent_group, ssid, pref_freq) < 0) {
- if (wpa_s->create_p2p_iface)
- wpas_p2p_remove_pending_group_interface(wpa_s);
- return -1;
- }
- return ret;
-}
-
-
-/**
- * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * @freq: Frequency of the channel in MHz
- * @duration: Duration of the stay on the channel in milliseconds
- *
- * This callback is called when the driver indicates that it has started the
- * requested remain-on-channel duration.
- */
-void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
- wpa_printf(MSG_DEBUG, "P2P: remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u duration=%u)",
- wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
- wpa_s->roc_waiting_drv_freq, freq, duration);
- if (wpa_s->off_channel_freq &&
- wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
- p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
- wpa_s->pending_listen_duration);
- wpa_s->pending_listen_freq = 0;
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Ignore remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d freq=%u duration=%u)",
- wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
- freq, duration);
- }
-}
-
-
-int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout)
-{
- /* Limit maximum Listen state time based on driver limitation. */
- if (timeout > wpa_s->max_remain_on_chan)
- timeout = wpa_s->max_remain_on_chan;
-
- return p2p_listen(wpa_s->global->p2p, timeout);
-}
-
-
-/**
- * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * @freq: Frequency of the channel in MHz
- *
- * This callback is called when the driver indicates that a remain-on-channel
- * operation has been completed, i.e., the duration on the requested channel
- * has timed out.
- */
-void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
- "(p2p_long_listen=%d ms pending_action_tx=%p)",
- wpa_s->global->p2p_long_listen,
- offchannel_pending_action_tx(wpa_s));
- wpas_p2p_listen_work_done(wpa_s);
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
- if (wpa_s->global->p2p_long_listen > 0)
- wpa_s->global->p2p_long_listen -= wpa_s->max_remain_on_chan;
- if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
- return; /* P2P module started a new operation */
- if (offchannel_pending_action_tx(wpa_s))
- return;
- if (wpa_s->global->p2p_long_listen > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
- wpas_p2p_listen_start(wpa_s, wpa_s->global->p2p_long_listen);
- } else {
- /*
- * When listen duration is over, stop listen & update p2p_state
- * to IDLE.
- */
- p2p_stop_listen(wpa_s->global->p2p);
- }
-}
-
-
-/**
- * wpas_p2p_group_remove - Remove a P2P group
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * @ifname: Network interface name of the group interface or "*" to remove all
- * groups
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to remove a P2P group. This can be used to disconnect
- * from a group in which the local end is a P2P Client or to end a P2P Group in
- * case the local end is the Group Owner. If a virtual network interface was
- * created for this group, that interface will be removed. Otherwise, only the
- * configured P2P group network will be removed from the interface.
- */
-int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
-{
- struct wpa_global *global = wpa_s->global;
- struct wpa_supplicant *calling_wpa_s = wpa_s;
-
- if (os_strcmp(ifname, "*") == 0) {
- struct wpa_supplicant *prev;
- bool calling_wpa_s_group_removed = false;
-
- wpa_s = global->ifaces;
- while (wpa_s) {
- prev = wpa_s;
- wpa_s = wpa_s->next;
- if (prev->p2p_group_interface !=
- NOT_P2P_GROUP_INTERFACE ||
- (prev->current_ssid &&
- prev->current_ssid->p2p_group)) {
- wpas_p2p_disconnect_safely(prev, calling_wpa_s);
- if (prev == calling_wpa_s)
- calling_wpa_s_group_removed = true;
- }
- }
-
- if (!calling_wpa_s_group_removed &&
- (calling_wpa_s->p2p_group_interface !=
- NOT_P2P_GROUP_INTERFACE ||
- (calling_wpa_s->current_ssid &&
- calling_wpa_s->current_ssid->p2p_group))) {
- wpa_printf(MSG_DEBUG, "Remove calling_wpa_s P2P group");
- wpas_p2p_disconnect_safely(calling_wpa_s,
- calling_wpa_s);
- }
-
- return 0;
- }
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_strcmp(wpa_s->ifname, ifname) == 0)
- break;
- }
-
- return wpas_p2p_disconnect_safely(wpa_s, calling_wpa_s);
-}
-
-
-static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
-{
- unsigned int r;
-
- if (!wpa_s->conf->num_p2p_pref_chan && !freq) {
- unsigned int i, size = P2P_MAX_PREF_CHANNELS;
- unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
- int res;
-
- res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
- &size, pref_freq_list);
- if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
- size = p2p_remove_6ghz_channels(pref_freq_list, size);
-
- if (!res && size > 0) {
- i = 0;
- while (i < size &&
- (!p2p_supported_freq(wpa_s->global->p2p,
- pref_freq_list[i]) ||
- wpas_p2p_disallowed_freq(wpa_s->global,
- pref_freq_list[i]))) {
- wpa_printf(MSG_DEBUG,
- "P2P: preferred_freq_list[%d]=%d is disallowed",
- i, pref_freq_list[i]);
- i++;
- }
- if (i != size) {
- freq = pref_freq_list[i];
- wpa_printf(MSG_DEBUG,
- "P2P: Using preferred_freq_list[%d]=%d",
- i, freq);
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: All driver preferred frequencies are disallowed for P2P use");
- }
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: No preferred frequency list available");
- }
- }
-
- if (freq == 2) {
- wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
- "band");
- if (wpa_s->best_24_freq > 0 &&
- p2p_supported_freq_go(wpa_s->global->p2p,
- wpa_s->best_24_freq)) {
- freq = wpa_s->best_24_freq;
- wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band "
- "channel: %d MHz", freq);
- } else {
- if (os_get_random((u8 *) &r, sizeof(r)) < 0)
- return -1;
- freq = 2412 + (r % 3) * 25;
- wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
- "channel: %d MHz", freq);
- }
- }
-
- if (freq == 5) {
- wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz "
- "band");
- if (wpa_s->best_5_freq > 0 &&
- p2p_supported_freq_go(wpa_s->global->p2p,
- wpa_s->best_5_freq)) {
- freq = wpa_s->best_5_freq;
- wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
- "channel: %d MHz", freq);
- } else {
- const int freqs[] = {
- /* operating class 115 */
- 5180, 5200, 5220, 5240,
- /* operating class 124 */
- 5745, 5765, 5785, 5805,
- };
- unsigned int i, num_freqs = ARRAY_SIZE(freqs);
-
- if (os_get_random((u8 *) &r, sizeof(r)) < 0)
- return -1;
-
- /*
- * Most of the 5 GHz channels require DFS. Only
- * operating classes 115 and 124 are available possibly
- * without that requirement. Check these for
- * availability starting from a randomly picked
- * position.
- */
- for (i = 0; i < num_freqs; i++, r++) {
- freq = freqs[r % num_freqs];
- if (p2p_supported_freq_go(wpa_s->global->p2p,
- freq))
- break;
- }
-
- if (i >= num_freqs) {
- wpa_printf(MSG_DEBUG, "P2P: Could not select "
- "5 GHz channel for P2P group");
- return -1;
- }
- wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band "
- "channel: %d MHz", freq);
- }
- }
-
- if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
- ieee80211_is_dfs(freq, wpa_s->hw.modes,
- wpa_s->hw.num_modes)) {
- /*
- * If freq is a DFS channel and DFS is offloaded to the
- * driver, allow P2P GO to use it.
- */
- wpa_printf(MSG_DEBUG, "P2P: "
- "%s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded",
- __func__, freq);
- return freq;
- }
- wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO "
- "(%u MHz) is not supported for P2P uses",
- freq);
- return -1;
- }
-
- return freq;
-}
-
-
-static int wpas_p2p_supported_freq_go(struct wpa_supplicant *wpa_s,
- const struct p2p_channels *channels,
- int freq)
-{
- if (!wpas_p2p_disallowed_freq(wpa_s->global, freq) &&
- p2p_supported_freq_go(wpa_s->global->p2p, freq) &&
- freq_included(wpa_s, channels, freq))
- return 1;
- return 0;
-}
-
-
-static void wpas_p2p_select_go_freq_no_pref(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params,
- const struct p2p_channels *channels)
-{
- unsigned int i, r;
-
- /* try all channels in operating class 115 */
- for (i = 0; i < 4; i++) {
- params->freq = 5180 + i * 20;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
- }
-
- /* try all channels in operating class 124 */
- for (i = 0; i < 4; i++) {
- params->freq = 5745 + i * 20;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
- }
-
- /* try social channel class 180 channel 2 */
- params->freq = 58320 + 1 * 2160;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
-
- /* try all channels in reg. class 180 */
- for (i = 0; i < 4; i++) {
- params->freq = 58320 + i * 2160;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
- }
-
- /* try some random selection of the social channels */
- if (os_get_random((u8 *) &r, sizeof(r)) < 0)
- return;
-
- for (i = 0; i < 3; i++) {
- params->freq = 2412 + ((r + i) % 3) * 25;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
- }
-
- /* try all other channels in operating class 81 */
- for (i = 0; i < 11; i++) {
- params->freq = 2412 + i * 5;
-
- /* skip social channels; covered in the previous loop */
- if (params->freq == 2412 ||
- params->freq == 2437 ||
- params->freq == 2462)
- continue;
-
- if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
- goto out;
- }
-
- params->freq = 0;
- wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
- return;
-out:
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
- params->freq);
-}
-
-
-static int wpas_same_band(int freq1, int freq2)
-{
- enum hostapd_hw_mode mode1, mode2;
- u8 chan1, chan2;
-
- mode1 = ieee80211_freq_to_chan(freq1, &chan1);
- mode2 = ieee80211_freq_to_chan(freq2, &chan2);
- if (mode1 == NUM_HOSTAPD_MODES)
- return 0;
- return mode1 == mode2;
-}
-
-
-static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params,
- int freq, int vht_center_freq2, int ht40,
- int vht, int max_oper_chwidth, int he,
- int edmg,
- const struct p2p_channels *channels)
-{
- struct wpa_used_freq_data *freqs;
- unsigned int cand;
- unsigned int num, i;
- int ignore_no_freqs = 0;
- int unused_channels = wpas_p2p_num_unused_channels(wpa_s) > 0;
-
- os_memset(params, 0, sizeof(*params));
- params->role_go = 1;
- params->ht40 = ht40;
- params->vht = vht;
- params->he = he;
- params->max_oper_chwidth = max_oper_chwidth;
- params->vht_center_freq2 = vht_center_freq2;
- params->edmg = edmg;
-
- freqs = os_calloc(wpa_s->num_multichan_concurrent,
- sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return -1;
-
- num = get_shared_radio_freqs_data(wpa_s, freqs,
- wpa_s->num_multichan_concurrent);
-
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO &&
- wpa_s->wpa_state == WPA_COMPLETED) {
- wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
- __func__);
-
- /*
- * If the frequency selection is done for an active P2P GO that
- * is not sharing a frequency, allow to select a new frequency
- * even if there are no unused frequencies as we are about to
- * move the P2P GO so its frequency can be re-used.
- */
- for (i = 0; i < num; i++) {
- if (freqs[i].freq == wpa_s->current_ssid->frequency &&
- freqs[i].flags == 0) {
- ignore_no_freqs = 1;
- break;
- }
- }
- }
-
- /* Try to use EDMG channel */
- if (params->edmg) {
- if (wpas_p2p_try_edmg_channel(wpa_s, params) == 0)
- goto success;
- params->edmg = 0;
- }
-
- /* try using the forced freq */
- if (freq) {
- if (wpas_p2p_disallowed_freq(wpa_s->global, freq) ||
- !freq_included(wpa_s, channels, freq)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Forced GO freq %d MHz disallowed",
- freq);
- goto fail;
- }
- if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
- ieee80211_is_dfs(freq, wpa_s->hw.modes,
- wpa_s->hw.num_modes)) {
- /*
- * If freq is a DFS channel and DFS is offloaded
- * to the driver, allow P2P GO to use it.
- */
- wpa_printf(MSG_DEBUG,
- "P2P: %s: The forced channel for GO (%u MHz) requires DFS and DFS is offloaded",
- __func__, freq);
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: The forced channel for GO (%u MHz) is not supported for P2P uses",
- freq);
- goto fail;
- }
- }
-
- for (i = 0; i < num; i++) {
- if (freqs[i].freq == freq) {
- wpa_printf(MSG_DEBUG,
- "P2P: forced freq (%d MHz) is also shared",
- freq);
- params->freq = freq;
- goto success;
- }
- }
-
- if (!ignore_no_freqs && !unused_channels) {
- wpa_printf(MSG_DEBUG,
- "P2P: Cannot force GO on freq (%d MHz) as all the channels are in use",
- freq);
- goto fail;
- }
-
- wpa_printf(MSG_DEBUG,
- "P2P: force GO freq (%d MHz) on a free channel",
- freq);
- params->freq = freq;
- goto success;
- }
-
- /* consider using one of the shared frequencies */
- if (num &&
- (!wpa_s->conf->p2p_ignore_shared_freq || !unused_channels)) {
- cand = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
- if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Use shared freq (%d MHz) for GO",
- cand);
- params->freq = cand;
- goto success;
- }
-
- /* try using one of the shared freqs */
- for (i = 0; i < num; i++) {
- if (wpas_p2p_supported_freq_go(wpa_s, channels,
- freqs[i].freq)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Use shared freq (%d MHz) for GO",
- freqs[i].freq);
- params->freq = freqs[i].freq;
- goto success;
- }
- }
- }
-
- if (!ignore_no_freqs && !unused_channels) {
- wpa_printf(MSG_DEBUG,
- "P2P: Cannot force GO on any of the channels we are already using");
- goto fail;
- }
-
- /* try using the setting from the configuration file */
- if (wpa_s->conf->p2p_oper_reg_class == 81 &&
- wpa_s->conf->p2p_oper_channel >= 1 &&
- wpa_s->conf->p2p_oper_channel <= 11 &&
- wpas_p2p_supported_freq_go(
- wpa_s, channels,
- 2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
- params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
- "frequency %d MHz", params->freq);
- goto success;
- }
-
- if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
- wpa_s->conf->p2p_oper_reg_class == 116 ||
- wpa_s->conf->p2p_oper_reg_class == 117 ||
- wpa_s->conf->p2p_oper_reg_class == 124 ||
- wpa_s->conf->p2p_oper_reg_class == 125 ||
- wpa_s->conf->p2p_oper_reg_class == 126 ||
- wpa_s->conf->p2p_oper_reg_class == 127) &&
- wpas_p2p_supported_freq_go(wpa_s, channels,
- 5000 +
- 5 * wpa_s->conf->p2p_oper_channel)) {
- params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
- "frequency %d MHz", params->freq);
- goto success;
- }
-
- /* Try using best channels */
- if (wpa_s->conf->p2p_oper_channel == 0 &&
- wpa_s->best_overall_freq > 0 &&
- wpas_p2p_supported_freq_go(wpa_s, channels,
- wpa_s->best_overall_freq)) {
- params->freq = wpa_s->best_overall_freq;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
- "channel %d MHz", params->freq);
- goto success;
- }
-
- if (wpa_s->conf->p2p_oper_channel == 0 &&
- wpa_s->best_24_freq > 0 &&
- wpas_p2p_supported_freq_go(wpa_s, channels,
- wpa_s->best_24_freq)) {
- params->freq = wpa_s->best_24_freq;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
- "channel %d MHz", params->freq);
- goto success;
- }
-
- if (wpa_s->conf->p2p_oper_channel == 0 &&
- wpa_s->best_5_freq > 0 &&
- wpas_p2p_supported_freq_go(wpa_s, channels,
- wpa_s->best_5_freq)) {
- params->freq = wpa_s->best_5_freq;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
- "channel %d MHz", params->freq);
- goto success;
- }
-
- /* try using preferred channels */
- cand = p2p_get_pref_freq(wpa_s->global->p2p, channels);
- if (cand && wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- params->freq = cand;
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
- "channels", params->freq);
- goto success;
- }
-
- /* Try using a channel that allows VHT to be used with 80 MHz */
- if (wpa_s->hw.modes && wpa_s->p2p_group_common_freqs) {
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- enum hostapd_hw_mode mode;
- struct hostapd_hw_modes *hwmode;
- u8 chan;
- u8 op_class;
-
- cand = wpa_s->p2p_group_common_freqs[i];
- op_class = is_6ghz_freq(cand) ? 133 : 128;
- mode = ieee80211_freq_to_chan(cand, &chan);
- hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- mode, is_6ghz_freq(cand));
- if (!hwmode ||
- wpas_p2p_verify_channel(wpa_s, hwmode, op_class,
- chan, BW80) != ALLOWED)
- continue;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- params->freq = cand;
- wpa_printf(MSG_DEBUG,
- "P2P: Use freq %d MHz common with the peer and allowing VHT80",
- params->freq);
- goto success;
- }
- }
- }
-
- /* Try using a channel that allows HT to be used with 40 MHz on the same
- * band so that CSA can be used */
- if (wpa_s->current_ssid && wpa_s->hw.modes &&
- wpa_s->p2p_group_common_freqs) {
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- enum hostapd_hw_mode mode;
- struct hostapd_hw_modes *hwmode;
- u8 chan, op_class;
- bool is_6ghz, supported = false;
-
- is_6ghz = is_6ghz_freq(cand);
- cand = wpa_s->p2p_group_common_freqs[i];
- mode = ieee80211_freq_to_chan(cand, &chan);
- hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- mode, is_6ghz);
- if (!wpas_same_band(wpa_s->current_ssid->frequency,
- cand) ||
- !hwmode)
- continue;
- if (is_6ghz &&
- wpas_p2p_verify_channel(wpa_s, hwmode, 132, chan,
- BW40) == ALLOWED)
- supported = true;
-
- if (!is_6ghz &&
- ieee80211_freq_to_channel_ext(
- cand, -1, CHANWIDTH_USE_HT, &op_class,
- &chan) != NUM_HOSTAPD_MODES &&
- wpas_p2p_verify_channel(
- wpa_s, hwmode, op_class, chan,
- BW40MINUS) == ALLOWED)
- supported = true;
-
- if (!supported && !is_6ghz &&
- ieee80211_freq_to_channel_ext(
- cand, 1, CHANWIDTH_USE_HT, &op_class,
- &chan) != NUM_HOSTAPD_MODES &&
- wpas_p2p_verify_channel(
- wpa_s, hwmode, op_class, chan,
- BW40PLUS) == ALLOWED)
- supported = true;
-
- if (!supported)
- continue;
-
- if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- params->freq = cand;
- wpa_printf(MSG_DEBUG,
- "P2P: Use freq %d MHz common with the peer, allowing HT40, and maintaining same band",
- params->freq);
- goto success;
- }
- }
- }
-
- /* Try using one of the group common freqs on the same band so that CSA
- * can be used */
- if (wpa_s->current_ssid && wpa_s->p2p_group_common_freqs) {
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- cand = wpa_s->p2p_group_common_freqs[i];
- if (!wpas_same_band(wpa_s->current_ssid->frequency,
- cand))
- continue;
- if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- params->freq = cand;
- wpa_printf(MSG_DEBUG,
- "P2P: Use freq %d MHz common with the peer and maintaining same band",
- params->freq);
- goto success;
- }
- }
- }
-
- /* Try using one of the group common freqs */
- if (wpa_s->p2p_group_common_freqs) {
- for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
- cand = wpa_s->p2p_group_common_freqs[i];
- if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
- params->freq = cand;
- wpa_printf(MSG_DEBUG,
- "P2P: Use freq %d MHz common with the peer",
- params->freq);
- goto success;
- }
- }
- }
-
- /* no preference, select some channel */
- wpas_p2p_select_go_freq_no_pref(wpa_s, params, channels);
-
- if (params->freq == 0) {
- wpa_printf(MSG_DEBUG, "P2P: did not find a freq for GO use");
- goto fail;
- }
-
-success:
- os_free(freqs);
- return 0;
-fail:
- os_free(freqs);
- return -1;
-}
-
-
-static struct wpa_supplicant *
-wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
- int go)
-{
- struct wpa_supplicant *group_wpa_s;
-
- if (!wpas_p2p_create_iface(wpa_s)) {
- if (wpa_s->p2p_mgmt) {
- /*
- * We may be called on the p2p_dev interface which
- * cannot be used for group operations, so always use
- * the primary interface.
- */
- wpa_s->parent->p2pdev = wpa_s;
- wpa_s = wpa_s->parent;
- }
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Use primary interface for group operations");
- wpa_s->p2p_first_connection_timeout = 0;
- if (wpa_s != wpa_s->p2pdev)
- wpas_p2p_clone_config(wpa_s, wpa_s->p2pdev);
- return wpa_s;
- }
-
- if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
- WPA_IF_P2P_CLIENT) < 0) {
- wpa_msg_global(wpa_s, MSG_ERROR,
- "P2P: Failed to add group interface");
- return NULL;
- }
- group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go);
- if (group_wpa_s == NULL) {
- wpa_msg_global(wpa_s, MSG_ERROR,
- "P2P: Failed to initialize group interface");
- wpas_p2p_remove_pending_group_interface(wpa_s);
- return NULL;
- }
-
- if (go && wpa_s->p2p_go_do_acs) {
- group_wpa_s->p2p_go_do_acs = wpa_s->p2p_go_do_acs;
- group_wpa_s->p2p_go_acs_band = wpa_s->p2p_go_acs_band;
- wpa_s->p2p_go_do_acs = 0;
- }
-
- if (go && wpa_s->p2p_go_allow_dfs) {
- group_wpa_s->p2p_go_allow_dfs = wpa_s->p2p_go_allow_dfs;
- wpa_s->p2p_go_allow_dfs = 0;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
- group_wpa_s->ifname);
- group_wpa_s->p2p_first_connection_timeout = 0;
- return group_wpa_s;
-}
-
-
-/**
- * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner
- * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
- * @persistent_group: Whether to create a persistent group
- * @freq: Frequency for the group or 0 to indicate no hardcoding
- * @vht_center_freq2: segment_1 center frequency for GO operating in VHT 80P80
- * @ht40: Start GO with 40 MHz channel width
- * @vht: Start GO with VHT support
- * @vht_chwidth: channel bandwidth for GO operating with VHT support
- * @edmg: Start GO with EDMG support
- * @allow_6ghz: Allow P2P group creation on a 6 GHz channel
- * Returns: 0 on success, -1 on failure
- *
- * This function creates a new P2P group with the local end as the Group Owner,
- * i.e., without using Group Owner Negotiation.
- */
-int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
- int freq, int vht_center_freq2, int ht40, int vht,
- int max_oper_chwidth, int he, int edmg,
- bool allow_6ghz)
-{
- struct p2p_go_neg_results params;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
- if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
- return -1;
-
- os_free(wpa_s->global->add_psk);
- wpa_s->global->add_psk = NULL;
-
- /* Make sure we are not running find during connection establishment */
- wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
- wpas_p2p_stop_find_oper(wpa_s);
-
- if (!wpa_s->p2p_go_do_acs) {
- freq = wpas_p2p_select_go_freq(wpa_s, freq);
- if (freq < 0)
- return -1;
- }
-
- if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
- ht40, vht, max_oper_chwidth, he, edmg,
- NULL))
- return -1;
-
- p2p_go_params(wpa_s->global->p2p, &params);
- params.persistent_group = persistent_group;
-
- wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1);
- if (wpa_s == NULL)
- return -1;
- wpas_start_wps_go(wpa_s, &params, 0);
-
- return 0;
-}
-
-
-static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *params, int addr_allocated,
- int freq, int force_scan)
-{
- struct wpa_ssid *ssid;
-
- wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
- if (wpa_s == NULL)
- return -1;
- if (force_scan)
- os_get_reltime(&wpa_s->scan_min_time);
- wpa_s->p2p_last_4way_hs_fail = NULL;
-
- wpa_supplicant_ap_deinit(wpa_s);
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL)
- return -1;
- os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
- wpa_config_set_network_defaults(ssid);
- ssid->temporary = 1;
- ssid->proto = WPA_PROTO_RSN;
- ssid->pbss = params->pbss;
- ssid->pairwise_cipher = params->pbss ? WPA_CIPHER_GCMP :
- WPA_CIPHER_CCMP;
- ssid->group_cipher = params->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
- ssid->key_mgmt = WPA_KEY_MGMT_PSK;
- ssid->ssid = os_malloc(params->ssid_len);
- if (ssid->ssid == NULL) {
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return -1;
- }
- os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
- ssid->ssid_len = params->ssid_len;
- ssid->p2p_group = 1;
- ssid->export_keys = 1;
- if (params->psk_set) {
- os_memcpy(ssid->psk, params->psk, 32);
- ssid->psk_set = 1;
- }
- if (params->passphrase)
- ssid->passphrase = os_strdup(params->passphrase);
-
- wpa_s->show_group_started = 1;
- wpa_s->p2p_in_invitation = 1;
- wpa_s->p2p_invite_go_freq = freq;
- wpa_s->p2p_go_group_formation_completed = 0;
- wpa_s->global->p2p_group_formation = wpa_s;
-
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->p2pdev,
- NULL);
- eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- wpa_supplicant_select_network(wpa_s, ssid);
-
- return 0;
-}
-
-
-int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int addr_allocated,
- int force_freq, int neg_freq,
- int vht_center_freq2, int ht40,
- int vht, int max_oper_chwidth, int he,
- int edmg,
- const struct p2p_channels *channels,
- int connection_timeout, int force_scan,
- bool allow_6ghz)
-{
- struct p2p_go_neg_results params;
- int go = 0, freq;
-
- if (ssid->disabled != 2 || ssid->ssid == NULL)
- return -1;
-
- if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) &&
- go == (ssid->mode == WPAS_MODE_P2P_GO)) {
- wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is "
- "already running");
- if (go == 0 &&
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL)) {
- /*
- * This can happen if Invitation Response frame was lost
- * and the peer (GO of a persistent group) tries to
- * invite us again. Reschedule the timeout to avoid
- * terminating the wait for the connection too early
- * since we now know that the peer is still trying to
- * invite us instead of having already started the GO.
- */
- wpa_printf(MSG_DEBUG,
- "P2P: Reschedule group formation timeout since peer is still trying to invite us");
- eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- }
- return 0;
- }
-
- os_free(wpa_s->global->add_psk);
- wpa_s->global->add_psk = NULL;
-
- /* Make sure we are not running find during connection establishment */
- wpas_p2p_stop_find_oper(wpa_s);
-
- wpa_s->p2p_fallback_to_go_neg = 0;
-
- if (ssid->mode == WPAS_MODE_P2P_GO) {
- if (force_freq > 0) {
- freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
- if (freq < 0)
- return -1;
- } else {
- freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
- if (freq < 0 ||
- (freq > 0 && !freq_included(wpa_s, channels, freq)))
- freq = 0;
- }
- } else if (ssid->mode == WPAS_MODE_INFRA) {
- freq = neg_freq;
- if (freq <= 0 || !freq_included(wpa_s, channels, freq)) {
- struct os_reltime now;
- struct wpa_bss *bss =
- wpa_bss_get_p2p_dev_addr(wpa_s, ssid->bssid);
-
- os_get_reltime(&now);
- if (bss &&
- !os_reltime_expired(&now, &bss->last_update, 5) &&
- freq_included(wpa_s, channels, bss->freq))
- freq = bss->freq;
- else
- freq = 0;
- }
-
- return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
- force_scan);
- } else {
- return -1;
- }
-
- if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
- ht40, vht, max_oper_chwidth, he, edmg,
- channels))
- return -1;
-
- params.role_go = 1;
- params.psk_set = ssid->psk_set;
- if (params.psk_set)
- os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
- if (ssid->passphrase) {
- if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
- wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
- "persistent group");
- return -1;
- }
- os_strlcpy(params.passphrase, ssid->passphrase,
- sizeof(params.passphrase));
- }
- os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
- params.ssid_len = ssid->ssid_len;
- params.persistent_group = 1;
-
- wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1);
- if (wpa_s == NULL)
- return -1;
-
- p2p_channels_to_freqs(channels, params.freq_list, P2P_MAX_CHANNELS);
-
- wpa_s->p2p_first_connection_timeout = connection_timeout;
- wpas_start_wps_go(wpa_s, &params, 0);
-
- return 0;
-}
-
-
-static void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
- struct wpabuf *proberesp_ies)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->ap_iface) {
- struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
- if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
- wpabuf_free(beacon_ies);
- wpabuf_free(proberesp_ies);
- return;
- }
- if (beacon_ies) {
- wpabuf_free(hapd->p2p_beacon_ie);
- hapd->p2p_beacon_ie = beacon_ies;
- }
- wpabuf_free(hapd->p2p_probe_resp_ie);
- hapd->p2p_probe_resp_ie = proberesp_ies;
- } else {
- wpabuf_free(beacon_ies);
- wpabuf_free(proberesp_ies);
- }
- wpa_supplicant_ap_update_beacon(wpa_s);
-}
-
-
-static void wpas_p2p_idle_update(void *ctx, int idle)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (!wpa_s->ap_iface)
- return;
- wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
- if (idle) {
- if (wpa_s->global->p2p_fail_on_wps_complete &&
- wpa_s->p2p_in_provisioning) {
- wpas_p2p_grpform_fail_after_wps(wpa_s);
- return;
- }
- wpas_p2p_set_group_idle_timeout(wpa_s);
- } else
- eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
-}
-
-
-struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct p2p_group *group;
- struct p2p_group_config *cfg;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
- !ssid->p2p_group)
- return NULL;
-
- cfg = os_zalloc(sizeof(*cfg));
- if (cfg == NULL)
- return NULL;
-
- if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect)
- cfg->persistent_group = 2;
- else if (ssid->p2p_persistent_group)
- cfg->persistent_group = 1;
- os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
- if (wpa_s->max_stations &&
- wpa_s->max_stations < wpa_s->conf->max_num_sta)
- cfg->max_clients = wpa_s->max_stations;
- else
- cfg->max_clients = wpa_s->conf->max_num_sta;
- os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len);
- cfg->ssid_len = ssid->ssid_len;
- cfg->freq = ssid->frequency;
- cfg->cb_ctx = wpa_s;
- cfg->ie_update = wpas_p2p_ie_update;
- cfg->idle_update = wpas_p2p_idle_update;
- cfg->ip_addr_alloc = WPA_GET_BE32(wpa_s->p2pdev->conf->ip_addr_start)
- != 0;
-
- group = p2p_group_init(wpa_s->global->p2p, cfg);
- if (group == NULL)
- os_free(cfg);
- if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
- p2p_group_notif_formation_done(group);
- wpa_s->p2p_group = group;
- return group;
-}
-
-
-void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- int registrar)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (!wpa_s->p2p_in_provisioning) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
- "provisioning not in progress");
- return;
- }
-
- if (ssid && ssid->mode == WPAS_MODE_INFRA) {
- u8 go_dev_addr[ETH_ALEN];
- os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
- wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
- ssid->ssid_len);
- /* Clear any stored provisioning info */
- p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
- }
-
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->p2pdev,
- NULL);
- wpa_s->p2p_go_group_formation_completed = 1;
- if (ssid && ssid->mode == WPAS_MODE_INFRA) {
- /*
- * Use a separate timeout for initial data connection to
- * complete to allow the group to be removed automatically if
- * something goes wrong in this step before the P2P group idle
- * timeout mechanism is taken into use.
- */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Re-start group formation timeout (%d seconds) as client for initial connection",
- P2P_MAX_INITIAL_CONN_WAIT);
- eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- /* Complete group formation on successful data connection. */
- wpa_s->p2p_go_group_formation_completed = 0;
- } else if (ssid) {
- /*
- * Use a separate timeout for initial data connection to
- * complete to allow the group to be removed automatically if
- * the client does not complete data connection successfully.
- */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Re-start group formation timeout (%d seconds) as GO for initial connection",
- P2P_MAX_INITIAL_CONN_WAIT_GO);
- eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- /*
- * Complete group formation on first successful data connection
- */
- wpa_s->p2p_go_group_formation_completed = 0;
- }
- if (wpa_s->global->p2p)
- p2p_wps_success_cb(wpa_s->global->p2p, peer_addr);
- wpas_group_formation_completed(wpa_s, 1, 0);
-}
-
-
-void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
- if (!wpa_s->p2p_in_provisioning) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P "
- "provisioning not in progress");
- return;
- }
-
- if (wpa_s->go_params) {
- p2p_clear_provisioning_info(
- wpa_s->global->p2p,
- wpa_s->go_params->peer_device_addr);
- }
-
- wpas_notify_p2p_wps_failed(wpa_s, fail);
-
- if (wpa_s == wpa_s->global->p2p_group_formation) {
- /*
- * Allow some time for the failed WPS negotiation exchange to
- * complete, but remove the group since group formation cannot
- * succeed after provisioning failure.
- */
- wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout");
- wpa_s->global->p2p_fail_on_wps_complete = 1;
- eloop_deplete_timeout(0, 50000,
- wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- }
-}
-
-
-int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->global->p2p_fail_on_wps_complete ||
- !wpa_s->p2p_in_provisioning)
- return 0;
-
- wpas_p2p_grpform_fail_after_wps(wpa_s);
-
- return 1;
-}
-
-
-int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *config_method,
- enum wpas_p2p_prov_disc_use use,
- struct p2ps_provision *p2ps_prov)
-{
- u16 config_methods;
-
- wpa_s->global->pending_p2ps_group = 0;
- wpa_s->global->pending_p2ps_group_freq = 0;
- wpa_s->p2p_fallback_to_go_neg = 0;
- wpa_s->pending_pd_use = NORMAL_PD;
- if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) {
- p2ps_prov->conncap = p2ps_group_capability(
- wpa_s, P2PS_SETUP_NONE, p2ps_prov->role,
- &p2ps_prov->force_freq, &p2ps_prov->pref_freq);
-
- wpa_printf(MSG_DEBUG,
- "P2P: %s conncap: %d - ASP parsed: %x %x %d %s",
- __func__, p2ps_prov->conncap,
- p2ps_prov->adv_id, p2ps_prov->conncap,
- p2ps_prov->status, p2ps_prov->info);
-
- config_methods = 0;
- } else if (os_strncmp(config_method, "display", 7) == 0)
- config_methods = WPS_CONFIG_DISPLAY;
- else if (os_strncmp(config_method, "keypad", 6) == 0)
- config_methods = WPS_CONFIG_KEYPAD;
- else if (os_strncmp(config_method, "pbc", 3) == 0 ||
- os_strncmp(config_method, "pushbutton", 10) == 0)
- config_methods = WPS_CONFIG_PUSHBUTTON;
- else {
- wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
- os_free(p2ps_prov);
- return -1;
- }
-
- if (use == WPAS_P2P_PD_AUTO) {
- os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
- wpa_s->pending_pd_config_methods = config_methods;
- wpa_s->p2p_auto_pd = 1;
- wpa_s->p2p_auto_join = 0;
- wpa_s->pending_pd_before_join = 0;
- wpa_s->auto_pd_scan_retry = 0;
- wpas_p2p_stop_find(wpa_s);
- wpa_s->p2p_join_scan_count = 0;
- os_get_reltime(&wpa_s->p2p_auto_started);
- wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld",
- wpa_s->p2p_auto_started.sec,
- wpa_s->p2p_auto_started.usec);
- wpas_p2p_join_scan(wpa_s, NULL);
- return 0;
- }
-
- if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
- os_free(p2ps_prov);
- return -1;
- }
-
- return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, p2ps_prov,
- config_methods, use == WPAS_P2P_PD_FOR_JOIN,
- 0, 1);
-}
-
-
-int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
- char *end)
-{
- return p2p_scan_result_text(ies, ies_len, buf, end);
-}
-
-
-static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
-{
- if (!offchannel_pending_action_tx(wpa_s))
- return;
-
- if (wpa_s->p2p_send_action_work) {
- wpas_p2p_free_send_action_work(wpa_s);
- eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
- wpa_s, NULL);
- offchannel_send_action_done(wpa_s);
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
- "operation request");
- offchannel_clear_pending_action_tx(wpa_s);
-}
-
-
-int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
- enum p2p_discovery_type type,
- unsigned int num_req_dev_types, const u8 *req_dev_types,
- const u8 *dev_id, unsigned int search_delay,
- u8 seek_cnt, const char **seek_string, int freq,
- bool include_6ghz)
-{
- wpas_p2p_clear_pending_action_tx(wpa_s);
- wpa_s->global->p2p_long_listen = 0;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
- wpa_s->p2p_in_provisioning) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Reject p2p_find operation%s%s",
- (wpa_s->global->p2p_disabled || !wpa_s->global->p2p) ?
- " (P2P disabled)" : "",
- wpa_s->p2p_in_provisioning ?
- " (p2p_in_provisioning)" : "");
- return -1;
- }
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
-
- return p2p_find(wpa_s->global->p2p, timeout, type,
- num_req_dev_types, req_dev_types, dev_id,
- search_delay, seek_cnt, seek_string, freq,
- include_6ghz);
-}
-
-
-static void wpas_p2p_scan_res_ignore_search(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
-
- if (wpa_s->p2p_scan_work) {
- struct wpa_radio_work *work = wpa_s->p2p_scan_work;
- wpa_s->p2p_scan_work = NULL;
- radio_work_done(work);
- }
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
-
- /*
- * Indicate that results have been processed so that the P2P module can
- * continue pending tasks.
- */
- wpas_p2p_scan_res_handled(wpa_s);
-}
-
-
-static void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
-{
- wpas_p2p_clear_pending_action_tx(wpa_s);
- wpa_s->global->p2p_long_listen = 0;
- eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
-
- if (wpa_s->global->p2p)
- p2p_stop_find(wpa_s->global->p2p);
-
- if (wpa_s->scan_res_handler == wpas_p2p_scan_res_handler) {
- wpa_printf(MSG_DEBUG,
- "P2P: Do not consider the scan results after stop_find");
- wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore_search;
- }
-}
-
-
-void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
-{
- wpas_p2p_stop_find_oper(wpa_s);
- if (!wpa_s->global->pending_group_iface_for_p2ps)
- wpas_p2p_remove_pending_group_interface(wpa_s);
-}
-
-
-static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpa_s->global->p2p_long_listen = 0;
-}
-
-
-int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
-{
- int res;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- if (wpa_s->p2p_lo_started) {
- wpa_printf(MSG_DEBUG,
- "P2P: Cannot start P2P listen, it is offloaded");
- return -1;
- }
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpas_p2p_clear_pending_action_tx(wpa_s);
-
- if (timeout == 0) {
- /*
- * This is a request for unlimited Listen state. However, at
- * least for now, this is mapped to a Listen state for one
- * hour.
- */
- timeout = 3600;
- }
- eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
- wpa_s->global->p2p_long_listen = 0;
-
- /*
- * Stop previous find/listen operation to avoid trying to request a new
- * remain-on-channel operation while the driver is still running the
- * previous one.
- */
- if (wpa_s->global->p2p)
- p2p_stop_find(wpa_s->global->p2p);
-
- res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
- if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
- wpa_s->global->p2p_long_listen = timeout * 1000;
- eloop_register_timeout(timeout, 0,
- wpas_p2p_long_listen_timeout,
- wpa_s, NULL);
- }
-
- return res;
-}
-
-
-int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- u8 *buf, size_t len, int p2p_group)
-{
- struct wpabuf *p2p_ie;
- int ret;
-
- if (wpa_s->global->p2p_disabled)
- return -1;
- /*
- * Advertize mandatory cross connection capability even on
- * p2p_disabled=1 interface when associating with a P2P Manager WLAN AP.
- */
- if (wpa_s->conf->p2p_disabled && p2p_group)
- return -1;
- if (wpa_s->global->p2p == NULL)
- return -1;
- if (bss == NULL)
- return -1;
-
- p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
- ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
- p2p_group, p2p_ie);
- wpabuf_free(p2p_ie);
-
- return ret;
-}
-
-
-int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
- const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len,
- unsigned int rx_freq, int ssi_signal)
-{
- if (wpa_s->global->p2p_disabled)
- return 0;
- if (wpa_s->global->p2p == NULL)
- return 0;
-
- switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
- ie, ie_len, rx_freq, wpa_s->p2p_lo_started)) {
- case P2P_PREQ_NOT_P2P:
- wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
- ssi_signal);
- /* fall through */
- case P2P_PREQ_MALFORMED:
- case P2P_PREQ_NOT_LISTEN:
- case P2P_PREQ_NOT_PROCESSED:
- default: /* make gcc happy */
- return 0;
- case P2P_PREQ_PROCESSED:
- return 1;
- }
-}
-
-
-void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
- const u8 *sa, const u8 *bssid,
- u8 category, const u8 *data, size_t len, int freq)
-{
- if (wpa_s->global->p2p_disabled)
- return;
- if (wpa_s->global->p2p == NULL)
- return;
-
- p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
- freq);
-}
-
-
-void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
-{
- unsigned int bands;
-
- if (wpa_s->global->p2p_disabled)
- return;
- if (wpa_s->global->p2p == NULL)
- return;
-
- bands = wpas_get_bands(wpa_s, NULL);
- p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
-}
-
-
-static void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
-{
- p2p_group_deinit(wpa_s->p2p_group);
- wpa_s->p2p_group = NULL;
-
- wpa_s->ap_configured_cb = NULL;
- wpa_s->ap_configured_cb_ctx = NULL;
- wpa_s->ap_configured_cb_data = NULL;
- wpa_s->connect_without_scan = NULL;
-}
-
-
-int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- wpa_s->global->p2p_long_listen = 0;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- return p2p_reject(wpa_s->global->p2p, addr);
-}
-
-
-/* Invite to reinvoke a persistent group */
-int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
- int vht_center_freq2, int ht40, int vht, int max_chwidth,
- int pref_freq, int he, int edmg, bool allow_6ghz)
-{
- enum p2p_invite_role role;
- u8 *bssid = NULL;
- int force_freq = 0;
- int res;
- int no_pref_freq_given = pref_freq == 0;
- unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
-
- if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
- return -1;
-
- wpa_s->global->p2p_invite_group = NULL;
- if (peer_addr)
- os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
- else
- os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
-
- wpa_s->p2p_persistent_go_freq = freq;
- wpa_s->p2p_go_ht40 = !!ht40;
- wpa_s->p2p_go_vht = !!vht;
- wpa_s->p2p_go_he = !!he;
- wpa_s->p2p_go_max_oper_chwidth = max_chwidth;
- wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
- wpa_s->p2p_go_edmg = !!edmg;
- if (ssid->mode == WPAS_MODE_P2P_GO) {
- role = P2P_INVITE_ROLE_GO;
- if (peer_addr == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Missing peer "
- "address in invitation command");
- return -1;
- }
- if (wpas_p2p_create_iface(wpa_s)) {
- if (wpas_p2p_add_group_interface(wpa_s,
- WPA_IF_P2P_GO) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Failed to "
- "allocate a new interface for the "
- "group");
- return -1;
- }
- bssid = wpa_s->pending_interface_addr;
- } else if (wpa_s->p2p_mgmt)
- bssid = wpa_s->parent->own_addr;
- else
- bssid = wpa_s->own_addr;
- } else {
- role = P2P_INVITE_ROLE_CLIENT;
- peer_addr = ssid->bssid;
- }
- wpa_s->pending_invite_ssid_id = ssid->id;
-
- size = P2P_MAX_PREF_CHANNELS;
- res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- role == P2P_INVITE_ROLE_GO,
- pref_freq_list, &size);
- if (res)
- return res;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);
-
- if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
- no_pref_freq_given && pref_freq > 0 &&
- wpa_s->num_multichan_concurrent > 1 &&
- wpas_p2p_num_unused_channels(wpa_s) > 0) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration",
- pref_freq);
- pref_freq = 0;
- }
-
- /*
- * Stop any find/listen operations before invitation and possibly
- * connection establishment.
- */
- wpas_p2p_stop_find_oper(wpa_s);
-
- return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
- ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
- 1, pref_freq, -1);
-}
-
-
-/* Invite to join an active group */
-int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
- const u8 *peer_addr, const u8 *go_dev_addr,
- bool allow_6ghz)
-{
- struct wpa_global *global = wpa_s->global;
- enum p2p_invite_role role;
- u8 *bssid = NULL;
- struct wpa_ssid *ssid;
- int persistent;
- int freq = 0, force_freq = 0, pref_freq = 0;
- int res;
- unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
-
- wpa_s->p2p_persistent_go_freq = 0;
- wpa_s->p2p_go_ht40 = 0;
- wpa_s->p2p_go_vht = 0;
- wpa_s->p2p_go_vht_center_freq2 = 0;
- wpa_s->p2p_go_max_oper_chwidth = 0;
- wpa_s->p2p_go_edmg = 0;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_strcmp(wpa_s->ifname, ifname) == 0)
- break;
- }
- if (wpa_s == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname);
- return -1;
- }
-
- ssid = wpa_s->current_ssid;
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for "
- "invitation");
- return -1;
- }
-
- wpa_s->global->p2p_invite_group = wpa_s;
- persistent = ssid->p2p_persistent_group &&
- wpas_p2p_get_persistent(wpa_s->p2pdev, peer_addr,
- ssid->ssid, ssid->ssid_len);
-
- if (ssid->mode == WPAS_MODE_P2P_GO) {
- role = P2P_INVITE_ROLE_ACTIVE_GO;
- bssid = wpa_s->own_addr;
- if (go_dev_addr == NULL)
- go_dev_addr = wpa_s->global->p2p_dev_addr;
- freq = ssid->frequency;
- } else {
- role = P2P_INVITE_ROLE_CLIENT;
- if (wpa_s->wpa_state < WPA_ASSOCIATED) {
- wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot "
- "invite to current group");
- return -1;
- }
- bssid = wpa_s->bssid;
- if (go_dev_addr == NULL &&
- !is_zero_ether_addr(wpa_s->go_dev_addr))
- go_dev_addr = wpa_s->go_dev_addr;
- freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
- (int) wpa_s->assoc_freq;
- }
- wpa_s->p2pdev->pending_invite_ssid_id = -1;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
- if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
- return -1;
-
- size = P2P_MAX_PREF_CHANNELS;
- res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- role == P2P_INVITE_ROLE_ACTIVE_GO,
- pref_freq_list, &size);
- if (res)
- return res;
- wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
-
- return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
- ssid->ssid, ssid->ssid_len, force_freq,
- go_dev_addr, persistent, pref_freq, -1);
-}
-
-
-void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- u8 go_dev_addr[ETH_ALEN];
- int persistent;
- int freq;
- u8 ip[3 * 4], *ip_ptr = NULL;
- char ip_addr[100];
-
- if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- }
-
- if (!wpa_s->show_group_started || !ssid)
- return;
-
- wpa_s->show_group_started = 0;
- if (!wpa_s->p2p_go_group_formation_completed &&
- wpa_s->global->p2p_group_formation == wpa_s) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Marking group formation completed on client on data connection");
- wpa_s->p2p_go_group_formation_completed = 1;
- wpa_s->global->p2p_group_formation = NULL;
- wpa_s->p2p_in_provisioning = 0;
- wpa_s->p2p_in_invitation = 0;
- }
-
- os_memset(go_dev_addr, 0, ETH_ALEN);
- if (ssid->bssid_set)
- os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN);
- persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
- ssid->ssid_len);
- os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN);
-
- if (wpa_s->global->p2p_group_formation == wpa_s)
- wpa_s->global->p2p_group_formation = NULL;
-
- freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
- (int) wpa_s->assoc_freq;
-
- ip_addr[0] = '\0';
- if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) {
- int res;
-
- res = os_snprintf(ip_addr, sizeof(ip_addr),
- " ip_addr=%u.%u.%u.%u "
- "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u",
- ip[0], ip[1], ip[2], ip[3],
- ip[4], ip[5], ip[6], ip[7],
- ip[8], ip[9], ip[10], ip[11]);
- if (os_snprintf_error(sizeof(ip_addr), res))
- ip_addr[0] = '\0';
- ip_ptr = ip;
- }
-
- wpas_p2p_group_started(wpa_s, 0, ssid, freq,
- ssid->passphrase == NULL && ssid->psk_set ?
- ssid->psk : NULL,
- ssid->passphrase, go_dev_addr, persistent,
- ip_addr);
-
- if (persistent)
- wpas_p2p_store_persistent_group(wpa_s->p2pdev,
- ssid, go_dev_addr);
-
- wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip_ptr);
-}
-
-
-int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
- u32 interval1, u32 duration2, u32 interval2)
-{
- int ret;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- if (wpa_s->wpa_state < WPA_ASSOCIATED ||
- wpa_s->current_ssid == NULL ||
- wpa_s->current_ssid->mode != WPAS_MODE_INFRA)
- return -1;
-
- ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->assoc_freq,
- duration1, interval1, duration2, interval2);
- if (ret == 0)
- wpa_s->waiting_presence_resp = 1;
-
- return ret;
-}
-
-
-int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
- unsigned int interval)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- return p2p_ext_listen(wpa_s->global->p2p, period, interval);
-}
-
-
-static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->current_ssid == NULL) {
- /*
- * current_ssid can be cleared when P2P client interface gets
- * disconnected, so assume this interface was used as P2P
- * client.
- */
- return 1;
- }
- return wpa_s->current_ssid->p2p_group &&
- wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
-}
-
-
-static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
- wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
- "disabled");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate "
- "group");
- wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT);
-}
-
-
-static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
-{
- int timeout;
-
- if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
- wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
-
- if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
- return;
-
- timeout = wpa_s->conf->p2p_group_idle;
- if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
- (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
- timeout = P2P_MAX_CLIENT_IDLE;
-
- if (timeout == 0)
- return;
-
- if (timeout < 0) {
- if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA)
- timeout = 0; /* special client mode no-timeout */
- else
- return;
- }
-
- if (wpa_s->p2p_in_provisioning) {
- /*
- * Use the normal group formation timeout during the
- * provisioning phase to avoid terminating this process too
- * early due to group idle timeout.
- */
- wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
- "during provisioning");
- return;
- }
-
- if (wpa_s->show_group_started) {
- /*
- * Use the normal group formation timeout between the end of
- * the provisioning phase and completion of 4-way handshake to
- * avoid terminating this process too early due to group idle
- * timeout.
- */
- wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
- "while waiting for initial 4-way handshake to "
- "complete");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
- timeout);
- eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
- wpa_s, NULL);
-}
-
-
-/* Returns 1 if the interface was removed */
-int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
- u16 reason_code, const u8 *ie, size_t ie_len,
- int locally_generated)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return 0;
-
- if (!locally_generated)
- p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie,
- ie_len);
-
- if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated &&
- wpa_s->current_ssid &&
- wpa_s->current_ssid->p2p_group &&
- wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
- wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group "
- "session is ending");
- if (wpas_p2p_group_delete(wpa_s,
- P2P_GROUP_REMOVAL_GO_ENDING_SESSION)
- > 0)
- return 1;
- }
-
- return 0;
-}
-
-
-void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
- u16 reason_code, const u8 *ie, size_t ie_len,
- int locally_generated)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
-
- if (!locally_generated)
- p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie,
- ie_len);
-}
-
-
-void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
-{
- struct p2p_data *p2p = wpa_s->global->p2p;
-
- if (p2p == NULL)
- return;
-
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
- return;
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
- p2p_set_dev_name(p2p, wpa_s->conf->device_name);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
- p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
-
- if (wpa_s->wps &&
- (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
- p2p_set_config_methods(p2p, wpa_s->wps->config_methods);
-
- if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
- p2p_set_uuid(p2p, wpa_s->wps->uuid);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
- p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
- p2p_set_model_name(p2p, wpa_s->conf->model_name);
- p2p_set_model_number(p2p, wpa_s->conf->model_number);
- p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
- p2p_set_sec_dev_types(p2p,
- (void *) wpa_s->conf->sec_device_type,
- wpa_s->conf->num_sec_device_types);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) {
- int i;
- p2p_remove_wps_vendor_extensions(p2p);
- for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
- if (wpa_s->conf->wps_vendor_ext[i] == NULL)
- continue;
- p2p_add_wps_vendor_extension(
- p2p, wpa_s->conf->wps_vendor_ext[i]);
- }
- }
-
- if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
- wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
- char country[3];
- country[0] = wpa_s->conf->country[0];
- country[1] = wpa_s->conf->country[1];
- country[2] = 0x04;
- p2p_set_country(p2p, country);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) {
- p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix,
- wpa_s->conf->p2p_ssid_postfix ?
- os_strlen(wpa_s->conf->p2p_ssid_postfix) :
- 0);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS)
- p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) {
- u8 reg_class, channel;
- int ret;
- unsigned int r;
- u8 channel_forced;
-
- if (wpa_s->conf->p2p_listen_reg_class &&
- wpa_s->conf->p2p_listen_channel) {
- reg_class = wpa_s->conf->p2p_listen_reg_class;
- channel = wpa_s->conf->p2p_listen_channel;
- channel_forced = 1;
- } else {
- reg_class = 81;
- /*
- * Pick one of the social channels randomly as the
- * listen channel.
- */
- if (os_get_random((u8 *) &r, sizeof(r)) < 0)
- channel = 1;
- else
- channel = 1 + (r % 3) * 5;
- channel_forced = 0;
- }
- ret = p2p_set_listen_channel(p2p, reg_class, channel,
- channel_forced);
- if (ret)
- wpa_printf(MSG_ERROR, "P2P: Own listen channel update "
- "failed: %d", ret);
- }
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) {
- u8 op_reg_class, op_channel, cfg_op_channel;
- int ret = 0;
- unsigned int r;
- if (wpa_s->conf->p2p_oper_reg_class &&
- wpa_s->conf->p2p_oper_channel) {
- op_reg_class = wpa_s->conf->p2p_oper_reg_class;
- op_channel = wpa_s->conf->p2p_oper_channel;
- cfg_op_channel = 1;
- } else {
- op_reg_class = 81;
- /*
- * Use random operation channel from (1, 6, 11)
- *if no other preference is indicated.
- */
- if (os_get_random((u8 *) &r, sizeof(r)) < 0)
- op_channel = 1;
- else
- op_channel = 1 + (r % 3) * 5;
- cfg_op_channel = 0;
- }
- ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel,
- cfg_op_channel);
- if (ret)
- wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
- "failed: %d", ret);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
- if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
- wpa_s->conf->p2p_pref_chan) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
- "update failed");
- }
-
- if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) {
- wpa_printf(MSG_ERROR, "P2P: No GO channel list "
- "update failed");
- }
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PASSPHRASE_LEN)
- p2p_set_passphrase_len(p2p, wpa_s->conf->p2p_passphrase_len);
-}
-
-
-int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
- int duration)
-{
- if (!wpa_s->ap_iface)
- return -1;
- return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
- duration);
-}
-
-
-int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- wpa_s->global->cross_connection = enabled;
- p2p_set_cross_connect(wpa_s->global->p2p, enabled);
-
- if (!enabled) {
- struct wpa_supplicant *iface;
-
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
- {
- if (iface->cross_connect_enabled == 0)
- continue;
-
- iface->cross_connect_enabled = 0;
- iface->cross_connect_in_use = 0;
- wpa_msg_global(iface->p2pdev, MSG_INFO,
- P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
- iface->ifname,
- iface->cross_connect_uplink);
- }
- }
-
- return 0;
-}
-
-
-static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
-{
- struct wpa_supplicant *iface;
-
- if (!uplink->global->cross_connection)
- return;
-
- for (iface = uplink->global->ifaces; iface; iface = iface->next) {
- if (!iface->cross_connect_enabled)
- continue;
- if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
- 0)
- continue;
- if (iface->ap_iface == NULL)
- continue;
- if (iface->cross_connect_in_use)
- continue;
-
- iface->cross_connect_in_use = 1;
- wpa_msg_global(iface->p2pdev, MSG_INFO,
- P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
- iface->ifname, iface->cross_connect_uplink);
- }
-}
-
-
-static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
-{
- struct wpa_supplicant *iface;
-
- for (iface = uplink->global->ifaces; iface; iface = iface->next) {
- if (!iface->cross_connect_enabled)
- continue;
- if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
- 0)
- continue;
- if (!iface->cross_connect_in_use)
- continue;
-
- wpa_msg_global(iface->p2pdev, MSG_INFO,
- P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
- iface->ifname, iface->cross_connect_uplink);
- iface->cross_connect_in_use = 0;
- }
-}
-
-
-void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
- wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
- wpa_s->cross_connect_disallowed)
- wpas_p2p_disable_cross_connect(wpa_s);
- else
- wpas_p2p_enable_cross_connect(wpa_s);
- if (!wpa_s->ap_iface &&
- eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
- wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
-}
-
-
-void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
-{
- wpas_p2p_disable_cross_connect(wpa_s);
- if (!wpa_s->ap_iface &&
- !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
- wpa_s, NULL))
- wpas_p2p_set_group_idle_timeout(wpa_s);
-}
-
-
-static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
-{
- struct wpa_supplicant *iface;
-
- if (!wpa_s->global->cross_connection)
- return;
-
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- if (iface == wpa_s)
- continue;
- if (iface->drv_flags &
- WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
- continue;
- if ((iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) &&
- iface != wpa_s->parent)
- continue;
-
- wpa_s->cross_connect_enabled = 1;
- os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
- sizeof(wpa_s->cross_connect_uplink));
- wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
- "%s to %s whenever uplink is available",
- wpa_s->ifname, wpa_s->cross_connect_uplink);
-
- if (iface->ap_iface || iface->current_ssid == NULL ||
- iface->current_ssid->mode != WPAS_MODE_INFRA ||
- iface->cross_connect_disallowed ||
- iface->wpa_state != WPA_COMPLETED)
- break;
-
- wpa_s->cross_connect_in_use = 1;
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
- wpa_s->ifname, wpa_s->cross_connect_uplink);
- break;
- }
-}
-
-
-int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
- !wpa_s->p2p_in_provisioning)
- return 0; /* not P2P client operation */
-
- wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC "
- "session overlap");
- if (wpa_s != wpa_s->p2pdev)
- wpa_msg_ctrl(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_OVERLAP);
- wpas_p2p_group_formation_failed(wpa_s, 0);
- return 1;
-}
-
-
-void wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpas_p2p_notif_pbc_overlap(wpa_s);
-}
-
-
-void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s,
- enum wpas_p2p_channel_update_trig trig)
-{
- struct p2p_channels chan, cli_chan;
- struct wpa_used_freq_data *freqs = NULL;
- unsigned int num = wpa_s->num_multichan_concurrent;
-
- if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
- return;
-
- freqs = os_calloc(num, sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return;
-
- num = get_shared_radio_freqs_data(wpa_s, freqs, num);
-
- os_memset(&chan, 0, sizeof(chan));
- os_memset(&cli_chan, 0, sizeof(cli_chan));
- if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan,
- is_p2p_6ghz_disabled(wpa_s->global->p2p))) {
- wpa_printf(MSG_ERROR, "P2P: Failed to update supported "
- "channel list");
- return;
- }
-
- p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);
-
- wpas_p2p_optimize_listen_channel(wpa_s, freqs, num);
-
- /*
- * The used frequencies map changed, so it is possible that a GO is
- * using a channel that is no longer valid for P2P use. It is also
- * possible that due to policy consideration, it would be preferable to
- * move it to a frequency already used by other station interfaces.
- */
- wpas_p2p_consider_moving_gos(wpa_s, freqs, num, trig);
-
- os_free(freqs);
-}
-
-
-static void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
-}
-
-
-int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
-{
- struct wpa_global *global = wpa_s->global;
- int found = 0;
- const u8 *peer;
-
- if (global->p2p == NULL)
- return -1;
-
- wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation");
-
- if (wpa_s->pending_interface_name[0] &&
- !is_zero_ether_addr(wpa_s->pending_interface_addr))
- found = 1;
-
- peer = p2p_get_go_neg_peer(global->p2p);
- if (peer) {
- wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
- MACSTR, MAC2STR(peer));
- p2p_unauthorize(global->p2p, peer);
- found = 1;
- }
-
- if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) {
- wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join");
- wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore;
- found = 1;
- }
-
- if (wpa_s->pending_pd_before_join) {
- wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join");
- wpa_s->pending_pd_before_join = 0;
- found = 1;
- }
-
- wpas_p2p_stop_find(wpa_s);
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (wpa_s == global->p2p_group_formation &&
- (wpa_s->p2p_in_provisioning ||
- wpa_s->parent->pending_interface_type ==
- WPA_IF_P2P_CLIENT)) {
- wpa_printf(MSG_DEBUG, "P2P: Interface %s in group "
- "formation found - cancelling",
- wpa_s->ifname);
- found = 1;
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- if (wpa_s->p2p_in_provisioning) {
- wpas_group_formation_completed(wpa_s, 0, 0);
- break;
- }
- wpas_p2p_group_delete(wpa_s,
- P2P_GROUP_REMOVAL_REQUESTED);
- break;
- } else if (wpa_s->p2p_in_invitation) {
- wpa_printf(MSG_DEBUG, "P2P: Interface %s in invitation found - cancelling",
- wpa_s->ifname);
- found = 1;
- wpas_p2p_group_formation_failed(wpa_s, 0);
- break;
- }
- }
-
- if (!found) {
- wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found");
- return -1;
- }
-
- return 0;
-}
-
-
-void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
- return;
-
- wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
- "being available anymore");
- wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE);
-}
-
-
-void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
- int freq_24, int freq_5, int freq_overall)
-{
- struct p2p_data *p2p = wpa_s->global->p2p;
- if (p2p == NULL)
- return;
- p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall);
-}
-
-
-int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
-{
- u8 peer[ETH_ALEN];
- struct p2p_data *p2p = wpa_s->global->p2p;
-
- if (p2p == NULL)
- return -1;
-
- if (hwaddr_aton(addr, peer))
- return -1;
-
- return p2p_unauthorize(p2p, peer);
-}
-
-
-/**
- * wpas_p2p_disconnect - Disconnect from a P2P Group
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success, -1 on failure
- *
- * This can be used to disconnect from a group in which the local end is a P2P
- * Client or to end a P2P Group in case the local end is the Group Owner. If a
- * virtual network interface was created for this group, that interface will be
- * removed. Otherwise, only the configured P2P group network will be removed
- * from the interface.
- */
-int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
-{
-
- if (wpa_s == NULL)
- return -1;
-
- return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ?
- -1 : 0;
-}
-
-
-int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
-{
- int ret;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return 0;
-
- ret = p2p_in_progress(wpa_s->global->p2p);
- if (ret == 0) {
- /*
- * Check whether there is an ongoing WPS provisioning step (or
- * other parts of group formation) on another interface since
- * p2p_in_progress() does not report this to avoid issues for
- * scans during such provisioning step.
- */
- if (wpa_s->global->p2p_group_formation &&
- wpa_s->global->p2p_group_formation != wpa_s) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) "
- "in group formation",
- wpa_s->global->p2p_group_formation->ifname);
- ret = 1;
- }
- }
-
- if (!ret && wpa_s->global->p2p_go_wait_client.sec) {
- struct os_reltime now;
- os_get_reltime(&now);
- if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client,
- P2P_MAX_INITIAL_CONN_WAIT_GO)) {
- /* Wait for the first client has expired */
- wpa_s->global->p2p_go_wait_client.sec = 0;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation");
- ret = 1;
- }
- }
-
- return ret;
-}
-
-
-void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL) > 0) {
- /**
- * Remove the network by scheduling the group formation
- * timeout to happen immediately. The teardown code
- * needs to be scheduled to run asynch later so that we
- * don't delete data from under ourselves unexpectedly.
- * Calling wpas_p2p_group_formation_timeout directly
- * causes a series of crashes in WPS failure scenarios.
- */
- wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
- "P2P group network getting removed");
- eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL);
- }
-}
-
-
-struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *ssid,
- size_t ssid_len)
-{
- struct wpa_ssid *s;
- size_t i;
-
- for (s = wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled != 2)
- continue;
- if (ssid &&
- (ssid_len != s->ssid_len ||
- os_memcmp(ssid, s->ssid, ssid_len) != 0))
- continue;
- if (addr == NULL) {
- if (s->mode == WPAS_MODE_P2P_GO)
- return s;
- continue;
- }
- if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
- return s; /* peer is GO in the persistent group */
- if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
- continue;
- for (i = 0; i < s->num_p2p_clients; i++) {
- if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
- addr, ETH_ALEN) == 0)
- return s; /* peer is P2P client in persistent
- * group */
- }
- }
-
- return NULL;
-}
-
-
-void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->p2pdev, NULL) > 0) {
- /*
- * This can happen if WPS provisioning step is not terminated
- * cleanly (e.g., P2P Client does not send WSC_Done). Since the
- * peer was able to connect, there is no need to time out group
- * formation after this, though. In addition, this is used with
- * the initial connection wait on the GO as a separate formation
- * timeout and as such, expected to be hit after the initial WPS
- * provisioning step.
- */
- wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection");
-
- if (!wpa_s->p2p_go_group_formation_completed &&
- !wpa_s->group_formation_reported) {
- /*
- * GO has not yet notified group formation success since
- * the WPS step was not completed cleanly. Do that
- * notification now since the P2P Client was able to
- * connect and as such, must have received the
- * credential from the WPS step.
- */
- if (wpa_s->global->p2p)
- p2p_wps_success_cb(wpa_s->global->p2p, addr);
- wpas_group_formation_completed(wpa_s, 1, 0);
- }
- }
- if (!wpa_s->p2p_go_group_formation_completed) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection");
- wpa_s->p2p_go_group_formation_completed = 1;
- wpa_s->global->p2p_group_formation = NULL;
- wpa_s->p2p_in_provisioning = 0;
- wpa_s->p2p_in_invitation = 0;
- }
- wpa_s->global->p2p_go_wait_client.sec = 0;
- if (addr == NULL)
- return;
- wpas_p2p_add_persistent_group_client(wpa_s, addr);
-}
-
-
-static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
- int group_added)
-{
- struct wpa_supplicant *group = wpa_s;
- int ret = 0;
-
- if (wpa_s->global->p2p_group_formation)
- group = wpa_s->global->p2p_group_formation;
- wpa_s = wpa_s->global->p2p_init_wpa_s;
- offchannel_send_action_done(wpa_s);
- if (group_added)
- ret = wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT);
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation");
- wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
- wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
- 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
- wpa_s->p2p_go_vht_center_freq2,
- wpa_s->p2p_persistent_id,
- wpa_s->p2p_pd_before_go_neg,
- wpa_s->p2p_go_ht40,
- wpa_s->p2p_go_vht,
- wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he,
- wpa_s->p2p_go_edmg,
- NULL, 0, is_p2p_allow_6ghz(wpa_s->global->p2p));
- return ret;
-}
-
-
-int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s)
-{
- int res;
-
- if (!wpa_s->p2p_fallback_to_go_neg ||
- wpa_s->p2p_in_provisioning <= 5)
- return 0;
-
- if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0)
- return 0; /* peer operating as a GO */
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - "
- "fallback to GO Negotiation");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO, P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=GO-not-found");
- res = wpas_p2p_fallback_to_go_neg(wpa_s, 1);
-
- return res == 1 ? 2 : 1;
-}
-
-
-unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s)
-{
- struct wpa_supplicant *ifs;
-
- if (wpa_s->wpa_state > WPA_SCANNING) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to "
- "concurrent operation",
- wpa_s->conf->p2p_search_delay);
- return wpa_s->conf->p2p_search_delay;
- }
-
- dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
- radio_list) {
- if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search "
- "delay due to concurrent operation on "
- "interface %s",
- wpa_s->conf->p2p_search_delay,
- ifs->ifname);
- return wpa_s->conf->p2p_search_delay;
- }
- }
-
- return 0;
-}
-
-
-static int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *s, const u8 *addr,
- int iface_addr)
-{
- struct psk_list_entry *psk, *tmp;
- int changed = 0;
-
- dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry,
- list) {
- if ((iface_addr && !psk->p2p &&
- os_memcmp(addr, psk->addr, ETH_ALEN) == 0) ||
- (!iface_addr && psk->p2p &&
- os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Remove persistent group PSK list entry for "
- MACSTR " p2p=%u",
- MAC2STR(psk->addr), psk->p2p);
- dl_list_del(&psk->list);
- os_free(psk);
- changed++;
- }
- }
-
- return changed;
-}
-
-
-void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
- const u8 *p2p_dev_addr,
- const u8 *psk, size_t psk_len)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpa_ssid *persistent;
- struct psk_list_entry *p, *last;
-
- if (psk_len != sizeof(p->psk))
- return;
-
- if (p2p_dev_addr) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR
- " p2p_dev_addr=" MACSTR,
- MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
- if (is_zero_ether_addr(p2p_dev_addr))
- p2p_dev_addr = NULL;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR,
- MAC2STR(mac_addr));
- }
-
- if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation");
- /* To be added to persistent group once created */
- if (wpa_s->global->add_psk == NULL) {
- wpa_s->global->add_psk = os_zalloc(sizeof(*p));
- if (wpa_s->global->add_psk == NULL)
- return;
- }
- p = wpa_s->global->add_psk;
- if (p2p_dev_addr) {
- p->p2p = 1;
- os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
- } else {
- p->p2p = 0;
- os_memcpy(p->addr, mac_addr, ETH_ALEN);
- }
- os_memcpy(p->psk, psk, psk_len);
- return;
- }
-
- if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO");
- return;
- }
-
- persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, NULL, ssid->ssid,
- ssid->ssid_len);
- if (!persistent) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK");
- return;
- }
-
- p = os_zalloc(sizeof(*p));
- if (p == NULL)
- return;
- if (p2p_dev_addr) {
- p->p2p = 1;
- os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
- } else {
- p->p2p = 0;
- os_memcpy(p->addr, mac_addr, ETH_ALEN);
- }
- os_memcpy(p->psk, psk, psk_len);
-
- if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS &&
- (last = dl_list_last(&persistent->psk_list,
- struct psk_list_entry, list))) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for "
- MACSTR " (p2p=%u) to make room for a new one",
- MAC2STR(last->addr), last->p2p);
- dl_list_del(&last->list);
- os_free(last);
- }
-
- wpas_p2p_remove_psk_entry(wpa_s->p2pdev, persistent,
- p2p_dev_addr ? p2p_dev_addr : mac_addr,
- p2p_dev_addr == NULL);
- if (p2p_dev_addr) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr="
- MACSTR, MAC2STR(p2p_dev_addr));
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR,
- MAC2STR(mac_addr));
- }
- dl_list_add(&persistent->psk_list, &p->list);
-
- if (wpa_s->p2pdev->conf->update_config &&
- wpa_config_write(wpa_s->p2pdev->confname, wpa_s->p2pdev->conf))
- wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
-}
-
-
-static void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *s, const u8 *addr,
- int iface_addr)
-{
- int res;
-
- res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr);
- if (res > 0 && wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf))
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Failed to update configuration");
-}
-
-
-static void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s,
- const u8 *peer, int iface_addr)
-{
- struct hostapd_data *hapd;
- struct hostapd_wpa_psk *psk, *prev, *rem;
- struct sta_info *sta;
-
- if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL ||
- wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO)
- return;
-
- /* Remove per-station PSK entry */
- hapd = wpa_s->ap_iface->bss[0];
- prev = NULL;
- psk = hapd->conf->ssid.wpa_psk;
- while (psk) {
- if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) ||
- (!iface_addr &&
- os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for "
- MACSTR " iface_addr=%d",
- MAC2STR(peer), iface_addr);
- if (prev)
- prev->next = psk->next;
- else
- hapd->conf->ssid.wpa_psk = psk->next;
- rem = psk;
- psk = psk->next;
- os_free(rem);
- } else {
- prev = psk;
- psk = psk->next;
- }
- }
-
- /* Disconnect from group */
- if (iface_addr)
- sta = ap_get_sta(hapd, peer);
- else
- sta = ap_get_sta_p2p(hapd, peer);
- if (sta) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR
- " (iface_addr=%d) from group",
- MAC2STR(peer), iface_addr);
- hostapd_drv_sta_deauth(hapd, sta->addr,
- WLAN_REASON_DEAUTH_LEAVING);
- ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING);
- }
-}
-
-
-void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
- int iface_addr)
-{
- struct wpa_ssid *s;
- struct wpa_supplicant *w;
- struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer));
-
- /* Remove from any persistent group */
- for (s = p2p_wpa_s->conf->ssid; s; s = s->next) {
- if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
- continue;
- if (!iface_addr)
- wpas_remove_persistent_peer(p2p_wpa_s, s, peer, 0);
- wpas_p2p_remove_psk(p2p_wpa_s, s, peer, iface_addr);
- }
-
- /* Remove from any operating group */
- for (w = wpa_s->global->ifaces; w; w = w->next)
- wpas_p2p_remove_client_go(w, peer, iface_addr);
-}
-
-
-static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE);
-}
-
-
-static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group");
- wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT);
-}
-
-
-int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
- struct wpa_ssid *ssid)
-{
- struct wpa_supplicant *iface;
-
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- if (!iface->current_ssid ||
- iface->current_ssid->frequency == freq ||
- (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
- !iface->current_ssid->p2p_group))
- continue;
-
- /* Remove the connection with least priority */
- if (!wpas_is_p2p_prioritized(iface)) {
- /* STA connection has priority over existing
- * P2P connection, so remove the interface. */
- wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict");
- eloop_register_timeout(0, 0,
- wpas_p2p_group_freq_conflict,
- iface, NULL);
- /* If connection in progress is P2P connection, do not
- * proceed for the connection. */
- if (wpa_s == iface)
- return -1;
- else
- return 0;
- } else {
- /* P2P connection has priority, disable the STA network
- */
- wpa_supplicant_disable_network(wpa_s->global->ifaces,
- ssid);
- wpa_msg(wpa_s->global->ifaces, MSG_INFO,
- WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id);
- os_memset(wpa_s->global->ifaces->pending_bssid, 0,
- ETH_ALEN);
- /* If P2P connection is in progress, continue
- * connecting...*/
- if (wpa_s == iface)
- return 0;
- else
- return -1;
- }
- }
-
- return 0;
-}
-
-
-int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL || !ssid->p2p_group)
- return 0;
-
- if (wpa_s->p2p_last_4way_hs_fail &&
- wpa_s->p2p_last_4way_hs_fail == ssid) {
- u8 go_dev_addr[ETH_ALEN];
- struct wpa_ssid *persistent;
-
- if (wpas_p2p_persistent_group(wpa_s, go_dev_addr,
- ssid->ssid,
- ssid->ssid_len) <= 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group");
- goto disconnect;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr="
- MACSTR, MAC2STR(go_dev_addr));
- persistent = wpas_p2p_get_persistent(wpa_s->p2pdev, go_dev_addr,
- ssid->ssid,
- ssid->ssid_len);
- if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored");
- goto disconnect;
- }
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_PERSISTENT_PSK_FAIL "%d",
- persistent->id);
- disconnect:
- wpa_s->p2p_last_4way_hs_fail = NULL;
- /*
- * Remove the group from a timeout to avoid issues with caller
- * continuing to use the interface if this is on a P2P group
- * interface.
- */
- eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal,
- wpa_s, NULL);
- return 1;
- }
-
- wpa_s->p2p_last_4way_hs_fail = ssid;
- return 0;
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-static struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc,
- struct wpabuf *p2p)
-{
- struct wpabuf *ret;
- size_t wsc_len;
-
- if (p2p == NULL) {
- wpabuf_free(wsc);
- wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover");
- return NULL;
- }
-
- wsc_len = wsc ? wpabuf_len(wsc) : 0;
- ret = wpabuf_alloc(2 + wsc_len + 2 + wpabuf_len(p2p));
- if (ret == NULL) {
- wpabuf_free(wsc);
- wpabuf_free(p2p);
- return NULL;
- }
-
- wpabuf_put_be16(ret, wsc_len);
- if (wsc)
- wpabuf_put_buf(ret, wsc);
- wpabuf_put_be16(ret, wpabuf_len(p2p));
- wpabuf_put_buf(ret, p2p);
-
- wpabuf_free(wsc);
- wpabuf_free(p2p);
- wpa_hexdump_buf(MSG_DEBUG,
- "P2P: Generated NFC connection handover message", ret);
-
- if (ndef && ret) {
- struct wpabuf *tmp;
- tmp = ndef_build_p2p(ret);
- wpabuf_free(ret);
- if (tmp == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request");
- return NULL;
- }
- ret = tmp;
- }
-
- return ret;
-}
-
-
-static int wpas_p2p_cli_freq(struct wpa_supplicant *wpa_s,
- struct wpa_ssid **ssid, u8 *go_dev_addr)
-{
- struct wpa_supplicant *iface;
-
- if (go_dev_addr)
- os_memset(go_dev_addr, 0, ETH_ALEN);
- if (ssid)
- *ssid = NULL;
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- if (iface->wpa_state < WPA_ASSOCIATING ||
- iface->current_ssid == NULL || iface->assoc_freq == 0 ||
- !iface->current_ssid->p2p_group ||
- iface->current_ssid->mode != WPAS_MODE_INFRA)
- continue;
- if (ssid)
- *ssid = iface->current_ssid;
- if (go_dev_addr)
- os_memcpy(go_dev_addr, iface->go_dev_addr, ETH_ALEN);
- return iface->assoc_freq;
- }
- return 0;
-}
-
-
-struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
- int ndef)
-{
- struct wpabuf *wsc, *p2p;
- struct wpa_ssid *ssid;
- u8 go_dev_addr[ETH_ALEN];
- int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request");
- return NULL;
- }
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
- wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request");
- return NULL;
- }
-
- if (cli_freq == 0) {
- wsc = wps_build_nfc_handover_req_p2p(
- wpa_s->parent->wps, wpa_s->conf->wps_nfc_dh_pubkey);
- } else
- wsc = NULL;
- p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p, cli_freq,
- go_dev_addr, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0);
-
- return wpas_p2p_nfc_handover(ndef, wsc, p2p);
-}
-
-
-struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef, int tag)
-{
- struct wpabuf *wsc, *p2p;
- struct wpa_ssid *ssid;
- u8 go_dev_addr[ETH_ALEN];
- int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return NULL;
-
- if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
- wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey) < 0)
- return NULL;
-
- if (cli_freq == 0) {
- wsc = wps_build_nfc_handover_sel_p2p(
- wpa_s->parent->wps,
- tag ? wpa_s->conf->wps_nfc_dev_pw_id :
- DEV_PW_NFC_CONNECTION_HANDOVER,
- wpa_s->conf->wps_nfc_dh_pubkey,
- tag ? wpa_s->conf->wps_nfc_dev_pw : NULL);
- } else
- wsc = NULL;
- p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p, cli_freq,
- go_dev_addr, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0);
-
- return wpas_p2p_nfc_handover(ndef, wsc, p2p);
-}
-
-
-static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
- struct p2p_nfc_params *params)
-{
- wpa_printf(MSG_DEBUG, "P2P: Initiate join-group based on NFC "
- "connection handover (freq=%d)",
- params->go_freq);
-
- if (params->go_freq && params->go_ssid_len) {
- wpa_s->p2p_wps_method = WPS_NFC;
- wpa_s->pending_join_wps_method = WPS_NFC;
- os_memset(wpa_s->pending_join_iface_addr, 0, ETH_ALEN);
- os_memcpy(wpa_s->pending_join_dev_addr, params->go_dev_addr,
- ETH_ALEN);
- return wpas_p2p_join_start(wpa_s, params->go_freq,
- params->go_ssid,
- params->go_ssid_len);
- }
-
- return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
- WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
- params->go_freq, wpa_s->p2p_go_vht_center_freq2,
- -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
- params->go_ssid_len ? params->go_ssid : NULL,
- params->go_ssid_len, false);
-}
-
-
-static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
- struct p2p_nfc_params *params, int tag)
-{
- int res, persistent;
- struct wpa_ssid *ssid;
-
- wpa_printf(MSG_DEBUG, "P2P: Authorize join-group based on NFC "
- "connection handover");
- for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- ssid = wpa_s->current_ssid;
- if (ssid == NULL)
- continue;
- if (ssid->mode != WPAS_MODE_P2P_GO)
- continue;
- if (wpa_s->ap_iface == NULL)
- continue;
- break;
- }
- if (wpa_s == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Could not find GO interface");
- return -1;
- }
-
- if (wpa_s->p2pdev->p2p_oob_dev_pw_id !=
- DEV_PW_NFC_CONNECTION_HANDOVER &&
- !wpa_s->p2pdev->p2p_oob_dev_pw) {
- wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
- return -1;
- }
- res = wpas_ap_wps_add_nfc_pw(
- wpa_s, wpa_s->p2pdev->p2p_oob_dev_pw_id,
- wpa_s->p2pdev->p2p_oob_dev_pw,
- wpa_s->p2pdev->p2p_peer_oob_pk_hash_known ?
- wpa_s->p2pdev->p2p_peer_oob_pubkey_hash : NULL);
- if (res)
- return res;
-
- if (!tag) {
- wpa_printf(MSG_DEBUG, "P2P: Negotiated handover - wait for peer to join without invitation");
- return 0;
- }
-
- if (!params->peer ||
- !(params->peer->dev_capab & P2P_DEV_CAPAB_INVITATION_PROCEDURE))
- return 0;
-
- wpa_printf(MSG_DEBUG, "P2P: Static handover - invite peer " MACSTR
- " to join", MAC2STR(params->peer->p2p_device_addr));
-
- wpa_s->global->p2p_invite_group = wpa_s;
- persistent = ssid->p2p_persistent_group &&
- wpas_p2p_get_persistent(wpa_s->p2pdev,
- params->peer->p2p_device_addr,
- ssid->ssid, ssid->ssid_len);
- wpa_s->p2pdev->pending_invite_ssid_id = -1;
-
- return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr,
- P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr,
- ssid->ssid, ssid->ssid_len, ssid->frequency,
- wpa_s->global->p2p_dev_addr, persistent, 0,
- wpa_s->p2pdev->p2p_oob_dev_pw_id);
-}
-
-
-static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
- struct p2p_nfc_params *params,
- int forced_freq)
-{
- wpa_printf(MSG_DEBUG, "P2P: Initiate GO Negotiation based on NFC "
- "connection handover");
- return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
- WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
- forced_freq, wpa_s->p2p_go_vht_center_freq2,
- -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
- NULL, 0, false);
-}
-
-
-static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
- struct p2p_nfc_params *params,
- int forced_freq)
-{
- int res;
-
- wpa_printf(MSG_DEBUG, "P2P: Authorize GO Negotiation based on NFC "
- "connection handover");
- res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
- WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
- forced_freq, wpa_s->p2p_go_vht_center_freq2,
- -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
- wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
- NULL, 0, false);
- if (res)
- return res;
-
- res = wpas_p2p_listen(wpa_s, 60);
- if (res) {
- p2p_unauthorize(wpa_s->global->p2p,
- params->peer->p2p_device_addr);
- }
-
- return res;
-}
-
-
-static int wpas_p2p_nfc_connection_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data,
- int sel, int tag, int forced_freq)
-{
- const u8 *pos, *end;
- u16 len, id;
- struct p2p_nfc_params params;
- int res;
-
- os_memset(&params, 0, sizeof(params));
- params.sel = sel;
-
- wpa_hexdump_buf(MSG_DEBUG, "P2P: Received NFC tag payload", data);
-
- pos = wpabuf_head(data);
- end = pos + wpabuf_len(data);
-
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of WSC "
- "attributes");
- return -1;
- }
- len = WPA_GET_BE16(pos);
- pos += 2;
- if (len > end - pos) {
- wpa_printf(MSG_DEBUG, "P2P: Not enough data for WSC "
- "attributes");
- return -1;
- }
- params.wsc_attr = pos;
- params.wsc_len = len;
- pos += len;
-
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of P2P "
- "attributes");
- return -1;
- }
- len = WPA_GET_BE16(pos);
- pos += 2;
- if (len > end - pos) {
- wpa_printf(MSG_DEBUG, "P2P: Not enough data for P2P "
- "attributes");
- return -1;
- }
- params.p2p_attr = pos;
- params.p2p_len = len;
- pos += len;
-
- wpa_hexdump(MSG_DEBUG, "P2P: WSC attributes",
- params.wsc_attr, params.wsc_len);
- wpa_hexdump(MSG_DEBUG, "P2P: P2P attributes",
- params.p2p_attr, params.p2p_len);
- if (pos < end) {
- wpa_hexdump(MSG_DEBUG,
- "P2P: Ignored extra data after P2P attributes",
- pos, end - pos);
- }
-
- res = p2p_process_nfc_connection_handover(wpa_s->global->p2p, &params);
- if (res)
- return res;
-
- if (params.next_step == NO_ACTION)
- return 0;
-
- if (params.next_step == BOTH_GO) {
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_BOTH_GO "peer=" MACSTR,
- MAC2STR(params.peer->p2p_device_addr));
- return 0;
- }
-
- if (params.next_step == PEER_CLIENT) {
- if (!is_zero_ether_addr(params.go_dev_addr)) {
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
- "peer=" MACSTR " freq=%d go_dev_addr=" MACSTR
- " ssid=\"%s\"",
- MAC2STR(params.peer->p2p_device_addr),
- params.go_freq,
- MAC2STR(params.go_dev_addr),
- wpa_ssid_txt(params.go_ssid,
- params.go_ssid_len));
- } else {
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
- "peer=" MACSTR " freq=%d",
- MAC2STR(params.peer->p2p_device_addr),
- params.go_freq);
- }
- return 0;
- }
-
- if (wpas_p2p_cli_freq(wpa_s, NULL, NULL)) {
- wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_WHILE_CLIENT "peer="
- MACSTR, MAC2STR(params.peer->p2p_device_addr));
- return 0;
- }
-
- wpabuf_free(wpa_s->p2p_oob_dev_pw);
- wpa_s->p2p_oob_dev_pw = NULL;
-
- if (params.oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
- wpa_printf(MSG_DEBUG, "P2P: No peer OOB Dev Pw "
- "received");
- return -1;
- }
-
- id = WPA_GET_BE16(params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN);
- wpa_printf(MSG_DEBUG, "P2P: Peer OOB Dev Pw %u", id);
- wpa_hexdump(MSG_DEBUG, "P2P: Peer OOB Public Key hash",
- params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
- os_memcpy(wpa_s->p2p_peer_oob_pubkey_hash,
- params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
- wpa_s->p2p_peer_oob_pk_hash_known = 1;
-
- if (tag) {
- if (id < 0x10) {
- wpa_printf(MSG_DEBUG, "P2P: Static handover - invalid "
- "peer OOB Device Password Id %u", id);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "P2P: Static handover - use peer OOB "
- "Device Password Id %u", id);
- wpa_hexdump_key(MSG_DEBUG, "P2P: Peer OOB Device Password",
- params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
- params.oob_dev_pw_len -
- WPS_OOB_PUBKEY_HASH_LEN - 2);
- wpa_s->p2p_oob_dev_pw_id = id;
- wpa_s->p2p_oob_dev_pw = wpabuf_alloc_copy(
- params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
- params.oob_dev_pw_len -
- WPS_OOB_PUBKEY_HASH_LEN - 2);
- if (wpa_s->p2p_oob_dev_pw == NULL)
- return -1;
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
- wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey) < 0)
- return -1;
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Using abbreviated WPS handshake "
- "without Device Password");
- wpa_s->p2p_oob_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
- }
-
- switch (params.next_step) {
- case NO_ACTION:
- case BOTH_GO:
- case PEER_CLIENT:
- /* already covered above */
- return 0;
- case JOIN_GROUP:
- return wpas_p2p_nfc_join_group(wpa_s, &params);
- case AUTH_JOIN:
- return wpas_p2p_nfc_auth_join(wpa_s, &params, tag);
- case INIT_GO_NEG:
- return wpas_p2p_nfc_init_go_neg(wpa_s, &params, forced_freq);
- case RESP_GO_NEG:
- /* TODO: use own OOB Dev Pw */
- return wpas_p2p_nfc_resp_go_neg(wpa_s, &params, forced_freq);
- }
-
- return -1;
-}
-
-
-int wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data, int forced_freq)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- return wpas_p2p_nfc_connection_handover(wpa_s, data, 1, 1, forced_freq);
-}
-
-
-int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
- const struct wpabuf *req,
- const struct wpabuf *sel, int forced_freq)
-{
- struct wpabuf *tmp;
- int ret;
-
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
-
- wpa_printf(MSG_DEBUG, "NFC: P2P connection handover reported");
-
- wpa_hexdump_ascii(MSG_DEBUG, "NFC: Req",
- wpabuf_head(req), wpabuf_len(req));
- wpa_hexdump_ascii(MSG_DEBUG, "NFC: Sel",
- wpabuf_head(sel), wpabuf_len(sel));
- if (forced_freq)
- wpa_printf(MSG_DEBUG, "NFC: Forced freq %d", forced_freq);
- tmp = ndef_parse_p2p(init ? sel : req);
- if (tmp == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: Could not parse NDEF");
- return -1;
- }
-
- ret = wpas_p2p_nfc_connection_handover(wpa_s, tmp, init, 0,
- forced_freq);
- wpabuf_free(tmp);
-
- return ret;
-}
-
-
-int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled)
-{
- const u8 *if_addr;
- int go_intent = wpa_s->conf->p2p_go_intent;
- struct wpa_supplicant *iface;
-
- if (wpa_s->global->p2p == NULL)
- return -1;
-
- if (!enabled) {
- wpa_printf(MSG_DEBUG, "P2P: Disable use of own NFC Tag");
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
- {
- if (!iface->ap_iface)
- continue;
- hostapd_wps_nfc_token_disable(iface->ap_iface->bss[0]);
- }
- p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0,
- 0, NULL);
- if (wpa_s->p2p_nfc_tag_enabled)
- wpas_p2p_remove_pending_group_interface(wpa_s);
- wpa_s->p2p_nfc_tag_enabled = 0;
- return 0;
- }
-
- if (wpa_s->global->p2p_disabled)
- return -1;
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
- wpa_s->conf->wps_nfc_dh_privkey == NULL ||
- wpa_s->conf->wps_nfc_dev_pw == NULL ||
- wpa_s->conf->wps_nfc_dev_pw_id < 0x10) {
- wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured "
- "to allow static handover cases");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "P2P: Enable use of own NFC Tag");
-
- wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
- wpabuf_free(wpa_s->p2p_oob_dev_pw);
- wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
- if (wpa_s->p2p_oob_dev_pw == NULL)
- return -1;
- wpa_s->p2p_peer_oob_pk_hash_known = 0;
-
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
- wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) {
- /*
- * P2P Group Interface present and the command came on group
- * interface, so enable the token for the current interface.
- */
- wpa_s->create_p2p_iface = 0;
- } else {
- wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
- }
-
- if (wpa_s->create_p2p_iface) {
- enum wpa_driver_if_type iftype;
- /* Prepare to add a new interface for the group */
- iftype = WPA_IF_P2P_GROUP;
- if (go_intent == 15)
- iftype = WPA_IF_P2P_GO;
- if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
- wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
- "interface for the group");
- return -1;
- }
-
- if_addr = wpa_s->pending_interface_addr;
- } else if (wpa_s->p2p_mgmt)
- if_addr = wpa_s->parent->own_addr;
- else
- if_addr = wpa_s->own_addr;
-
- wpa_s->p2p_nfc_tag_enabled = enabled;
-
- for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
- struct hostapd_data *hapd;
- if (iface->ap_iface == NULL)
- continue;
- hapd = iface->ap_iface->bss[0];
- wpabuf_free(hapd->conf->wps_nfc_dh_pubkey);
- hapd->conf->wps_nfc_dh_pubkey =
- wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
- wpabuf_free(hapd->conf->wps_nfc_dh_privkey);
- hapd->conf->wps_nfc_dh_privkey =
- wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
- wpabuf_free(hapd->conf->wps_nfc_dev_pw);
- hapd->conf->wps_nfc_dev_pw =
- wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
- hapd->conf->wps_nfc_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
-
- if (hostapd_wps_nfc_token_enable(iface->ap_iface->bss[0]) < 0) {
- wpa_dbg(iface, MSG_DEBUG,
- "P2P: Failed to enable NFC Tag for GO");
- }
- }
- p2p_set_authorized_oob_dev_pw_id(
- wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent,
- if_addr);
-
- return 0;
-}
-
-#endif /* CONFIG_WPS_NFC */
-
-
-static void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs,
- unsigned int num)
-{
- u8 curr_chan, cand, chan;
- unsigned int i;
-
- /*
- * If possible, optimize the Listen channel to be a channel that is
- * already used by one of the other interfaces.
- */
- if (!wpa_s->conf->p2p_optimize_listen_chan)
- return;
-
- if (!wpa_s->current_ssid || wpa_s->wpa_state != WPA_COMPLETED)
- return;
-
- curr_chan = p2p_get_listen_channel(wpa_s->global->p2p);
- for (i = 0, cand = 0; i < num; i++) {
- ieee80211_freq_to_chan(freqs[i].freq, &chan);
- if (curr_chan == chan) {
- cand = 0;
- break;
- }
-
- if (chan == 1 || chan == 6 || chan == 11)
- cand = chan;
- }
-
- if (cand) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Update Listen channel to %u based on operating channel",
- cand);
- p2p_set_listen_channel(wpa_s->global->p2p, 81, cand, 0);
- }
-}
-
-
-static int wpas_p2p_move_go_csa(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_config *conf;
- struct p2p_go_neg_results params;
- struct csa_settings csa_settings;
- struct wpa_ssid *current_ssid = wpa_s->current_ssid;
- int old_freq = current_ssid->frequency;
- int ret;
-
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "CSA is not enabled");
- return -1;
- }
-
- /*
- * TODO: This function may not always work correctly. For example,
- * when we have a running GO and a BSS on a DFS channel.
- */
- if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, 0, 0,
- NULL)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: Failed to select new frequency for GO");
- return -1;
- }
-
- if (current_ssid->frequency == params.freq) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: Selected same frequency - not moving GO");
- return 0;
- }
-
- conf = hostapd_config_defaults();
- if (!conf) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: Failed to allocate default config");
- return -1;
- }
-
- current_ssid->frequency = params.freq;
- if (wpa_supplicant_conf_ap_ht(wpa_s, current_ssid, conf)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: Failed to create new GO config");
- ret = -1;
- goto out;
- }
-
- if (conf->hw_mode != wpa_s->ap_iface->current_mode->mode) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: CSA to a different band is not supported");
- ret = -1;
- goto out;
- }
-
- os_memset(&csa_settings, 0, sizeof(csa_settings));
- csa_settings.cs_count = P2P_GO_CSA_COUNT;
- csa_settings.block_tx = P2P_GO_CSA_BLOCK_TX;
- csa_settings.freq_params.freq = params.freq;
- csa_settings.freq_params.sec_channel_offset = conf->secondary_channel;
- csa_settings.freq_params.ht_enabled = conf->ieee80211n;
- csa_settings.freq_params.bandwidth = conf->secondary_channel ? 40 : 20;
-
- if (conf->ieee80211ac) {
- int freq1 = 0, freq2 = 0;
- u8 chan, opclass;
-
- if (ieee80211_freq_to_channel_ext(params.freq,
- conf->secondary_channel,
- conf->vht_oper_chwidth,
- &opclass, &chan) ==
- NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_ERROR, "P2P CSA: Bad freq");
- ret = -1;
- goto out;
- }
-
- if (conf->vht_oper_centr_freq_seg0_idx)
- freq1 = ieee80211_chan_to_freq(
- NULL, opclass,
- conf->vht_oper_centr_freq_seg0_idx);
-
- if (conf->vht_oper_centr_freq_seg1_idx)
- freq2 = ieee80211_chan_to_freq(
- NULL, opclass,
- conf->vht_oper_centr_freq_seg1_idx);
-
- if (freq1 < 0 || freq2 < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P CSA: Selected invalid VHT center freqs");
- ret = -1;
- goto out;
- }
-
- csa_settings.freq_params.vht_enabled = conf->ieee80211ac;
- csa_settings.freq_params.center_freq1 = freq1;
- csa_settings.freq_params.center_freq2 = freq2;
-
- switch (conf->vht_oper_chwidth) {
- case CHANWIDTH_80MHZ:
- case CHANWIDTH_80P80MHZ:
- csa_settings.freq_params.bandwidth = 80;
- break;
- case CHANWIDTH_160MHZ:
- csa_settings.freq_params.bandwidth = 160;
- break;
- }
- }
-
- ret = ap_switch_channel(wpa_s, &csa_settings);
-out:
- current_ssid->frequency = old_freq;
- hostapd_config_free(conf);
- return ret;
-}
-
-
-static void wpas_p2p_move_go_no_csa(struct wpa_supplicant *wpa_s)
-{
- struct p2p_go_neg_results params;
- struct wpa_ssid *current_ssid = wpa_s->current_ssid;
- void (*ap_configured_cb)(void *ctx, void *data);
- void *ap_configured_cb_ctx, *ap_configured_cb_data;
-
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Move GO from freq=%d MHz",
- current_ssid->frequency);
-
- /* Stop the AP functionality */
- /* TODO: Should do this in a way that does not indicated to possible
- * P2P Clients in the group that the group is terminated. */
- /* If this action occurs before a group is started, the callback should
- * be preserved, or GROUP-STARTED event would be lost. If this action
- * occurs after a group is started, these pointers are all NULL and
- * harmless. */
- ap_configured_cb = wpa_s->ap_configured_cb;
- ap_configured_cb_ctx = wpa_s->ap_configured_cb_ctx;
- ap_configured_cb_data = wpa_s->ap_configured_cb_data;
- wpa_supplicant_ap_deinit(wpa_s);
-
- /* Reselect the GO frequency */
- if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, 0, 0,
- NULL)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Failed to reselect freq");
- wpas_p2p_group_delete(wpa_s,
- P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL);
- return;
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New freq selected for the GO (%u MHz)",
- params.freq);
-
- if (params.freq &&
- !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
- wpa_printf(MSG_DEBUG,
- "P2P: Selected freq (%u MHz) is not valid for P2P",
- params.freq);
- wpas_p2p_group_delete(wpa_s,
- P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL);
- return;
- }
-
- /* Restore preserved callback parameters */
- wpa_s->ap_configured_cb = ap_configured_cb;
- wpa_s->ap_configured_cb_ctx = ap_configured_cb_ctx;
- wpa_s->ap_configured_cb_data = ap_configured_cb_data;
-
- /* Update the frequency */
- current_ssid->frequency = params.freq;
- wpa_s->connect_without_scan = current_ssid;
- wpa_s->reassociate = 1;
- wpa_s->disconnected = 0;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (!wpa_s->ap_iface || !wpa_s->current_ssid)
- return;
-
- wpas_p2p_go_update_common_freqs(wpa_s);
-
- /* Do not move GO in the middle of a CSA */
- if (hostapd_csa_in_progress(wpa_s->ap_iface)) {
- wpa_printf(MSG_DEBUG,
- "P2P: CSA is in progress - not moving GO");
- return;
- }
-
- /*
- * First, try a channel switch flow. If it is not supported or fails,
- * take down the GO and bring it up again.
- */
- if (wpas_p2p_move_go_csa(wpa_s) < 0)
- wpas_p2p_move_go_no_csa(wpa_s);
-}
-
-
-static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_used_freq_data *freqs = NULL;
- unsigned int num = wpa_s->num_multichan_concurrent;
-
- freqs = os_calloc(num, sizeof(struct wpa_used_freq_data));
- if (!freqs)
- return;
-
- num = get_shared_radio_freqs_data(wpa_s, freqs, num);
-
- /* Previous attempt to move a GO was not possible -- try again. */
- wpas_p2p_consider_moving_gos(wpa_s, freqs, num,
- WPAS_P2P_CHANNEL_UPDATE_ANY);
-
- os_free(freqs);
-}
-
-
-/*
- * Consider moving a GO from its currently used frequency:
- * 1. It is possible that due to regulatory consideration the frequency
- * can no longer be used and there is a need to evacuate the GO.
- * 2. It is possible that due to MCC considerations, it would be preferable
- * to move the GO to a channel that is currently used by some other
- * station interface.
- *
- * In case a frequency that became invalid is once again valid, cancel a
- * previously initiated GO frequency change.
- */
-static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs,
- unsigned int num)
-{
- unsigned int i, invalid_freq = 0, policy_move = 0, flags = 0;
- unsigned int timeout;
- int freq;
- int dfs_offload;
-
- wpas_p2p_go_update_common_freqs(wpa_s);
-
- freq = wpa_s->current_ssid->frequency;
- dfs_offload = (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
- ieee80211_is_dfs(freq, wpa_s->hw.modes, wpa_s->hw.num_modes);
- for (i = 0, invalid_freq = 0; i < num; i++) {
- if (freqs[i].freq == freq) {
- flags = freqs[i].flags;
-
- /* The channel is invalid, must change it */
- if (!p2p_supported_freq_go(wpa_s->global->p2p, freq) &&
- !dfs_offload) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Freq=%d MHz no longer valid for GO",
- freq);
- invalid_freq = 1;
- }
- } else if (freqs[i].flags == 0) {
- /* Freq is not used by any other station interface */
- continue;
- } else if (!p2p_supported_freq(wpa_s->global->p2p,
- freqs[i].freq) && !dfs_offload) {
- /* Freq is not valid for P2P use cases */
- continue;
- } else if (wpa_s->conf->p2p_go_freq_change_policy ==
- P2P_GO_FREQ_MOVE_SCM) {
- policy_move = 1;
- } else if (wpa_s->conf->p2p_go_freq_change_policy ==
- P2P_GO_FREQ_MOVE_SCM_PEER_SUPPORTS &&
- wpas_p2p_go_is_peer_freq(wpa_s, freqs[i].freq)) {
- policy_move = 1;
- } else if ((wpa_s->conf->p2p_go_freq_change_policy ==
- P2P_GO_FREQ_MOVE_SCM_ECSA) &&
- wpas_p2p_go_is_peer_freq(wpa_s, freqs[i].freq)) {
- if (!p2p_get_group_num_members(wpa_s->p2p_group)) {
- policy_move = 1;
- } else if ((wpa_s->drv_flags &
- WPA_DRIVER_FLAGS_AP_CSA) &&
- wpas_p2p_go_clients_support_ecsa(wpa_s)) {
- u8 chan;
-
- /*
- * We do not support CSA between bands, so move
- * GO only within the same band.
- */
- if (wpa_s->ap_iface->current_mode->mode ==
- ieee80211_freq_to_chan(freqs[i].freq,
- &chan))
- policy_move = 1;
- }
- }
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: GO move: invalid_freq=%u, policy_move=%u, flags=0x%X",
- invalid_freq, policy_move, flags);
-
- /*
- * The channel is valid, or we are going to have a policy move, so
- * cancel timeout.
- */
- if (!invalid_freq || policy_move) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Cancel a GO move from freq=%d MHz", freq);
- eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
-
- if (wpas_p2p_in_progress(wpa_s)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: GO move: policy CS is not allowed - setting timeout to re-consider GO move");
- eloop_cancel_timeout(wpas_p2p_reconsider_moving_go,
- wpa_s, NULL);
- eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0,
- wpas_p2p_reconsider_moving_go,
- wpa_s, NULL);
- return;
- }
- }
-
- if (!invalid_freq && (!policy_move || flags != 0)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Not initiating a GO frequency change");
- return;
- }
-
- /*
- * Do not consider moving GO if it is in the middle of a CSA. When the
- * CSA is finished this flow should be retriggered.
- */
- if (hostapd_csa_in_progress(wpa_s->ap_iface)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Not initiating a GO frequency change - CSA is in progress");
- return;
- }
-
- if (invalid_freq && !wpas_p2p_disallowed_freq(wpa_s->global, freq))
- timeout = P2P_GO_FREQ_CHANGE_TIME;
- else
- timeout = 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Move GO from freq=%d MHz in %d secs",
- freq, timeout);
- eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
- eloop_register_timeout(timeout, 0, wpas_p2p_move_go, wpa_s, NULL);
-}
-
-
-static void wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs,
- unsigned int num,
- enum wpas_p2p_channel_update_trig trig)
-{
- struct wpa_supplicant *ifs;
-
- eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, ELOOP_ALL_CTX,
- NULL);
-
- /*
- * Travers all the radio interfaces, and for each GO interface, check
- * if there is a need to move the GO from the frequency it is using,
- * or in case the frequency is valid again, cancel the evacuation flow.
- */
- dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
- radio_list) {
- if (ifs->current_ssid == NULL ||
- ifs->current_ssid->mode != WPAS_MODE_P2P_GO)
- continue;
-
- /*
- * The GO was just started or completed channel switch, no need
- * to move it.
- */
- if (wpa_s == ifs &&
- (trig == WPAS_P2P_CHANNEL_UPDATE_STATE_CHANGE ||
- trig == WPAS_P2P_CHANNEL_UPDATE_CS)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: GO move - schedule re-consideration");
- eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0,
- wpas_p2p_reconsider_moving_go,
- wpa_s, NULL);
- continue;
- }
-
- wpas_p2p_consider_moving_one_go(ifs, freqs, num);
- }
-}
-
-
-void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
-
- wpas_p2p_update_channel_list(wpa_s,
- WPAS_P2P_CHANNEL_UPDATE_STATE_CHANGE);
-}
-
-
-void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
- "the management interface is being removed");
- wpas_p2p_deinit_global(wpa_s->global);
- }
-}
-
-
-void wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->ap_iface->bss)
- wpa_s->ap_iface->bss[0]->p2p_group = NULL;
- wpas_p2p_group_deinit(wpa_s);
-}
-
-
-int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq,
- unsigned int period, unsigned int interval,
- unsigned int count)
-{
- struct p2p_data *p2p = wpa_s->global->p2p;
- u8 *device_types;
- size_t dev_types_len;
- struct wpabuf *buf;
- int ret;
-
- if (wpa_s->p2p_lo_started) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P Listen offload is already started");
- return 0;
- }
-
- if (wpa_s->global->p2p == NULL ||
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD)) {
- wpa_printf(MSG_DEBUG, "P2P: Listen offload not supported");
- return -1;
- }
-
- if (!p2p_supported_freq(wpa_s->global->p2p, freq)) {
- wpa_printf(MSG_ERROR, "P2P: Input channel not supported: %u",
- freq);
- return -1;
- }
-
- /* Get device type */
- dev_types_len = (wpa_s->conf->num_sec_device_types + 1) *
- WPS_DEV_TYPE_LEN;
- device_types = os_malloc(dev_types_len);
- if (!device_types)
- return -1;
- os_memcpy(device_types, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN);
- os_memcpy(&device_types[WPS_DEV_TYPE_LEN], wpa_s->conf->sec_device_type,
- wpa_s->conf->num_sec_device_types * WPS_DEV_TYPE_LEN);
-
- /* Get Probe Response IE(s) */
- buf = p2p_build_probe_resp_template(p2p, freq);
- if (!buf) {
- os_free(device_types);
- return -1;
- }
-
- ret = wpa_drv_p2p_lo_start(wpa_s, freq, period, interval, count,
- device_types, dev_types_len,
- wpabuf_mhead_u8(buf), wpabuf_len(buf));
- if (ret < 0)
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Failed to start P2P listen offload");
-
- os_free(device_types);
- wpabuf_free(buf);
-
- if (ret == 0) {
- wpa_s->p2p_lo_started = 1;
-
- /* Stop current P2P listen if any */
- wpas_stop_listen(wpa_s);
- }
-
- return ret;
-}
-
-
-int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s)
-{
- int ret;
-
- if (!wpa_s->p2p_lo_started)
- return 0;
-
- ret = wpa_drv_p2p_lo_stop(wpa_s);
- if (ret < 0)
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Failed to stop P2P listen offload");
-
- wpa_s->p2p_lo_started = 0;
- return ret;
-}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
deleted file mode 100644
index 5a869e7309a3..000000000000
--- a/wpa_supplicant/p2p_supplicant.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * wpa_supplicant - P2P
- * Copyright (c) 2009-2010, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef P2P_SUPPLICANT_H
-#define P2P_SUPPLICANT_H
-
-enum p2p_wps_method;
-struct p2p_go_neg_results;
-enum p2p_send_action_result;
-struct p2p_peer_info;
-struct p2p_channels;
-struct wps_event_fail;
-struct p2ps_provision;
-
-enum wpas_p2p_channel_update_trig {
- WPAS_P2P_CHANNEL_UPDATE_ANY,
- WPAS_P2P_CHANNEL_UPDATE_DRIVER,
- WPAS_P2P_CHANNEL_UPDATE_STATE_CHANGE,
- WPAS_P2P_CHANNEL_UPDATE_AVOID,
- WPAS_P2P_CHANNEL_UPDATE_DISALLOW,
- WPAS_P2P_CHANNEL_UPDATE_CS,
-};
-
-int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
- const char *conf_p2p_dev);
-struct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s,
- const u8 *ssid, size_t ssid_len);
-struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
- const u8 *peer_dev_addr);
-int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *pin, enum p2p_wps_method wps_method,
- int persistent_group, int auto_join, int join, int auth,
- int go_intent, int freq, unsigned int vht_center_freq2,
- int persistent_id, int pd, int ht40, int vht,
- unsigned int vht_chwidth, int he, int edmg,
- const u8 *group_ssid, size_t group_ssid_len,
- bool allow_6ghz);
-int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
- int freq, struct wpa_ssid *ssid);
-int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
- int freq, int vht_center_freq2, int ht40, int vht,
- int max_oper_chwidth, int he, int edmg, bool allow_6ghz);
-int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int addr_allocated,
- int force_freq, int neg_freq,
- int vht_center_freq2, int ht40, int vht,
- int max_oper_chwidth, int he, int edmg,
- const struct p2p_channels *channels,
- int connection_timeout, int force_scan,
- bool allow_6ghz);
-struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-enum wpas_p2p_prov_disc_use {
- WPAS_P2P_PD_FOR_GO_NEG,
- WPAS_P2P_PD_FOR_JOIN,
- WPAS_P2P_PD_AUTO,
- WPAS_P2P_PD_FOR_ASP
-};
-int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- const char *config_method,
- enum wpas_p2p_prov_disc_use use,
- struct p2ps_provision *p2ps_prov);
-void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
- const u8 *data, size_t data_len,
- enum p2p_send_action_result result);
-int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
- char *end);
-enum p2p_discovery_type;
-int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
- enum p2p_discovery_type type,
- unsigned int num_req_dev_types, const u8 *req_dev_types,
- const u8 *dev_id, unsigned int search_delay,
- u8 seek_cnt, const char **seek_string, int freq,
- bool include_6ghz);
-void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
-int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
-int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout);
-int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- u8 *buf, size_t len, int p2p_group);
-void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies);
-u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *tlvs);
-u64 wpas_p2p_sd_request_asp(struct wpa_supplicant *wpa_s, const u8 *dst, u8 id,
- const char *svc_str, const char *info_substr);
-u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
- u8 version, const char *query);
-u64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s,
- const u8 *dst, const char *role);
-int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req);
-void wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq,
- const u8 *dst, u8 dialog_token,
- const struct wpabuf *resp_tlvs);
-void wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s);
-void wpas_p2p_service_flush(struct wpa_supplicant *wpa_s);
-int wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s,
- struct wpabuf *query, struct wpabuf *resp);
-int wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s,
- const struct wpabuf *query);
-int wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version,
- const char *service);
-int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
- const char *service);
-int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s, int auto_accept,
- u32 adv_id, const char *adv_str, u8 svc_state,
- u16 config_methods, const char *svc_info,
- const u8 *cpt_priority);
-int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id);
-void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s);
-int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id);
-void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs, size_t tlvs_len);
-void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len);
-int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr);
-int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
- int vht_center_freq2, int ht40, int vht, int max_chwidth,
- int pref_freq, int he, int edmg, bool allow_6ghz);
-int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
- const u8 *peer_addr, const u8 *go_dev_addr,
- bool allow_6ghz);
-int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
- u32 interval1, u32 duration2, u32 interval2);
-int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
- unsigned int interval);
-int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
- u16 reason_code, const u8 *ie, size_t ie_len,
- int locally_generated);
-void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
- u16 reason_code, const u8 *ie, size_t ie_len,
- int locally_generated);
-int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
- int duration);
-int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled);
-int wpas_p2p_cancel(struct wpa_supplicant *wpa_s);
-int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr);
-int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s);
-struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *ssid,
- size_t ssid_len);
-void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
- const u8 *addr);
-int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s);
-int wpas_p2p_get_sec_channel_offset_40mhz(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode,
- u8 channel);
-int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode, u8 channel,
- u8 op_class);
-int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
- struct hostapd_hw_modes *mode, u8 channel,
- u8 op_class);
-unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s);
-void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
- const u8 *p2p_dev_addr,
- const u8 *psk, size_t psk_len);
-void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
- int iface_addr);
-struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
- int ndef);
-struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef, int tag);
-int wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data, int forced_freq);
-int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
- const struct wpabuf *req,
- const struct wpabuf *sel, int forced_freq);
-int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled);
-void wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx);
-int wpas_p2p_try_edmg_channel(struct wpa_supplicant *wpa_s,
- struct p2p_go_neg_results *params);
-
-#ifdef CONFIG_P2P
-
-int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
-void wpas_p2p_deinit(struct wpa_supplicant *wpa_s);
-void wpas_p2p_completed(struct wpa_supplicant *wpa_s);
-void wpas_p2p_update_config(struct wpa_supplicant *wpa_s);
-int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
- const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len,
- unsigned int rx_freq, int ssi_signal);
-void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
- int registrar);
-
-void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s,
- enum wpas_p2p_channel_update_trig trig);
-
-void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
- int freq_24, int freq_5, int freq_overall);
-void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
- const u8 *sa, const u8 *bssid,
- u8 category, const u8 *data, size_t len, int freq);
-void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration);
-void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq);
-void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s);
-void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s);
-void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
-int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s);
-int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);
-void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s);
-void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s);
-void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s);
-void wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s);
-void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
-int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s);
-void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail);
-int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
-int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq,
- unsigned int period, unsigned int interval,
- unsigned int count);
-int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
-int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
-
-#else /* CONFIG_P2P */
-
-static inline int
-wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s,
- const u8 *addr,
- const u8 *dst, const u8 *bssid,
- const u8 *ie, size_t ie_len,
- unsigned int rx_freq, int ssi_signal)
-{
- return 0;
-}
-
-static inline void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr, int registrar)
-{
-}
-
-static inline void
-wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s,
- enum wpas_p2p_channel_update_trig trig)
-{
-}
-
-static inline void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
- int freq_24, int freq_5,
- int freq_overall)
-{
-}
-
-static inline void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s,
- const u8 *da,
- const u8 *sa, const u8 *bssid,
- u8 category, const u8 *data, size_t len,
- int freq)
-{
-}
-
-static inline void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- unsigned int duration)
-{
-}
-
-static inline void
-wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
-}
-
-static inline void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-}
-
-static inline int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
-}
-
-static inline int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s,
- const char *ifname)
-{
- return 0;
-}
-
-#endif /* CONFIG_P2P */
-
-#endif /* P2P_SUPPLICANT_H */
diff --git a/wpa_supplicant/p2p_supplicant_sd.c b/wpa_supplicant/p2p_supplicant_sd.c
deleted file mode 100644
index b400cbacae61..000000000000
--- a/wpa_supplicant/p2p_supplicant_sd.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * wpa_supplicant - P2P service discovery
- * Copyright (c) 2009-2010, Atheros Communications
- * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "p2p/p2p.h"
-#include "wpa_supplicant_i.h"
-#include "notify.h"
-#include "p2p_supplicant.h"
-
-
-/*
- * DNS Header section is used only to calculate compression pointers, so the
- * contents of this data does not matter, but the length needs to be reserved
- * in the virtual packet.
- */
-#define DNS_HEADER_LEN 12
-
-/*
- * 27-octet in-memory packet from P2P specification containing two implied
- * queries for _tcp.lcoal. PTR IN and _udp.local. PTR IN
- */
-#define P2P_SD_IN_MEMORY_LEN 27
-
-static int p2p_sd_dns_uncompress_label(char **upos, char *uend, u8 *start,
- u8 **spos, const u8 *end)
-{
- while (*spos < end) {
- u8 val = ((*spos)[0] & 0xc0) >> 6;
- int len;
-
- if (val == 1 || val == 2) {
- /* These are reserved values in RFC 1035 */
- wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
- "sequence starting with 0x%x", val);
- return -1;
- }
-
- if (val == 3) {
- u16 offset;
- u8 *spos_tmp;
-
- /* Offset */
- if (end - *spos < 2) {
- wpa_printf(MSG_DEBUG, "P2P: No room for full "
- "DNS offset field");
- return -1;
- }
-
- offset = (((*spos)[0] & 0x3f) << 8) | (*spos)[1];
- if (offset >= *spos - start) {
- wpa_printf(MSG_DEBUG, "P2P: Invalid DNS "
- "pointer offset %u", offset);
- return -1;
- }
-
- (*spos) += 2;
- spos_tmp = start + offset;
- return p2p_sd_dns_uncompress_label(upos, uend, start,
- &spos_tmp,
- *spos - 2);
- }
-
- /* Label */
- len = (*spos)[0] & 0x3f;
- if (len == 0)
- return 0;
-
- (*spos)++;
- if (len > end - *spos) {
- wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
- "sequence - no room for label with length "
- "%u", len);
- return -1;
- }
-
- if (len + 2 > uend - *upos)
- return -2;
-
- os_memcpy(*upos, *spos, len);
- *spos += len;
- *upos += len;
- (*upos)[0] = '.';
- (*upos)++;
- (*upos)[0] = '\0';
- }
-
- return 0;
-}
-
-
-/* Uncompress domain names per RFC 1035 using the P2P SD in-memory packet.
- * Returns -1 on parsing error (invalid input sequence), -2 if output buffer is
- * not large enough */
-static int p2p_sd_dns_uncompress(char *buf, size_t buf_len, const u8 *msg,
- size_t msg_len, size_t offset)
-{
- /* 27-octet in-memory packet from P2P specification */
- const char *prefix = "\x04_tcp\x05local\x00\x00\x0C\x00\x01"
- "\x04_udp\xC0\x11\x00\x0C\x00\x01";
- u8 *tmp, *end, *spos;
- char *upos, *uend;
- int ret = 0;
-
- if (buf_len < 2)
- return -1;
- if (offset > msg_len)
- return -1;
-
- tmp = os_malloc(DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN + msg_len);
- if (tmp == NULL)
- return -1;
- spos = tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN;
- end = spos + msg_len;
- spos += offset;
-
- os_memset(tmp, 0, DNS_HEADER_LEN);
- os_memcpy(tmp + DNS_HEADER_LEN, prefix, P2P_SD_IN_MEMORY_LEN);
- os_memcpy(tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN, msg, msg_len);
-
- upos = buf;
- uend = buf + buf_len;
-
- ret = p2p_sd_dns_uncompress_label(&upos, uend, tmp, &spos, end);
- if (ret) {
- os_free(tmp);
- return ret;
- }
-
- if (upos == buf) {
- upos[0] = '.';
- upos[1] = '\0';
- } else if (upos[-1] == '.')
- upos[-1] = '\0';
-
- os_free(tmp);
- return 0;
-}
-
-
-static struct p2p_srv_bonjour *
-wpas_p2p_service_get_bonjour(struct wpa_supplicant *wpa_s,
- const struct wpabuf *query)
-{
- struct p2p_srv_bonjour *bsrv;
- size_t len;
-
- len = wpabuf_len(query);
- dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
- struct p2p_srv_bonjour, list) {
- if (len == wpabuf_len(bsrv->query) &&
- os_memcmp(wpabuf_head(query), wpabuf_head(bsrv->query),
- len) == 0)
- return bsrv;
- }
- return NULL;
-}
-
-
-static struct p2p_srv_upnp *
-wpas_p2p_service_get_upnp(struct wpa_supplicant *wpa_s, u8 version,
- const char *service)
-{
- struct p2p_srv_upnp *usrv;
-
- dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
- struct p2p_srv_upnp, list) {
- if (version == usrv->version &&
- os_strcmp(service, usrv->service) == 0)
- return usrv;
- }
- return NULL;
-}
-
-
-static void wpas_sd_add_empty(struct wpabuf *resp, u8 srv_proto,
- u8 srv_trans_id, u8 status)
-{
- u8 *len_pos;
-
- if (wpabuf_tailroom(resp) < 5)
- return;
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, srv_proto);
- wpabuf_put_u8(resp, srv_trans_id);
- /* Status Code */
- wpabuf_put_u8(resp, status);
- /* Response Data: empty */
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
-}
-
-
-static void wpas_sd_add_proto_not_avail(struct wpabuf *resp, u8 srv_proto,
- u8 srv_trans_id)
-{
- wpas_sd_add_empty(resp, srv_proto, srv_trans_id,
- P2P_SD_PROTO_NOT_AVAILABLE);
-}
-
-
-static void wpas_sd_add_bad_request(struct wpabuf *resp, u8 srv_proto,
- u8 srv_trans_id)
-{
- wpas_sd_add_empty(resp, srv_proto, srv_trans_id, P2P_SD_BAD_REQUEST);
-}
-
-
-static void wpas_sd_add_not_found(struct wpabuf *resp, u8 srv_proto,
- u8 srv_trans_id)
-{
- wpas_sd_add_empty(resp, srv_proto, srv_trans_id,
- P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
-}
-
-
-static void wpas_sd_all_bonjour(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id)
-{
- struct p2p_srv_bonjour *bsrv;
- u8 *len_pos;
-
- wpa_printf(MSG_DEBUG, "P2P: SD Request for all Bonjour services");
-
- if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
- wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
- return;
- }
-
- dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
- struct p2p_srv_bonjour, list) {
- if (wpabuf_tailroom(resp) <
- 5 + wpabuf_len(bsrv->query) + wpabuf_len(bsrv->resp))
- return;
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
- wpabuf_put_u8(resp, srv_trans_id);
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_SUCCESS);
- wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
- wpabuf_head(bsrv->resp),
- wpabuf_len(bsrv->resp));
- /* Response Data */
- wpabuf_put_buf(resp, bsrv->query); /* Key */
- wpabuf_put_buf(resp, bsrv->resp); /* Value */
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
- 2);
- }
-}
-
-
-static int match_bonjour_query(struct p2p_srv_bonjour *bsrv, const u8 *query,
- size_t query_len)
-{
- char str_rx[256], str_srv[256];
-
- if (query_len < 3 || wpabuf_len(bsrv->query) < 3)
- return 0; /* Too short to include DNS Type and Version */
- if (os_memcmp(query + query_len - 3,
- wpabuf_head_u8(bsrv->query) + wpabuf_len(bsrv->query) - 3,
- 3) != 0)
- return 0; /* Mismatch in DNS Type or Version */
- if (query_len == wpabuf_len(bsrv->query) &&
- os_memcmp(query, wpabuf_head(bsrv->query), query_len - 3) == 0)
- return 1; /* Binary match */
-
- if (p2p_sd_dns_uncompress(str_rx, sizeof(str_rx), query, query_len - 3,
- 0))
- return 0; /* Failed to uncompress query */
- if (p2p_sd_dns_uncompress(str_srv, sizeof(str_srv),
- wpabuf_head(bsrv->query),
- wpabuf_len(bsrv->query) - 3, 0))
- return 0; /* Failed to uncompress service */
-
- return os_strcmp(str_rx, str_srv) == 0;
-}
-
-
-static void wpas_sd_req_bonjour(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id,
- const u8 *query, size_t query_len)
-{
- struct p2p_srv_bonjour *bsrv;
- u8 *len_pos;
- int matches = 0;
-
- wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for Bonjour",
- query, query_len);
- if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
- wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
- wpas_sd_add_proto_not_avail(resp, P2P_SERV_BONJOUR,
- srv_trans_id);
- return;
- }
-
- if (query_len == 0) {
- wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
- return;
- }
-
- dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
- struct p2p_srv_bonjour, list) {
- if (!match_bonjour_query(bsrv, query, query_len))
- continue;
-
- if (wpabuf_tailroom(resp) <
- 5 + query_len + wpabuf_len(bsrv->resp))
- return;
-
- matches++;
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
- wpabuf_put_u8(resp, srv_trans_id);
-
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_SUCCESS);
- wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
- wpabuf_head(bsrv->resp),
- wpabuf_len(bsrv->resp));
-
- /* Response Data */
- wpabuf_put_data(resp, query, query_len); /* Key */
- wpabuf_put_buf(resp, bsrv->resp); /* Value */
-
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
- }
-
- if (matches == 0) {
- wpa_printf(MSG_DEBUG, "P2P: Requested Bonjour service not "
- "available");
- if (wpabuf_tailroom(resp) < 5)
- return;
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
- wpabuf_put_u8(resp, srv_trans_id);
-
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
- /* Response Data: empty */
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
- 2);
- }
-}
-
-
-static void wpas_sd_all_upnp(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id)
-{
- struct p2p_srv_upnp *usrv;
- u8 *len_pos;
-
- wpa_printf(MSG_DEBUG, "P2P: SD Request for all UPnP services");
-
- if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
- wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
- return;
- }
-
- dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
- struct p2p_srv_upnp, list) {
- if (wpabuf_tailroom(resp) < 5 + 1 + os_strlen(usrv->service))
- return;
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_UPNP);
- wpabuf_put_u8(resp, srv_trans_id);
-
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_SUCCESS);
- /* Response Data */
- wpabuf_put_u8(resp, usrv->version);
- wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
- usrv->service);
- wpabuf_put_str(resp, usrv->service);
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
- 2);
- }
-}
-
-
-static void wpas_sd_req_upnp(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id,
- const u8 *query, size_t query_len)
-{
- struct p2p_srv_upnp *usrv;
- u8 *len_pos;
- u8 version;
- char *str;
- int count = 0;
-
- wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for UPnP",
- query, query_len);
-
- if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
- wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
- wpas_sd_add_proto_not_avail(resp, P2P_SERV_UPNP,
- srv_trans_id);
- return;
- }
-
- if (query_len == 0) {
- wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
- return;
- }
-
- if (wpabuf_tailroom(resp) < 5)
- return;
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_UPNP);
- wpabuf_put_u8(resp, srv_trans_id);
-
- version = query[0];
- str = os_malloc(query_len);
- if (str == NULL)
- return;
- os_memcpy(str, query + 1, query_len - 1);
- str[query_len - 1] = '\0';
-
- dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
- struct p2p_srv_upnp, list) {
- if (version != usrv->version)
- continue;
-
- if (os_strcmp(str, "ssdp:all") != 0 &&
- os_strstr(usrv->service, str) == NULL)
- continue;
-
- if (wpabuf_tailroom(resp) < 2)
- break;
- if (count == 0) {
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_SUCCESS);
- /* Response Data */
- wpabuf_put_u8(resp, version);
- } else
- wpabuf_put_u8(resp, ',');
-
- count++;
-
- wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
- usrv->service);
- if (wpabuf_tailroom(resp) < os_strlen(usrv->service))
- break;
- wpabuf_put_str(resp, usrv->service);
- }
- os_free(str);
-
- if (count == 0) {
- wpa_printf(MSG_DEBUG, "P2P: Requested UPnP service not "
- "available");
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
- /* Response Data: empty */
- }
-
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
-}
-
-
-#ifdef CONFIG_WIFI_DISPLAY
-static void wpas_sd_req_wfd(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id,
- const u8 *query, size_t query_len)
-{
- const u8 *pos;
- u8 role;
- u8 *len_pos;
-
- wpa_hexdump(MSG_DEBUG, "P2P: SD Request for WFD", query, query_len);
-
- if (!wpa_s->global->wifi_display) {
- wpa_printf(MSG_DEBUG, "P2P: WFD protocol not available");
- wpas_sd_add_proto_not_avail(resp, P2P_SERV_WIFI_DISPLAY,
- srv_trans_id);
- return;
- }
-
- if (query_len < 1) {
- wpa_printf(MSG_DEBUG, "P2P: Missing WFD Requested Device "
- "Role");
- return;
- }
-
- if (wpabuf_tailroom(resp) < 5)
- return;
-
- pos = query;
- role = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: WSD for device role 0x%x", role);
-
- /* TODO: role specific handling */
-
- /* Length (to be filled) */
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_WIFI_DISPLAY);
- wpabuf_put_u8(resp, srv_trans_id);
- wpabuf_put_u8(resp, P2P_SD_SUCCESS); /* Status Code */
-
- while (pos < query + query_len) {
- if (*pos < MAX_WFD_SUBELEMS &&
- wpa_s->global->wfd_subelem[*pos] &&
- wpabuf_tailroom(resp) >=
- wpabuf_len(wpa_s->global->wfd_subelem[*pos])) {
- wpa_printf(MSG_DEBUG, "P2P: Add WSD response "
- "subelement %u", *pos);
- wpabuf_put_buf(resp, wpa_s->global->wfd_subelem[*pos]);
- }
- pos++;
- }
-
- WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
-}
-#endif /* CONFIG_WIFI_DISPLAY */
-
-
-static int find_p2ps_substr(struct p2ps_advertisement *adv_data,
- const u8 *needle, size_t needle_len)
-{
- const u8 *haystack = (const u8 *) adv_data->svc_info;
- size_t haystack_len, i;
-
- /* Allow search term to be empty */
- if (!needle || !needle_len)
- return 1;
-
- if (!haystack)
- return 0;
-
- haystack_len = os_strlen(adv_data->svc_info);
- for (i = 0; i < haystack_len; i++) {
- if (haystack_len - i < needle_len)
- break;
- if (os_memcmp(haystack + i, needle, needle_len) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static void wpas_sd_req_asp(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id,
- const u8 *query, size_t query_len)
-{
- struct p2ps_advertisement *adv_data;
- const u8 *svc = &query[1];
- const u8 *info = NULL;
- size_t svc_len = query[0];
- size_t info_len = 0;
- int prefix = 0;
- u8 *count_pos = NULL;
- u8 *len_pos = NULL;
-
- wpa_hexdump(MSG_DEBUG, "P2P: SD Request for ASP", query, query_len);
-
- if (!wpa_s->global->p2p) {
- wpa_printf(MSG_DEBUG, "P2P: ASP protocol not available");
- wpas_sd_add_proto_not_avail(resp, P2P_SERV_P2PS, srv_trans_id);
- return;
- }
-
- /* Info block is optional */
- if (svc_len + 1 < query_len) {
- info = &svc[svc_len];
- info_len = *info++;
- }
-
- /* Range check length of svc string and info block */
- if (svc_len + (info_len ? info_len + 2 : 1) > query_len) {
- wpa_printf(MSG_DEBUG, "P2P: ASP bad request");
- wpas_sd_add_bad_request(resp, P2P_SERV_P2PS, srv_trans_id);
- return;
- }
-
- /* Detect and correct for prefix search */
- if (svc_len && svc[svc_len - 1] == '*') {
- prefix = 1;
- svc_len--;
- }
-
- for (adv_data = p2p_get_p2ps_adv_list(wpa_s->global->p2p);
- adv_data; adv_data = adv_data->next) {
- /* If not a prefix match, reject length mismatches */
- if (!prefix && svc_len != os_strlen(adv_data->svc_name))
- continue;
-
- /* Search each service for request */
- if (os_memcmp(adv_data->svc_name, svc, svc_len) == 0 &&
- find_p2ps_substr(adv_data, info, info_len)) {
- size_t len = os_strlen(adv_data->svc_name);
- size_t svc_info_len = 0;
-
- if (adv_data->svc_info)
- svc_info_len = os_strlen(adv_data->svc_info);
-
- if (len > 0xff || svc_info_len > 0xffff)
- return;
-
- /* Length & Count to be filled as we go */
- if (!len_pos && !count_pos) {
- if (wpabuf_tailroom(resp) <
- len + svc_info_len + 16)
- return;
-
- len_pos = wpabuf_put(resp, 2);
- wpabuf_put_u8(resp, P2P_SERV_P2PS);
- wpabuf_put_u8(resp, srv_trans_id);
- /* Status Code */
- wpabuf_put_u8(resp, P2P_SD_SUCCESS);
- count_pos = wpabuf_put(resp, 1);
- *count_pos = 0;
- } else if (wpabuf_tailroom(resp) <
- len + svc_info_len + 10)
- return;
-
- if (svc_info_len) {
- wpa_printf(MSG_DEBUG,
- "P2P: Add Svc: %s info: %s",
- adv_data->svc_name,
- adv_data->svc_info);
- } else {
- wpa_printf(MSG_DEBUG, "P2P: Add Svc: %s",
- adv_data->svc_name);
- }
-
- /* Advertisement ID */
- wpabuf_put_le32(resp, adv_data->id);
-
- /* Config Methods */
- wpabuf_put_be16(resp, adv_data->config_methods);
-
- /* Service Name */
- wpabuf_put_u8(resp, (u8) len);
- wpabuf_put_data(resp, adv_data->svc_name, len);
-
- /* Service State */
- wpabuf_put_u8(resp, adv_data->state);
-
- /* Service Information */
- wpabuf_put_le16(resp, (u16) svc_info_len);
- wpabuf_put_data(resp, adv_data->svc_info, svc_info_len);
-
- /* Update length and count */
- (*count_pos)++;
- WPA_PUT_LE16(len_pos,
- (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
- }
- }
-
- /* Return error if no matching svc found */
- if (count_pos == NULL) {
- wpa_printf(MSG_DEBUG, "P2P: ASP service not found");
- wpas_sd_add_not_found(resp, P2P_SERV_P2PS, srv_trans_id);
- }
-}
-
-
-static void wpas_sd_all_asp(struct wpa_supplicant *wpa_s,
- struct wpabuf *resp, u8 srv_trans_id)
-{
- /* Query data to add all P2PS advertisements:
- * - Service name length: 1
- * - Service name: '*'
- * - Service Information Request Length: 0
- */
- const u8 q[] = { 1, (const u8) '*', 0 };
-
- if (p2p_get_p2ps_adv_list(wpa_s->global->p2p))
- wpas_sd_req_asp(wpa_s, resp, srv_trans_id, q, sizeof(q));
-}
-
-
-void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
- u16 update_indic, const u8 *tlvs, size_t tlvs_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const u8 *pos = tlvs;
- const u8 *end = tlvs + tlvs_len;
- const u8 *tlv_end;
- u16 slen;
- struct wpabuf *resp;
- u8 srv_proto, srv_trans_id;
- size_t buf_len;
- char *buf;
-
- wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Request TLVs",
- tlvs, tlvs_len);
- buf_len = 2 * tlvs_len + 1;
- buf = os_malloc(buf_len);
- if (buf) {
- wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
- wpa_msg_ctrl(wpa_s, MSG_INFO, P2P_EVENT_SERV_DISC_REQ "%d "
- MACSTR " %u %u %s",
- freq, MAC2STR(sa), dialog_token, update_indic,
- buf);
- os_free(buf);
- }
-
- if (wpa_s->p2p_sd_over_ctrl_iface) {
- wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
- update_indic, tlvs, tlvs_len);
- return; /* to be processed by an external program */
- }
-
- resp = wpabuf_alloc(10000);
- if (resp == NULL)
- return;
-
- while (end - pos > 1) {
- wpa_printf(MSG_DEBUG, "P2P: Service Request TLV");
- slen = WPA_GET_LE16(pos);
- pos += 2;
- if (slen > end - pos || slen < 2) {
- wpa_printf(MSG_DEBUG, "P2P: Unexpected Query Data "
- "length");
- wpabuf_free(resp);
- return;
- }
- tlv_end = pos + slen;
-
- srv_proto = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
- srv_proto);
- srv_trans_id = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
- srv_trans_id);
-
- wpa_hexdump(MSG_MSGDUMP, "P2P: Query Data",
- pos, tlv_end - pos);
-
-
- if (wpa_s->force_long_sd) {
- wpa_printf(MSG_DEBUG, "P2P: SD test - force long "
- "response");
- wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
- wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
- wpas_sd_all_asp(wpa_s, resp, srv_trans_id);
- goto done;
- }
-
- switch (srv_proto) {
- case P2P_SERV_ALL_SERVICES:
- wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request "
- "for all services");
- if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) &&
- dl_list_empty(&wpa_s->global->p2p_srv_bonjour) &&
- !p2p_get_p2ps_adv_list(wpa_s->global->p2p)) {
- wpa_printf(MSG_DEBUG, "P2P: No service "
- "discovery protocols available");
- wpas_sd_add_proto_not_avail(
- resp, P2P_SERV_ALL_SERVICES,
- srv_trans_id);
- break;
- }
- wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
- wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
- wpas_sd_all_asp(wpa_s, resp, srv_trans_id);
- break;
- case P2P_SERV_BONJOUR:
- wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id,
- pos, tlv_end - pos);
- break;
- case P2P_SERV_UPNP:
- wpas_sd_req_upnp(wpa_s, resp, srv_trans_id,
- pos, tlv_end - pos);
- break;
-#ifdef CONFIG_WIFI_DISPLAY
- case P2P_SERV_WIFI_DISPLAY:
- wpas_sd_req_wfd(wpa_s, resp, srv_trans_id,
- pos, tlv_end - pos);
- break;
-#endif /* CONFIG_WIFI_DISPLAY */
- case P2P_SERV_P2PS:
- wpas_sd_req_asp(wpa_s, resp, srv_trans_id,
- pos, tlv_end - pos);
- break;
- default:
- wpa_printf(MSG_DEBUG, "P2P: Unavailable service "
- "protocol %u", srv_proto);
- wpas_sd_add_proto_not_avail(resp, srv_proto,
- srv_trans_id);
- break;
- }
-
- pos = tlv_end;
- }
-
-done:
- wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
- update_indic, tlvs, tlvs_len);
-
- wpas_p2p_sd_response(wpa_s, freq, sa, dialog_token, resp);
-
- wpabuf_free(resp);
-}
-
-
-static void wpas_sd_p2ps_serv_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, u8 srv_trans_id,
- const u8 *pos, const u8 *tlv_end)
-{
- u8 left = *pos++;
- u32 adv_id;
- u8 svc_status;
- u16 config_methods;
- char svc_str[256];
-
- while (left-- && pos < tlv_end) {
- char *buf = NULL;
- size_t buf_len;
- u8 svc_len;
-
- /* Validity check fixed length+svc_str */
- if (6 >= tlv_end - pos)
- break;
- svc_len = pos[6];
- if (svc_len + 10 > tlv_end - pos)
- break;
-
- /* Advertisement ID */
- adv_id = WPA_GET_LE32(pos);
- pos += sizeof(u32);
-
- /* Config Methods */
- config_methods = WPA_GET_BE16(pos);
- pos += sizeof(u16);
-
- /* Service Name */
- pos++; /* svc_len */
- os_memcpy(svc_str, pos, svc_len);
- svc_str[svc_len] = '\0';
- pos += svc_len;
-
- /* Service Status */
- svc_status = *pos++;
-
- /* Service Information Length */
- buf_len = WPA_GET_LE16(pos);
- pos += sizeof(u16);
-
- /* Validity check buffer length */
- if (buf_len > (unsigned int) (tlv_end - pos))
- break;
-
- if (buf_len) {
- buf = os_zalloc(2 * buf_len + 1);
- if (buf) {
- utf8_escape((const char *) pos, buf_len, buf,
- 2 * buf_len + 1);
- }
- }
-
- pos += buf_len;
-
- if (buf) {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_SERV_ASP_RESP
- MACSTR " %x %x %x %x %s '%s'",
- MAC2STR(sa), srv_trans_id, adv_id,
- svc_status, config_methods, svc_str,
- buf);
- os_free(buf);
- } else {
- wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_SERV_ASP_RESP
- MACSTR " %x %x %x %x %s",
- MAC2STR(sa), srv_trans_id, adv_id,
- svc_status, config_methods, svc_str);
- }
- }
-}
-
-
-void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
- const u8 *tlvs, size_t tlvs_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const u8 *pos = tlvs;
- const u8 *end = tlvs + tlvs_len;
- const u8 *tlv_end;
- u16 slen;
- size_t buf_len;
- char *buf;
-
- wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Response TLVs",
- tlvs, tlvs_len);
- if (tlvs_len > 1500) {
- /* TODO: better way for handling this */
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- P2P_EVENT_SERV_DISC_RESP MACSTR
- " %u <long response: %u bytes>",
- MAC2STR(sa), update_indic,
- (unsigned int) tlvs_len);
- } else {
- buf_len = 2 * tlvs_len + 1;
- buf = os_malloc(buf_len);
- if (buf) {
- wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
- wpa_msg_ctrl(wpa_s, MSG_INFO,
- P2P_EVENT_SERV_DISC_RESP MACSTR " %u %s",
- MAC2STR(sa), update_indic, buf);
- os_free(buf);
- }
- }
-
- while (end - pos >= 2) {
- u8 srv_proto, srv_trans_id, status;
-
- wpa_printf(MSG_DEBUG, "P2P: Service Response TLV");
- slen = WPA_GET_LE16(pos);
- pos += 2;
- if (slen > end - pos || slen < 3) {
- wpa_printf(MSG_DEBUG, "P2P: Unexpected Response Data "
- "length");
- return;
- }
- tlv_end = pos + slen;
-
- srv_proto = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
- srv_proto);
- srv_trans_id = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
- srv_trans_id);
- status = *pos++;
- wpa_printf(MSG_DEBUG, "P2P: Status Code ID %u",
- status);
-
- wpa_hexdump(MSG_MSGDUMP, "P2P: Response Data",
- pos, tlv_end - pos);
-
- if (srv_proto == P2P_SERV_P2PS && pos < tlv_end) {
- wpas_sd_p2ps_serv_response(wpa_s, sa, srv_trans_id,
- pos, tlv_end);
- }
-
- pos = tlv_end;
- }
-
- wpas_notify_p2p_sd_response(wpa_s, sa, update_indic, tlvs, tlvs_len);
-}
-
-
-u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *tlvs)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return 0;
- return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs);
-}
-
-
-u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
- u8 version, const char *query)
-{
- struct wpabuf *tlvs;
- u64 ret;
-
- tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query));
- if (tlvs == NULL)
- return 0;
- wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query));
- wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */
- wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */
- wpabuf_put_u8(tlvs, version);
- wpabuf_put_str(tlvs, query);
- ret = wpas_p2p_sd_request(wpa_s, dst, tlvs);
- wpabuf_free(tlvs);
- return ret;
-}
-
-
-u64 wpas_p2p_sd_request_asp(struct wpa_supplicant *wpa_s, const u8 *dst, u8 id,
- const char *svc_str, const char *info_substr)
-{
- struct wpabuf *tlvs;
- size_t plen, svc_len, substr_len = 0;
- u64 ret;
-
- svc_len = os_strlen(svc_str);
- if (info_substr)
- substr_len = os_strlen(info_substr);
-
- if (svc_len > 0xff || substr_len > 0xff)
- return 0;
-
- plen = 1 + 1 + 1 + svc_len + 1 + substr_len;
- tlvs = wpabuf_alloc(2 + plen);
- if (tlvs == NULL)
- return 0;
-
- wpabuf_put_le16(tlvs, plen);
- wpabuf_put_u8(tlvs, P2P_SERV_P2PS);
- wpabuf_put_u8(tlvs, id); /* Service Transaction ID */
- wpabuf_put_u8(tlvs, (u8) svc_len); /* Service String Length */
- wpabuf_put_data(tlvs, svc_str, svc_len);
- wpabuf_put_u8(tlvs, (u8) substr_len); /* Info Substring Length */
- wpabuf_put_data(tlvs, info_substr, substr_len);
- ret = wpas_p2p_sd_request(wpa_s, dst, tlvs);
- wpabuf_free(tlvs);
-
- return ret;
-}
-
-
-#ifdef CONFIG_WIFI_DISPLAY
-
-static u64 wpas_p2p_sd_request_wfd(struct wpa_supplicant *wpa_s, const u8 *dst,
- const struct wpabuf *tlvs)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return 0;
- return (uintptr_t) p2p_sd_request_wfd(wpa_s->global->p2p, dst, tlvs);
-}
-
-
-#define MAX_WFD_SD_SUBELEMS 20
-
-static void wfd_add_sd_req_role(struct wpabuf *tlvs, u8 id, u8 role,
- const char *subelems)
-{
- u8 *len;
- const char *pos;
- int val;
- int count = 0;
-
- len = wpabuf_put(tlvs, 2);
- wpabuf_put_u8(tlvs, P2P_SERV_WIFI_DISPLAY); /* Service Protocol Type */
- wpabuf_put_u8(tlvs, id); /* Service Transaction ID */
-
- wpabuf_put_u8(tlvs, role);
-
- pos = subelems;
- while (*pos) {
- val = atoi(pos);
- if (val >= 0 && val < 256) {
- wpabuf_put_u8(tlvs, val);
- count++;
- if (count == MAX_WFD_SD_SUBELEMS)
- break;
- }
- pos = os_strchr(pos + 1, ',');
- if (pos == NULL)
- break;
- pos++;
- }
-
- WPA_PUT_LE16(len, (u8 *) wpabuf_put(tlvs, 0) - len - 2);
-}
-
-
-u64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s,
- const u8 *dst, const char *role)
-{
- struct wpabuf *tlvs;
- u64 ret;
- const char *subelems;
- u8 id = 1;
-
- subelems = os_strchr(role, ' ');
- if (subelems == NULL)
- return 0;
- subelems++;
-
- tlvs = wpabuf_alloc(4 * (2 + 1 + 1 + 1 + MAX_WFD_SD_SUBELEMS));
- if (tlvs == NULL)
- return 0;
-
- if (os_strstr(role, "[source]"))
- wfd_add_sd_req_role(tlvs, id++, 0x00, subelems);
- if (os_strstr(role, "[pri-sink]"))
- wfd_add_sd_req_role(tlvs, id++, 0x01, subelems);
- if (os_strstr(role, "[sec-sink]"))
- wfd_add_sd_req_role(tlvs, id++, 0x02, subelems);
- if (os_strstr(role, "[source+sink]"))
- wfd_add_sd_req_role(tlvs, id++, 0x03, subelems);
-
- ret = wpas_p2p_sd_request_wfd(wpa_s, dst, tlvs);
- wpabuf_free(tlvs);
- return ret;
-}
-
-#endif /* CONFIG_WIFI_DISPLAY */
-
-
-int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return -1;
- return p2p_sd_cancel_request(wpa_s->global->p2p,
- (void *) (uintptr_t) req);
-}
-
-
-void wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq,
- const u8 *dst, u8 dialog_token,
- const struct wpabuf *resp_tlvs)
-{
- if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
- return;
- p2p_sd_response(wpa_s->global->p2p, freq, dst, dialog_token,
- resp_tlvs);
-}
-
-
-void wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->global->p2p)
- p2p_sd_service_update(wpa_s->global->p2p);
-}
-
-
-static void wpas_p2p_srv_bonjour_free(struct p2p_srv_bonjour *bsrv)
-{
- dl_list_del(&bsrv->list);
- wpabuf_free(bsrv->query);
- wpabuf_free(bsrv->resp);
- os_free(bsrv);
-}
-
-
-static void wpas_p2p_srv_upnp_free(struct p2p_srv_upnp *usrv)
-{
- dl_list_del(&usrv->list);
- os_free(usrv->service);
- os_free(usrv);
-}
-
-
-void wpas_p2p_service_flush(struct wpa_supplicant *wpa_s)
-{
- struct p2p_srv_bonjour *bsrv, *bn;
- struct p2p_srv_upnp *usrv, *un;
-
- dl_list_for_each_safe(bsrv, bn, &wpa_s->global->p2p_srv_bonjour,
- struct p2p_srv_bonjour, list)
- wpas_p2p_srv_bonjour_free(bsrv);
-
- dl_list_for_each_safe(usrv, un, &wpa_s->global->p2p_srv_upnp,
- struct p2p_srv_upnp, list)
- wpas_p2p_srv_upnp_free(usrv);
-
- wpas_p2p_service_flush_asp(wpa_s);
- wpas_p2p_sd_service_update(wpa_s);
-}
-
-
-int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id)
-{
- if (adv_id == 0)
- return 1;
-
- if (p2p_service_p2ps_id(wpa_s->global->p2p, adv_id))
- return 1;
-
- return 0;
-}
-
-
-int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id)
-{
- int ret;
-
- ret = p2p_service_del_asp(wpa_s->global->p2p, adv_id);
- if (ret == 0)
- wpas_p2p_sd_service_update(wpa_s);
- return ret;
-}
-
-
-int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s,
- int auto_accept, u32 adv_id,
- const char *adv_str, u8 svc_state,
- u16 config_methods, const char *svc_info,
- const u8 *cpt_priority)
-{
- int ret;
-
- ret = p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id,
- adv_str, svc_state, config_methods,
- svc_info, cpt_priority);
- if (ret == 0)
- wpas_p2p_sd_service_update(wpa_s);
- return ret;
-}
-
-
-void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s)
-{
- p2p_service_flush_asp(wpa_s->global->p2p);
-}
-
-
-int wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s,
- struct wpabuf *query, struct wpabuf *resp)
-{
- struct p2p_srv_bonjour *bsrv;
-
- bsrv = os_zalloc(sizeof(*bsrv));
- if (bsrv == NULL)
- return -1;
- bsrv->query = query;
- bsrv->resp = resp;
- dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list);
-
- wpas_p2p_sd_service_update(wpa_s);
- return 0;
-}
-
-
-int wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s,
- const struct wpabuf *query)
-{
- struct p2p_srv_bonjour *bsrv;
-
- bsrv = wpas_p2p_service_get_bonjour(wpa_s, query);
- if (bsrv == NULL)
- return -1;
- wpas_p2p_srv_bonjour_free(bsrv);
- wpas_p2p_sd_service_update(wpa_s);
- return 0;
-}
-
-
-int wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version,
- const char *service)
-{
- struct p2p_srv_upnp *usrv;
-
- if (wpas_p2p_service_get_upnp(wpa_s, version, service))
- return 0; /* Already listed */
- usrv = os_zalloc(sizeof(*usrv));
- if (usrv == NULL)
- return -1;
- usrv->version = version;
- usrv->service = os_strdup(service);
- if (usrv->service == NULL) {
- os_free(usrv);
- return -1;
- }
- dl_list_add(&wpa_s->global->p2p_srv_upnp, &usrv->list);
-
- wpas_p2p_sd_service_update(wpa_s);
- return 0;
-}
-
-
-int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
- const char *service)
-{
- struct p2p_srv_upnp *usrv;
-
- usrv = wpas_p2p_service_get_upnp(wpa_s, version, service);
- if (usrv == NULL)
- return -1;
- wpas_p2p_srv_upnp_free(usrv);
- wpas_p2p_sd_service_update(wpa_s);
- return 0;
-}
diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
deleted file mode 100644
index baf4c2643e42..000000000000
--- a/wpa_supplicant/pasn_supplicant.c
+++ /dev/null
@@ -1,1710 +0,0 @@
-/*
- * wpa_supplicant - PASN processing
- *
- * Copyright (C) 2019 Intel Corporation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/dragonfly.h"
-#include "common/ptksa_cache.h"
-#include "utils/eloop.h"
-#include "drivers/driver.h"
-#include "crypto/crypto.h"
-#include "crypto/random.h"
-#include "eap_common/eap_defs.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "bss.h"
-#include "config.h"
-
-static const int dot11RSNAConfigPMKLifetime = 43200;
-
-struct wpa_pasn_auth_work {
- u8 bssid[ETH_ALEN];
- int akmp;
- int cipher;
- u16 group;
- int network_id;
- struct wpabuf *comeback;
-};
-
-
-static void wpas_pasn_free_auth_work(struct wpa_pasn_auth_work *awork)
-{
- wpabuf_free(awork->comeback);
- awork->comeback = NULL;
- os_free(awork);
-}
-
-
-static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
-
- wpas_pasn_auth_stop(wpa_s);
-}
-
-
-static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
-
- /* Remove pending/started work */
- radio_remove_works(wpa_s, "pasn-start-auth", 0);
-}
-
-
-static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int akmp, int cipher, u8 status,
- struct wpabuf *comeback,
- u16 comeback_after)
-{
- if (comeback) {
- size_t comeback_len = wpabuf_len(comeback);
- size_t buflen = comeback_len * 2 + 1;
- char *comeback_txt = os_malloc(buflen);
-
- if (comeback_txt) {
- wpa_snprintf_hex(comeback_txt, buflen,
- wpabuf_head(comeback), comeback_len);
-
- wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
- " akmp=%s, status=%u comeback_after=%u comeback=%s",
- MAC2STR(bssid),
- wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
- status, comeback_after, comeback_txt);
-
- os_free(comeback_txt);
- return;
- }
- }
-
- wpa_msg(wpa_s, MSG_INFO,
- PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
- MAC2STR(bssid), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
- status);
-}
-
-
-#ifdef CONFIG_SAE
-
-static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpabuf *buf = NULL;
- int ret;
-
- ret = sae_set_group(&pasn->sae, pasn->group);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
- return NULL;
- }
-
- ret = sae_prepare_commit_pt(&pasn->sae, pasn->ssid->pt,
- wpa_s->own_addr, pasn->bssid,
- NULL, NULL);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
- return NULL;
- }
-
- /* Need to add the entire Authentication frame body */
- buf = wpabuf_alloc(6 + SAE_COMMIT_MAX_LEN);
- if (!buf) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
- return NULL;
- }
-
- wpabuf_put_le16(buf, WLAN_AUTH_SAE);
- wpabuf_put_le16(buf, 1);
- wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
-
- sae_write_commit(&pasn->sae, buf, NULL, 0);
- pasn->sae.state = SAE_COMMITTED;
-
- return buf;
-}
-
-
-static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- const u8 *data;
- size_t buf_len;
- u16 len, res, alg, seq, status;
- int groups[] = { pasn->group, 0 };
- int ret;
-
- if (!wd)
- return -1;
-
- data = wpabuf_head_u8(wd);
- buf_len = wpabuf_len(wd);
-
- /* first handle the commit message */
- if (buf_len < 2) {
- wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (commit)");
- return -1;
- }
-
- len = WPA_GET_LE16(data);
- if (len < 6 || buf_len - 2 < len) {
- wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for commit");
- return -1;
- }
-
- buf_len -= 2;
- data += 2;
-
- alg = WPA_GET_LE16(data);
- seq = WPA_GET_LE16(data + 2);
- status = WPA_GET_LE16(data + 4);
-
- wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
- alg, seq, status);
-
- if (alg != WLAN_AUTH_SAE || seq != 1 ||
- status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
- wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
- return -1;
- }
-
- res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
- 1);
- if (res != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
- return -1;
- }
-
- /* Process the commit message and derive the PMK */
- ret = sae_process_commit(&pasn->sae);
- if (ret) {
- wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
- return -1;
- }
-
- buf_len -= len;
- data += len;
-
- /* Handle the confirm message */
- if (buf_len < 2) {
- wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (confirm)");
- return -1;
- }
-
- len = WPA_GET_LE16(data);
- if (len < 6 || buf_len - 2 < len) {
- wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for confirm");
- return -1;
- }
-
- buf_len -= 2;
- data += 2;
-
- alg = WPA_GET_LE16(data);
- seq = WPA_GET_LE16(data + 2);
- status = WPA_GET_LE16(data + 4);
-
- wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
- alg, seq, status);
-
- if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
- return -1;
- }
-
- res = sae_check_confirm(&pasn->sae, data + 6, len - 6);
- if (res != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "PASN: SAE completed successfully");
- pasn->sae.state = SAE_ACCEPTED;
-
- return 0;
-}
-
-
-static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpabuf *buf = NULL;
-
- /* Need to add the entire authentication frame body */
- buf = wpabuf_alloc(6 + SAE_CONFIRM_MAX_LEN);
- if (!buf) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
- return NULL;
- }
-
- wpabuf_put_le16(buf, WLAN_AUTH_SAE);
- wpabuf_put_le16(buf, 2);
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
-
- sae_write_confirm(&pasn->sae, buf);
- pasn->sae.state = SAE_CONFIRMED;
-
- return buf;
-}
-
-
-static int wpas_pasn_sae_setup_pt(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int group)
-{
- const char *password = ssid->sae_password;
- int groups[2] = { group, 0 };
-
- if (!password)
- password = ssid->passphrase;
-
- if (!password) {
- wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
- return -1;
- }
-
- if (ssid->pt)
- return 0; /* PT already derived */
-
- ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
- (const u8 *) password, os_strlen(password),
- ssid->sae_password_id);
-
- return ssid->pt ? 0 : -1;
-}
-
-#endif /* CONFIG_SAE */
-
-
-#ifdef CONFIG_FILS
-
-static struct wpabuf * wpas_pasn_fils_build_auth(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpabuf *buf = NULL;
- struct wpabuf *erp_msg;
- int ret;
-
- erp_msg = eapol_sm_build_erp_reauth_start(wpa_s->eapol);
- if (!erp_msg) {
- wpa_printf(MSG_DEBUG,
- "PASN: FILS: ERP EAP-Initiate/Re-auth unavailable");
- return NULL;
- }
-
- if (random_get_bytes(pasn->fils.nonce, FILS_NONCE_LEN) < 0 ||
- random_get_bytes(pasn->fils.session, FILS_SESSION_LEN) < 0)
- goto fail;
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", pasn->fils.nonce,
- FILS_NONCE_LEN);
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", pasn->fils.session,
- FILS_SESSION_LEN);
-
- buf = wpabuf_alloc(1500);
- if (!buf)
- goto fail;
-
- /* Add the authentication algorithm */
- wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
-
- /* Authentication Transaction seq# */
- wpabuf_put_le16(buf, 1);
-
- /* Status Code */
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
-
- /* Own RSNE */
- wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
-
- /* FILS Nonce */
- wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
- wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
- wpabuf_put_data(buf, pasn->fils.nonce, FILS_NONCE_LEN);
-
- /* FILS Session */
- wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
- wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
- wpabuf_put_data(buf, pasn->fils.session, FILS_SESSION_LEN);
-
- /* Wrapped Data (ERP) */
- wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg));
- wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
- wpabuf_put_buf(buf, erp_msg);
-
- /*
- * Calculate pending PMKID here so that we do not need to maintain a
- * copy of the EAP-Initiate/Reauth message.
- */
- ret = fils_pmkid_erp(pasn->akmp, wpabuf_head(erp_msg),
- wpabuf_len(erp_msg),
- pasn->fils.erp_pmkid);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ERP PMKID");
- goto fail;
- }
-
- wpabuf_free(erp_msg);
- erp_msg = NULL;
-
- wpa_hexdump_buf(MSG_DEBUG, "PASN: FILS: Authentication frame", buf);
- return buf;
-fail:
- wpabuf_free(erp_msg);
- wpabuf_free(buf);
- return NULL;
-}
-
-
-static void wpas_pasn_initiate_eapol(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct eapol_config eapol_conf;
- struct wpa_ssid *ssid = pasn->ssid;
-
- wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
-
- eapol_sm_notify_eap_success(wpa_s->eapol, false);
- eapol_sm_notify_eap_fail(wpa_s->eapol, false);
- eapol_sm_notify_portControl(wpa_s->eapol, Auto);
-
- os_memset(&eapol_conf, 0, sizeof(eapol_conf));
- eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
- eapol_conf.workaround = ssid->eap_workaround;
-
- eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
-}
-
-
-static struct wpabuf * wpas_pasn_wd_fils_auth(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpa_bss *bss;
- const u8 *indic;
- u16 fils_info;
-
- wpa_printf(MSG_DEBUG, "PASN: FILS: wrapped data - completed=%u",
- pasn->fils.completed);
-
- /* Nothing to add as we are done */
- if (pasn->fils.completed)
- return NULL;
-
- if (!pasn->ssid) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
- return NULL;
- }
-
- bss = wpa_bss_get_bssid(wpa_s, pasn->bssid);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: BSS not found");
- return NULL;
- }
-
- indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
- if (!indic || indic[1] < 2) {
- wpa_printf(MSG_DEBUG, "PASN: Missing FILS Indication IE");
- return NULL;
- }
-
- fils_info = WPA_GET_LE16(indic + 2);
- if (!(fils_info & BIT(9))) {
- wpa_printf(MSG_DEBUG,
- "PASN: FILS auth without PFS not supported");
- return NULL;
- }
-
- wpas_pasn_initiate_eapol(wpa_s);
-
- return wpas_pasn_fils_build_auth(wpa_s);
-}
-
-
-static int wpas_pasn_wd_fils_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct ieee802_11_elems elems;
- struct wpa_ie_data rsne_data;
- u8 rmsk[ERP_MAX_KEY_LEN];
- size_t rmsk_len;
- u8 anonce[FILS_NONCE_LEN];
- const u8 *data;
- size_t buf_len;
- struct wpabuf *fils_wd = NULL;
- u16 alg, seq, status;
- int ret;
-
- if (!wd)
- return -1;
-
- data = wpabuf_head(wd);
- buf_len = wpabuf_len(wd);
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: Authentication frame len=%zu",
- data, buf_len);
-
- /* first handle the header */
- if (buf_len < 6) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short");
- return -1;
- }
-
- alg = WPA_GET_LE16(data);
- seq = WPA_GET_LE16(data + 2);
- status = WPA_GET_LE16(data + 4);
-
- wpa_printf(MSG_DEBUG, "PASN: FILS: commit: alg=%u, seq=%u, status=%u",
- alg, seq, status);
-
- if (alg != WLAN_AUTH_FILS_SK || seq != 2 ||
- status != WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG,
- "PASN: FILS: Dropping peer authentication");
- return -1;
- }
-
- data += 6;
- buf_len -= 6;
-
- if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
- return -1;
- }
-
- if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
- !elems.wrapped_data) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
- return -1;
- }
-
- ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
- &rsne_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
- return -1;
- }
-
- ret = wpa_pasn_validate_rsne(&rsne_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
- return -1;
- }
-
- if (rsne_data.num_pmkid) {
- wpa_printf(MSG_DEBUG,
- "PASN: FILS: Not expecting PMKID in RSNE");
- return -1;
- }
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: ANonce", elems.fils_nonce,
- FILS_NONCE_LEN);
- os_memcpy(anonce, elems.fils_nonce, FILS_NONCE_LEN);
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: FILS Session", elems.fils_session,
- FILS_SESSION_LEN);
-
- if (os_memcmp(pasn->fils.session, elems.fils_session,
- FILS_SESSION_LEN)) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Session mismatch");
- return -1;
- }
-
- fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
- WLAN_EID_EXT_WRAPPED_DATA);
-
- if (!fils_wd) {
- wpa_printf(MSG_DEBUG,
- "PASN: FILS: Failed getting wrapped data");
- return -1;
- }
-
- eapol_sm_process_erp_finish(wpa_s->eapol, wpabuf_head(fils_wd),
- wpabuf_len(fils_wd));
-
- wpabuf_free(fils_wd);
- fils_wd = NULL;
-
- if (eapol_sm_failed(wpa_s->eapol)) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: ERP finish failed");
- return -1;
- }
-
- rmsk_len = ERP_MAX_KEY_LEN;
- ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
-
- if (ret == PMK_LEN) {
- rmsk_len = PMK_LEN;
- ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
- }
-
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Failed getting RMSK");
- return -1;
- }
-
- ret = fils_rmsk_to_pmk(pasn->akmp, rmsk, rmsk_len,
- pasn->fils.nonce, anonce, NULL, 0,
- pasn->pmk, &pasn->pmk_len);
-
- forced_memzero(rmsk, sizeof(rmsk));
-
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PMK");
- return -1;
- }
-
- wpa_hexdump(MSG_DEBUG, "PASN: FILS: PMKID", pasn->fils.erp_pmkid,
- PMKID_LEN);
-
- wpa_printf(MSG_DEBUG, "PASN: FILS: ERP processing succeeded");
-
- wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
- pasn->pmk_len, pasn->fils.erp_pmkid,
- pasn->bssid, pasn->akmp);
-
- pasn->fils.completed = true;
- return 0;
-}
-
-#endif /* CONFIG_FILS */
-
-
-static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
-
- if (pasn->using_pmksa)
- return NULL;
-
- switch (pasn->akmp) {
- case WPA_KEY_MGMT_PASN:
- /* no wrapped data */
- return NULL;
- case WPA_KEY_MGMT_SAE:
-#ifdef CONFIG_SAE
- if (pasn->trans_seq == 0)
- return wpas_pasn_wd_sae_commit(wpa_s);
- if (pasn->trans_seq == 2)
- return wpas_pasn_wd_sae_confirm(wpa_s);
-#endif /* CONFIG_SAE */
- wpa_printf(MSG_ERROR,
- "PASN: SAE: Cannot derive wrapped data");
- return NULL;
- case WPA_KEY_MGMT_FILS_SHA256:
- case WPA_KEY_MGMT_FILS_SHA384:
-#ifdef CONFIG_FILS
- return wpas_pasn_wd_fils_auth(wpa_s);
-#endif /* CONFIG_FILS */
- case WPA_KEY_MGMT_FT_PSK:
- case WPA_KEY_MGMT_FT_IEEE8021X:
- case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
- /*
- * Wrapped data with these AKMs is optional and is only needed
- * for further validation of FT security parameters. For now do
- * not use them.
- */
- return NULL;
- default:
- wpa_printf(MSG_ERROR,
- "PASN: TODO: Wrapped data for akmp=0x%x",
- pasn->akmp);
- return NULL;
- }
-}
-
-
-static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
-{
- if (pasn->using_pmksa)
- return WPA_PASN_WRAPPED_DATA_NO;
-
- /* Note: Valid AKMP is expected to already be validated */
- switch (pasn->akmp) {
- case WPA_KEY_MGMT_SAE:
- return WPA_PASN_WRAPPED_DATA_SAE;
- case WPA_KEY_MGMT_FILS_SHA256:
- case WPA_KEY_MGMT_FILS_SHA384:
- return WPA_PASN_WRAPPED_DATA_FILS_SK;
- case WPA_KEY_MGMT_FT_PSK:
- case WPA_KEY_MGMT_FT_IEEE8021X:
- case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
- /*
- * Wrapped data with these AKMs is optional and is only needed
- * for further validation of FT security parameters. For now do
- * not use them.
- */
- return WPA_PASN_WRAPPED_DATA_NO;
- case WPA_KEY_MGMT_PASN:
- default:
- return WPA_PASN_WRAPPED_DATA_NO;
- }
-}
-
-
-static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s,
- const struct wpabuf *comeback)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
- const u8 *pmkid;
- u8 wrapped_data;
- int ret;
- u16 capab;
-
- wpa_printf(MSG_DEBUG, "PASN: Building frame 1");
-
- if (pasn->trans_seq)
- return NULL;
-
- buf = wpabuf_alloc(1500);
- if (!buf)
- goto fail;
-
- /* Get public key */
- pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
- pubkey = wpabuf_zeropad(pubkey, crypto_ecdh_prime_len(pasn->ecdh));
- if (!pubkey) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
- goto fail;
- }
-
- wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
-
- wpa_pasn_build_auth_header(buf, pasn->bssid,
- wpa_s->own_addr, pasn->bssid,
- pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
-
- pmkid = NULL;
- if (wpa_key_mgmt_ft(pasn->akmp)) {
- ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, pasn->akmp,
- pasn->bssid,
- pasn->pmk_r1,
- &pasn->pmk_r1_len,
- pasn->pmk_r1_name);
- if (ret) {
- wpa_printf(MSG_DEBUG,
- "PASN: FT: Failed to derive keys");
- goto fail;
- }
-
- pmkid = pasn->pmk_r1_name;
- } else if (wrapped_data != WPA_PASN_WRAPPED_DATA_NO) {
- struct rsn_pmksa_cache_entry *pmksa;
-
- pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
- NULL, NULL, pasn->akmp);
- if (pmksa)
- pmkid = pmksa->pmkid;
-
- /*
- * Note: Even when PMKSA is available, also add wrapped data as
- * it is possible that the PMKID is no longer valid at the AP.
- */
- wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
- }
-
- if (wpa_pasn_add_rsne(buf, pmkid, pasn->akmp, pasn->cipher) < 0)
- goto fail;
-
- if (!wrapped_data_buf)
- wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
-
- wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
- pubkey, true, comeback, -1);
-
- if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
- goto fail;
-
- /* Add own RNSXE */
- capab = 0;
- capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
- capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
- capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)
- capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
- wpa_pasn_add_rsnxe(buf, capab);
-
- ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
- wpabuf_head_u8(buf) + IEEE80211_HDRLEN,
- wpabuf_len(buf) - IEEE80211_HDRLEN,
- pasn->hash);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
- goto fail;
- }
-
- pasn->trans_seq++;
-
- wpabuf_free(wrapped_data_buf);
- wpabuf_free(pubkey);
-
- wpa_printf(MSG_DEBUG, "PASN: Frame 1: Success");
- return buf;
-fail:
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- wpabuf_free(wrapped_data_buf);
- wpabuf_free(pubkey);
- wpabuf_free(buf);
- return NULL;
-}
-
-
-static struct wpabuf * wpas_pasn_build_auth_3(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpabuf *buf, *wrapped_data_buf = NULL;
- u8 mic[WPA_PASN_MAX_MIC_LEN];
- u8 mic_len, data_len;
- const u8 *data;
- u8 *ptr;
- u8 wrapped_data;
- int ret;
-
- wpa_printf(MSG_DEBUG, "PASN: Building frame 3");
-
- if (pasn->trans_seq != 2)
- return NULL;
-
- buf = wpabuf_alloc(1500);
- if (!buf)
- goto fail;
-
- wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
-
- wpa_pasn_build_auth_header(buf, pasn->bssid,
- wpa_s->own_addr, pasn->bssid,
- pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
-
- wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
-
- if (!wrapped_data_buf)
- wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
-
- wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
- NULL, false, NULL, -1);
-
- if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
- goto fail;
- wpabuf_free(wrapped_data_buf);
- wrapped_data_buf = NULL;
-
- /* Add the MIC */
- mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
- wpabuf_put_u8(buf, WLAN_EID_MIC);
- wpabuf_put_u8(buf, mic_len);
- ptr = wpabuf_put(buf, mic_len);
-
- os_memset(ptr, 0, mic_len);
-
- data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
- data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
-
- ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
- wpa_s->own_addr, pasn->bssid,
- pasn->hash, mic_len * 2, data, data_len, mic);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed MIC calculation");
- goto fail;
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->conf->pasn_corrupt_mic) {
- wpa_printf(MSG_DEBUG, "PASN: frame 3: Corrupt MIC");
- mic[0] = ~mic[0];
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- os_memcpy(ptr, mic, mic_len);
-
- pasn->trans_seq++;
-
- wpa_printf(MSG_DEBUG, "PASN: frame 3: Success");
- return buf;
-fail:
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- wpabuf_free(wrapped_data_buf);
- wpabuf_free(buf);
- return NULL;
-}
-
-
-static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
-
- wpa_printf(MSG_DEBUG, "PASN: Reset");
-
- crypto_ecdh_deinit(pasn->ecdh);
- pasn->ecdh = NULL;
-
- wpas_pasn_cancel_auth_work(wpa_s);
- wpa_s->pasn_auth_work = NULL;
-
- eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
-
- pasn->akmp = 0;
- pasn->cipher = 0;
- pasn->group = 0;
- pasn->trans_seq = 0;
- pasn->pmk_len = 0;
- pasn->using_pmksa = false;
-
- forced_memzero(pasn->pmk, sizeof(pasn->pmk));
- forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
- forced_memzero(&pasn->hash, sizeof(pasn->hash));
-
- wpabuf_free(pasn->beacon_rsne_rsnxe);
- pasn->beacon_rsne_rsnxe = NULL;
-
- wpabuf_free(pasn->comeback);
- pasn->comeback = NULL;
- pasn->comeback_after = 0;
-
-#ifdef CONFIG_SAE
- sae_clear_data(&pasn->sae);
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_FILS
- os_memset(&pasn->fils, 0, sizeof(pasn->fils));
-#endif /* CONFIG_FILS*/
-
-#ifdef CONFIG_IEEE80211R
- forced_memzero(pasn->pmk_r1, sizeof(pasn->pmk_r1));
- pasn->pmk_r1_len = 0;
- os_memset(pasn->pmk_r1_name, 0, sizeof(pasn->pmk_r1_name));
-#endif /* CONFIG_IEEE80211R */
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
-}
-
-
-static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
- struct wpa_ie_data *rsn_data,
- struct wpa_pasn_params_data *pasn_data,
- struct wpabuf *wrapped_data)
-{
- static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
- struct wpas_pasn *pasn = &wpa_s->pasn;
-
- os_memset(pasn->pmk, 0, sizeof(pasn->pmk));
- pasn->pmk_len = 0;
-
- if (pasn->akmp == WPA_KEY_MGMT_PASN) {
- wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
-
- pasn->pmk_len = WPA_PASN_PMK_LEN;
- os_memcpy(pasn->pmk, pasn_default_pmk,
- sizeof(pasn_default_pmk));
- return 0;
- }
-
- if (wpa_key_mgmt_ft(pasn->akmp)) {
-#ifdef CONFIG_IEEE80211R
- wpa_printf(MSG_DEBUG, "PASN: FT: Using PMK-R1");
- pasn->pmk_len = pasn->pmk_r1_len;
- os_memcpy(pasn->pmk, pasn->pmk_r1, pasn->pmk_r1_len);
- pasn->using_pmksa = true;
- return 0;
-#else /* CONFIG_IEEE80211R */
- wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
- return -1;
-#endif /* CONFIG_IEEE80211R */
- }
-
- if (rsn_data->num_pmkid) {
- struct rsn_pmksa_cache_entry *pmksa;
-
- pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
- rsn_data->pmkid, NULL,
- pasn->akmp);
- if (pmksa) {
- wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");
-
- pasn->pmk_len = pmksa->pmk_len;
- os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
- pasn->using_pmksa = true;
-
- return 0;
- }
- }
-
-#ifdef CONFIG_SAE
- if (pasn->akmp == WPA_KEY_MGMT_SAE) {
- int ret;
-
- ret = wpas_pasn_wd_sae_rx(wpa_s, wrapped_data);
- if (ret) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed processing SAE wrapped data");
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "PASN: Success deriving PMK with SAE");
- pasn->pmk_len = PMK_LEN;
- os_memcpy(pasn->pmk, pasn->sae.pmk, PMK_LEN);
-
- wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
- pasn->pmk_len, pasn->sae.pmkid,
- pasn->bssid, pasn->akmp);
- return 0;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_FILS
- if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
- pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
- int ret;
-
- ret = wpas_pasn_wd_fils_rx(wpa_s, wrapped_data);
- if (ret) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed processing FILS wrapped data");
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- return -1;
- }
-
- return 0;
- }
-#endif /* CONFIG_FILS */
-
- /* TODO: Derive PMK based on wrapped data */
- wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- return -1;
-}
-
-
-static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int akmp, int cipher, u16 group, int freq,
- const u8 *beacon_rsne, u8 beacon_rsne_len,
- const u8 *beacon_rsnxe, u8 beacon_rsnxe_len,
- int network_id, struct wpabuf *comeback)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct wpa_ssid *ssid = NULL;
- struct wpabuf *frame;
- int ret;
-
- /* TODO: Currently support only ECC groups */
- if (!dragonfly_suitable_group(group, 1)) {
- wpa_printf(MSG_DEBUG,
- "PASN: Reject unsuitable group %u", group);
- return -1;
- }
-
- ssid = wpa_config_get_network(wpa_s->conf, network_id);
-
- switch (akmp) {
- case WPA_KEY_MGMT_PASN:
- break;
-#ifdef CONFIG_SAE
- case WPA_KEY_MGMT_SAE:
- if (!ssid) {
- wpa_printf(MSG_DEBUG,
- "PASN: No network profile found for SAE");
- return -1;
- }
-
- if (!ieee802_11_rsnx_capab(beacon_rsnxe,
- WLAN_RSNX_CAPAB_SAE_H2E)) {
- wpa_printf(MSG_DEBUG,
- "PASN: AP does not support SAE H2E");
- return -1;
- }
-
- if (wpas_pasn_sae_setup_pt(wpa_s, ssid, group) < 0) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed to derive PT");
- return -1;
- }
-
- pasn->sae.state = SAE_NOTHING;
- pasn->sae.send_confirm = 0;
- pasn->ssid = ssid;
- break;
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_FILS
- case WPA_KEY_MGMT_FILS_SHA256:
- case WPA_KEY_MGMT_FILS_SHA384:
- pasn->ssid = ssid;
- break;
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_IEEE80211R
- case WPA_KEY_MGMT_FT_PSK:
- case WPA_KEY_MGMT_FT_IEEE8021X:
- case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
- break;
-#endif /* CONFIG_IEEE80211R */
- default:
- wpa_printf(MSG_ERROR, "PASN: Unsupported AKMP=0x%x", akmp);
- return -1;
- }
-
- pasn->ecdh = crypto_ecdh_init(group);
- if (!pasn->ecdh) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
- goto fail;
- }
-
- pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
- beacon_rsnxe_len);
- if (!pasn->beacon_rsne_rsnxe) {
- wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE");
- goto fail;
- }
-
- wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len);
- if (beacon_rsnxe && beacon_rsnxe_len)
- wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
- beacon_rsnxe_len);
-
- pasn->akmp = akmp;
- pasn->cipher = cipher;
- pasn->group = group;
- pasn->freq = freq;
-
- if (wpa_s->conf->force_kdk_derivation ||
- (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
- ieee802_11_rsnx_capab(beacon_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
- pasn->kdk_len = WPA_KDK_MAX_LEN;
- else
- pasn->kdk_len = 0;
- wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
-
- os_memcpy(pasn->bssid, bssid, ETH_ALEN);
-
- wpa_printf(MSG_DEBUG,
- "PASN: Init: " MACSTR " akmp=0x%x, cipher=0x%x, group=%u",
- MAC2STR(pasn->bssid), pasn->akmp, pasn->cipher,
- pasn->group);
-
- frame = wpas_pasn_build_auth_1(wpa_s, comeback);
- if (!frame) {
- wpa_printf(MSG_DEBUG, "PASN: Failed building 1st auth frame");
- goto fail;
- }
-
- ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
- pasn->freq, 1000);
-
- wpabuf_free(frame);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed sending 1st auth frame");
- goto fail;
- }
-
- eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
- return 0;
-
-fail:
- return -1;
-}
-
-
-static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
- const u8 *bssid, int akmp, int cipher)
-{
- struct wpa_bss *bss;
- const u8 *rsne;
- struct wpa_ie_data rsne_data;
- int ret;
-
- if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "PASN: Not doing authentication with current BSS");
- return NULL;
- }
-
- bss = wpa_bss_get_bssid(wpa_s, bssid);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "PASN: BSS not found");
- return NULL;
- }
-
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (!rsne) {
- wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
- return NULL;
- }
-
- ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
- return NULL;
- }
-
- if (!(rsne_data.key_mgmt & akmp) ||
- !(rsne_data.pairwise_cipher & cipher)) {
- wpa_printf(MSG_DEBUG,
- "PASN: AP does not support requested AKMP or cipher");
- return NULL;
- }
-
- return bss;
-}
-
-
-static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpa_pasn_auth_work *awork = work->ctx;
- struct wpa_bss *bss;
- const u8 *rsne, *rsnxe;
- int ret;
-
- wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
-
- if (deinit) {
- if (work->started) {
- eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
- wpa_s, NULL);
- wpa_s->pasn_auth_work = NULL;
- }
-
- wpas_pasn_free_auth_work(awork);
- return;
- }
-
- /*
- * It is possible that by the time the callback is called, the PASN
- * authentication is not allowed, e.g., a connection with the AP was
- * established.
- */
- bss = wpas_pasn_allowed(wpa_s, awork->bssid, awork->akmp,
- awork->cipher);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
- goto fail;
- }
-
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (!rsne) {
- wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
- goto fail;
- }
-
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
-
- ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
- awork->group, bss->freq, rsne, *(rsne + 1) + 2,
- rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
- awork->network_id, awork->comeback);
- if (ret) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed to start PASN authentication");
- goto fail;
- }
-
- /* comeback token is no longer needed at this stage */
- wpabuf_free(awork->comeback);
- awork->comeback = NULL;
-
- wpa_s->pasn_auth_work = work;
- return;
-fail:
- wpas_pasn_free_auth_work(awork);
- work->ctx = NULL;
- radio_work_done(work);
-}
-
-
-int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int akmp, int cipher, u16 group, int network_id,
- const u8 *comeback, size_t comeback_len)
-{
- struct wpa_pasn_auth_work *awork;
- struct wpa_bss *bss;
-
- wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR " akmp=0x%x, cipher=0x%x",
- MAC2STR(bssid), akmp, cipher);
-
- /*
- * TODO: Consider modifying the offchannel logic to handle additional
- * Management frames other then Action frames. For now allow PASN only
- * with drivers that support off-channel TX.
- */
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
- wpa_printf(MSG_DEBUG,
- "PASN: Driver does not support offchannel TX");
- return -1;
- }
-
- if (radio_work_pending(wpa_s, "pasn-start-auth")) {
- wpa_printf(MSG_DEBUG,
- "PASN: send_auth: Work is already pending");
- return -1;
- }
-
- if (wpa_s->pasn_auth_work) {
- wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
- return -1;
- }
-
- bss = wpas_pasn_allowed(wpa_s, bssid, akmp, cipher);
- if (!bss)
- return -1;
-
- wpas_pasn_reset(wpa_s);
-
- awork = os_zalloc(sizeof(*awork));
- if (!awork)
- return -1;
-
- os_memcpy(awork->bssid, bssid, ETH_ALEN);
- awork->akmp = akmp;
- awork->cipher = cipher;
- awork->group = group;
- awork->network_id = network_id;
-
- if (comeback && comeback_len) {
- awork->comeback = wpabuf_alloc_copy(comeback, comeback_len);
- if (!awork->comeback) {
- wpas_pasn_free_auth_work(awork);
- return -1;
- }
- }
-
- if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
- wpas_pasn_auth_start_cb, awork) < 0) {
- wpas_pasn_free_auth_work(awork);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
- return 0;
-}
-
-
-void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
-
- if (!wpa_s->pasn.ecdh)
- return;
-
- wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
-
- wpas_pasn_auth_status(wpa_s, pasn->bssid, pasn->akmp, pasn->cipher,
- pasn->status, pasn->comeback,
- pasn->comeback_after);
-
- wpas_pasn_reset(wpa_s);
-}
-
-
-static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s,
- struct wpas_pasn *pasn,
- struct wpa_pasn_params_data *params)
-{
- int akmp = pasn->akmp;
- int cipher = pasn->cipher;
- u16 group = pasn->group;
- u8 bssid[ETH_ALEN];
- int network_id = pasn->ssid ? pasn->ssid->id : 0;
-
- wpa_printf(MSG_DEBUG, "PASN: Immediate retry");
- os_memcpy(bssid, pasn->bssid, ETH_ALEN);
- wpas_pasn_reset(wpa_s);
-
- return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group,
- network_id,
- params->comeback, params->comeback_len);
-}
-
-
-int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len)
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- struct ieee802_11_elems elems;
- struct wpa_ie_data rsn_data;
- struct wpa_pasn_params_data pasn_params;
- struct wpabuf *wrapped_data = NULL, *secret = NULL, *frame = NULL;
- u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
- u8 mic_len;
- u16 status;
- int ret, inc_y;
- u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_AUTH << 4));
-
- if (!wpa_s->pasn_auth_work || !mgmt ||
- len < offsetof(struct ieee80211_mgmt, u.auth.variable))
- return -2;
-
- /* Not an Authentication frame; do nothing */
- if ((mgmt->frame_control & fc) != fc)
- return -2;
-
- /* Not our frame; do nothing */
- if (os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN) != 0 ||
- os_memcmp(mgmt->sa, pasn->bssid, ETH_ALEN) != 0 ||
- os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN) != 0)
- return -2;
-
- /* Not PASN; do nothing */
- if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
- return -2;
-
- if (mgmt->u.auth.auth_transaction !=
- host_to_le16(pasn->trans_seq + 1)) {
- wpa_printf(MSG_DEBUG,
- "PASN: RX: Invalid transaction sequence: (%u != %u)",
- le_to_host16(mgmt->u.auth.auth_transaction),
- pasn->trans_seq + 1);
- return -1;
- }
-
- status = le_to_host16(mgmt->u.auth.status_code);
-
- if (status != WLAN_STATUS_SUCCESS &&
- status != WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
- wpa_printf(MSG_DEBUG,
- "PASN: Authentication rejected - status=%u", status);
- pasn->status = status;
- wpas_pasn_auth_stop(wpa_s);
- return -1;
- }
-
- if (ieee802_11_parse_elems(mgmt->u.auth.variable,
- len - offsetof(struct ieee80211_mgmt,
- u.auth.variable),
- &elems, 0) == ParseFailed) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed parsing Authentication frame");
- goto fail;
- }
-
- /* Check that the MIC IE exists. Save it and zero out the memory */
- mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
- if (status == WLAN_STATUS_SUCCESS) {
- if (!elems.mic || elems.mic_len != mic_len) {
- wpa_printf(MSG_DEBUG,
- "PASN: Invalid MIC. Expecting len=%u",
- mic_len);
- goto fail;
- } else {
- os_memcpy(mic, elems.mic, mic_len);
- /* TODO: Clean this up.. Should not be modifying the
- * received message buffer. */
- os_memset((u8 *) elems.mic, 0, mic_len);
- }
- }
-
- if (!elems.pasn_params || !elems.pasn_params_len) {
- wpa_printf(MSG_DEBUG,
- "PASN: Missing PASN Parameters IE");
- goto fail;
- }
-
- ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
- elems.pasn_params_len + 3,
- true, &pasn_params);
- if (ret) {
- wpa_printf(MSG_DEBUG,
- "PASN: Failed validation PASN of Parameters IE");
- goto fail;
- }
-
- if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
- wpa_printf(MSG_DEBUG,
- "PASN: Authentication temporarily rejected");
-
- if (pasn_params.comeback && pasn_params.comeback_len) {
- wpa_printf(MSG_DEBUG,
- "PASN: Comeback token available. After=%u",
- pasn_params.after);
-
- if (!pasn_params.after)
- return wpas_pasn_immediate_retry(wpa_s, pasn,
- &pasn_params);
-
- pasn->comeback = wpabuf_alloc_copy(
- pasn_params.comeback, pasn_params.comeback_len);
- if (pasn->comeback)
- pasn->comeback_after = pasn_params.after;
- }
-
- pasn->status = status;
- goto fail;
- }
-
- ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
- &rsn_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
- goto fail;
- }
-
- ret = wpa_pasn_validate_rsne(&rsn_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
- goto fail;
- }
-
- if (pasn->akmp != rsn_data.key_mgmt ||
- pasn->cipher != rsn_data.pairwise_cipher) {
- wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
- goto fail;
- }
-
- if (pasn->group != pasn_params.group) {
- wpa_printf(MSG_DEBUG, "PASN: Mismatch in group");
- goto fail;
- }
-
- if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
- wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
- goto fail;
- }
-
- if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
- inc_y = 1;
- } else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
- pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
- inc_y = 0;
- } else {
- wpa_printf(MSG_DEBUG,
- "PASN: Invalid first octet in pubkey=0x%x",
- pasn_params.pubkey[0]);
- goto fail;
- }
-
- secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
- pasn_params.pubkey + 1,
- pasn_params.pubkey_len - 1);
-
- if (!secret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
- goto fail;
- }
-
- if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
- wrapped_data = ieee802_11_defrag(&elems,
- WLAN_EID_EXTENSION,
- WLAN_EID_EXT_WRAPPED_DATA);
-
- if (!wrapped_data) {
- wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
- goto fail;
- }
- }
-
- ret = wpas_pasn_set_pmk(wpa_s, &rsn_data, &pasn_params, wrapped_data);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to set PMK");
- goto fail;
- }
-
- ret = pasn_pmk_to_ptk(pasn->pmk, pasn->pmk_len,
- wpa_s->own_addr, pasn->bssid,
- wpabuf_head(secret), wpabuf_len(secret),
- &pasn->ptk, pasn->akmp, pasn->cipher,
- pasn->kdk_len);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
- goto fail;
- }
-
- wpabuf_free(wrapped_data);
- wrapped_data = NULL;
- wpabuf_free(secret);
- secret = NULL;
-
- /* Verify the MIC */
- ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
- pasn->bssid, wpa_s->own_addr,
- wpabuf_head(pasn->beacon_rsne_rsnxe),
- wpabuf_len(pasn->beacon_rsne_rsnxe),
- (u8 *) &mgmt->u.auth,
- len - offsetof(struct ieee80211_mgmt, u.auth),
- out_mic);
-
- wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
- if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
- wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
- goto fail;
- }
-
- pasn->trans_seq++;
-
- wpa_printf(MSG_DEBUG, "PASN: Success verifying Authentication frame");
-
- frame = wpas_pasn_build_auth_3(wpa_s);
- if (!frame) {
- wpa_printf(MSG_DEBUG, "PASN: Failed building 3rd auth frame");
- goto fail;
- }
-
- ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
- pasn->freq, 100);
- wpabuf_free(frame);
- if (ret) {
- wpa_printf(MSG_DEBUG, "PASN: Failed sending 3st auth frame");
- goto fail;
- }
-
- wpa_printf(MSG_DEBUG, "PASN: Success sending last frame. Store PTK");
-
- ptksa_cache_add(wpa_s->ptksa, pasn->bssid, pasn->cipher,
- dot11RSNAConfigPMKLifetime, &pasn->ptk);
-
- forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
-
- pasn->status = WLAN_STATUS_SUCCESS;
- return 0;
-fail:
- wpa_printf(MSG_DEBUG, "PASN: Failed RX processing - terminating");
- wpabuf_free(wrapped_data);
- wpabuf_free(secret);
-
- /*
- * TODO: In case of an error the standard allows to silently drop
- * the frame and terminate the authentication exchange. However, better
- * reply to the AP with an error status.
- */
- if (status == WLAN_STATUS_SUCCESS)
- pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- else
- pasn->status = status;
-
- wpas_pasn_auth_stop(wpa_s);
- return -1;
-}
-
-
-int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t data_len, u8 acked)
-
-{
- struct wpas_pasn *pasn = &wpa_s->pasn;
- const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) data;
- u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_AUTH << 4));
-
- wpa_printf(MSG_DEBUG, "PASN: auth_tx_status: acked=%u", acked);
-
- if (!wpa_s->pasn_auth_work) {
- wpa_printf(MSG_DEBUG,
- "PASN: auth_tx_status: no work in progress");
- return -1;
- }
-
- if (!mgmt ||
- data_len < offsetof(struct ieee80211_mgmt, u.auth.variable))
- return -1;
-
- /* Not an authentication frame; do nothing */
- if ((mgmt->frame_control & fc) != fc)
- return -1;
-
- /* Not our frame; do nothing */
- if (os_memcmp(mgmt->da, pasn->bssid, ETH_ALEN) ||
- os_memcmp(mgmt->sa, wpa_s->own_addr, ETH_ALEN) ||
- os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN))
- return -1;
-
- /* Not PASN; do nothing */
- if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
- return -1;
-
- if (mgmt->u.auth.auth_transaction != host_to_le16(pasn->trans_seq)) {
- wpa_printf(MSG_ERROR,
- "PASN: Invalid transaction sequence: (%u != %u)",
- pasn->trans_seq,
- le_to_host16(mgmt->u.auth.auth_transaction));
- return 0;
- }
-
- wpa_printf(MSG_ERROR,
- "PASN: auth with trans_seq=%u, acked=%u", pasn->trans_seq,
- acked);
-
- /*
- * Even if the frame was not acked, do not treat this is an error, and
- * try to complete the flow, relying on the PASN timeout callback to
- * clean up.
- */
- if (pasn->trans_seq == 3) {
- wpa_printf(MSG_DEBUG, "PASN: auth complete with: " MACSTR,
- MAC2STR(pasn->bssid));
- /*
- * Either frame was not ACKed or it was ACKed but the trans_seq
- * != 1, i.e., not expecting an RX frame, so we are done.
- */
- wpas_pasn_auth_stop(wpa_s);
- }
-
- return 0;
-}
-
-
-int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wpa_bss *bss;
- struct wpabuf *buf;
- struct ieee80211_mgmt *deauth;
- int ret;
-
- if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "PASN: Cannot deauthenticate from current BSS");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
- MACSTR, MAC2STR(bssid));
- ptksa_cache_flush(wpa_s->ptksa, bssid, WPA_CIPHER_NONE);
-
- bss = wpa_bss_get_bssid(wpa_s, bssid);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
- return -1;
- }
-
- buf = wpabuf_alloc(64);
- if (!buf) {
- wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
- return -1;
- }
-
- deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
- u.deauth.variable));
-
- deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_DEAUTH << 4));
-
- os_memcpy(deauth->da, bssid, ETH_ALEN);
- os_memcpy(deauth->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(deauth->bssid, bssid, ETH_ALEN);
- deauth->u.deauth.reason_code =
- host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
-
- /*
- * Since we do not expect any response from the AP, implement the
- * Deauthentication frame transmission using direct call to the driver
- * without a radio work.
- */
- ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
- bss->freq, 0);
-
- wpabuf_free(buf);
- wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
-
- return ret;
-}
diff --git a/wpa_supplicant/preauth_test.c b/wpa_supplicant/preauth_test.c
deleted file mode 100644
index 31b55325f7f7..000000000000
--- a/wpa_supplicant/preauth_test.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * WPA Supplicant - test code for pre-authentication
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c.
- * Not used in production version.
- */
-
-#include "includes.h"
-#include <assert.h>
-
-#include "common.h"
-#include "config.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "eloop.h"
-#include "rsn_supp/wpa.h"
-#include "eap_peer/eap.h"
-#include "wpa_supplicant_i.h"
-#include "l2_packet/l2_packet.h"
-#include "ctrl_iface.h"
-#include "pcsc_funcs.h"
-#include "rsn_supp/preauth.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "drivers/driver.h"
-
-
-const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
-
-
-struct preauth_test_data {
- int auth_timed_out;
-};
-
-
-static void _wpa_supplicant_deauthenticate(void *wpa_s, u16 reason_code)
-{
- wpa_supplicant_deauthenticate(wpa_s, reason_code);
-}
-
-
-static void _wpa_supplicant_reconnect(void *wpa_s)
-{
- wpa_supplicant_reconnect(wpa_s);
-}
-
-
-static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
- const void *data, u16 data_len,
- size_t *msg_len, void **data_pos)
-{
- struct ieee802_1x_hdr *hdr;
-
- *msg_len = sizeof(*hdr) + data_len;
- hdr = os_malloc(*msg_len);
- if (hdr == NULL)
- return NULL;
-
- hdr->version = wpa_s->conf->eapol_version;
- hdr->type = type;
- hdr->length = htons(data_len);
-
- if (data)
- os_memcpy(hdr + 1, data, data_len);
- else
- os_memset(hdr + 1, 0, data_len);
-
- if (data_pos)
- *data_pos = hdr + 1;
-
- return (u8 *) hdr;
-}
-
-
-static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
- const void *data, u16 data_len,
- size_t *msg_len, void **data_pos)
-{
- return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
-}
-
-
-static void _wpa_supplicant_set_state(void *ctx, enum wpa_states state)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_s->wpa_state = state;
-}
-
-
-static enum wpa_states _wpa_supplicant_get_state(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_s->wpa_state;
-}
-
-
-static int wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
- const u8 *buf, size_t len)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static void * wpa_supplicant_get_network_ctx(void *wpa_s)
-{
- return wpa_supplicant_get_ssid(wpa_s);
-}
-
-
-static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
-{
- wpa_supplicant_cancel_auth_timeout(wpa_s);
-}
-
-
-static int wpa_supplicant_get_beacon_ie(void *wpa_s)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static int wpa_supplicant_set_key(void *wpa_s, enum wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len,
- enum key_flag key_flag)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
- int protection_type,
- int key_type)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static int wpa_supplicant_add_pmkid(void *wpa_s, void *network_ctx,
- const u8 *bssid, const u8 *pmkid,
- const u8 *fils_cache_id,
- const u8 *pmk, size_t pmk_len,
- u32 pmk_lifetime, u8 pmk_reauth_threshold,
- int akmp)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static int wpa_supplicant_remove_pmkid(void *wpa_s, void *network_ctx,
- const u8 *bssid, const u8 *pmkid,
- const u8 *fils_cache_id)
-{
- printf("%s - not implemented\n", __func__);
- return -1;
-}
-
-
-static void wpa_supplicant_set_config_blob(void *ctx,
- struct wpa_config_blob *blob)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_config_set_blob(wpa_s->conf, blob);
-}
-
-
-static const struct wpa_config_blob *
-wpa_supplicant_get_config_blob(void *ctx, const char *name)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_config_get_blob(wpa_s->conf, name);
-}
-
-
-static void test_eapol_clean(struct wpa_supplicant *wpa_s)
-{
- rsn_preauth_deinit(wpa_s->wpa);
- pmksa_candidate_free(wpa_s->wpa);
- wpa_sm_deinit(wpa_s->wpa);
- scard_deinit(wpa_s->scard);
- wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
- wpa_s->ctrl_iface = NULL;
- wpa_config_free(wpa_s->conf);
-}
-
-
-static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct preauth_test_data *p = eloop_ctx;
- printf("EAPOL test timed out\n");
- p->auth_timed_out = 1;
- eloop_terminate();
-}
-
-
-static void eapol_test_poll(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- if (!rsn_preauth_in_progress(wpa_s->wpa))
- eloop_terminate();
- else {
- eloop_register_timeout(0, 100000, eapol_test_poll, eloop_ctx,
- timeout_ctx);
- }
-}
-
-
-static struct wpa_driver_ops stub_driver;
-
-
-static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname)
-{
- struct l2_packet_data *l2;
- struct wpa_sm_ctx *ctx;
-
- os_memset(&stub_driver, 0, sizeof(stub_driver));
- wpa_s->driver = &stub_driver;
-
- ctx = os_zalloc(sizeof(*ctx));
- assert(ctx != NULL);
-
- ctx->ctx = wpa_s;
- ctx->msg_ctx = wpa_s;
- ctx->set_state = _wpa_supplicant_set_state;
- ctx->get_state = _wpa_supplicant_get_state;
- ctx->deauthenticate = _wpa_supplicant_deauthenticate;
- ctx->set_key = wpa_supplicant_set_key;
- ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
- ctx->get_bssid = wpa_supplicant_get_bssid;
- ctx->ether_send = wpa_ether_send;
- ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
- ctx->alloc_eapol = _wpa_alloc_eapol;
- ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
- ctx->add_pmkid = wpa_supplicant_add_pmkid;
- ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
- ctx->set_config_blob = wpa_supplicant_set_config_blob;
- ctx->get_config_blob = wpa_supplicant_get_config_blob;
- ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
- ctx->reconnect = _wpa_supplicant_reconnect;
-
- wpa_s->wpa = wpa_sm_init(ctx);
- assert(wpa_s->wpa != NULL);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN);
-
- os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
- wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname, NULL);
-
- l2 = l2_packet_init(wpa_s->ifname, NULL, ETH_P_RSN_PREAUTH, NULL,
- NULL, 0);
- assert(l2 != NULL);
- if (l2_packet_get_own_addr(l2, wpa_s->own_addr)) {
- wpa_printf(MSG_WARNING, "Failed to get own L2 address\n");
- exit(-1);
- }
- l2_packet_deinit(l2);
- wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-}
-
-
-static void eapol_test_terminate(int sig, void *signal_ctx)
-{
- struct wpa_supplicant *wpa_s = signal_ctx;
- wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig);
- eloop_terminate();
-}
-
-
-int main(int argc, char *argv[])
-{
- struct wpa_supplicant wpa_s;
- int ret = 1;
- u8 bssid[ETH_ALEN];
- struct preauth_test_data preauth_test;
-
- if (os_program_init())
- return -1;
-
- os_memset(&preauth_test, 0, sizeof(preauth_test));
-
- wpa_debug_level = 0;
- wpa_debug_show_keys = 1;
-
- if (argc != 4) {
- printf("usage: preauth_test <conf> <target MAC address> "
- "<ifname>\n");
- return -1;
- }
-
- if (hwaddr_aton(argv[2], bssid)) {
- printf("Failed to parse target address '%s'.\n", argv[2]);
- return -1;
- }
-
- if (eap_register_methods()) {
- wpa_printf(MSG_ERROR, "Failed to register EAP methods");
- return -1;
- }
-
- if (eloop_init()) {
- wpa_printf(MSG_ERROR, "Failed to initialize event loop");
- return -1;
- }
-
- os_memset(&wpa_s, 0, sizeof(wpa_s));
- wpa_s.conf = wpa_config_read(argv[1], NULL);
- if (wpa_s.conf == NULL) {
- printf("Failed to parse configuration file '%s'.\n", argv[1]);
- return -1;
- }
- if (wpa_s.conf->ssid == NULL) {
- printf("No networks defined.\n");
- return -1;
- }
-
- wpa_init_conf(&wpa_s, argv[3]);
- wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
- if (wpa_s.ctrl_iface == NULL) {
- printf("Failed to initialize control interface '%s'.\n"
- "You may have another preauth_test process already "
- "running or the file was\n"
- "left by an unclean termination of preauth_test in "
- "which case you will need\n"
- "to manually remove this file before starting "
- "preauth_test again.\n",
- wpa_s.conf->ctrl_interface);
- return -1;
- }
- if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid))
- return -1;
-
- if (rsn_preauth_init(wpa_s.wpa, bssid, &wpa_s.conf->ssid->eap))
- return -1;
-
- eloop_register_timeout(30, 0, eapol_test_timeout, &preauth_test, NULL);
- eloop_register_timeout(0, 100000, eapol_test_poll, &wpa_s, NULL);
- eloop_register_signal_terminate(eapol_test_terminate, &wpa_s);
- eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s);
- eloop_run();
-
- if (preauth_test.auth_timed_out)
- ret = -2;
- else {
- ret = pmksa_cache_set_current(wpa_s.wpa, NULL, bssid, NULL, 0,
- NULL, 0) ? 0 : -3;
- }
-
- test_eapol_clean(&wpa_s);
-
- eap_peer_unregister_methods();
-
- eloop_destroy();
-
- os_program_deinit();
-
- return ret;
-}
diff --git a/wpa_supplicant/robust_av.c b/wpa_supplicant/robust_av.c
deleted file mode 100644
index 770c8fcab189..000000000000
--- a/wpa_supplicant/robust_av.c
+++ /dev/null
@@ -1,1487 +0,0 @@
-/*
- * wpa_supplicant - Robust AV procedures
- * Copyright (c) 2020, The Linux Foundation
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/wpa_ctrl.h"
-#include "common/ieee802_11_common.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "bss.h"
-
-
-#define SCS_RESP_TIMEOUT 1
-#define DSCP_REQ_TIMEOUT 5
-
-
-void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
- struct wpabuf *buf)
-{
- u8 *len, *len1;
-
- /* MSCS descriptor element */
- wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- len = wpabuf_put(buf, 1);
- wpabuf_put_u8(buf, WLAN_EID_EXT_MSCS_DESCRIPTOR);
- wpabuf_put_u8(buf, robust_av->request_type);
- wpabuf_put_u8(buf, robust_av->up_bitmap);
- wpabuf_put_u8(buf, robust_av->up_limit);
- wpabuf_put_le32(buf, robust_av->stream_timeout);
-
- if (robust_av->request_type != SCS_REQ_REMOVE) {
- /* TCLAS mask element */
- wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- len1 = wpabuf_put(buf, 1);
- wpabuf_put_u8(buf, WLAN_EID_EXT_TCLAS_MASK);
-
- /* Frame classifier */
- wpabuf_put_data(buf, robust_av->frame_classifier,
- robust_av->frame_classifier_len);
- *len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
- }
-
- *len = (u8 *) wpabuf_put(buf, 0) - len - 1;
-}
-
-
-static int wpas_populate_type4_classifier(struct type4_params *type4_param,
- struct wpabuf *buf)
-{
- /* classifier parameters */
- wpabuf_put_u8(buf, type4_param->classifier_mask);
- if (type4_param->ip_version == IPV4) {
- wpabuf_put_u8(buf, IPV4); /* IP version */
- wpabuf_put_data(buf, &type4_param->ip_params.v4.src_ip.s_addr,
- 4);
- wpabuf_put_data(buf, &type4_param->ip_params.v4.dst_ip.s_addr,
- 4);
- wpabuf_put_be16(buf, type4_param->ip_params.v4.src_port);
- wpabuf_put_be16(buf, type4_param->ip_params.v4.dst_port);
- wpabuf_put_u8(buf, type4_param->ip_params.v4.dscp);
- wpabuf_put_u8(buf, type4_param->ip_params.v4.protocol);
- wpabuf_put_u8(buf, 0); /* Reserved octet */
- } else {
- wpabuf_put_u8(buf, IPV6);
- wpabuf_put_data(buf, &type4_param->ip_params.v6.src_ip.s6_addr,
- 16);
- wpabuf_put_data(buf, &type4_param->ip_params.v6.dst_ip.s6_addr,
- 16);
- wpabuf_put_be16(buf, type4_param->ip_params.v6.src_port);
- wpabuf_put_be16(buf, type4_param->ip_params.v6.dst_port);
- wpabuf_put_u8(buf, type4_param->ip_params.v6.dscp);
- wpabuf_put_u8(buf, type4_param->ip_params.v6.next_header);
- wpabuf_put_data(buf, type4_param->ip_params.v6.flow_label, 3);
- }
-
- return 0;
-}
-
-
-static int wpas_populate_type10_classifier(struct type10_params *type10_param,
- struct wpabuf *buf)
-{
- /* classifier parameters */
- wpabuf_put_u8(buf, type10_param->prot_instance);
- wpabuf_put_u8(buf, type10_param->prot_number);
- wpabuf_put_data(buf, type10_param->filter_value,
- type10_param->filter_len);
- wpabuf_put_data(buf, type10_param->filter_mask,
- type10_param->filter_len);
- return 0;
-}
-
-
-static int wpas_populate_scs_descriptor_ie(struct scs_desc_elem *desc_elem,
- struct wpabuf *buf)
-{
- u8 *len, *len1;
- struct tclas_element *tclas_elem;
- unsigned int i;
-
- /* SCS Descriptor element */
- wpabuf_put_u8(buf, WLAN_EID_SCS_DESCRIPTOR);
- len = wpabuf_put(buf, 1);
- wpabuf_put_u8(buf, desc_elem->scs_id);
- wpabuf_put_u8(buf, desc_elem->request_type);
- if (desc_elem->request_type == SCS_REQ_REMOVE)
- goto end;
-
- if (desc_elem->intra_access_priority || desc_elem->scs_up_avail) {
- wpabuf_put_u8(buf, WLAN_EID_INTRA_ACCESS_CATEGORY_PRIORITY);
- wpabuf_put_u8(buf, 1);
- wpabuf_put_u8(buf, desc_elem->intra_access_priority);
- }
-
- tclas_elem = desc_elem->tclas_elems;
-
- if (!tclas_elem)
- return -1;
-
- for (i = 0; i < desc_elem->num_tclas_elem; i++, tclas_elem++) {
- int ret;
-
- /* TCLAS element */
- wpabuf_put_u8(buf, WLAN_EID_TCLAS);
- len1 = wpabuf_put(buf, 1);
- wpabuf_put_u8(buf, 255); /* User Priority: not compared */
- /* Frame Classifier */
- wpabuf_put_u8(buf, tclas_elem->classifier_type);
- /* Frame classifier parameters */
- switch (tclas_elem->classifier_type) {
- case 4:
- ret = wpas_populate_type4_classifier(
- &tclas_elem->frame_classifier.type4_param,
- buf);
- break;
- case 10:
- ret = wpas_populate_type10_classifier(
- &tclas_elem->frame_classifier.type10_param,
- buf);
- break;
- default:
- return -1;
- }
-
- if (ret == -1) {
- wpa_printf(MSG_ERROR,
- "Failed to populate frame classifier");
- return -1;
- }
-
- *len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
- }
-
- if (desc_elem->num_tclas_elem > 1) {
- /* TCLAS Processing element */
- wpabuf_put_u8(buf, WLAN_EID_TCLAS_PROCESSING);
- wpabuf_put_u8(buf, 1);
- wpabuf_put_u8(buf, desc_elem->tclas_processing);
- }
-
-end:
- *len = (u8 *) wpabuf_put(buf, 0) - len - 1;
- return 0;
-}
-
-
-int wpas_send_mscs_req(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *buf;
- size_t buf_len;
- int ret;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
- return 0;
-
- if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS)) {
- wpa_dbg(wpa_s, MSG_INFO,
- "AP does not support MSCS - could not send MSCS Req");
- return -1;
- }
-
- if (!wpa_s->mscs_setup_done &&
- wpa_s->robust_av.request_type != SCS_REQ_ADD) {
- wpa_msg(wpa_s, MSG_INFO,
- "MSCS: Failed to send MSCS Request: request type invalid");
- return -1;
- }
-
- buf_len = 3 + /* Action frame header */
- 3 + /* MSCS descriptor IE header */
- 1 + /* Request type */
- 2 + /* User priority control */
- 4 + /* Stream timeout */
- 3 + /* TCLAS Mask IE header */
- wpa_s->robust_av.frame_classifier_len;
-
- buf = wpabuf_alloc(buf_len);
- if (!buf) {
- wpa_printf(MSG_ERROR, "Failed to allocate MSCS req");
- return -1;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
- wpabuf_put_u8(buf, ROBUST_AV_MSCS_REQ);
- wpa_s->robust_av.dialog_token++;
- wpabuf_put_u8(buf, wpa_s->robust_av.dialog_token);
-
- /* MSCS descriptor element */
- wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, buf);
-
- wpa_hexdump_buf(MSG_MSGDUMP, "MSCS Request", buf);
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret < 0)
- wpa_dbg(wpa_s, MSG_INFO, "MSCS: Failed to send MSCS Request");
-
- wpabuf_free(buf);
- return ret;
-}
-
-
-static size_t tclas_elem_len(const struct tclas_element *elem)
-{
- size_t buf_len = 0;
-
- buf_len += 2 + /* TCLAS element header */
- 1 + /* User Priority */
- 1 ; /* Classifier Type */
-
- if (elem->classifier_type == 4) {
- enum ip_version ip_ver;
-
- buf_len += 1 + /* Classifier mask */
- 1 + /* IP version */
- 1 + /* user priority */
- 2 + /* src_port */
- 2 + /* dst_port */
- 1 ; /* dscp */
- ip_ver = elem->frame_classifier.type4_param.ip_version;
- if (ip_ver == IPV4) {
- buf_len += 4 + /* src_ip */
- 4 + /* dst_ip */
- 1 + /* protocol */
- 1 ; /* Reserved */
- } else if (ip_ver == IPV6) {
- buf_len += 16 + /* src_ip */
- 16 + /* dst_ip */
- 1 + /* next_header */
- 3 ; /* flow_label */
- } else {
- wpa_printf(MSG_ERROR, "%s: Incorrect IP version %d",
- __func__, ip_ver);
- return 0;
- }
- } else if (elem->classifier_type == 10) {
- buf_len += 1 + /* protocol instance */
- 1 + /* protocol number */
- 2 * elem->frame_classifier.type10_param.filter_len;
- } else {
- wpa_printf(MSG_ERROR, "%s: Incorrect classifier type %u",
- __func__, elem->classifier_type);
- return 0;
- }
-
- return buf_len;
-}
-
-
-static struct wpabuf * allocate_scs_buf(struct scs_desc_elem *desc_elem,
- unsigned int num_scs_desc)
-{
- struct wpabuf *buf;
- size_t buf_len = 0;
- unsigned int i, j;
-
- buf_len = 3; /* Action frame header */
-
- for (i = 0; i < num_scs_desc; i++, desc_elem++) {
- struct tclas_element *tclas_elem;
-
- buf_len += 2 + /* SCS descriptor IE header */
- 1 + /* SCSID */
- 1 ; /* Request type */
-
- if (desc_elem->request_type == SCS_REQ_REMOVE)
- continue;
-
- if (desc_elem->intra_access_priority || desc_elem->scs_up_avail)
- buf_len += 3;
-
- tclas_elem = desc_elem->tclas_elems;
- if (!tclas_elem) {
- wpa_printf(MSG_ERROR, "%s: TCLAS element null",
- __func__);
- return NULL;
- }
-
- for (j = 0; j < desc_elem->num_tclas_elem; j++, tclas_elem++) {
- size_t elen;
-
- elen = tclas_elem_len(tclas_elem);
- if (elen == 0)
- return NULL;
- buf_len += elen;
- }
-
- if (desc_elem->num_tclas_elem > 1) {
- buf_len += 1 + /* TCLAS Processing eid */
- 1 + /* length */
- 1 ; /* processing */
- }
- }
-
- buf = wpabuf_alloc(buf_len);
- if (!buf) {
- wpa_printf(MSG_ERROR, "Failed to allocate SCS req");
- return NULL;
- }
-
- return buf;
-}
-
-
-static void scs_request_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct active_scs_elem *scs_desc, *prev;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
- return;
-
- /* Once timeout is over, remove all SCS descriptors with no response */
- dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
- struct active_scs_elem, list) {
- u8 bssid[ETH_ALEN] = { 0 };
- const u8 *src;
-
- if (scs_desc->status == SCS_DESC_SUCCESS)
- continue;
-
- if (wpa_s->current_bss)
- src = wpa_s->current_bss->bssid;
- else
- src = bssid;
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
- " SCSID=%u status_code=timedout", MAC2STR(src),
- scs_desc->scs_id);
-
- dl_list_del(&scs_desc->list);
- wpa_printf(MSG_INFO, "%s: SCSID %d removed after timeout",
- __func__, scs_desc->scs_id);
- os_free(scs_desc);
- }
-
- eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
- wpa_s->ongoing_scs_req = false;
-}
-
-
-int wpas_send_scs_req(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *buf = NULL;
- struct scs_desc_elem *desc_elem = NULL;
- int ret = -1;
- unsigned int i;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
- return -1;
-
- if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_SCS)) {
- wpa_dbg(wpa_s, MSG_INFO,
- "AP does not support SCS - could not send SCS Request");
- return -1;
- }
-
- desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
- if (!desc_elem)
- return -1;
-
- buf = allocate_scs_buf(desc_elem,
- wpa_s->scs_robust_av_req.num_scs_desc);
- if (!buf)
- return -1;
-
- wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
- wpabuf_put_u8(buf, ROBUST_AV_SCS_REQ);
- wpa_s->scs_dialog_token++;
- if (wpa_s->scs_dialog_token == 0)
- wpa_s->scs_dialog_token++;
- wpabuf_put_u8(buf, wpa_s->scs_dialog_token);
-
- for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
- i++, desc_elem++) {
- /* SCS Descriptor element */
- if (wpas_populate_scs_descriptor_ie(desc_elem, buf) < 0)
- goto end;
- }
-
- wpa_hexdump_buf(MSG_DEBUG, "SCS Request", buf);
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret < 0) {
- wpa_dbg(wpa_s, MSG_ERROR, "SCS: Failed to send SCS Request");
- wpa_s->scs_dialog_token--;
- goto end;
- }
-
- desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
- for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
- i++, desc_elem++) {
- struct active_scs_elem *active_scs_elem;
-
- if (desc_elem->request_type != SCS_REQ_ADD)
- continue;
-
- active_scs_elem = os_malloc(sizeof(struct active_scs_elem));
- if (!active_scs_elem)
- break;
- active_scs_elem->scs_id = desc_elem->scs_id;
- active_scs_elem->status = SCS_DESC_SENT;
- dl_list_add(&wpa_s->active_scs_ids, &active_scs_elem->list);
- }
-
- /*
- * Register a timeout after which this request will be removed from
- * the cache.
- */
- eloop_register_timeout(SCS_RESP_TIMEOUT, 0, scs_request_timer, wpa_s,
- NULL);
- wpa_s->ongoing_scs_req = true;
-
-end:
- wpabuf_free(buf);
- free_up_scs_desc(&wpa_s->scs_robust_av_req);
-
- return ret;
-}
-
-
-void free_up_tclas_elem(struct scs_desc_elem *elem)
-{
- struct tclas_element *tclas_elems = elem->tclas_elems;
- unsigned int num_tclas_elem = elem->num_tclas_elem;
- struct tclas_element *tclas_data;
- unsigned int j;
-
- elem->tclas_elems = NULL;
- elem->num_tclas_elem = 0;
-
- if (!tclas_elems)
- return;
-
- tclas_data = tclas_elems;
- for (j = 0; j < num_tclas_elem; j++, tclas_data++) {
- if (tclas_data->classifier_type != 10)
- continue;
-
- os_free(tclas_data->frame_classifier.type10_param.filter_value);
- os_free(tclas_data->frame_classifier.type10_param.filter_mask);
- }
-
- os_free(tclas_elems);
-}
-
-
-void free_up_scs_desc(struct scs_robust_av_data *data)
-{
- struct scs_desc_elem *desc_elems = data->scs_desc_elems;
- unsigned int num_scs_desc = data->num_scs_desc;
- struct scs_desc_elem *desc_data;
- unsigned int i;
-
- data->scs_desc_elems = NULL;
- data->num_scs_desc = 0;
-
- if (!desc_elems)
- return;
-
- desc_data = desc_elems;
- for (i = 0; i < num_scs_desc; i++, desc_data++) {
- if (desc_data->request_type == SCS_REQ_REMOVE ||
- !desc_data->tclas_elems)
- continue;
-
- free_up_tclas_elem(desc_data);
- }
- os_free(desc_elems);
-}
-
-
-void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *buf, size_t len)
-{
- u8 dialog_token;
- u16 status_code;
-
- if (len < 3)
- return;
-
- dialog_token = *buf++;
- if (dialog_token != wpa_s->robust_av.dialog_token) {
- wpa_printf(MSG_INFO,
- "MSCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
- dialog_token, wpa_s->robust_av.dialog_token);
- return;
- }
-
- status_code = WPA_GET_LE16(buf);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
- " status_code=%u", MAC2STR(src), status_code);
- wpa_s->mscs_setup_done = status_code == WLAN_STATUS_SUCCESS;
-}
-
-
-void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ies, size_t ies_len)
-{
- const u8 *mscs_desc_ie, *mscs_status;
- u16 status;
-
- /* Process optional MSCS Status subelement when MSCS IE is in
- * (Re)Association Response frame */
- if (!ies || ies_len == 0 || !wpa_s->robust_av.valid_config)
- return;
-
- mscs_desc_ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_MSCS_DESCRIPTOR);
- if (!mscs_desc_ie || mscs_desc_ie[1] <= 8)
- return;
-
- /* Subelements start after (ie_id(1) + ie_len(1) + ext_id(1) +
- * request type(1) + upc(2) + stream timeout(4) =) 10.
- */
- mscs_status = get_ie(&mscs_desc_ie[10], mscs_desc_ie[1] - 8,
- MCSC_SUBELEM_STATUS);
- if (!mscs_status || mscs_status[1] < 2)
- return;
-
- status = WPA_GET_LE16(mscs_status + 2);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
- " status_code=%u", MAC2STR(bssid), status);
- wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS;
-}
-
-
-static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- /* Once timeout is over, reset wait flag and allow sending DSCP query */
- wpa_printf(MSG_DEBUG,
- "QM: Wait time over for sending DSCP request - allow DSCP query");
- wpa_s->wait_for_dscp_req = 0;
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
-}
-
-
-void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len)
-{
- const u8 *wfa_capa;
-
- wpa_s->connection_dscp = 0;
- if (wpa_s->wait_for_dscp_req)
- eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
-
- if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
- return;
-
- wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
- if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
- !(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
- return; /* AP does not enable QM DSCP Policy */
-
- wpa_s->connection_dscp = 1;
- wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
- WFA_CAPA_QM_UNSOLIC_DSCP);
- if (!wpa_s->wait_for_dscp_req)
- return;
-
- /* Register a timeout after which dscp query can be sent to AP. */
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
- eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
- wpas_wait_for_dscp_req_timer, wpa_s, NULL);
-}
-
-
-void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *buf,
- size_t len)
-{
- u8 dialog_token;
- unsigned int i, count;
- struct active_scs_elem *scs_desc, *prev;
-
- if (len < 2)
- return;
- if (!wpa_s->ongoing_scs_req) {
- wpa_printf(MSG_INFO,
- "SCS: Drop received response due to no ongoing request");
- return;
- }
-
- dialog_token = *buf++;
- len--;
- if (dialog_token != wpa_s->scs_dialog_token) {
- wpa_printf(MSG_INFO,
- "SCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
- dialog_token, wpa_s->scs_dialog_token);
- return;
- }
-
- /* This Count field does not exist in the IEEE Std 802.11-2020
- * definition of the SCS Response frame. However, it was accepted to
- * be added into REVme per REVme/D0.0 CC35 CID 49 (edits in document
- * 11-21-0688-07). */
- count = *buf++;
- len--;
- if (count == 0 || count * 3 > len) {
- wpa_printf(MSG_INFO,
- "SCS: Drop received frame due to invalid count: %u (remaining %zu octets)",
- count, len);
- return;
- }
-
- for (i = 0; i < count; i++) {
- u8 id;
- u16 status;
- bool scs_desc_found = false;
-
- id = *buf++;
- status = WPA_GET_LE16(buf);
- buf += 2;
- len -= 3;
-
- dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
- struct active_scs_elem, list) {
- if (id == scs_desc->scs_id) {
- scs_desc_found = true;
- break;
- }
- }
-
- if (!scs_desc_found) {
- wpa_printf(MSG_INFO, "SCS: SCS ID invalid %u", id);
- continue;
- }
-
- if (status != WLAN_STATUS_SUCCESS) {
- dl_list_del(&scs_desc->list);
- os_free(scs_desc);
- } else if (status == WLAN_STATUS_SUCCESS) {
- scs_desc->status = SCS_DESC_SUCCESS;
- }
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
- " SCSID=%u status_code=%u", MAC2STR(src), id, status);
- }
-
- eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
- wpa_s->ongoing_scs_req = false;
-
- dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
- struct active_scs_elem, list) {
- if (scs_desc->status != SCS_DESC_SUCCESS) {
- wpa_msg(wpa_s, MSG_INFO,
- WPA_EVENT_SCS_RESULT "bssid=" MACSTR
- " SCSID=%u status_code=response_not_received",
- MAC2STR(src), scs_desc->scs_id);
- dl_list_del(&scs_desc->list);
- os_free(scs_desc);
- }
- }
-}
-
-
-static void wpas_clear_active_scs_ids(struct wpa_supplicant *wpa_s)
-{
- struct active_scs_elem *scs_elem;
-
- while ((scs_elem = dl_list_first(&wpa_s->active_scs_ids,
- struct active_scs_elem, list))) {
- dl_list_del(&scs_elem->list);
- os_free(scs_elem);
- }
-}
-
-
-void wpas_scs_deinit(struct wpa_supplicant *wpa_s)
-{
- free_up_scs_desc(&wpa_s->scs_robust_av_req);
- wpa_s->scs_dialog_token = 0;
- wpas_clear_active_scs_ids(wpa_s);
- eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
- wpa_s->ongoing_scs_req = false;
-}
-
-
-static int write_ipv4_info(char *pos, int total_len,
- const struct ipv4_params *v4)
-{
- int res, rem_len;
- char addr[INET_ADDRSTRLEN];
-
- rem_len = total_len;
-
- if (v4->param_mask & BIT(1)) {
- if (!inet_ntop(AF_INET, &v4->src_ip, addr, INET_ADDRSTRLEN)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv4 source address");
- return -1;
- }
-
- res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v4->param_mask & BIT(2)) {
- if (!inet_ntop(AF_INET, &v4->dst_ip, addr, INET_ADDRSTRLEN)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv4 destination address");
- return -1;
- }
-
- res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v4->param_mask & BIT(3)) {
- res = os_snprintf(pos, rem_len, " src_port=%d", v4->src_port);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v4->param_mask & BIT(4)) {
- res = os_snprintf(pos, rem_len, " dst_port=%d", v4->dst_port);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v4->param_mask & BIT(6)) {
- res = os_snprintf(pos, rem_len, " protocol=%d", v4->protocol);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- return total_len - rem_len;
-}
-
-
-static int write_ipv6_info(char *pos, int total_len,
- const struct ipv6_params *v6)
-{
- int res, rem_len;
- char addr[INET6_ADDRSTRLEN];
-
- rem_len = total_len;
-
- if (v6->param_mask & BIT(1)) {
- if (!inet_ntop(AF_INET6, &v6->src_ip, addr, INET6_ADDRSTRLEN)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv6 source addr");
- return -1;
- }
-
- res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v6->param_mask & BIT(2)) {
- if (!inet_ntop(AF_INET6, &v6->dst_ip, addr, INET6_ADDRSTRLEN)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv6 destination addr");
- return -1;
- }
-
- res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v6->param_mask & BIT(3)) {
- res = os_snprintf(pos, rem_len, " src_port=%d", v6->src_port);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v6->param_mask & BIT(4)) {
- res = os_snprintf(pos, rem_len, " dst_port=%d", v6->dst_port);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- if (v6->param_mask & BIT(6)) {
- res = os_snprintf(pos, rem_len, " protocol=%d",
- v6->next_header);
- if (os_snprintf_error(rem_len, res))
- return -1;
-
- pos += res;
- rem_len -= res;
- }
-
- return total_len - rem_len;
-}
-
-
-struct dscp_policy_data {
- u8 policy_id;
- u8 req_type;
- u8 dscp;
- bool dscp_info;
- const u8 *frame_classifier;
- u8 frame_classifier_len;
- struct type4_params type4_param;
- const u8 *domain_name;
- u8 domain_name_len;
- u16 start_port;
- u16 end_port;
- bool port_range_info;
-};
-
-
-static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
-{
- u8 classifier_mask;
- const u8 *frame_classifier = policy->frame_classifier;
- struct type4_params *type4_param = &policy->type4_param;
-
- if (policy->frame_classifier_len < 18) {
- wpa_printf(MSG_ERROR,
- "QM: Received IPv4 frame classifier with insufficient length %d",
- policy->frame_classifier_len);
- return -1;
- }
-
- classifier_mask = frame_classifier[1];
-
- /* Classifier Mask - bit 1 = Source IP Address */
- if (classifier_mask & BIT(1)) {
- type4_param->ip_params.v4.param_mask |= BIT(1);
- os_memcpy(&type4_param->ip_params.v4.src_ip,
- &frame_classifier[3], 4);
- }
-
- /* Classifier Mask - bit 2 = Destination IP Address */
- if (classifier_mask & BIT(2)) {
- if (policy->domain_name) {
- wpa_printf(MSG_ERROR,
- "QM: IPv4: Both domain name and destination IP address not expected");
- return -1;
- }
-
- type4_param->ip_params.v4.param_mask |= BIT(2);
- os_memcpy(&type4_param->ip_params.v4.dst_ip,
- &frame_classifier[7], 4);
- }
-
- /* Classifier Mask - bit 3 = Source Port */
- if (classifier_mask & BIT(3)) {
- type4_param->ip_params.v4.param_mask |= BIT(3);
- type4_param->ip_params.v4.src_port =
- WPA_GET_BE16(&frame_classifier[11]);
- }
-
- /* Classifier Mask - bit 4 = Destination Port */
- if (classifier_mask & BIT(4)) {
- if (policy->port_range_info) {
- wpa_printf(MSG_ERROR,
- "QM: IPv4: Both port range and destination port not expected");
- return -1;
- }
-
- type4_param->ip_params.v4.param_mask |= BIT(4);
- type4_param->ip_params.v4.dst_port =
- WPA_GET_BE16(&frame_classifier[13]);
- }
-
- /* Classifier Mask - bit 5 = DSCP (ignored) */
-
- /* Classifier Mask - bit 6 = Protocol */
- if (classifier_mask & BIT(6)) {
- type4_param->ip_params.v4.param_mask |= BIT(6);
- type4_param->ip_params.v4.protocol = frame_classifier[16];
- }
-
- return 0;
-}
-
-
-static int set_frame_classifier_type4_ipv6(struct dscp_policy_data *policy)
-{
- u8 classifier_mask;
- const u8 *frame_classifier = policy->frame_classifier;
- struct type4_params *type4_param = &policy->type4_param;
-
- if (policy->frame_classifier_len < 44) {
- wpa_printf(MSG_ERROR,
- "QM: Received IPv6 frame classifier with insufficient length %d",
- policy->frame_classifier_len);
- return -1;
- }
-
- classifier_mask = frame_classifier[1];
-
- /* Classifier Mask - bit 1 = Source IP Address */
- if (classifier_mask & BIT(1)) {
- type4_param->ip_params.v6.param_mask |= BIT(1);
- os_memcpy(&type4_param->ip_params.v6.src_ip,
- &frame_classifier[3], 16);
- }
-
- /* Classifier Mask - bit 2 = Destination IP Address */
- if (classifier_mask & BIT(2)) {
- if (policy->domain_name) {
- wpa_printf(MSG_ERROR,
- "QM: IPv6: Both domain name and destination IP address not expected");
- return -1;
- }
- type4_param->ip_params.v6.param_mask |= BIT(2);
- os_memcpy(&type4_param->ip_params.v6.dst_ip,
- &frame_classifier[19], 16);
- }
-
- /* Classifier Mask - bit 3 = Source Port */
- if (classifier_mask & BIT(3)) {
- type4_param->ip_params.v6.param_mask |= BIT(3);
- type4_param->ip_params.v6.src_port =
- WPA_GET_BE16(&frame_classifier[35]);
- }
-
- /* Classifier Mask - bit 4 = Destination Port */
- if (classifier_mask & BIT(4)) {
- if (policy->port_range_info) {
- wpa_printf(MSG_ERROR,
- "IPv6: Both port range and destination port not expected");
- return -1;
- }
-
- type4_param->ip_params.v6.param_mask |= BIT(4);
- type4_param->ip_params.v6.dst_port =
- WPA_GET_BE16(&frame_classifier[37]);
- }
-
- /* Classifier Mask - bit 5 = DSCP (ignored) */
-
- /* Classifier Mask - bit 6 = Next Header */
- if (classifier_mask & BIT(6)) {
- type4_param->ip_params.v6.param_mask |= BIT(6);
- type4_param->ip_params.v6.next_header = frame_classifier[40];
- }
-
- return 0;
-}
-
-
-static int wpas_set_frame_classifier_params(struct dscp_policy_data *policy)
-{
- const u8 *frame_classifier = policy->frame_classifier;
- u8 frame_classifier_len = policy->frame_classifier_len;
-
- if (frame_classifier_len < 3) {
- wpa_printf(MSG_ERROR,
- "QM: Received frame classifier with insufficient length %d",
- frame_classifier_len);
- return -1;
- }
-
- /* Only allowed Classifier Type: IP and higher layer parameters (4) */
- if (frame_classifier[0] != 4) {
- wpa_printf(MSG_ERROR,
- "QM: Received frame classifier with invalid classifier type %d",
- frame_classifier[0]);
- return -1;
- }
-
- /* Classifier Mask - bit 0 = Version */
- if (!(frame_classifier[1] & BIT(0))) {
- wpa_printf(MSG_ERROR,
- "QM: Received frame classifier without IP version");
- return -1;
- }
-
- /* Version (4 or 6) */
- if (frame_classifier[2] == 4) {
- if (set_frame_classifier_type4_ipv4(policy)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv4 parameters");
- return -1;
- }
-
- policy->type4_param.ip_version = IPV4;
- } else if (frame_classifier[2] == 6) {
- if (set_frame_classifier_type4_ipv6(policy)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set IPv6 parameters");
- return -1;
- }
-
- policy->type4_param.ip_version = IPV6;
- } else {
- wpa_printf(MSG_ERROR,
- "QM: Received unknown IP version %d",
- frame_classifier[2]);
- return -1;
- }
-
- return 0;
-}
-
-
-static bool dscp_valid_domain_name(const char *str)
-{
- if (!str[0])
- return false;
-
- while (*str) {
- if (is_ctrl_char(*str) || *str == ' ' || *str == '=')
- return false;
- str++;
- }
-
- return true;
-}
-
-
-static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
- struct dscp_policy_data *policy)
-{
- int ip_ver = 0, res;
- char policy_str[1000], *pos;
- int len;
-
- if (!policy->frame_classifier && !policy->domain_name &&
- !policy->port_range_info) {
- wpa_printf(MSG_ERROR,
- "QM: Invalid DSCP policy - no attributes present");
- goto fail;
- }
-
- policy_str[0] = '\0';
- pos = policy_str;
- len = sizeof(policy_str);
-
- if (policy->frame_classifier) {
- struct type4_params *type4 = &policy->type4_param;
-
- if (wpas_set_frame_classifier_params(policy)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to set frame classifier parameters");
- goto fail;
- }
-
- if (type4->ip_version == IPV4)
- res = write_ipv4_info(pos, len, &type4->ip_params.v4);
- else
- res = write_ipv6_info(pos, len, &type4->ip_params.v6);
-
- if (res <= 0) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to write IP parameters");
- goto fail;
- }
-
- ip_ver = type4->ip_version;
-
- pos += res;
- len -= res;
- }
-
- if (policy->port_range_info) {
- res = os_snprintf(pos, len, " start_port=%u end_port=%u",
- policy->start_port, policy->end_port);
- if (os_snprintf_error(len, res)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to write port range attributes for policy id = %d",
- policy->policy_id);
- goto fail;
- }
-
- pos += res;
- len -= res;
- }
-
- if (policy->domain_name) {
- char domain_name_str[250];
-
- if (policy->domain_name_len >= sizeof(domain_name_str)) {
- wpa_printf(MSG_ERROR,
- "QM: Domain name length higher than max expected");
- goto fail;
- }
- os_memcpy(domain_name_str, policy->domain_name,
- policy->domain_name_len);
- domain_name_str[policy->domain_name_len] = '\0';
- if (!dscp_valid_domain_name(domain_name_str)) {
- wpa_printf(MSG_ERROR, "QM: Invalid domain name string");
- goto fail;
- }
- res = os_snprintf(pos, len, " domain_name=%s", domain_name_str);
- if (os_snprintf_error(len, res)) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to write domain name attribute for policy id = %d",
- policy->policy_id);
- goto fail;
- }
- }
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
- "add policy_id=%u dscp=%u ip_version=%d%s",
- policy->policy_id, policy->dscp, ip_ver, policy_str);
- return;
-fail:
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
- policy->policy_id);
-}
-
-
-void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
-{
- wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
- wpa_s->dscp_req_dialog_token = 0;
- wpa_s->dscp_query_dialog_token = 0;
- wpa_s->connection_dscp = 0;
- if (wpa_s->wait_for_dscp_req) {
- wpa_s->wait_for_dscp_req = 0;
- eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
- }
-}
-
-
-static void wpas_fill_dscp_policy(struct dscp_policy_data *policy, u8 attr_id,
- u8 attr_len, const u8 *attr_data)
-{
- switch (attr_id) {
- case QM_ATTR_PORT_RANGE:
- if (attr_len < 4) {
- wpa_printf(MSG_ERROR,
- "QM: Received Port Range attribute with insufficient length %d",
- attr_len);
- break;
- }
- policy->start_port = WPA_GET_BE16(attr_data);
- policy->end_port = WPA_GET_BE16(attr_data + 2);
- policy->port_range_info = true;
- break;
- case QM_ATTR_DSCP_POLICY:
- if (attr_len < 3) {
- wpa_printf(MSG_ERROR,
- "QM: Received DSCP Policy attribute with insufficient length %d",
- attr_len);
- return;
- }
- policy->policy_id = attr_data[0];
- policy->req_type = attr_data[1];
- policy->dscp = attr_data[2];
- policy->dscp_info = true;
- break;
- case QM_ATTR_TCLAS:
- if (attr_len < 1) {
- wpa_printf(MSG_ERROR,
- "QM: Received TCLAS attribute with insufficient length %d",
- attr_len);
- return;
- }
- policy->frame_classifier = attr_data;
- policy->frame_classifier_len = attr_len;
- break;
- case QM_ATTR_DOMAIN_NAME:
- if (attr_len < 1) {
- wpa_printf(MSG_ERROR,
- "QM: Received domain name attribute with insufficient length %d",
- attr_len);
- return;
- }
- policy->domain_name = attr_data;
- policy->domain_name_len = attr_len;
- break;
- default:
- wpa_printf(MSG_ERROR, "QM: Received invalid QoS attribute %d",
- attr_id);
- break;
- }
-}
-
-
-void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src,
- const u8 *buf, size_t len)
-{
- int rem_len;
- const u8 *qos_ie, *attr;
- int more, reset;
-
- if (!wpa_s->enable_dscp_policy_capa) {
- wpa_printf(MSG_ERROR,
- "QM: Ignore DSCP Policy frame since the capability is not enabled");
- return;
- }
-
- if (!pmf_in_use(wpa_s, src)) {
- wpa_printf(MSG_ERROR,
- "QM: Ignore DSCP Policy frame since PMF is not in use");
- return;
- }
-
- if (!wpa_s->connection_dscp) {
- wpa_printf(MSG_DEBUG,
- "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
- return;
- }
-
- if (len < 1)
- return;
-
- /* Handle only DSCP Policy Request frame */
- if (buf[0] != QM_DSCP_POLICY_REQ) {
- wpa_printf(MSG_ERROR, "QM: Received unexpected QoS action frame %d",
- buf[0]);
- return;
- }
-
- if (len < 3) {
- wpa_printf(MSG_ERROR,
- "Received QoS Management DSCP Policy Request frame with invalid length %zu",
- len);
- return;
- }
-
- /* Clear wait_for_dscp_req on receiving first DSCP request from AP */
- if (wpa_s->wait_for_dscp_req) {
- wpa_s->wait_for_dscp_req = 0;
- eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
- }
-
- wpa_s->dscp_req_dialog_token = buf[1];
- more = buf[2] & DSCP_POLICY_CTRL_MORE;
- reset = buf[2] & DSCP_POLICY_CTRL_RESET;
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
- reset ? " clear_all" : "", more ? " more" : "");
-
- qos_ie = buf + 3;
- rem_len = len - 3;
- while (rem_len > 2) {
- struct dscp_policy_data policy;
- int rem_attrs_len, ie_len;
-
- ie_len = 2 + qos_ie[1];
- if (rem_len < ie_len)
- break;
-
- if (rem_len < 6 || qos_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
- qos_ie[1] < 4 ||
- WPA_GET_BE32(&qos_ie[2]) != QM_IE_VENDOR_TYPE) {
- rem_len -= ie_len;
- qos_ie += ie_len;
- continue;
- }
-
- os_memset(&policy, 0, sizeof(struct dscp_policy_data));
- attr = qos_ie + 6;
- rem_attrs_len = qos_ie[1] - 4;
-
- while (rem_attrs_len > 2 && rem_attrs_len >= 2 + attr[1]) {
- wpas_fill_dscp_policy(&policy, attr[0], attr[1],
- &attr[2]);
- rem_attrs_len -= 2 + attr[1];
- attr += 2 + attr[1];
- }
-
- rem_len -= ie_len;
- qos_ie += ie_len;
-
- if (!policy.dscp_info) {
- wpa_printf(MSG_ERROR,
- "QM: Received QoS IE without DSCP Policy attribute");
- continue;
- }
-
- if (policy.req_type == DSCP_POLICY_REQ_ADD)
- wpas_add_dscp_policy(wpa_s, &policy);
- else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
- "remove policy_id=%u", policy.policy_id);
- else
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
- "reject policy_id=%u", policy.policy_id);
- }
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
-}
-
-
-int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
- struct dscp_resp_data *resp_data)
-{
- struct wpabuf *buf = NULL;
- size_t buf_len;
- int ret = -1, i;
- u8 resp_control = 0;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to send DSCP response - not connected to AP");
- return -1;
- }
-
- if (resp_data->solicited && !wpa_s->dscp_req_dialog_token) {
- wpa_printf(MSG_ERROR, "QM: No ongoing DSCP request");
- return -1;
- }
-
- if (!wpa_s->connection_dscp) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
- return -1;
-
- }
-
- buf_len = 1 + /* Category */
- 3 + /* OUI */
- 1 + /* OUI Type */
- 1 + /* OUI Subtype */
- 1 + /* Dialog Token */
- 1 + /* Response Control */
- 1 + /* Count */
- 2 * resp_data->num_policies; /* Status list */
- buf = wpabuf_alloc(buf_len);
- if (!buf) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to allocate DSCP policy response");
- return -1;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
- wpabuf_put_be24(buf, OUI_WFA);
- wpabuf_put_u8(buf, QM_ACTION_OUI_TYPE);
- wpabuf_put_u8(buf, QM_DSCP_POLICY_RESP);
-
- wpabuf_put_u8(buf, resp_data->solicited ?
- wpa_s->dscp_req_dialog_token : 0);
-
- if (resp_data->more)
- resp_control |= DSCP_POLICY_CTRL_MORE;
- if (resp_data->reset)
- resp_control |= DSCP_POLICY_CTRL_RESET;
- wpabuf_put_u8(buf, resp_control);
-
- wpabuf_put_u8(buf, resp_data->num_policies);
- for (i = 0; i < resp_data->num_policies; i++) {
- wpabuf_put_u8(buf, resp_data->policy[i].id);
- wpabuf_put_u8(buf, resp_data->policy[i].status);
- }
-
- wpa_hexdump_buf(MSG_MSGDUMP, "DSCP response frame: ", buf);
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret < 0) {
- wpa_msg(wpa_s, MSG_INFO, "QM: Failed to send DSCP response");
- goto fail;
- }
-
- /*
- * Mark DSCP request complete whether response sent is solicited or
- * unsolicited
- */
- wpa_s->dscp_req_dialog_token = 0;
-
-fail:
- wpabuf_free(buf);
- return ret;
-}
-
-
-int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
- size_t domain_name_length)
-{
- struct wpabuf *buf = NULL;
- int ret, dscp_query_size;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
- return -1;
-
- if (!wpa_s->connection_dscp) {
- wpa_printf(MSG_ERROR,
- "QM: Failed to send DSCP query - DSCP capability not enabled for the current association");
- return -1;
- }
-
- if (wpa_s->wait_for_dscp_req) {
- wpa_printf(MSG_INFO, "QM: Wait until AP sends a DSCP request");
- return -1;
- }
-
-#define DOMAIN_NAME_OFFSET (4 /* OUI */ + 1 /* Attr Id */ + 1 /* Attr len */)
-
- if (domain_name_length > 255 - DOMAIN_NAME_OFFSET) {
- wpa_printf(MSG_ERROR, "QM: Too long domain name");
- return -1;
- }
-
- dscp_query_size = 1 + /* Category */
- 4 + /* OUI Type */
- 1 + /* OUI subtype */
- 1; /* Dialog Token */
- if (domain_name && domain_name_length)
- dscp_query_size += 1 + /* Element ID */
- 1 + /* IE Length */
- DOMAIN_NAME_OFFSET + domain_name_length;
-
- buf = wpabuf_alloc(dscp_query_size);
- if (!buf) {
- wpa_printf(MSG_ERROR, "QM: Failed to allocate DSCP query");
- return -1;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
- wpabuf_put_be32(buf, QM_ACTION_VENDOR_TYPE);
- wpabuf_put_u8(buf, QM_DSCP_POLICY_QUERY);
- wpa_s->dscp_query_dialog_token++;
- if (wpa_s->dscp_query_dialog_token == 0)
- wpa_s->dscp_query_dialog_token++;
- wpabuf_put_u8(buf, wpa_s->dscp_query_dialog_token);
-
- if (domain_name && domain_name_length) {
- /* Domain Name attribute */
- wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(buf, DOMAIN_NAME_OFFSET + domain_name_length);
- wpabuf_put_be32(buf, QM_IE_VENDOR_TYPE);
- wpabuf_put_u8(buf, QM_ATTR_DOMAIN_NAME);
- wpabuf_put_u8(buf, domain_name_length);
- wpabuf_put_data(buf, domain_name, domain_name_length);
- }
-#undef DOMAIN_NAME_OFFSET
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret < 0) {
- wpa_dbg(wpa_s, MSG_ERROR, "QM: Failed to send DSCP query");
- wpa_s->dscp_query_dialog_token--;
- }
-
- wpabuf_free(buf);
- return ret;
-}
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
deleted file mode 100644
index cf107ebaf639..000000000000
--- a/wpa_supplicant/rrm.c
+++ /dev/null
@@ -1,1594 +0,0 @@
-/*
- * wpa_supplicant - Radio Measurements
- * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_common.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "bss.h"
-#include "scan.h"
-#include "p2p_supplicant.h"
-
-
-static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
-{
- struct rrm_data *rrm = data;
-
- if (!rrm->notify_neighbor_rep) {
- wpa_printf(MSG_ERROR,
- "RRM: Unexpected neighbor report timeout");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
- rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
-
- rrm->notify_neighbor_rep = NULL;
- rrm->neighbor_rep_cb_ctx = NULL;
-}
-
-
-/*
- * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
- * @wpa_s: Pointer to wpa_supplicant
- */
-void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
-{
- wpa_s->rrm.rrm_used = 0;
-
- eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
- NULL);
- if (wpa_s->rrm.notify_neighbor_rep)
- wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
- wpa_s->rrm.next_neighbor_rep_token = 1;
- wpas_clear_beacon_rep_data(wpa_s);
-}
-
-
-/*
- * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
- * @wpa_s: Pointer to wpa_supplicant
- * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
- * @report_len: Length of neighbor report buffer
- */
-void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
- const u8 *report, size_t report_len)
-{
- struct wpabuf *neighbor_rep;
-
- wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
- if (report_len < 1)
- return;
-
- if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
- wpa_printf(MSG_DEBUG,
- "RRM: Discarding neighbor report with token %d (expected %d)",
- report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
- return;
- }
-
- eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
- NULL);
-
- if (!wpa_s->rrm.notify_neighbor_rep) {
- wpa_msg(wpa_s, MSG_INFO, "RRM: Unexpected neighbor report");
- return;
- }
-
- /* skipping the first byte, which is only an id (dialog token) */
- neighbor_rep = wpabuf_alloc(report_len - 1);
- if (!neighbor_rep) {
- wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
- return;
- }
- wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
- wpa_dbg(wpa_s, MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
- report[0]);
- wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
- neighbor_rep);
- wpa_s->rrm.notify_neighbor_rep = NULL;
- wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
-}
-
-
-#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
-/* Workaround different, undefined for Windows, error codes used here */
-#ifndef ENOTCONN
-#define ENOTCONN -1
-#endif
-#ifndef EOPNOTSUPP
-#define EOPNOTSUPP -1
-#endif
-#ifndef ECANCELED
-#define ECANCELED -1
-#endif
-#endif
-
-/* Measurement Request element + Location Subject + Maximum Age subelement */
-#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
-/* Measurement Request element + Location Civic Request */
-#define MEASURE_REQUEST_CIVIC_LEN (3 + 5)
-
-
-/**
- * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
- * @wpa_s: Pointer to wpa_supplicant
- * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
- * is sent in the request.
- * @lci: if set, neighbor request will include LCI request
- * @civic: if set, neighbor request will include civic location request
- * @cb: Callback function to be called once the requested report arrives, or
- * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
- * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
- * the requester's responsibility to free it.
- * In the latter case NULL will be sent in 'neighbor_rep'.
- * @cb_ctx: Context value to send the callback function
- * Returns: 0 in case of success, negative error code otherwise
- *
- * In case there is a previous request which has not been answered yet, the
- * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
- * Request must contain a callback function.
- */
-int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid_value *ssid,
- int lci, int civic,
- void (*cb)(void *ctx,
- struct wpabuf *neighbor_rep),
- void *cb_ctx)
-{
- struct wpabuf *buf;
- const u8 *rrm_ie;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No connection, no RRM.");
- return -ENOTCONN;
- }
-
- if (!wpa_s->rrm.rrm_used) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No RRM in current connection.");
- return -EOPNOTSUPP;
- }
-
- rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
- WLAN_EID_RRM_ENABLED_CAPABILITIES);
- if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
- !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RRM: No network support for Neighbor Report.");
- return -EOPNOTSUPP;
- }
-
- /* Refuse if there's a live request */
- if (wpa_s->rrm.notify_neighbor_rep) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RRM: Currently handling previous Neighbor Report.");
- return -EBUSY;
- }
-
- /* 3 = action category + action code + dialog token */
- buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
- (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
- (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
- if (buf == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RRM: Failed to allocate Neighbor Report Request");
- return -ENOMEM;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RRM: Neighbor report request (for %s), token=%d",
- (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
- wpa_s->rrm.next_neighbor_rep_token);
-
- wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
- wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
- wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
- if (ssid) {
- wpabuf_put_u8(buf, WLAN_EID_SSID);
- wpabuf_put_u8(buf, ssid->ssid_len);
- wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
- }
-
- if (lci) {
- /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
- wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
- wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);
-
- /*
- * Measurement token; nonzero number that is unique among the
- * Measurement Request elements in a particular frame.
- */
- wpabuf_put_u8(buf, 1); /* Measurement Token */
-
- /*
- * Parallel, Enable, Request, and Report bits are 0, Duration is
- * reserved.
- */
- wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
- wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */
-
- /* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */
- /* Location Subject */
- wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
-
- /* Optional Subelements */
- /*
- * IEEE P802.11-REVmc/D5.0 Figure 9-170
- * The Maximum Age subelement is required, otherwise the AP can
- * send only data that was determined after receiving the
- * request. Setting it here to unlimited age.
- */
- wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE);
- wpabuf_put_u8(buf, 2);
- wpabuf_put_le16(buf, 0xffff);
- }
-
- if (civic) {
- /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
- wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
- wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);
-
- /*
- * Measurement token; nonzero number that is unique among the
- * Measurement Request elements in a particular frame.
- */
- wpabuf_put_u8(buf, 2); /* Measurement Token */
-
- /*
- * Parallel, Enable, Request, and Report bits are 0, Duration is
- * reserved.
- */
- wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
- /* Measurement Type */
- wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);
-
- /* IEEE P802.11-REVmc/D5.0 9.4.2.21.14:
- * Location Civic request */
- /* Location Subject */
- wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
- wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */
- /* Location Service Interval Units: Seconds */
- wpabuf_put_u8(buf, 0);
- /* Location Service Interval: 0 - Only one report is requested
- */
- wpabuf_put_le16(buf, 0);
- /* No optional subelements */
- }
-
- wpa_s->rrm.next_neighbor_rep_token++;
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RRM: Failed to send Neighbor Report Request");
- wpabuf_free(buf);
- return -ECANCELED;
- }
-
- wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
- wpa_s->rrm.notify_neighbor_rep = cb;
- eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
- wpas_rrm_neighbor_rep_timeout_handler,
- &wpa_s->rrm, NULL);
-
- wpabuf_free(buf);
- return 0;
-}
-
-
-static int wpas_rrm_report_elem(struct wpabuf **buf, u8 token, u8 mode, u8 type,
- const u8 *data, size_t data_len)
-{
- if (wpabuf_resize(buf, 5 + data_len))
- return -1;
-
- wpabuf_put_u8(*buf, WLAN_EID_MEASURE_REPORT);
- wpabuf_put_u8(*buf, 3 + data_len);
- wpabuf_put_u8(*buf, token);
- wpabuf_put_u8(*buf, mode);
- wpabuf_put_u8(*buf, type);
-
- if (data_len)
- wpabuf_put_data(*buf, data, data_len);
-
- return 0;
-}
-
-
-static int
-wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s,
- const struct rrm_measurement_request_element *req,
- struct wpabuf **buf)
-{
- u8 subject;
- u16 max_age = 0;
- struct os_reltime t, diff;
- unsigned long diff_l;
- const u8 *subelem;
- const u8 *request = req->variable;
- size_t len = req->len - 3;
-
- if (len < 1)
- return -1;
-
- if (!wpa_s->lci)
- goto reject;
-
- subject = *request++;
- len--;
-
- wpa_printf(MSG_DEBUG, "Measurement request location subject=%u",
- subject);
-
- if (subject != LOCATION_SUBJECT_REMOTE) {
- wpa_printf(MSG_INFO,
- "Not building LCI report - bad location subject");
- return 0;
- }
-
- /* Subelements are formatted exactly like elements */
- wpa_hexdump(MSG_DEBUG, "LCI request subelements", request, len);
- subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE);
- if (subelem && subelem[1] == 2)
- max_age = WPA_GET_LE16(subelem + 2);
-
- if (os_get_reltime(&t))
- goto reject;
-
- os_reltime_sub(&t, &wpa_s->lci_time, &diff);
- /* LCI age is calculated in 10th of a second units. */
- diff_l = diff.sec * 10 + diff.usec / 100000;
-
- if (max_age != 0xffff && max_age < diff_l)
- goto reject;
-
- if (wpas_rrm_report_elem(buf, req->token,
- MEASUREMENT_REPORT_MODE_ACCEPT, req->type,
- wpabuf_head_u8(wpa_s->lci),
- wpabuf_len(wpa_s->lci)) < 0) {
- wpa_printf(MSG_DEBUG, "Failed to add LCI report element");
- return -1;
- }
-
- return 0;
-
-reject:
- if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
- wpas_rrm_report_elem(buf, req->token,
- MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE,
- req->type, NULL, 0) < 0) {
- wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
- return -1;
- }
-
- return 0;
-}
-
-
-static void wpas_rrm_send_msr_report_mpdu(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t len)
-{
- struct wpabuf *report = wpabuf_alloc(len + 3);
-
- if (!report)
- return;
-
- wpabuf_put_u8(report, WLAN_ACTION_RADIO_MEASUREMENT);
- wpabuf_put_u8(report, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
- wpabuf_put_u8(report, wpa_s->rrm.token);
-
- wpabuf_put_data(report, data, len);
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(report), wpabuf_len(report), 0)) {
- wpa_printf(MSG_ERROR,
- "RRM: Radio measurement report failed: Sending Action frame failed");
- }
-
- wpabuf_free(report);
-}
-
-
-static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
-{
- struct rrm_measurement_report_element *msr_rep;
- u8 *end = pos + len;
- u8 *msr_rep_end;
- struct rrm_measurement_beacon_report *rep = NULL;
- u8 *subelem;
-
- /* Find the last beacon report element */
- while (end - pos >= (int) sizeof(*msr_rep)) {
- msr_rep = (struct rrm_measurement_report_element *) pos;
- msr_rep_end = pos + msr_rep->len + 2;
-
- if (msr_rep->eid != WLAN_EID_MEASURE_REPORT ||
- msr_rep_end > end) {
- /* Should not happen. This indicates a bug. */
- wpa_printf(MSG_ERROR,
- "RRM: non-measurement report element in measurement report frame");
- return -1;
- }
-
- if (msr_rep->type == MEASURE_TYPE_BEACON)
- rep = (struct rrm_measurement_beacon_report *)
- msr_rep->variable;
-
- pos += pos[1] + 2;
- }
-
- if (!rep)
- return 0;
-
- subelem = rep->variable;
- while (subelem + 2 < msr_rep_end &&
- subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
- subelem += 2 + subelem[1];
-
- if (subelem + 2 < msr_rep_end &&
- subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
- subelem[1] == 1 &&
- subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
- subelem[2] = 1;
-
- return 0;
-}
-
-
-static void wpas_rrm_send_msr_report(struct wpa_supplicant *wpa_s,
- struct wpabuf *buf)
-{
- int len = wpabuf_len(buf);
- u8 *pos = wpabuf_mhead_u8(buf), *next = pos;
-
-#define MPDU_REPORT_LEN (int) (IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN - 3)
-
- while (len) {
- int send_len = (len > MPDU_REPORT_LEN) ? next - pos : len;
-
- if (send_len == len)
- wpas_rrm_beacon_rep_update_last_frame(pos, len);
-
- if (send_len == len ||
- (send_len + next[1] + 2) > MPDU_REPORT_LEN) {
- wpas_rrm_send_msr_report_mpdu(wpa_s, pos, send_len);
- len -= send_len;
- pos = next;
- }
-
- if (len)
- next += next[1] + 2;
- }
-#undef MPDU_REPORT_LEN
-}
-
-
-static int wpas_add_channel(u8 op_class, u8 chan, u8 num_primary_channels,
- int *freqs)
-{
- size_t i;
-
- for (i = 0; i < num_primary_channels; i++) {
- u8 primary_chan = chan - (2 * num_primary_channels - 2) + i * 4;
-
- freqs[i] = ieee80211_chan_to_freq(NULL, op_class, primary_chan);
- /* ieee80211_chan_to_freq() is not really meant for this
- * conversion of 20 MHz primary channel numbers for wider VHT
- * channels, so handle those as special cases here for now. */
- if (freqs[i] < 0 &&
- (op_class == 128 || op_class == 129 || op_class == 130))
- freqs[i] = 5000 + 5 * primary_chan;
- if (freqs[i] < 0) {
- wpa_printf(MSG_DEBUG,
- "Beacon Report: Invalid channel %u",
- chan);
- return -1;
- }
- }
-
- return 0;
-}
-
-
-static int * wpas_add_channels(const struct oper_class_map *op,
- struct hostapd_hw_modes *mode, int active,
- const u8 *channels, const u8 size)
-{
- int *freqs, *next_freq;
- u8 num_primary_channels, i;
- u8 num_chans;
-
- num_chans = channels ? size :
- (op->max_chan - op->min_chan) / op->inc + 1;
-
- if (op->bw == BW80 || op->bw == BW80P80)
- num_primary_channels = 4;
- else if (op->bw == BW160)
- num_primary_channels = 8;
- else
- num_primary_channels = 1;
-
- /* one extra place for the zero-terminator */
- freqs = os_calloc(num_chans * num_primary_channels + 1, sizeof(*freqs));
- if (!freqs) {
- wpa_printf(MSG_ERROR,
- "Beacon Report: Failed to allocate freqs array");
- return NULL;
- }
-
- next_freq = freqs;
- for (i = 0; i < num_chans; i++) {
- u8 chan = channels ? channels[i] : op->min_chan + i * op->inc;
- enum chan_allowed res = verify_channel(mode, op->op_class, chan,
- op->bw);
-
- if (res == NOT_ALLOWED || (res == NO_IR && active))
- continue;
-
- if (wpas_add_channel(op->op_class, chan, num_primary_channels,
- next_freq) < 0) {
- os_free(freqs);
- return NULL;
- }
-
- next_freq += num_primary_channels;
- }
-
- if (!freqs[0]) {
- os_free(freqs);
- return NULL;
- }
-
- return freqs;
-}
-
-
-static int * wpas_op_class_freqs(const struct oper_class_map *op,
- struct hostapd_hw_modes *mode, int active)
-{
- u8 channels_80mhz_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
- u8 channels_160mhz_5ghz[] = { 50, 114, 163 };
- u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
- 167, 183, 199, 215 };
- u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
- const u8 *channels = NULL;
- size_t num_chan = 0;
- bool is_6ghz = is_6ghz_op_class(op->op_class);
-
- /*
- * When adding all channels in the operating class, 80 + 80 MHz
- * operating classes are like 80 MHz channels because we add all valid
- * channels anyway.
- */
- if (op->bw == BW80 || op->bw == BW80P80) {
- channels = is_6ghz ? channels_80mhz_6ghz : channels_80mhz_5ghz;
- num_chan = is_6ghz ? ARRAY_SIZE(channels_80mhz_6ghz) :
- ARRAY_SIZE(channels_80mhz_5ghz);
- } else if (op->bw == BW160) {
- channels = is_6ghz ? channels_160mhz_6ghz :
- channels_160mhz_5ghz;
- num_chan = is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) :
- ARRAY_SIZE(channels_160mhz_5ghz);
- }
-
- return wpas_add_channels(op, mode, active, channels, num_chan);
-}
-
-
-static int * wpas_channel_report_freqs(struct wpa_supplicant *wpa_s, int active,
- const char *country, const u8 *subelems,
- size_t len)
-{
- int *freqs = NULL, *new_freqs;
- const u8 *end = subelems + len;
-
- while (end - subelems > 2) {
- const struct oper_class_map *op;
- const u8 *ap_chan_elem, *pos;
- u8 left;
- struct hostapd_hw_modes *mode;
-
- ap_chan_elem = get_ie(subelems, end - subelems,
- WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL);
- if (!ap_chan_elem)
- break;
- pos = ap_chan_elem + 2;
- left = ap_chan_elem[1];
- if (left < 1)
- break;
- subelems = ap_chan_elem + 2 + left;
-
- op = get_oper_class(country, *pos);
- if (!op) {
- wpa_printf(MSG_DEBUG,
- "Beacon request: unknown operating class in AP Channel Report subelement %u",
- *pos);
- goto out;
- }
- pos++;
- left--;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode,
- is_6ghz_op_class(op->op_class));
- if (!mode)
- continue;
-
- /*
- * For 80 + 80 MHz operating classes, this AP Channel Report
- * element should be followed by another element specifying
- * the second 80 MHz channel. For now just add this 80 MHz
- * channel, the second 80 MHz channel will be added when the
- * next element is parsed.
- * TODO: Verify that this AP Channel Report element is followed
- * by a corresponding AP Channel Report element as specified in
- * IEEE Std 802.11-2016, 11.11.9.1.
- */
- new_freqs = wpas_add_channels(op, mode, active, pos, left);
- if (new_freqs)
- int_array_concat(&freqs, new_freqs);
-
- os_free(new_freqs);
- }
-
- return freqs;
-out:
- os_free(freqs);
- return NULL;
-}
-
-
-static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s,
- u8 op_class, u8 chan, int active,
- const u8 *subelems, size_t len)
-{
- int *freqs = NULL, *ext_freqs = NULL;
- struct hostapd_hw_modes *mode;
- const char *country = NULL;
- const struct oper_class_map *op;
- const u8 *elem;
-
- if (!wpa_s->current_bss)
- return NULL;
- elem = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
- if (elem && elem[1] >= 2)
- country = (const char *) (elem + 2);
-
- op = get_oper_class(country, op_class);
- if (!op) {
- wpa_printf(MSG_DEBUG,
- "Beacon request: invalid operating class %d",
- op_class);
- return NULL;
- }
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode,
- is_6ghz_op_class(op->op_class));
- if (!mode)
- return NULL;
-
- switch (chan) {
- case 0:
- freqs = wpas_op_class_freqs(op, mode, active);
- if (!freqs)
- return NULL;
- break;
- case 255:
- /* freqs will be added from AP channel subelements */
- break;
- default:
- freqs = wpas_add_channels(op, mode, active, &chan, 1);
- if (!freqs)
- return NULL;
- break;
- }
-
- ext_freqs = wpas_channel_report_freqs(wpa_s, active, country, subelems,
- len);
- if (ext_freqs) {
- int_array_concat(&freqs, ext_freqs);
- os_free(ext_freqs);
- int_array_sort_unique(freqs);
- }
-
- return freqs;
-}
-
-
-int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
- u8 *op_class, u8 *chan, u8 *phy_type)
-{
- const u8 *ie;
- int sec_chan = 0, vht = 0;
- struct ieee80211_ht_operation *ht_oper = NULL;
- struct ieee80211_vht_operation *vht_oper = NULL;
- u8 seg0, seg1;
-
- ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= sizeof(struct ieee80211_ht_operation)) {
- u8 sec_chan_offset;
-
- ht_oper = (struct ieee80211_ht_operation *) (ie + 2);
- sec_chan_offset = ht_oper->ht_param &
- HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
- if (sec_chan_offset == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
- sec_chan = 1;
- else if (sec_chan_offset ==
- HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
- sec_chan = -1;
- }
-
- ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
- if (ie && ie[1] >= sizeof(struct ieee80211_vht_operation)) {
- vht_oper = (struct ieee80211_vht_operation *) (ie + 2);
-
- switch (vht_oper->vht_op_info_chwidth) {
- case 1:
- seg0 = vht_oper->vht_op_info_chan_center_freq_seg0_idx;
- seg1 = vht_oper->vht_op_info_chan_center_freq_seg1_idx;
- if (seg1 && abs(seg1 - seg0) == 8)
- vht = CHANWIDTH_160MHZ;
- else if (seg1)
- vht = CHANWIDTH_80P80MHZ;
- else
- vht = CHANWIDTH_80MHZ;
- break;
- case 2:
- vht = CHANWIDTH_160MHZ;
- break;
- case 3:
- vht = CHANWIDTH_80P80MHZ;
- break;
- default:
- vht = CHANWIDTH_USE_HT;
- break;
- }
- }
-
- if (ieee80211_freq_to_channel_ext(freq, sec_chan, vht, op_class,
- chan) == NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_DEBUG,
- "Cannot determine operating class and channel");
- return -1;
- }
-
- *phy_type = ieee80211_get_phy_type(freq, ht_oper != NULL,
- vht_oper != NULL);
- if (*phy_type == PHY_TYPE_UNSPECIFIED) {
- wpa_printf(MSG_DEBUG, "Cannot determine phy type");
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpas_beacon_rep_add_frame_body(struct bitfield *eids,
- enum beacon_report_detail detail,
- struct wpa_bss *bss, u8 *buf,
- size_t buf_len, const u8 **ies_buf,
- size_t *ie_len, int add_fixed)
-{
- const u8 *ies = *ies_buf;
- size_t ies_len = *ie_len;
- u8 *pos = buf;
- int rem_len;
-
- rem_len = 255 - sizeof(struct rrm_measurement_beacon_report) -
- sizeof(struct rrm_measurement_report_element) - 2 -
- REPORTED_FRAME_BODY_SUBELEM_LEN;
-
- if (detail > BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) {
- wpa_printf(MSG_DEBUG,
- "Beacon Request: Invalid reporting detail: %d",
- detail);
- return -1;
- }
-
- if (detail == BEACON_REPORT_DETAIL_NONE)
- return 0;
-
- /*
- * Minimal frame body subelement size: EID(1) + length(1) + TSF(8) +
- * beacon interval(2) + capabilities(2) = 14 bytes
- */
- if (add_fixed && buf_len < 14)
- return -1;
-
- *pos++ = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY;
- /* The length will be filled later */
- pos++;
-
- if (add_fixed) {
- WPA_PUT_LE64(pos, bss->tsf);
- pos += sizeof(bss->tsf);
- WPA_PUT_LE16(pos, bss->beacon_int);
- pos += 2;
- WPA_PUT_LE16(pos, bss->caps);
- pos += 2;
- }
-
- rem_len -= pos - buf;
-
- /*
- * According to IEEE Std 802.11-2016, 9.4.2.22.7, if the reported frame
- * body subelement causes the element to exceed the maximum element
- * size, the subelement is truncated so that the last IE is a complete
- * IE. So even when required to report all IEs, add elements one after
- * the other and stop once there is no more room in the measurement
- * element.
- */
- while (ies_len > 2 && 2U + ies[1] <= ies_len && rem_len > 0) {
- if (detail == BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS ||
- (eids && bitfield_is_set(eids, ies[0]))) {
- u8 elen = ies[1];
-
- if (2 + elen > buf + buf_len - pos ||
- 2 + elen > rem_len)
- break;
-
- *pos++ = ies[0];
- *pos++ = elen;
- os_memcpy(pos, ies + 2, elen);
- pos += elen;
- rem_len -= 2 + elen;
- }
-
- ies_len -= 2 + ies[1];
- ies += 2 + ies[1];
- }
-
- *ie_len = ies_len;
- *ies_buf = ies;
-
- /* Now the length is known */
- buf[1] = pos - buf - 2;
- return pos - buf;
-}
-
-
-static int wpas_add_beacon_rep_elem(struct beacon_rep_data *data,
- struct wpa_bss *bss,
- struct wpabuf **wpa_buf,
- struct rrm_measurement_beacon_report *rep,
- const u8 **ie, size_t *ie_len, u8 idx)
-{
- int ret;
- u8 *buf, *pos;
- u32 subelems_len = REPORTED_FRAME_BODY_SUBELEM_LEN +
- (data->last_indication ?
- BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN : 0);
-
- /* Maximum element length: Beacon Report element + Reported Frame Body
- * subelement + all IEs of the reported Beacon frame + Reported Frame
- * Body Fragment ID subelement */
- buf = os_malloc(sizeof(*rep) + 14 + *ie_len + subelems_len);
- if (!buf)
- return -1;
-
- os_memcpy(buf, rep, sizeof(*rep));
-
- ret = wpas_beacon_rep_add_frame_body(data->eids, data->report_detail,
- bss, buf + sizeof(*rep),
- 14 + *ie_len, ie, ie_len,
- idx == 0);
- if (ret < 0)
- goto out;
-
- pos = buf + ret + sizeof(*rep);
- pos[0] = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID;
- pos[1] = 2;
-
- /*
- * Only one Beacon Report Measurement is supported at a time, so
- * the Beacon Report ID can always be set to 1.
- */
- pos[2] = 1;
-
- /* Fragment ID Number (bits 0..6) and More Frame Body Fragments (bit 7)
- */
- pos[3] = idx;
- if (data->report_detail != BEACON_REPORT_DETAIL_NONE && *ie_len)
- pos[3] |= REPORTED_FRAME_BODY_MORE_FRAGMENTS;
- else
- pos[3] &= ~REPORTED_FRAME_BODY_MORE_FRAGMENTS;
-
- pos += REPORTED_FRAME_BODY_SUBELEM_LEN;
-
- if (data->last_indication) {
- pos[0] = WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION;
- pos[1] = 1;
-
- /* This field will be updated later if this is the last frame */
- pos[2] = 0;
- }
-
- ret = wpas_rrm_report_elem(wpa_buf, data->token,
- MEASUREMENT_REPORT_MODE_ACCEPT,
- MEASURE_TYPE_BEACON, buf,
- ret + sizeof(*rep) + subelems_len);
-out:
- os_free(buf);
- return ret;
-}
-
-
-static int wpas_add_beacon_rep(struct wpa_supplicant *wpa_s,
- struct wpabuf **wpa_buf, struct wpa_bss *bss,
- u64 start, u64 parent_tsf)
-{
- struct beacon_rep_data *data = &wpa_s->beacon_rep_data;
- const u8 *ies = wpa_bss_ie_ptr(bss);
- const u8 *pos = ies;
- size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
- struct rrm_measurement_beacon_report rep;
- u8 idx = 0;
-
- if (os_memcmp(data->bssid, broadcast_ether_addr, ETH_ALEN) != 0 &&
- os_memcmp(data->bssid, bss->bssid, ETH_ALEN) != 0)
- return 0;
-
- if (data->ssid_len &&
- (data->ssid_len != bss->ssid_len ||
- os_memcmp(data->ssid, bss->ssid, bss->ssid_len) != 0))
- return 0;
-
- if (wpas_get_op_chan_phy(bss->freq, ies, ies_len, &rep.op_class,
- &rep.channel, &rep.report_info) < 0)
- return 0;
-
- rep.start_time = host_to_le64(start);
- rep.duration = host_to_le16(data->scan_params.duration);
- rep.rcpi = rssi_to_rcpi(bss->level);
- rep.rsni = 255; /* 255 indicates that RSNI is not available */
- os_memcpy(rep.bssid, bss->bssid, ETH_ALEN);
- rep.antenna_id = 0; /* unknown */
- rep.parent_tsf = host_to_le32(parent_tsf);
-
- do {
- int ret;
-
- ret = wpas_add_beacon_rep_elem(data, bss, wpa_buf, &rep,
- &pos, &ies_len, idx++);
- if (ret)
- return ret;
- } while (data->report_detail != BEACON_REPORT_DETAIL_NONE &&
- ies_len >= 2);
-
- return 0;
-}
-
-
-static int wpas_beacon_rep_no_results(struct wpa_supplicant *wpa_s,
- struct wpabuf **buf)
-{
- return wpas_rrm_report_elem(buf, wpa_s->beacon_rep_data.token,
- MEASUREMENT_REPORT_MODE_ACCEPT,
- MEASURE_TYPE_BEACON, NULL, 0);
-}
-
-
-static void wpas_beacon_rep_table(struct wpa_supplicant *wpa_s,
- struct wpabuf **buf)
-{
- size_t i;
-
- for (i = 0; i < wpa_s->last_scan_res_used; i++) {
- if (wpas_add_beacon_rep(wpa_s, buf, wpa_s->last_scan_res[i],
- 0, 0) < 0)
- break;
- }
-
- if (!(*buf))
- wpas_beacon_rep_no_results(wpa_s, buf);
-
- wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", *buf);
-}
-
-
-void wpas_rrm_refuse_request(struct wpa_supplicant *wpa_s)
-{
- if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr)) {
- struct wpabuf *buf = NULL;
-
- if (wpas_rrm_report_elem(&buf, wpa_s->beacon_rep_data.token,
- MEASUREMENT_REPORT_MODE_REJECT_REFUSED,
- MEASURE_TYPE_BEACON, NULL, 0)) {
- wpa_printf(MSG_ERROR, "RRM: Memory allocation failed");
- wpabuf_free(buf);
- return;
- }
-
- wpas_rrm_send_msr_report(wpa_s, buf);
- wpabuf_free(buf);
- }
-
- wpas_clear_beacon_rep_data(wpa_s);
-}
-
-
-static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_driver_scan_params *params =
- &wpa_s->beacon_rep_data.scan_params;
- u16 prev_duration = params->duration;
-
- if (!wpa_s->current_bss)
- return;
-
- if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL) &&
- params->duration) {
- wpa_printf(MSG_DEBUG,
- "RRM: Cannot set scan duration due to missing driver support");
- params->duration = 0;
- }
- os_get_reltime(&wpa_s->beacon_rep_scan);
- if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
- wpa_supplicant_trigger_scan(wpa_s, params))
- wpas_rrm_refuse_request(wpa_s);
- params->duration = prev_duration;
-}
-
-
-static int wpas_rm_handle_beacon_req_subelem(struct wpa_supplicant *wpa_s,
- struct beacon_rep_data *data,
- u8 sid, u8 slen, const u8 *subelem)
-{
- u8 report_info, i;
-
- switch (sid) {
- case WLAN_BEACON_REQUEST_SUBELEM_SSID:
- if (!slen) {
- wpa_printf(MSG_DEBUG,
- "SSID subelement with zero length - wildcard SSID");
- break;
- }
-
- if (slen > SSID_MAX_LEN) {
- wpa_printf(MSG_DEBUG,
- "Invalid SSID subelement length: %u", slen);
- return -1;
- }
-
- data->ssid_len = slen;
- os_memcpy(data->ssid, subelem, data->ssid_len);
- break;
- case WLAN_BEACON_REQUEST_SUBELEM_INFO:
- if (slen != 2) {
- wpa_printf(MSG_DEBUG,
- "Invalid reporting information subelement length: %u",
- slen);
- return -1;
- }
-
- report_info = subelem[0];
- if (report_info != 0) {
- wpa_printf(MSG_DEBUG,
- "reporting information=%u is not supported",
- report_info);
- return 0;
- }
- break;
- case WLAN_BEACON_REQUEST_SUBELEM_DETAIL:
- if (slen != 1) {
- wpa_printf(MSG_DEBUG,
- "Invalid reporting detail subelement length: %u",
- slen);
- return -1;
- }
-
- data->report_detail = subelem[0];
- if (data->report_detail >
- BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) {
- wpa_printf(MSG_DEBUG, "Invalid reporting detail: %u",
- subelem[0]);
- return -1;
- }
-
- break;
- case WLAN_BEACON_REQUEST_SUBELEM_REQUEST:
- if (data->report_detail !=
- BEACON_REPORT_DETAIL_REQUESTED_ONLY) {
- wpa_printf(MSG_DEBUG,
- "Beacon request: request subelement is present but report detail is %u",
- data->report_detail);
- return -1;
- }
-
- if (!slen) {
- wpa_printf(MSG_DEBUG,
- "Invalid request subelement length: %u",
- slen);
- return -1;
- }
-
- if (data->eids) {
- wpa_printf(MSG_DEBUG,
- "Beacon Request: Request subelement appears more than once");
- return -1;
- }
-
- data->eids = bitfield_alloc(255);
- if (!data->eids) {
- wpa_printf(MSG_DEBUG, "Failed to allocate EIDs bitmap");
- return -1;
- }
-
- for (i = 0; i < slen; i++)
- bitfield_set(data->eids, subelem[i]);
- break;
- case WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL:
- /* Skip - it will be processed when freqs are added */
- break;
- case WLAN_BEACON_REQUEST_SUBELEM_LAST_INDICATION:
- if (slen != 1) {
- wpa_printf(MSG_DEBUG,
- "Beacon request: Invalid last indication request subelement length: %u",
- slen);
- return -1;
- }
-
- data->last_indication = subelem[0];
- break;
- default:
- wpa_printf(MSG_DEBUG,
- "Beacon request: Unknown subelement id %u", sid);
- break;
- }
-
- return 1;
-}
-
-
-/**
- * Returns 0 if the next element can be processed, 1 if some operation was
- * triggered, and -1 if processing failed (i.e., the element is in invalid
- * format or an internal error occurred).
- */
-static int
-wpas_rm_handle_beacon_req(struct wpa_supplicant *wpa_s,
- u8 elem_token, int duration_mandatory,
- const struct rrm_measurement_beacon_request *req,
- size_t len, struct wpabuf **buf)
-{
- struct beacon_rep_data *data = &wpa_s->beacon_rep_data;
- struct wpa_driver_scan_params *params = &data->scan_params;
- const u8 *subelems;
- size_t elems_len;
- u16 rand_interval;
- u32 interval_usec;
- u32 _rand;
- int ret = 0, res;
- u8 reject_mode;
-
- if (len < sizeof(*req))
- return -1;
-
- if (req->mode != BEACON_REPORT_MODE_PASSIVE &&
- req->mode != BEACON_REPORT_MODE_ACTIVE &&
- req->mode != BEACON_REPORT_MODE_TABLE)
- return 0;
-
- subelems = req->variable;
- elems_len = len - sizeof(*req);
- rand_interval = le_to_host16(req->rand_interval);
-
- os_free(params->freqs);
- os_memset(params, 0, sizeof(*params));
-
- data->token = elem_token;
-
- /* default reporting detail is all fixed length fields and all
- * elements */
- data->report_detail = BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS;
- os_memcpy(data->bssid, req->bssid, ETH_ALEN);
-
- while (elems_len >= 2) {
- if (subelems[1] > elems_len - 2) {
- wpa_printf(MSG_DEBUG,
- "Beacon Request: Truncated subelement");
- ret = -1;
- goto out;
- }
-
- res = wpas_rm_handle_beacon_req_subelem(
- wpa_s, data, subelems[0], subelems[1], &subelems[2]);
- if (res < 0) {
- ret = res;
- goto out;
- } else if (!res) {
- reject_mode = MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE;
- goto out_reject;
- }
-
- elems_len -= 2 + subelems[1];
- subelems += 2 + subelems[1];
- }
-
- if (req->mode == BEACON_REPORT_MODE_TABLE) {
- wpas_beacon_rep_table(wpa_s, buf);
- goto out;
- }
-
- params->freqs = wpas_beacon_request_freqs(
- wpa_s, req->oper_class, req->channel,
- req->mode == BEACON_REPORT_MODE_ACTIVE,
- req->variable, len - sizeof(*req));
- if (!params->freqs) {
- wpa_printf(MSG_DEBUG, "Beacon request: No valid channels");
- reject_mode = MEASUREMENT_REPORT_MODE_REJECT_REFUSED;
- goto out_reject;
- }
-
- params->duration = le_to_host16(req->duration);
- params->duration_mandatory = duration_mandatory;
- if (!params->duration) {
- wpa_printf(MSG_DEBUG, "Beacon request: Duration is 0");
- ret = -1;
- goto out;
- }
-
- params->only_new_results = 1;
-
- if (req->mode == BEACON_REPORT_MODE_ACTIVE) {
- params->ssids[params->num_ssids].ssid = data->ssid;
- params->ssids[params->num_ssids++].ssid_len = data->ssid_len;
- }
-
- if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
- _rand = os_random();
- interval_usec = (_rand % (rand_interval + 1)) * 1024;
- eloop_register_timeout(0, interval_usec, wpas_rrm_scan_timeout, wpa_s,
- NULL);
- return 1;
-out_reject:
- if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
- wpas_rrm_report_elem(buf, elem_token, reject_mode,
- MEASURE_TYPE_BEACON, NULL, 0) < 0) {
- wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
- ret = -1;
- }
-out:
- wpas_clear_beacon_rep_data(wpa_s);
- return ret;
-}
-
-
-static int
-wpas_rrm_handle_msr_req_element(
- struct wpa_supplicant *wpa_s,
- const struct rrm_measurement_request_element *req,
- struct wpabuf **buf)
-{
- int duration_mandatory;
-
- wpa_printf(MSG_DEBUG, "Measurement request type %d token %d",
- req->type, req->token);
-
- if (req->mode & MEASUREMENT_REQUEST_MODE_ENABLE) {
- /* Enable bit is not supported for now */
- wpa_printf(MSG_DEBUG, "RRM: Enable bit not supported, ignore");
- return 0;
- }
-
- if ((req->mode & MEASUREMENT_REQUEST_MODE_PARALLEL) &&
- req->type > MEASURE_TYPE_RPI_HIST) {
- /* Parallel measurements are not supported for now */
- wpa_printf(MSG_DEBUG,
- "RRM: Parallel measurements are not supported, reject");
- goto reject;
- }
-
- duration_mandatory =
- !!(req->mode & MEASUREMENT_REQUEST_MODE_DURATION_MANDATORY);
-
- switch (req->type) {
- case MEASURE_TYPE_LCI:
- return wpas_rrm_build_lci_report(wpa_s, req, buf);
- case MEASURE_TYPE_BEACON:
- if (duration_mandatory &&
- !(wpa_s->drv_rrm_flags &
- WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL)) {
- wpa_printf(MSG_DEBUG,
- "RRM: Driver does not support dwell time configuration - reject beacon report with mandatory duration");
- goto reject;
- }
- return wpas_rm_handle_beacon_req(wpa_s, req->token,
- duration_mandatory,
- (const void *) req->variable,
- req->len - 3, buf);
- default:
- wpa_printf(MSG_INFO,
- "RRM: Unsupported radio measurement type %u",
- req->type);
- break;
- }
-
-reject:
- if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
- wpas_rrm_report_elem(buf, req->token,
- MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE,
- req->type, NULL, 0) < 0) {
- wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
- return -1;
- }
-
- return 0;
-}
-
-
-static struct wpabuf *
-wpas_rrm_process_msr_req_elems(struct wpa_supplicant *wpa_s, const u8 *pos,
- size_t len)
-{
- struct wpabuf *buf = NULL;
-
- while (len) {
- const struct rrm_measurement_request_element *req;
- int res;
-
- if (len < 2) {
- wpa_printf(MSG_DEBUG, "RRM: Truncated element");
- goto out;
- }
-
- req = (const struct rrm_measurement_request_element *) pos;
- if (req->eid != WLAN_EID_MEASURE_REQUEST) {
- wpa_printf(MSG_DEBUG,
- "RRM: Expected Measurement Request element, but EID is %u",
- req->eid);
- goto out;
- }
-
- if (req->len < 3) {
- wpa_printf(MSG_DEBUG, "RRM: Element length too short");
- goto out;
- }
-
- if (req->len > len - 2) {
- wpa_printf(MSG_DEBUG, "RRM: Element length too long");
- goto out;
- }
-
- res = wpas_rrm_handle_msr_req_element(wpa_s, req, &buf);
- if (res < 0)
- goto out;
-
- pos += req->len + 2;
- len -= req->len + 2;
- }
-
- return buf;
-
-out:
- wpabuf_free(buf);
- return NULL;
-}
-
-
-void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *dst,
- const u8 *frame, size_t len)
-{
- struct wpabuf *report;
-
- if (wpa_s->wpa_state != WPA_COMPLETED) {
- wpa_printf(MSG_INFO,
- "RRM: Ignoring radio measurement request: Not associated");
- return;
- }
-
- if (!wpa_s->rrm.rrm_used) {
- wpa_printf(MSG_INFO,
- "RRM: Ignoring radio measurement request: Not RRM network");
- return;
- }
-
- if (len < 3) {
- wpa_printf(MSG_INFO,
- "RRM: Ignoring too short radio measurement request");
- return;
- }
-
- wpa_s->rrm.token = *frame;
- os_memcpy(wpa_s->rrm.dst_addr, dst, ETH_ALEN);
-
- /* Number of repetitions is not supported */
-
- report = wpas_rrm_process_msr_req_elems(wpa_s, frame + 3, len - 3);
- if (!report)
- return;
-
- wpas_rrm_send_msr_report(wpa_s, report);
- wpabuf_free(report);
-}
-
-
-void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
- const u8 *src,
- const u8 *frame, size_t len,
- int rssi)
-{
- struct wpabuf *buf;
- const struct rrm_link_measurement_request *req;
- struct rrm_link_measurement_report report;
-
- if (wpa_s->wpa_state != WPA_COMPLETED) {
- wpa_printf(MSG_INFO,
- "RRM: Ignoring link measurement request. Not associated");
- return;
- }
-
- if (!wpa_s->rrm.rrm_used) {
- wpa_printf(MSG_INFO,
- "RRM: Ignoring link measurement request. Not RRM network");
- return;
- }
-
- if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
- wpa_printf(MSG_INFO,
- "RRM: Measurement report failed. TX power insertion not supported");
- return;
- }
-
- req = (const struct rrm_link_measurement_request *) frame;
- if (len < sizeof(*req)) {
- wpa_printf(MSG_INFO,
- "RRM: Link measurement report failed. Request too short");
- return;
- }
-
- os_memset(&report, 0, sizeof(report));
- report.dialog_token = req->dialog_token;
- report.tpc.eid = WLAN_EID_TPC_REPORT;
- report.tpc.len = 2;
- /* Note: The driver is expected to update report.tpc.tx_power and
- * report.tpc.link_margin subfields when sending out this frame.
- * Similarly, the driver would need to update report.rx_ant_id and
- * report.tx_ant_id subfields. */
- report.rsni = 255; /* 255 indicates that RSNI is not available */
- report.rcpi = rssi_to_rcpi(rssi);
-
- /* action_category + action_code */
- buf = wpabuf_alloc(2 + sizeof(report));
- if (buf == NULL) {
- wpa_printf(MSG_ERROR,
- "RRM: Link measurement report failed. Buffer allocation failed");
- return;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
- wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
- wpabuf_put_data(buf, &report, sizeof(report));
- wpa_hexdump_buf(MSG_DEBUG, "RRM: Link measurement report", buf);
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0)) {
- wpa_printf(MSG_ERROR,
- "RRM: Link measurement report failed. Send action failed");
- }
- wpabuf_free(buf);
-}
-
-
-int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res,
- struct scan_info *info)
-{
- size_t i = 0;
- struct wpabuf *buf = NULL;
-
- if (!wpa_s->beacon_rep_data.token)
- return 0;
-
- if (!wpa_s->current_bss)
- goto out;
-
- /* If the measurement was aborted, don't report partial results */
- if (info->aborted)
- goto out;
-
- wpa_printf(MSG_DEBUG, "RRM: TSF BSSID: " MACSTR " current BSS: " MACSTR,
- MAC2STR(info->scan_start_tsf_bssid),
- MAC2STR(wpa_s->current_bss->bssid));
- if ((wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
- os_memcmp(info->scan_start_tsf_bssid, wpa_s->current_bss->bssid,
- ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG,
- "RRM: Ignore scan results due to mismatching TSF BSSID");
- goto out;
- }
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_bss *bss =
- wpa_bss_get_bssid(wpa_s, scan_res->res[i]->bssid);
-
- if (!bss)
- continue;
-
- if ((wpa_s->drv_rrm_flags &
- WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
- os_memcmp(scan_res->res[i]->tsf_bssid,
- wpa_s->current_bss->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG,
- "RRM: Ignore scan result for " MACSTR
- " due to mismatching TSF BSSID" MACSTR,
- MAC2STR(scan_res->res[i]->bssid),
- MAC2STR(scan_res->res[i]->tsf_bssid));
- continue;
- }
-
- /*
- * Don't report results that were not received during the
- * current measurement.
- */
- if (!(wpa_s->drv_rrm_flags &
- WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)) {
- struct os_reltime update_time, diff;
-
- /* For now, allow 8 ms older results due to some
- * unknown issue with cfg80211 BSS table updates during
- * a scan with the current BSS.
- * TODO: Fix this more properly to avoid having to have
- * this type of hacks in place. */
- calculate_update_time(&scan_res->fetch_time,
- scan_res->res[i]->age,
- &update_time);
- os_reltime_sub(&wpa_s->beacon_rep_scan,
- &update_time, &diff);
- if (os_reltime_before(&update_time,
- &wpa_s->beacon_rep_scan) &&
- (diff.sec || diff.usec >= 8000)) {
- wpa_printf(MSG_DEBUG,
- "RRM: Ignore scan result for " MACSTR
- " due to old update (age(ms) %u, calculated age %u.%06u seconds)",
- MAC2STR(scan_res->res[i]->bssid),
- scan_res->res[i]->age,
- (unsigned int) diff.sec,
- (unsigned int) diff.usec);
- continue;
- }
- } else if (info->scan_start_tsf >
- scan_res->res[i]->parent_tsf) {
- continue;
- }
-
- if (wpas_add_beacon_rep(wpa_s, &buf, bss, info->scan_start_tsf,
- scan_res->res[i]->parent_tsf) < 0)
- break;
- }
-
- if (!buf && wpas_beacon_rep_no_results(wpa_s, &buf))
- goto out;
-
- wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", buf);
-
- wpas_rrm_send_msr_report(wpa_s, buf);
- wpabuf_free(buf);
-
-out:
- wpas_clear_beacon_rep_data(wpa_s);
- return 1;
-}
-
-
-void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s)
-{
- struct beacon_rep_data *data = &wpa_s->beacon_rep_data;
-
- eloop_cancel_timeout(wpas_rrm_scan_timeout, wpa_s, NULL);
- bitfield_free(data->eids);
- os_free(data->scan_params.freqs);
- os_memset(data, 0, sizeof(*data));
-}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
deleted file mode 100644
index b0094ca6ca5b..000000000000
--- a/wpa_supplicant/scan.c
+++ /dev/null
@@ -1,3360 +0,0 @@
-/*
- * WPA Supplicant - Scanning
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_defs.h"
-#include "common/wpa_ctrl.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "wps_supplicant.h"
-#include "p2p_supplicant.h"
-#include "p2p/p2p.h"
-#include "hs20_supplicant.h"
-#include "notify.h"
-#include "bss.h"
-#include "scan.h"
-#include "mesh.h"
-
-
-static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
- union wpa_event_data data;
-
- ssid = wpa_supplicant_get_ssid(wpa_s);
- if (ssid == NULL)
- return;
-
- if (wpa_s->current_ssid == NULL) {
- wpa_s->current_ssid = ssid;
- wpas_notify_network_changed(wpa_s);
- }
- wpa_supplicant_initiate_eapol(wpa_s);
- wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured "
- "network - generating associated event");
- os_memset(&data, 0, sizeof(data));
- wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
-}
-
-
-#ifdef CONFIG_WPS
-static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
- enum wps_request_type *req_type)
-{
- struct wpa_ssid *ssid;
- int wps = 0;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
- continue;
-
- wps = 1;
- *req_type = wpas_wps_get_req_type(ssid);
- if (ssid->eap.phase1 && os_strstr(ssid->eap.phase1, "pbc=1"))
- return 2;
- }
-
-#ifdef CONFIG_P2P
- if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
- !wpa_s->conf->p2p_disabled) {
- wpa_s->wps->dev.p2p = 1;
- if (!wps) {
- wps = 1;
- *req_type = WPS_REQ_ENROLLEE_INFO;
- }
- }
-#endif /* CONFIG_P2P */
-
- return wps;
-}
-#endif /* CONFIG_WPS */
-
-
-static int wpa_setup_mac_addr_rand_params(struct wpa_driver_scan_params *params,
- const u8 *mac_addr)
-{
- u8 *tmp;
-
- if (params->mac_addr) {
- params->mac_addr_mask = NULL;
- os_free(params->mac_addr);
- params->mac_addr = NULL;
- }
-
- params->mac_addr_rand = 1;
-
- if (!mac_addr)
- return 0;
-
- tmp = os_malloc(2 * ETH_ALEN);
- if (!tmp)
- return -1;
-
- os_memcpy(tmp, mac_addr, 2 * ETH_ALEN);
- params->mac_addr = tmp;
- params->mac_addr_mask = tmp + ETH_ALEN;
- return 0;
-}
-
-
-/**
- * wpa_supplicant_enabled_networks - Check whether there are enabled networks
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 if no networks are enabled, >0 if networks are enabled
- *
- * This function is used to figure out whether any networks (or Interworking
- * with enabled credentials and auto_interworking) are present in the current
- * configuration.
- */
-int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->conf->ssid;
- int count = 0, disabled = 0;
-
- if (wpa_s->p2p_mgmt)
- return 0; /* no normal network profiles on p2p_mgmt interface */
-
- while (ssid) {
- if (!wpas_network_disabled(wpa_s, ssid))
- count++;
- else
- disabled++;
- ssid = ssid->next;
- }
- if (wpa_s->conf->cred && wpa_s->conf->interworking &&
- wpa_s->conf->auto_interworking)
- count++;
- if (count == 0 && disabled > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled "
- "networks)", disabled);
- }
- return count;
-}
-
-
-static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- int min_temp_disabled = 0;
-
- while (ssid) {
- if (!wpas_network_disabled(wpa_s, ssid)) {
- int temp_disabled = wpas_temp_disabled(wpa_s, ssid);
-
- if (temp_disabled <= 0)
- break;
-
- if (!min_temp_disabled ||
- temp_disabled < min_temp_disabled)
- min_temp_disabled = temp_disabled;
- }
- ssid = ssid->next;
- }
-
- /* ap_scan=2 mode - try to associate with each SSID. */
- if (ssid == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
- "end of scan list - go back to beginning");
- wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
- wpa_supplicant_req_scan(wpa_s, min_temp_disabled, 0);
- return;
- }
- if (ssid->next) {
- /* Continue from the next SSID on the next attempt. */
- wpa_s->prev_scan_ssid = ssid;
- } else {
- /* Start from the beginning of the SSID list. */
- wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
- }
- wpa_supplicant_associate(wpa_s, NULL, ssid);
-}
-
-
-static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpa_driver_scan_params *params = work->ctx;
- int ret;
-
- if (deinit) {
- if (!work->started) {
- wpa_scan_free_params(params);
- return;
- }
- wpa_supplicant_notify_scanning(wpa_s, 0);
- wpas_notify_scan_done(wpa_s, 0);
- wpa_s->scan_work = NULL;
- return;
- }
-
- if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
- wpa_s->wpa_state <= WPA_SCANNING)
- wpa_setup_mac_addr_rand_params(params, wpa_s->mac_addr_scan);
-
- if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to assign random MAC address for a scan");
- wpa_scan_free_params(params);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
- radio_work_done(work);
- return;
- }
-
- wpa_supplicant_notify_scanning(wpa_s, 1);
-
- if (wpa_s->clear_driver_scan_cache) {
- wpa_printf(MSG_DEBUG,
- "Request driver to clear scan cache due to local BSS flush");
- params->only_new_results = 1;
- }
- ret = wpa_drv_scan(wpa_s, params);
- /*
- * Store the obtained vendor scan cookie (if any) in wpa_s context.
- * The current design is to allow only one scan request on each
- * interface, hence having this scan cookie stored in wpa_s context is
- * fine for now.
- *
- * Revisit this logic if concurrent scan operations per interface
- * is supported.
- */
- if (ret == 0)
- wpa_s->curr_scan_cookie = params->scan_cookie;
- wpa_scan_free_params(params);
- work->ctx = NULL;
- if (ret) {
- int retry = wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
- !wpa_s->beacon_rep_data.token;
-
- if (wpa_s->disconnected)
- retry = 0;
-
- /* do not retry if operation is not supported */
- if (ret == -EOPNOTSUPP)
- retry = 0;
-
- wpa_supplicant_notify_scanning(wpa_s, 0);
- wpas_notify_scan_done(wpa_s, 0);
- if (wpa_s->wpa_state == WPA_SCANNING)
- wpa_supplicant_set_state(wpa_s,
- wpa_s->scan_prev_wpa_state);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=%d%s",
- ret, retry ? " retry=1" : "");
- radio_work_done(work);
-
- if (retry) {
- /* Restore scan_req since we will try to scan again */
- wpa_s->scan_req = wpa_s->last_scan_req;
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- } else if (wpa_s->scan_res_handler) {
- /* Clear the scan_res_handler */
- wpa_s->scan_res_handler = NULL;
- }
-
- if (wpa_s->beacon_rep_data.token)
- wpas_rrm_refuse_request(wpa_s);
-
- return;
- }
-
- os_get_reltime(&wpa_s->scan_trigger_time);
- wpa_s->scan_runs++;
- wpa_s->normal_scans++;
- wpa_s->own_scan_requested = 1;
- wpa_s->clear_driver_scan_cache = 0;
- wpa_s->scan_work = work;
-}
-
-
-/**
- * wpa_supplicant_trigger_scan - Request driver to start a scan
- * @wpa_s: Pointer to wpa_supplicant data
- * @params: Scan parameters
- * Returns: 0 on success, -1 on failure
- */
-int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- struct wpa_driver_scan_params *ctx;
-
- if (wpa_s->scan_work) {
- wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
- return -1;
- }
-
- ctx = wpa_scan_clone_params(params);
- if (!ctx ||
- radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
- {
- wpa_scan_free_params(ctx);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
- return -1;
- }
-
- return 0;
-}
-
-
-static void
-wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
-
- if (wpa_supplicant_req_sched_scan(wpa_s))
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-static void
-wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
-
- wpa_s->sched_scan_timed_out = 1;
- wpa_supplicant_cancel_sched_scan(wpa_s);
-}
-
-
-static int
-wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- int ret;
-
- wpa_supplicant_notify_scanning(wpa_s, 1);
- ret = wpa_drv_sched_scan(wpa_s, params);
- if (ret)
- wpa_supplicant_notify_scanning(wpa_s, 0);
- else
- wpa_s->sched_scanning = 1;
-
- return ret;
-}
-
-
-static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
-{
- int ret;
-
- ret = wpa_drv_stop_sched_scan(wpa_s);
- if (ret) {
- wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
- /* TODO: what to do if stopping fails? */
- return -1;
- }
-
- return ret;
-}
-
-
-static struct wpa_driver_scan_filter *
-wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
-{
- struct wpa_driver_scan_filter *ssids;
- struct wpa_ssid *ssid;
- size_t count;
-
- *num_ssids = 0;
- if (!conf->filter_ssids)
- return NULL;
-
- for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
- if (ssid->ssid && ssid->ssid_len)
- count++;
- }
- if (count == 0)
- return NULL;
- ssids = os_calloc(count, sizeof(struct wpa_driver_scan_filter));
- if (ssids == NULL)
- return NULL;
-
- for (ssid = conf->ssid; ssid; ssid = ssid->next) {
- if (!ssid->ssid || !ssid->ssid_len)
- continue;
- os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
- ssids[*num_ssids].ssid_len = ssid->ssid_len;
- (*num_ssids)++;
- }
-
- return ssids;
-}
-
-
-#ifdef CONFIG_P2P
-static bool is_6ghz_supported(struct wpa_supplicant *wpa_s)
-{
- struct hostapd_channel_data *chnl;
- int i, j;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211A) {
- chnl = wpa_s->hw.modes[i].channels;
- for (j = 0; j < wpa_s->hw.modes[i].num_channels; j++) {
- if (chnl[j].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- if (is_6ghz_freq(chnl[j].freq))
- return true;
- }
- }
- }
-
- return false;
-}
-#endif /* CONFIG_P2P */
-
-
-static void wpa_supplicant_optimize_freqs(
- struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
-{
-#ifdef CONFIG_P2P
- if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
- wpa_s->go_params) {
- /* Optimize provisioning state scan based on GO information */
- if (wpa_s->p2p_in_provisioning < 5 &&
- wpa_s->go_params->freq > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
- "preferred frequency %d MHz",
- wpa_s->go_params->freq);
- params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
- params->freqs[0] = wpa_s->go_params->freq;
- } else if (wpa_s->p2p_in_provisioning < 8 &&
- wpa_s->go_params->freq_list[0]) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
- "channels");
- int_array_concat(&params->freqs,
- wpa_s->go_params->freq_list);
- if (params->freqs)
- int_array_sort_unique(params->freqs);
- }
- wpa_s->p2p_in_provisioning++;
- }
-
- if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
- /*
- * Optimize scan based on GO information during persistent
- * group reinvocation
- */
- if (wpa_s->p2p_in_invitation < 5 &&
- wpa_s->p2p_invite_go_freq > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
- wpa_s->p2p_invite_go_freq);
- params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
- params->freqs[0] = wpa_s->p2p_invite_go_freq;
- }
- wpa_s->p2p_in_invitation++;
- if (wpa_s->p2p_in_invitation > 20) {
- /*
- * This should not really happen since the variable is
- * cleared on group removal, but if it does happen, make
- * sure we do not get stuck in special invitation scan
- * mode.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
- wpa_s->p2p_in_invitation = 0;
- }
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_WPS
- if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
- /*
- * Optimize post-provisioning scan based on channel used
- * during provisioning.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
- "that was used during provisioning", wpa_s->wps_freq);
- params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
- params->freqs[0] = wpa_s->wps_freq;
- wpa_s->after_wps--;
- } else if (wpa_s->after_wps)
- wpa_s->after_wps--;
-
- if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq)
- {
- /* Optimize provisioning scan based on already known channel */
- wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz",
- wpa_s->wps_freq);
- params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
- params->freqs[0] = wpa_s->wps_freq;
- wpa_s->known_wps_freq = 0; /* only do this once */
- }
-#endif /* CONFIG_WPS */
-}
-
-
-#ifdef CONFIG_INTERWORKING
-static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
- struct wpabuf *buf)
-{
- wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
- wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
- 1 + ETH_ALEN);
- wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
- /* No Venue Info */
- if (!is_zero_ether_addr(wpa_s->conf->hessid))
- wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
-}
-#endif /* CONFIG_INTERWORKING */
-
-
-#ifdef CONFIG_MBO
-static void wpas_fils_req_param_add_max_channel(struct wpa_supplicant *wpa_s,
- struct wpabuf **ie)
-{
- if (wpabuf_resize(ie, 5)) {
- wpa_printf(MSG_DEBUG,
- "Failed to allocate space for FILS Request Parameters element");
- return;
- }
-
- /* FILS Request Parameters element */
- wpabuf_put_u8(*ie, WLAN_EID_EXTENSION);
- wpabuf_put_u8(*ie, 3); /* FILS Request attribute length */
- wpabuf_put_u8(*ie, WLAN_EID_EXT_FILS_REQ_PARAMS);
- /* Parameter control bitmap */
- wpabuf_put_u8(*ie, 0);
- /* Max Channel Time field - contains the value of MaxChannelTime
- * parameter of the MLME-SCAN.request primitive represented in units of
- * TUs, as an unsigned integer. A Max Channel Time field value of 255
- * is used to indicate any duration of more than 254 TUs, or an
- * unspecified or unknown duration. (IEEE Std 802.11ai-2016, 9.4.2.178)
- */
- wpabuf_put_u8(*ie, 255);
-}
-#endif /* CONFIG_MBO */
-
-
-void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *default_ies = NULL;
- u8 ext_capab[18];
- int ext_capab_len, frame_id;
- enum wpa_driver_if_type type = WPA_IF_STATION;
-
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
- type = WPA_IF_P2P_CLIENT;
-#endif /* CONFIG_P2P */
-
- wpa_drv_get_ext_capa(wpa_s, type);
-
- ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
- if (ext_capab_len > 0 &&
- wpabuf_resize(&default_ies, ext_capab_len) == 0)
- wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
-
-#ifdef CONFIG_MBO
- if (wpa_s->enable_oce & OCE_STA)
- wpas_fils_req_param_add_max_channel(wpa_s, &default_ies);
- /* Send MBO and OCE capabilities */
- if (wpabuf_resize(&default_ies, 12) == 0)
- wpas_mbo_scan_ie(wpa_s, default_ies);
-#endif /* CONFIG_MBO */
-
- if (type == WPA_IF_P2P_CLIENT)
- frame_id = VENDOR_ELEM_PROBE_REQ_P2P;
- else
- frame_id = VENDOR_ELEM_PROBE_REQ;
-
- if (wpa_s->vendor_elem[frame_id]) {
- size_t len;
-
- len = wpabuf_len(wpa_s->vendor_elem[frame_id]);
- if (len > 0 && wpabuf_resize(&default_ies, len) == 0)
- wpabuf_put_buf(default_ies,
- wpa_s->vendor_elem[frame_id]);
- }
-
- if (default_ies)
- wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
- wpabuf_len(default_ies));
- wpabuf_free(default_ies);
-}
-
-
-static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
-{
- struct wpabuf *extra_ie = NULL;
- u8 ext_capab[18];
- int ext_capab_len;
-#ifdef CONFIG_WPS
- int wps = 0;
- enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
- else
-#endif /* CONFIG_P2P */
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
-
- ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
- if (ext_capab_len > 0 &&
- wpabuf_resize(&extra_ie, ext_capab_len) == 0)
- wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
-
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->conf->interworking &&
- wpabuf_resize(&extra_ie, 100) == 0)
- wpas_add_interworking_elements(wpa_s, extra_ie);
-#endif /* CONFIG_INTERWORKING */
-
-#ifdef CONFIG_MBO
- if (wpa_s->enable_oce & OCE_STA)
- wpas_fils_req_param_add_max_channel(wpa_s, &extra_ie);
-#endif /* CONFIG_MBO */
-
-#ifdef CONFIG_WPS
- wps = wpas_wps_in_use(wpa_s, &req_type);
-
- if (wps) {
- struct wpabuf *wps_ie;
- wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON :
- DEV_PW_DEFAULT,
- &wpa_s->wps->dev,
- wpa_s->wps->uuid, req_type,
- 0, NULL);
- if (wps_ie) {
- if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
- wpabuf_put_buf(extra_ie, wps_ie);
- wpabuf_free(wps_ie);
- }
- }
-
-#ifdef CONFIG_P2P
- if (wps) {
- size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
- if (wpabuf_resize(&extra_ie, ielen) == 0)
- wpas_p2p_scan_ie(wpa_s, extra_ie);
- }
-#endif /* CONFIG_P2P */
-
- wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie);
-
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_HS20
- if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 9) == 0)
- wpas_hs20_add_indication(extra_ie, -1, 0);
-#endif /* CONFIG_HS20 */
-
-#ifdef CONFIG_FST
- if (wpa_s->fst_ies &&
- wpabuf_resize(&extra_ie, wpabuf_len(wpa_s->fst_ies)) == 0)
- wpabuf_put_buf(extra_ie, wpa_s->fst_ies);
-#endif /* CONFIG_FST */
-
-#ifdef CONFIG_MBO
- /* Send MBO and OCE capabilities */
- if (wpabuf_resize(&extra_ie, 12) == 0)
- wpas_mbo_scan_ie(wpa_s, extra_ie);
-#endif /* CONFIG_MBO */
-
- if (wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ]) {
- struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ];
-
- if (wpabuf_resize(&extra_ie, wpabuf_len(buf)) == 0)
- wpabuf_put_buf(extra_ie, buf);
- }
-
- return extra_ie;
-}
-
-
-#ifdef CONFIG_P2P
-
-/*
- * Check whether there are any enabled networks or credentials that could be
- * used for a non-P2P connection.
- */
-static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (wpas_network_disabled(wpa_s, ssid))
- continue;
- if (!ssid->p2p_group)
- return 1;
- }
-
- if (wpa_s->conf->cred && wpa_s->conf->interworking &&
- wpa_s->conf->auto_interworking)
- return 1;
-
- return 0;
-}
-
-#endif /* CONFIG_P2P */
-
-
-int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s,
- enum hostapd_hw_mode band,
- struct wpa_driver_scan_params *params, bool is_6ghz)
-{
- /* Include only supported channels for the specified band */
- struct hostapd_hw_modes *mode;
- int num_chans = 0;
- int *freqs, i;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, is_6ghz);
- if (!mode)
- return -1;
-
- if (params->freqs) {
- while (params->freqs[num_chans])
- num_chans++;
- }
-
- freqs = os_realloc(params->freqs,
- (num_chans + mode->num_channels + 1) * sizeof(int));
- if (!freqs)
- return -1;
-
- params->freqs = freqs;
- for (i = 0; i < mode->num_channels; i++) {
- if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- params->freqs[num_chans++] = mode->channels[i].freq;
- }
- params->freqs[num_chans] = 0;
-
- return 0;
-}
-
-
-static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- if (wpa_s->hw.modes == NULL)
- return; /* unknown what channels the driver supports */
- if (params->freqs)
- return; /* already using a limited channel set */
-
- if (wpa_s->setband_mask & WPA_SETBAND_5G)
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
- false);
- if (wpa_s->setband_mask & WPA_SETBAND_2G)
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
- false);
- if (wpa_s->setband_mask & WPA_SETBAND_6G)
- wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
- true);
-}
-
-
-static void wpa_add_scan_ssid(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params,
- size_t max_ssids, const u8 *ssid, size_t ssid_len)
-{
- unsigned int j;
-
- for (j = 0; j < params->num_ssids; j++) {
- if (params->ssids[j].ssid_len == ssid_len &&
- params->ssids[j].ssid &&
- os_memcmp(params->ssids[j].ssid, ssid, ssid_len) == 0)
- return; /* already in the list */
- }
-
- if (params->num_ssids + 1 > max_ssids) {
- wpa_printf(MSG_DEBUG, "Over max scan SSIDs for manual request");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
- wpa_ssid_txt(ssid, ssid_len));
-
- params->ssids[params->num_ssids].ssid = ssid;
- params->ssids[params->num_ssids].ssid_len = ssid_len;
- params->num_ssids++;
-}
-
-
-static void wpa_add_owe_scan_ssid(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params,
- struct wpa_ssid *ssid, size_t max_ssids)
-{
-#ifdef CONFIG_OWE
- struct wpa_bss *bss;
-
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE))
- return;
-
- wpa_printf(MSG_DEBUG, "OWE: Look for transition mode AP. ssid=%s",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- const u8 *owe, *pos, *end;
- const u8 *owe_ssid;
- size_t owe_ssid_len;
-
- if (bss->ssid_len != ssid->ssid_len ||
- os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) != 0)
- continue;
-
- owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (!owe || owe[1] < 4)
- continue;
-
- pos = owe + 6;
- end = owe + 2 + owe[1];
-
- /* Must include BSSID and ssid_len */
- if (end - pos < ETH_ALEN + 1)
- return;
-
- /* Skip BSSID */
- pos += ETH_ALEN;
- owe_ssid_len = *pos++;
- owe_ssid = pos;
-
- if ((size_t) (end - pos) < owe_ssid_len ||
- owe_ssid_len > SSID_MAX_LEN)
- return;
-
- wpa_printf(MSG_DEBUG,
- "OWE: scan_ssids: transition mode OWE ssid=%s",
- wpa_ssid_txt(owe_ssid, owe_ssid_len));
-
- wpa_add_scan_ssid(wpa_s, params, max_ssids,
- owe_ssid, owe_ssid_len);
- return;
- }
-#endif /* CONFIG_OWE */
-}
-
-
-static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params,
- size_t max_ssids)
-{
- unsigned int i;
- struct wpa_ssid *ssid;
-
- /*
- * For devices with max_ssids greater than 1, leave the last slot empty
- * for adding the wildcard scan entry.
- */
- max_ssids = max_ssids > 1 ? max_ssids - 1 : max_ssids;
-
- for (i = 0; i < wpa_s->scan_id_count; i++) {
- ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
- if (!ssid)
- continue;
- if (ssid->scan_ssid)
- wpa_add_scan_ssid(wpa_s, params, max_ssids,
- ssid->ssid, ssid->ssid_len);
- /*
- * Also add the SSID of the OWE BSS, to allow discovery of
- * transition mode APs more quickly.
- */
- wpa_add_owe_scan_ssid(wpa_s, params, ssid, max_ssids);
- }
-
- wpa_s->scan_id_count = 0;
-}
-
-
-static int wpa_set_ssids_from_scan_req(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params,
- size_t max_ssids)
-{
- unsigned int i;
-
- if (wpa_s->ssids_from_scan_req == NULL ||
- wpa_s->num_ssids_from_scan_req == 0)
- return 0;
-
- if (wpa_s->num_ssids_from_scan_req > max_ssids) {
- wpa_s->num_ssids_from_scan_req = max_ssids;
- wpa_printf(MSG_DEBUG, "Over max scan SSIDs from scan req: %u",
- (unsigned int) max_ssids);
- }
-
- for (i = 0; i < wpa_s->num_ssids_from_scan_req; i++) {
- params->ssids[i].ssid = wpa_s->ssids_from_scan_req[i].ssid;
- params->ssids[i].ssid_len =
- wpa_s->ssids_from_scan_req[i].ssid_len;
- wpa_hexdump_ascii(MSG_DEBUG, "specific SSID",
- params->ssids[i].ssid,
- params->ssids[i].ssid_len);
- }
-
- params->num_ssids = wpa_s->num_ssids_from_scan_req;
- wpa_s->num_ssids_from_scan_req = 0;
- return 1;
-}
-
-
-static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_ssid *ssid;
- int ret, p2p_in_prog;
- struct wpabuf *extra_ie = NULL;
- struct wpa_driver_scan_params params;
- struct wpa_driver_scan_params *scan_params;
- size_t max_ssids;
- int connect_without_scan = 0;
-
- wpa_s->ignore_post_flush_scan_res = 0;
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
- return;
- }
-
- if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- return;
- }
-
- if (wpa_s->scanning) {
- /*
- * If we are already in scanning state, we shall reschedule the
- * the incoming scan request.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Reschedule the incoming scan req");
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- return;
- }
-
- if (!wpa_supplicant_enabled_networks(wpa_s) &&
- wpa_s->scan_req == NORMAL_SCAN_REQ) {
- wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
- return;
- }
-
- if (wpa_s->conf->ap_scan != 0 &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
- "overriding ap_scan configuration");
- wpa_s->conf->ap_scan = 0;
- wpas_notify_ap_scan_changed(wpa_s);
- }
-
- if (wpa_s->conf->ap_scan == 0) {
- wpa_supplicant_gen_assoc_event(wpa_s);
- return;
- }
-
- ssid = NULL;
- if (wpa_s->scan_req != MANUAL_SCAN_REQ &&
- wpa_s->connect_without_scan) {
- connect_without_scan = 1;
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid == wpa_s->connect_without_scan)
- break;
- }
- }
-
- p2p_in_prog = wpas_p2p_in_progress(wpa_s);
- if (p2p_in_prog && p2p_in_prog != 2 &&
- (!ssid ||
- (ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_P2P_GO))) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan while P2P operation is in progress");
- wpa_supplicant_req_scan(wpa_s, 5, 0);
- return;
- }
-
- /*
- * Don't cancel the scan based on ongoing PNO; defer it. Some scans are
- * used for changing modes inside wpa_supplicant (roaming,
- * auto-reconnect, etc). Discarding the scan might hurt these processes.
- * The normal use case for PNO is to suspend the host immediately after
- * starting PNO, so the periodic 100 ms attempts to run the scan do not
- * normally happen in practice multiple times, i.e., this is simply
- * restarting scanning once the host is woken up and PNO stopped.
- */
- if (wpa_s->pno || wpa_s->pno_sched_pending) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Defer scan - PNO is in progress");
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- return;
- }
-
- if (wpa_s->conf->ap_scan == 2)
- max_ssids = 1;
- else {
- max_ssids = wpa_s->max_scan_ssids;
- if (max_ssids > WPAS_MAX_SCAN_SSIDS)
- max_ssids = WPAS_MAX_SCAN_SSIDS;
- }
-
- wpa_s->last_scan_req = wpa_s->scan_req;
- wpa_s->scan_req = NORMAL_SCAN_REQ;
-
- if (connect_without_scan) {
- wpa_s->connect_without_scan = NULL;
- if (ssid) {
- wpa_printf(MSG_DEBUG, "Start a pre-selected network "
- "without scan step");
- wpa_supplicant_associate(wpa_s, NULL, ssid);
- return;
- }
- }
-
- os_memset(&params, 0, sizeof(params));
-
- wpa_s->scan_prev_wpa_state = wpa_s->wpa_state;
- if (wpa_s->wpa_state == WPA_DISCONNECTED ||
- wpa_s->wpa_state == WPA_INACTIVE)
- wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
-
- /*
- * If autoscan has set its own scanning parameters
- */
- if (wpa_s->autoscan_params != NULL) {
- scan_params = wpa_s->autoscan_params;
- goto scan;
- }
-
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_set_ssids_from_scan_req(wpa_s, &params, max_ssids)) {
- wpa_printf(MSG_DEBUG, "Use specific SSIDs from SCAN command");
- goto ssid_list_set;
- }
-
-#ifdef CONFIG_P2P
- if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
- wpa_s->go_params && !wpa_s->conf->passive_scan) {
- wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during P2P group formation (p2p_in_provisioning=%d show_group_started=%d)",
- wpa_s->p2p_in_provisioning,
- wpa_s->show_group_started);
- params.ssids[0].ssid = wpa_s->go_params->ssid;
- params.ssids[0].ssid_len = wpa_s->go_params->ssid_len;
- params.num_ssids = 1;
- goto ssid_list_set;
- }
-
- if (wpa_s->p2p_in_invitation) {
- if (wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
- params.ssids[0].ssid = wpa_s->current_ssid->ssid;
- params.ssids[0].ssid_len =
- wpa_s->current_ssid->ssid_len;
- params.num_ssids = 1;
- } else {
- wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
- }
- goto ssid_list_set;
- }
-#endif /* CONFIG_P2P */
-
- /* Find the starting point from which to continue scanning */
- ssid = wpa_s->conf->ssid;
- if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
- while (ssid) {
- if (ssid == wpa_s->prev_scan_ssid) {
- ssid = ssid->next;
- break;
- }
- ssid = ssid->next;
- }
- }
-
- if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
-#ifdef CONFIG_AP
- !wpa_s->ap_iface &&
-#endif /* CONFIG_AP */
- wpa_s->conf->ap_scan == 2) {
- wpa_s->connect_without_scan = NULL;
- wpa_s->prev_scan_wildcard = 0;
- wpa_supplicant_assoc_try(wpa_s, ssid);
- return;
- } else if (wpa_s->conf->ap_scan == 2) {
- /*
- * User-initiated scan request in ap_scan == 2; scan with
- * wildcard SSID.
- */
- ssid = NULL;
- } else if (wpa_s->reattach && wpa_s->current_ssid != NULL) {
- /*
- * Perform single-channel single-SSID scan for
- * reassociate-to-same-BSS operation.
- */
- /* Setup SSID */
- ssid = wpa_s->current_ssid;
- wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
- ssid->ssid, ssid->ssid_len);
- params.ssids[0].ssid = ssid->ssid;
- params.ssids[0].ssid_len = ssid->ssid_len;
- params.num_ssids = 1;
-
- /*
- * Allocate memory for frequency array, allocate one extra
- * slot for the zero-terminator.
- */
- params.freqs = os_malloc(sizeof(int) * 2);
- if (params.freqs) {
- params.freqs[0] = wpa_s->assoc_freq;
- params.freqs[1] = 0;
- }
-
- /*
- * Reset the reattach flag so that we fall back to full scan if
- * this scan fails.
- */
- wpa_s->reattach = 0;
- } else {
- struct wpa_ssid *start = ssid, *tssid;
- int freqs_set = 0;
- if (ssid == NULL && max_ssids > 1)
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- if (!wpas_network_disabled(wpa_s, ssid) &&
- ssid->scan_ssid) {
- wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
- ssid->ssid, ssid->ssid_len);
- params.ssids[params.num_ssids].ssid =
- ssid->ssid;
- params.ssids[params.num_ssids].ssid_len =
- ssid->ssid_len;
- params.num_ssids++;
- if (params.num_ssids + 1 >= max_ssids)
- break;
- }
-
- if (!wpas_network_disabled(wpa_s, ssid)) {
- /*
- * Also add the SSID of the OWE BSS, to allow
- * discovery of transition mode APs more
- * quickly.
- */
- wpa_add_owe_scan_ssid(wpa_s, &params, ssid,
- max_ssids);
- }
-
- ssid = ssid->next;
- if (ssid == start)
- break;
- if (ssid == NULL && max_ssids > 1 &&
- start != wpa_s->conf->ssid)
- ssid = wpa_s->conf->ssid;
- }
-
- if (wpa_s->scan_id_count &&
- wpa_s->last_scan_req == MANUAL_SCAN_REQ)
- wpa_set_scan_ssids(wpa_s, &params, max_ssids);
-
- for (tssid = wpa_s->conf->ssid;
- wpa_s->last_scan_req != MANUAL_SCAN_REQ && tssid;
- tssid = tssid->next) {
- if (wpas_network_disabled(wpa_s, tssid))
- continue;
- if (((params.freqs || !freqs_set) &&
- tssid->scan_freq) &&
- int_array_len(params.freqs) < 100) {
- int_array_concat(&params.freqs,
- tssid->scan_freq);
- } else {
- os_free(params.freqs);
- params.freqs = NULL;
- }
- freqs_set = 1;
- }
- int_array_sort_unique(params.freqs);
- }
-
- if (ssid && max_ssids == 1) {
- /*
- * If the driver is limited to 1 SSID at a time interleave
- * wildcard SSID scans with specific SSID scans to avoid
- * waiting a long time for a wildcard scan.
- */
- if (!wpa_s->prev_scan_wildcard) {
- params.ssids[0].ssid = NULL;
- params.ssids[0].ssid_len = 0;
- wpa_s->prev_scan_wildcard = 1;
- wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for "
- "wildcard SSID (Interleave with specific)");
- } else {
- wpa_s->prev_scan_ssid = ssid;
- wpa_s->prev_scan_wildcard = 0;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Starting AP scan for specific SSID: %s",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- }
- } else if (ssid) {
- /* max_ssids > 1 */
-
- wpa_s->prev_scan_ssid = ssid;
- wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
- "the scan request");
- params.num_ssids++;
- } else if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_s->manual_scan_passive && params.num_ssids == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Use passive scan based on manual request");
- } else if (wpa_s->conf->passive_scan) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Use passive scan based on configuration");
- } else {
- wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
- params.num_ssids++;
- wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
- "SSID");
- }
-
-ssid_list_set:
- wpa_supplicant_optimize_freqs(wpa_s, &params);
- extra_ie = wpa_supplicant_extra_ies(wpa_s);
-
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_s->manual_scan_only_new) {
- wpa_printf(MSG_DEBUG,
- "Request driver to clear scan cache due to manual only_new=1 scan");
- params.only_new_results = 1;
- }
-
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL &&
- wpa_s->manual_scan_freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels");
- params.freqs = wpa_s->manual_scan_freqs;
- wpa_s->manual_scan_freqs = NULL;
- }
-
- if (params.freqs == NULL && wpa_s->select_network_scan_freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Limit select_network scan to specified channels");
- params.freqs = wpa_s->select_network_scan_freqs;
- wpa_s->select_network_scan_freqs = NULL;
- }
-
- if (params.freqs == NULL && wpa_s->next_scan_freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
- "generated frequency list");
- params.freqs = wpa_s->next_scan_freqs;
- } else
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = NULL;
- wpa_setband_scan_freqs(wpa_s, &params);
-
- /* See if user specified frequencies. If so, scan only those. */
- if (wpa_s->last_scan_req == INITIAL_SCAN_REQ &&
- wpa_s->conf->initial_freq_list && !params.freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Optimize scan based on conf->initial_freq_list");
- int_array_concat(&params.freqs, wpa_s->conf->initial_freq_list);
- } else if (wpa_s->conf->freq_list && !params.freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Optimize scan based on conf->freq_list");
- int_array_concat(&params.freqs, wpa_s->conf->freq_list);
- }
-
- /* Use current associated channel? */
- if (wpa_s->conf->scan_cur_freq && !params.freqs) {
- unsigned int num = wpa_s->num_multichan_concurrent;
-
- params.freqs = os_calloc(num + 1, sizeof(int));
- if (params.freqs) {
- num = get_shared_radio_freqs(wpa_s, params.freqs, num);
- if (num > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
- "current operating channels since "
- "scan_cur_freq is enabled");
- } else {
- os_free(params.freqs);
- params.freqs = NULL;
- }
- }
- }
-
-#ifdef CONFIG_MBO
- if (wpa_s->enable_oce & OCE_STA)
- params.oce_scan = 1;
-#endif /* CONFIG_MBO */
-
- params.filter_ssids = wpa_supplicant_build_filter_ssids(
- wpa_s->conf, &params.num_filter_ssids);
- if (extra_ie) {
- params.extra_ies = wpabuf_head(extra_ie);
- params.extra_ies_len = wpabuf_len(extra_ie);
- }
-
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_in_provisioning || wpa_s->p2p_in_invitation ||
- (wpa_s->show_group_started && wpa_s->go_params)) {
- /*
- * The interface may not yet be in P2P mode, so we have to
- * explicitly request P2P probe to disable CCK rates.
- */
- params.p2p_probe = 1;
- }
-#endif /* CONFIG_P2P */
-
- if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
- wpa_s->wpa_state <= WPA_SCANNING)
- wpa_setup_mac_addr_rand_params(&params, wpa_s->mac_addr_scan);
-
- if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
- struct wpa_bss *bss;
-
- params.bssid = wpa_s->next_scan_bssid;
- bss = wpa_bss_get_bssid_latest(wpa_s, params.bssid);
- if (!wpa_s->next_scan_bssid_wildcard_ssid &&
- bss && bss->ssid_len && params.num_ssids == 1 &&
- params.ssids[0].ssid_len == 0) {
- params.ssids[0].ssid = bss->ssid;
- params.ssids[0].ssid_len = bss->ssid_len;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Scan a previously specified BSSID " MACSTR
- " and SSID %s",
- MAC2STR(params.bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Scan a previously specified BSSID " MACSTR,
- MAC2STR(params.bssid));
- }
- }
-
- scan_params = &params;
-
-scan:
-#ifdef CONFIG_P2P
- /*
- * If the driver does not support multi-channel concurrency and a
- * virtual interface that shares the same radio with the wpa_s interface
- * is operating there may not be need to scan other channels apart from
- * the current operating channel on the other virtual interface. Filter
- * out other channels in case we are trying to find a connection for a
- * station interface when we are not configured to prefer station
- * connection and a concurrent operation is already in process.
- */
- if (wpa_s->scan_for_connection &&
- wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
- !scan_params->freqs && !params.freqs &&
- wpas_is_p2p_prioritized(wpa_s) &&
- wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
- non_p2p_network_enabled(wpa_s)) {
- unsigned int num = wpa_s->num_multichan_concurrent;
-
- params.freqs = os_calloc(num + 1, sizeof(int));
- if (params.freqs) {
- num = get_shared_radio_freqs(wpa_s, params.freqs, num);
- if (num > 0 && num == wpa_s->num_multichan_concurrent) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used");
- } else {
- os_free(params.freqs);
- params.freqs = NULL;
- }
- }
- }
-
- if (!params.freqs &&
- (wpa_s->p2p_in_invitation || wpa_s->p2p_in_provisioning) &&
- !is_p2p_allow_6ghz(wpa_s->global->p2p) &&
- is_6ghz_supported(wpa_s)) {
- int i;
-
- /* Exclude 5 GHz channels from the full scan for P2P connection
- * since the 6 GHz band is disabled for P2P uses. */
- wpa_printf(MSG_DEBUG,
- "P2P: 6 GHz disabled - update the scan frequency list");
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].num_channels == 0)
- continue;
- if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211G)
- wpa_add_scan_freqs_list(
- wpa_s, HOSTAPD_MODE_IEEE80211G,
- &params, false);
- if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211A)
- wpa_add_scan_freqs_list(
- wpa_s, HOSTAPD_MODE_IEEE80211A,
- &params, false);
- if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211AD)
- wpa_add_scan_freqs_list(
- wpa_s, HOSTAPD_MODE_IEEE80211AD,
- &params, false);
- }
- }
-#endif /* CONFIG_P2P */
-
- ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
-
- if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
- !wpa_s->manual_scan_freqs) {
- /* Restore manual_scan_freqs for the next attempt */
- wpa_s->manual_scan_freqs = params.freqs;
- params.freqs = NULL;
- }
-
- wpabuf_free(extra_ie);
- os_free(params.freqs);
- os_free(params.filter_ssids);
- os_free(params.mac_addr);
-
- if (ret) {
- wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
- if (wpa_s->scan_prev_wpa_state != wpa_s->wpa_state)
- wpa_supplicant_set_state(wpa_s,
- wpa_s->scan_prev_wpa_state);
- /* Restore scan_req since we will try to scan again */
- wpa_s->scan_req = wpa_s->last_scan_req;
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- } else {
- wpa_s->scan_for_connection = 0;
-#ifdef CONFIG_INTERWORKING
- wpa_s->interworking_fast_assoc_tried = 0;
-#endif /* CONFIG_INTERWORKING */
- wpa_s->next_scan_bssid_wildcard_ssid = 0;
- if (params.bssid)
- os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
- }
-}
-
-
-void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec)
-{
- struct os_reltime remaining, new_int;
- int cancelled;
-
- cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL,
- &remaining);
-
- new_int.sec = sec;
- new_int.usec = 0;
- if (cancelled && os_reltime_before(&remaining, &new_int)) {
- new_int.sec = remaining.sec;
- new_int.usec = remaining.usec;
- }
-
- if (cancelled) {
- eloop_register_timeout(new_int.sec, new_int.usec,
- wpa_supplicant_scan, wpa_s, NULL);
- }
- wpa_s->scan_interval = sec;
-}
-
-
-/**
- * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
- * @wpa_s: Pointer to wpa_supplicant data
- * @sec: Number of seconds after which to scan
- * @usec: Number of microseconds after which to scan
- *
- * This function is used to schedule a scan for neighboring access points after
- * the specified time.
- */
-void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
-{
- int res;
-
- if (wpa_s->p2p_mgmt) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Ignore scan request (%d.%06d sec) on p2p_mgmt interface",
- sec, usec);
- return;
- }
-
- res = eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s,
- NULL);
- if (res == 1) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d.%06d sec",
- sec, usec);
- } else if (res == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore new scan request for %d.%06d sec since an earlier request is scheduled to trigger sooner",
- sec, usec);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d.%06d sec",
- sec, usec);
- eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
- }
-}
-
-
-/**
- * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
- * @wpa_s: Pointer to wpa_supplicant data
- * @sec: Number of seconds after which to scan
- * @usec: Number of microseconds after which to scan
- * Returns: 0 on success or -1 otherwise
- *
- * This function is used to schedule periodic scans for neighboring
- * access points after the specified time.
- */
-int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
- int sec, int usec)
-{
- if (!wpa_s->sched_scan_supported)
- return -1;
-
- eloop_register_timeout(sec, usec,
- wpa_supplicant_delayed_sched_scan_timeout,
- wpa_s, NULL);
-
- return 0;
-}
-
-
-static void
-wpa_scan_set_relative_rssi_params(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- if (wpa_s->wpa_state != WPA_COMPLETED ||
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI) ||
- wpa_s->srp.relative_rssi_set == 0)
- return;
-
- params->relative_rssi_set = 1;
- params->relative_rssi = wpa_s->srp.relative_rssi;
-
- if (wpa_s->srp.relative_adjust_rssi == 0)
- return;
-
- params->relative_adjust_band = wpa_s->srp.relative_adjust_band;
- params->relative_adjust_rssi = wpa_s->srp.relative_adjust_rssi;
-}
-
-
-/**
- * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 is sched_scan was started or -1 otherwise
- *
- * This function is used to schedule periodic scans for neighboring
- * access points repeating the scan continuously.
- */
-int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_scan_params params;
- struct wpa_driver_scan_params *scan_params;
- enum wpa_states prev_state;
- struct wpa_ssid *ssid = NULL;
- struct wpabuf *extra_ie = NULL;
- int ret;
- unsigned int max_sched_scan_ssids;
- int wildcard = 0;
- int need_ssids;
- struct sched_scan_plan scan_plan;
-
- if (!wpa_s->sched_scan_supported)
- return -1;
-
- if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
- max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
- else
- max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
- if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload)
- return -1;
-
- wpa_s->sched_scan_stop_req = 0;
-
- if (wpa_s->sched_scanning) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
- return 0;
- }
-
- need_ssids = 0;
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
- /* Use wildcard SSID to find this network */
- wildcard = 1;
- } else if (!wpas_network_disabled(wpa_s, ssid) &&
- ssid->ssid_len)
- need_ssids++;
-
-#ifdef CONFIG_WPS
- if (!wpas_network_disabled(wpa_s, ssid) &&
- ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
- /*
- * Normal scan is more reliable and faster for WPS
- * operations and since these are for short periods of
- * time, the benefit of trying to use sched_scan would
- * be limited.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
- "sched_scan for WPS");
- return -1;
- }
-#endif /* CONFIG_WPS */
- }
- if (wildcard)
- need_ssids++;
-
- if (wpa_s->normal_scans < 3 &&
- (need_ssids <= wpa_s->max_scan_ssids ||
- wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
- /*
- * When normal scan can speed up operations, use that for the
- * first operations before starting the sched_scan to allow
- * user space sleep more. We do this only if the normal scan
- * has functionality that is suitable for this or if the
- * sched_scan does not have better support for multiple SSIDs.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
- "sched_scan for initial scans (normal_scans=%d)",
- wpa_s->normal_scans);
- return -1;
- }
-
- os_memset(&params, 0, sizeof(params));
-
- /* If we can't allocate space for the filters, we just don't filter */
- params.filter_ssids = os_calloc(wpa_s->max_match_sets,
- sizeof(struct wpa_driver_scan_filter));
-
- prev_state = wpa_s->wpa_state;
- if (wpa_s->wpa_state == WPA_DISCONNECTED ||
- wpa_s->wpa_state == WPA_INACTIVE)
- wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
-
- if (wpa_s->autoscan_params != NULL) {
- scan_params = wpa_s->autoscan_params;
- goto scan;
- }
-
- /* Find the starting point from which to continue scanning */
- ssid = wpa_s->conf->ssid;
- if (wpa_s->prev_sched_ssid) {
- while (ssid) {
- if (ssid == wpa_s->prev_sched_ssid) {
- ssid = ssid->next;
- break;
- }
- ssid = ssid->next;
- }
- }
-
- if (!ssid || !wpa_s->prev_sched_ssid) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
- wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
- wpa_s->first_sched_scan = 1;
- ssid = wpa_s->conf->ssid;
- wpa_s->prev_sched_ssid = ssid;
- }
-
- if (wildcard) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
- params.num_ssids++;
- }
-
- while (ssid) {
- if (wpas_network_disabled(wpa_s, ssid))
- goto next;
-
- if (params.num_filter_ssids < wpa_s->max_match_sets &&
- params.filter_ssids && ssid->ssid && ssid->ssid_len) {
- wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
- ssid->ssid, ssid->ssid_len);
- params.filter_ssids[params.num_filter_ssids].ssid_len =
- ssid->ssid_len;
- params.num_filter_ssids++;
- } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
- {
- wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
- "filter for sched_scan - drop filter");
- os_free(params.filter_ssids);
- params.filter_ssids = NULL;
- params.num_filter_ssids = 0;
- }
-
- if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
- if (params.num_ssids == max_sched_scan_ssids)
- break; /* only room for broadcast SSID */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "add to active scan ssid: %s",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- params.ssids[params.num_ssids].ssid =
- ssid->ssid;
- params.ssids[params.num_ssids].ssid_len =
- ssid->ssid_len;
- params.num_ssids++;
- if (params.num_ssids >= max_sched_scan_ssids) {
- wpa_s->prev_sched_ssid = ssid;
- do {
- ssid = ssid->next;
- } while (ssid &&
- (wpas_network_disabled(wpa_s, ssid) ||
- !ssid->scan_ssid));
- break;
- }
- }
-
- next:
- wpa_s->prev_sched_ssid = ssid;
- ssid = ssid->next;
- }
-
- if (params.num_filter_ssids == 0) {
- os_free(params.filter_ssids);
- params.filter_ssids = NULL;
- }
-
- extra_ie = wpa_supplicant_extra_ies(wpa_s);
- if (extra_ie) {
- params.extra_ies = wpabuf_head(extra_ie);
- params.extra_ies_len = wpabuf_len(extra_ie);
- }
-
- if (wpa_s->conf->filter_rssi)
- params.filter_rssi = wpa_s->conf->filter_rssi;
-
- /* See if user specified frequencies. If so, scan only those. */
- if (wpa_s->conf->freq_list && !params.freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Optimize scan based on conf->freq_list");
- int_array_concat(&params.freqs, wpa_s->conf->freq_list);
- }
-
-#ifdef CONFIG_MBO
- if (wpa_s->enable_oce & OCE_STA)
- params.oce_scan = 1;
-#endif /* CONFIG_MBO */
-
- scan_params = &params;
-
-scan:
- wpa_s->sched_scan_timed_out = 0;
-
- /*
- * We cannot support multiple scan plans if the scan request includes
- * too many SSID's, so in this case use only the last scan plan and make
- * it run infinitely. It will be stopped by the timeout.
- */
- if (wpa_s->sched_scan_plans_num == 1 ||
- (wpa_s->sched_scan_plans_num && !ssid && wpa_s->first_sched_scan)) {
- params.sched_scan_plans = wpa_s->sched_scan_plans;
- params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
- } else if (wpa_s->sched_scan_plans_num > 1) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Too many SSIDs. Default to using single scheduled_scan plan");
- params.sched_scan_plans =
- &wpa_s->sched_scan_plans[wpa_s->sched_scan_plans_num -
- 1];
- params.sched_scan_plans_num = 1;
- } else {
- if (wpa_s->conf->sched_scan_interval)
- scan_plan.interval = wpa_s->conf->sched_scan_interval;
- else
- scan_plan.interval = 10;
-
- if (scan_plan.interval > wpa_s->max_sched_scan_plan_interval) {
- wpa_printf(MSG_WARNING,
- "Scan interval too long(%u), use the maximum allowed(%u)",
- scan_plan.interval,
- wpa_s->max_sched_scan_plan_interval);
- scan_plan.interval =
- wpa_s->max_sched_scan_plan_interval;
- }
-
- scan_plan.iterations = 0;
- params.sched_scan_plans = &scan_plan;
- params.sched_scan_plans_num = 1;
- }
-
- params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
-
- if (ssid || !wpa_s->first_sched_scan) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Starting sched scan after %u seconds: interval %u timeout %d",
- params.sched_scan_start_delay,
- params.sched_scan_plans[0].interval,
- wpa_s->sched_scan_timeout);
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Starting sched scan after %u seconds (no timeout)",
- params.sched_scan_start_delay);
- }
-
- wpa_setband_scan_freqs(wpa_s, scan_params);
-
- if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) &&
- wpa_s->wpa_state <= WPA_SCANNING)
- wpa_setup_mac_addr_rand_params(&params,
- wpa_s->mac_addr_sched_scan);
-
- wpa_scan_set_relative_rssi_params(wpa_s, scan_params);
-
- ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params);
- wpabuf_free(extra_ie);
- os_free(params.filter_ssids);
- os_free(params.mac_addr);
- if (ret) {
- wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
- if (prev_state != wpa_s->wpa_state)
- wpa_supplicant_set_state(wpa_s, prev_state);
- return ret;
- }
-
- /* If we have more SSIDs to scan, add a timeout so we scan them too */
- if (ssid || !wpa_s->first_sched_scan) {
- wpa_s->sched_scan_timed_out = 0;
- eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
- wpa_supplicant_sched_scan_timeout,
- wpa_s, NULL);
- wpa_s->first_sched_scan = 0;
- wpa_s->sched_scan_timeout /= 2;
- params.sched_scan_plans[0].interval *= 2;
- if ((unsigned int) wpa_s->sched_scan_timeout <
- params.sched_scan_plans[0].interval ||
- params.sched_scan_plans[0].interval >
- wpa_s->max_sched_scan_plan_interval) {
- params.sched_scan_plans[0].interval = 10;
- wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
- }
- }
-
- /* If there is no more ssids, start next time from the beginning */
- if (!ssid)
- wpa_s->prev_sched_ssid = NULL;
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to cancel a scan request scheduled with
- * wpa_supplicant_req_scan().
- */
-void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
- eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
-}
-
-
-/**
- * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to stop a delayed scheduled scan.
- */
-void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->sched_scan_supported)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan");
- eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
- wpa_s, NULL);
-}
-
-
-/**
- * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to stop a periodic scheduled scan.
- */
-void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->sched_scanning)
- return;
-
- if (wpa_s->sched_scanning)
- wpa_s->sched_scan_stop_req = 1;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
- eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
- wpa_supplicant_stop_sched_scan(wpa_s);
-}
-
-
-/**
- * wpa_supplicant_notify_scanning - Indicate possible scan state change
- * @wpa_s: Pointer to wpa_supplicant data
- * @scanning: Whether scanning is currently in progress
- *
- * This function is to generate scanning notifycations. It is called whenever
- * there may have been a change in scanning (scan started, completed, stopped).
- * wpas_notify_scanning() is called whenever the scanning state changed from the
- * previously notified state.
- */
-void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
- int scanning)
-{
- if (wpa_s->scanning != scanning) {
- wpa_s->scanning = scanning;
- wpas_notify_scanning(wpa_s);
- }
-}
-
-
-static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
-{
- int rate = 0;
- const u8 *ie;
- int i;
-
- ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
- for (i = 0; ie && i < ie[1]; i++) {
- if ((ie[i + 2] & 0x7f) > rate)
- rate = ie[i + 2] & 0x7f;
- }
-
- ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
- for (i = 0; ie && i < ie[1]; i++) {
- if ((ie[i + 2] & 0x7f) > rate)
- rate = ie[i + 2] & 0x7f;
- }
-
- return rate;
-}
-
-
-/**
- * wpa_scan_get_ie - Fetch a specified information element from a scan result
- * @res: Scan result entry
- * @ie: Information element identitifier (WLAN_EID_*)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the scan
- * result.
- */
-const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
-{
- size_t ie_len = res->ie_len;
-
- /* Use the Beacon frame IEs if res->ie_len is not available */
- if (!ie_len)
- ie_len = res->beacon_ie_len;
-
- return get_ie((const u8 *) (res + 1), ie_len, ie);
-}
-
-
-/**
- * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result
- * @res: Scan result entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the scan
- * result.
- */
-const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
- u32 vendor_type)
-{
- const u8 *ies;
- const struct element *elem;
-
- ies = (const u8 *) (res + 1);
-
- for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, res->ie_len) {
- if (elem->datalen >= 4 &&
- vendor_type == WPA_GET_BE32(elem->data))
- return &elem->id;
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
- * @res: Scan result entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the first matching information element in the scan
- * result.
- *
- * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
- * from Beacon frames instead of either Beacon or Probe Response frames.
- */
-const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
- u32 vendor_type)
-{
- const u8 *ies;
- const struct element *elem;
-
- if (res->beacon_ie_len == 0)
- return NULL;
-
- ies = (const u8 *) (res + 1);
- ies += res->ie_len;
-
- for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies,
- res->beacon_ie_len) {
- if (elem->datalen >= 4 &&
- vendor_type == WPA_GET_BE32(elem->data))
- return &elem->id;
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
- * @res: Scan result entry
- * @vendor_type: Vendor type (four octets starting the IE payload)
- * Returns: Pointer to the information element payload or %NULL if not found
- *
- * This function returns concatenated payload of possibly fragmented vendor
- * specific information elements in the scan result. The caller is responsible
- * for freeing the returned buffer.
- */
-struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
- u32 vendor_type)
-{
- struct wpabuf *buf;
- const u8 *end, *pos;
-
- buf = wpabuf_alloc(res->ie_len);
- if (buf == NULL)
- return NULL;
-
- pos = (const u8 *) (res + 1);
- end = pos + res->ie_len;
-
- while (end - pos > 1) {
- u8 ie, len;
-
- ie = pos[0];
- len = pos[1];
- if (len > end - pos - 2)
- break;
- pos += 2;
- if (ie == WLAN_EID_VENDOR_SPECIFIC && len >= 4 &&
- vendor_type == WPA_GET_BE32(pos))
- wpabuf_put_data(buf, pos + 4, len - 4);
- pos += len;
- }
-
- if (wpabuf_len(buf) == 0) {
- wpabuf_free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-
-
-/* Compare function for sorting scan results. Return >0 if @b is considered
- * better. */
-static int wpa_scan_result_compar(const void *a, const void *b)
-{
-#define MIN(a,b) a < b ? a : b
- struct wpa_scan_res **_wa = (void *) a;
- struct wpa_scan_res **_wb = (void *) b;
- struct wpa_scan_res *wa = *_wa;
- struct wpa_scan_res *wb = *_wb;
- int wpa_a, wpa_b;
- int snr_a, snr_b, snr_a_full, snr_b_full;
-
- /* WPA/WPA2 support preferred */
- wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
- wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
- wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
- wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
-
- if (wpa_b && !wpa_a)
- return 1;
- if (!wpa_b && wpa_a)
- return -1;
-
- /* privacy support preferred */
- if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
- (wb->caps & IEEE80211_CAP_PRIVACY))
- return 1;
- if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
- (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
- return -1;
-
- if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) {
- snr_a_full = wa->snr;
- snr_a = MIN(wa->snr, GREAT_SNR);
- snr_b_full = wb->snr;
- snr_b = MIN(wb->snr, GREAT_SNR);
- } else {
- /* Level is not in dBm, so we can't calculate
- * SNR. Just use raw level (units unknown). */
- snr_a = snr_a_full = wa->level;
- snr_b = snr_b_full = wb->level;
- }
-
- /* If SNR is close, decide by max rate or frequency band. For cases
- * involving the 6 GHz band, use the throughput estimate irrespective
- * of the SNR difference since the LPI/VLP rules may result in
- * significant differences in SNR for cases where the estimated
- * throughput can be considerably higher with the lower SNR. */
- if (snr_a && snr_b && (abs(snr_b - snr_a) < 7 ||
- is_6ghz_freq(wa->freq) ||
- is_6ghz_freq(wb->freq))) {
- if (wa->est_throughput != wb->est_throughput)
- return (int) wb->est_throughput -
- (int) wa->est_throughput;
- }
- if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
- (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
- if (is_6ghz_freq(wa->freq) ^ is_6ghz_freq(wb->freq))
- return is_6ghz_freq(wa->freq) ? -1 : 1;
- if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
- return IS_5GHZ(wa->freq) ? -1 : 1;
- }
-
- /* all things being equal, use SNR; if SNRs are
- * identical, use quality values since some drivers may only report
- * that value and leave the signal level zero */
- if (snr_b_full == snr_a_full)
- return wb->qual - wa->qual;
- return snr_b_full - snr_a_full;
-#undef MIN
-}
-
-
-#ifdef CONFIG_WPS
-/* Compare function for sorting scan results when searching a WPS AP for
- * provisioning. Return >0 if @b is considered better. */
-static int wpa_scan_result_wps_compar(const void *a, const void *b)
-{
- struct wpa_scan_res **_wa = (void *) a;
- struct wpa_scan_res **_wb = (void *) b;
- struct wpa_scan_res *wa = *_wa;
- struct wpa_scan_res *wb = *_wb;
- int uses_wps_a, uses_wps_b;
- struct wpabuf *wps_a, *wps_b;
- int res;
-
- /* Optimization - check WPS IE existence before allocated memory and
- * doing full reassembly. */
- uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
- uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
- if (uses_wps_a && !uses_wps_b)
- return -1;
- if (!uses_wps_a && uses_wps_b)
- return 1;
-
- if (uses_wps_a && uses_wps_b) {
- wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
- wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
- res = wps_ap_priority_compar(wps_a, wps_b);
- wpabuf_free(wps_a);
- wpabuf_free(wps_b);
- if (res)
- return res;
- }
-
- /*
- * Do not use current AP security policy as a sorting criteria during
- * WPS provisioning step since the AP may get reconfigured at the
- * completion of provisioning.
- */
-
- /* all things being equal, use signal level; if signal levels are
- * identical, use quality values since some drivers may only report
- * that value and leave the signal level zero */
- if (wb->level == wa->level)
- return wb->qual - wa->qual;
- return wb->level - wa->level;
-}
-#endif /* CONFIG_WPS */
-
-
-static void dump_scan_res(struct wpa_scan_results *scan_res)
-{
-#ifndef CONFIG_NO_STDOUT_DEBUG
- size_t i;
-
- if (scan_res->res == NULL || scan_res->num == 0)
- return;
-
- wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *r = scan_res->res[i];
- u8 *pos;
- if (r->flags & WPA_SCAN_LEVEL_DBM) {
- int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID);
-
- wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
- "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u",
- MAC2STR(r->bssid), r->freq, r->qual,
- r->noise, noise_valid ? "" : "~", r->level,
- r->snr, r->snr >= GREAT_SNR ? "*" : "",
- r->flags,
- r->age, r->est_throughput);
- } else {
- wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
- "noise=%d level=%d flags=0x%x age=%u est=%u",
- MAC2STR(r->bssid), r->freq, r->qual,
- r->noise, r->level, r->flags, r->age,
- r->est_throughput);
- }
- pos = (u8 *) (r + 1);
- if (r->ie_len)
- wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len);
- pos += r->ie_len;
- if (r->beacon_ie_len)
- wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs",
- pos, r->beacon_ie_len);
- }
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-}
-
-
-/**
- * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID to check
- * Returns: 0 if the BSSID is filtered or 1 if not
- *
- * This function is used to filter out specific BSSIDs from scan reslts mainly
- * for testing purposes (SET bssid_filter ctrl_iface command).
- */
-int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- size_t i;
-
- if (wpa_s->bssid_filter == NULL)
- return 1;
-
- for (i = 0; i < wpa_s->bssid_filter_count; i++) {
- if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
- ETH_ALEN) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-void filter_scan_res(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *res)
-{
- size_t i, j;
-
- if (wpa_s->bssid_filter == NULL)
- return;
-
- for (i = 0, j = 0; i < res->num; i++) {
- if (wpa_supplicant_filter_bssid_match(wpa_s,
- res->res[i]->bssid)) {
- res->res[j++] = res->res[i];
- } else {
- os_free(res->res[i]);
- res->res[i] = NULL;
- }
- }
-
- if (res->num != j) {
- wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
- (int) (res->num - j));
- res->num = j;
- }
-}
-
-
-void scan_snr(struct wpa_scan_res *res)
-{
- if (res->flags & WPA_SCAN_NOISE_INVALID) {
- res->noise = is_6ghz_freq(res->freq) ?
- DEFAULT_NOISE_FLOOR_6GHZ :
- (IS_5GHZ(res->freq) ?
- DEFAULT_NOISE_FLOOR_5GHZ : DEFAULT_NOISE_FLOOR_2GHZ);
- }
-
- if (res->flags & WPA_SCAN_LEVEL_DBM) {
- res->snr = res->level - res->noise;
- } else {
- /* Level is not in dBm, so we can't calculate
- * SNR. Just use raw level (units unknown). */
- res->snr = res->level;
- }
-}
-
-
-/* Minimum SNR required to achieve a certain bitrate. */
-struct minsnr_bitrate_entry {
- int minsnr;
- unsigned int bitrate; /* in Mbps */
-};
-
-/* VHT needs to be enabled in order to achieve MCS8 and MCS9 rates. */
-static const int vht_mcs = 8;
-
-static const struct minsnr_bitrate_entry vht20_table[] = {
- { 0, 0 },
- { 2, 6500 }, /* HT20 MCS0 */
- { 5, 13000 }, /* HT20 MCS1 */
- { 9, 19500 }, /* HT20 MCS2 */
- { 11, 26000 }, /* HT20 MCS3 */
- { 15, 39000 }, /* HT20 MCS4 */
- { 18, 52000 }, /* HT20 MCS5 */
- { 20, 58500 }, /* HT20 MCS6 */
- { 25, 65000 }, /* HT20 MCS7 */
- { 29, 78000 }, /* VHT20 MCS8 */
- { -1, 78000 } /* SNR > 29 */
-};
-
-static const struct minsnr_bitrate_entry vht40_table[] = {
- { 0, 0 },
- { 5, 13500 }, /* HT40 MCS0 */
- { 8, 27000 }, /* HT40 MCS1 */
- { 12, 40500 }, /* HT40 MCS2 */
- { 14, 54000 }, /* HT40 MCS3 */
- { 18, 81000 }, /* HT40 MCS4 */
- { 21, 108000 }, /* HT40 MCS5 */
- { 23, 121500 }, /* HT40 MCS6 */
- { 28, 135000 }, /* HT40 MCS7 */
- { 32, 162000 }, /* VHT40 MCS8 */
- { 34, 180000 }, /* VHT40 MCS9 */
- { -1, 180000 } /* SNR > 34 */
-};
-
-static const struct minsnr_bitrate_entry vht80_table[] = {
- { 0, 0 },
- { 8, 29300 }, /* VHT80 MCS0 */
- { 11, 58500 }, /* VHT80 MCS1 */
- { 15, 87800 }, /* VHT80 MCS2 */
- { 17, 117000 }, /* VHT80 MCS3 */
- { 21, 175500 }, /* VHT80 MCS4 */
- { 24, 234000 }, /* VHT80 MCS5 */
- { 26, 263300 }, /* VHT80 MCS6 */
- { 31, 292500 }, /* VHT80 MCS7 */
- { 35, 351000 }, /* VHT80 MCS8 */
- { 37, 390000 }, /* VHT80 MCS9 */
- { -1, 390000 } /* SNR > 37 */
-};
-
-
-static const struct minsnr_bitrate_entry vht160_table[] = {
- { 0, 0 },
- { 11, 58500 }, /* VHT160 MCS0 */
- { 14, 117000 }, /* VHT160 MCS1 */
- { 18, 175500 }, /* VHT160 MCS2 */
- { 20, 234000 }, /* VHT160 MCS3 */
- { 24, 351000 }, /* VHT160 MCS4 */
- { 27, 468000 }, /* VHT160 MCS5 */
- { 29, 526500 }, /* VHT160 MCS6 */
- { 34, 585000 }, /* VHT160 MCS7 */
- { 38, 702000 }, /* VHT160 MCS8 */
- { 40, 780000 }, /* VHT160 MCS9 */
- { -1, 780000 } /* SNR > 37 */
-};
-
-
-static const struct minsnr_bitrate_entry he20_table[] = {
- { 0, 0 },
- { 2, 8600 }, /* HE20 MCS0 */
- { 5, 17200 }, /* HE20 MCS1 */
- { 9, 25800 }, /* HE20 MCS2 */
- { 11, 34400 }, /* HE20 MCS3 */
- { 15, 51600 }, /* HE20 MCS4 */
- { 18, 68800 }, /* HE20 MCS5 */
- { 20, 77400 }, /* HE20 MCS6 */
- { 25, 86000 }, /* HE20 MCS7 */
- { 29, 103200 }, /* HE20 MCS8 */
- { 31, 114700 }, /* HE20 MCS9 */
- { 34, 129000 }, /* HE20 MCS10 */
- { 36, 143400 }, /* HE20 MCS11 */
- { -1, 143400 } /* SNR > 29 */
-};
-
-static const struct minsnr_bitrate_entry he40_table[] = {
- { 0, 0 },
- { 5, 17200 }, /* HE40 MCS0 */
- { 8, 34400 }, /* HE40 MCS1 */
- { 12, 51600 }, /* HE40 MCS2 */
- { 14, 68800 }, /* HE40 MCS3 */
- { 18, 103200 }, /* HE40 MCS4 */
- { 21, 137600 }, /* HE40 MCS5 */
- { 23, 154900 }, /* HE40 MCS6 */
- { 28, 172100 }, /* HE40 MCS7 */
- { 32, 206500 }, /* HE40 MCS8 */
- { 34, 229400 }, /* HE40 MCS9 */
- { 37, 258100 }, /* HE40 MCS10 */
- { 39, 286800 }, /* HE40 MCS11 */
- { -1, 286800 } /* SNR > 34 */
-};
-
-static const struct minsnr_bitrate_entry he80_table[] = {
- { 0, 0 },
- { 8, 36000 }, /* HE80 MCS0 */
- { 11, 72100 }, /* HE80 MCS1 */
- { 15, 108100 }, /* HE80 MCS2 */
- { 17, 144100 }, /* HE80 MCS3 */
- { 21, 216200 }, /* HE80 MCS4 */
- { 24, 288200 }, /* HE80 MCS5 */
- { 26, 324300 }, /* HE80 MCS6 */
- { 31, 360300 }, /* HE80 MCS7 */
- { 35, 432400 }, /* HE80 MCS8 */
- { 37, 480400 }, /* HE80 MCS9 */
- { 40, 540400 }, /* HE80 MCS10 */
- { 42, 600500 }, /* HE80 MCS11 */
- { -1, 600500 } /* SNR > 37 */
-};
-
-
-static const struct minsnr_bitrate_entry he160_table[] = {
- { 0, 0 },
- { 11, 72100 }, /* HE160 MCS0 */
- { 14, 144100 }, /* HE160 MCS1 */
- { 18, 216200 }, /* HE160 MCS2 */
- { 20, 288200 }, /* HE160 MCS3 */
- { 24, 432400 }, /* HE160 MCS4 */
- { 27, 576500 }, /* HE160 MCS5 */
- { 29, 648500 }, /* HE160 MCS6 */
- { 34, 720600 }, /* HE160 MCS7 */
- { 38, 864700 }, /* HE160 MCS8 */
- { 40, 960800 }, /* HE160 MCS9 */
- { 43, 1080900 }, /* HE160 MCS10 */
- { 45, 1201000 }, /* HE160 MCS11 */
- { -1, 1201000 } /* SNR > 37 */
-};
-
-
-static unsigned int interpolate_rate(int snr, int snr0, int snr1,
- int rate0, int rate1)
-{
- return rate0 + (snr - snr0) * (rate1 - rate0) / (snr1 - snr0);
-}
-
-
-static unsigned int max_rate(const struct minsnr_bitrate_entry table[],
- int snr, bool vht)
-{
- const struct minsnr_bitrate_entry *prev, *entry = table;
-
- while ((entry->minsnr != -1) &&
- (snr >= entry->minsnr) &&
- (vht || entry - table <= vht_mcs))
- entry++;
- if (entry == table)
- return entry->bitrate;
- prev = entry - 1;
- if (entry->minsnr == -1 || (!vht && entry - table > vht_mcs))
- return prev->bitrate;
- return interpolate_rate(snr, prev->minsnr, entry->minsnr, prev->bitrate,
- entry->bitrate);
-}
-
-
-static unsigned int max_ht20_rate(int snr, bool vht)
-{
- return max_rate(vht20_table, snr, vht);
-}
-
-
-static unsigned int max_ht40_rate(int snr, bool vht)
-{
- return max_rate(vht40_table, snr, vht);
-}
-
-
-static unsigned int max_vht80_rate(int snr)
-{
- return max_rate(vht80_table, snr, 1);
-}
-
-
-static unsigned int max_vht160_rate(int snr)
-{
- return max_rate(vht160_table, snr, 1);
-}
-
-
-static unsigned int max_he_rate(const struct minsnr_bitrate_entry table[],
- int snr)
-{
- const struct minsnr_bitrate_entry *prev, *entry = table;
-
- while (entry->minsnr != -1 && snr >= entry->minsnr)
- entry++;
- if (entry == table)
- return 0;
- prev = entry - 1;
- if (entry->minsnr == -1)
- return prev->bitrate;
- return interpolate_rate(snr, prev->minsnr, entry->minsnr,
- prev->bitrate, entry->bitrate);
-}
-
-
-unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len, int rate,
- int snr, int freq)
-{
- struct hostapd_hw_modes *hw_mode;
- unsigned int est, tmp;
- const u8 *ie;
-
- /* Limit based on estimated SNR */
- if (rate > 1 * 2 && snr < 1)
- rate = 1 * 2;
- else if (rate > 2 * 2 && snr < 4)
- rate = 2 * 2;
- else if (rate > 6 * 2 && snr < 5)
- rate = 6 * 2;
- else if (rate > 9 * 2 && snr < 6)
- rate = 9 * 2;
- else if (rate > 12 * 2 && snr < 7)
- rate = 12 * 2;
- else if (rate > 12 * 2 && snr < 8)
- rate = 14 * 2;
- else if (rate > 12 * 2 && snr < 9)
- rate = 16 * 2;
- else if (rate > 18 * 2 && snr < 10)
- rate = 18 * 2;
- else if (rate > 24 * 2 && snr < 11)
- rate = 24 * 2;
- else if (rate > 24 * 2 && snr < 12)
- rate = 27 * 2;
- else if (rate > 24 * 2 && snr < 13)
- rate = 30 * 2;
- else if (rate > 24 * 2 && snr < 14)
- rate = 33 * 2;
- else if (rate > 36 * 2 && snr < 15)
- rate = 36 * 2;
- else if (rate > 36 * 2 && snr < 16)
- rate = 39 * 2;
- else if (rate > 36 * 2 && snr < 17)
- rate = 42 * 2;
- else if (rate > 36 * 2 && snr < 18)
- rate = 45 * 2;
- else if (rate > 48 * 2 && snr < 19)
- rate = 48 * 2;
- else if (rate > 48 * 2 && snr < 20)
- rate = 51 * 2;
- else if (rate > 54 * 2 && snr < 21)
- rate = 54 * 2;
- est = rate * 500;
-
- hw_mode = get_mode_with_freq(wpa_s->hw.modes, wpa_s->hw.num_modes,
- freq);
-
- if (hw_mode && hw_mode->ht_capab) {
- ie = get_ie(ies, ies_len, WLAN_EID_HT_CAP);
- if (ie) {
- tmp = max_ht20_rate(snr, false);
- if (tmp > est)
- est = tmp;
- }
- }
-
- if (hw_mode &&
- (hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
- ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= 2 &&
- (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
- tmp = max_ht40_rate(snr, false);
- if (tmp > est)
- est = tmp;
- }
- }
-
- if (hw_mode && hw_mode->vht_capab) {
- /* Use +1 to assume VHT is always faster than HT */
- ie = get_ie(ies, ies_len, WLAN_EID_VHT_CAP);
- if (ie) {
- bool vht80 = false, vht160 = false;
-
- tmp = max_ht20_rate(snr, true) + 1;
- if (tmp > est)
- est = tmp;
-
- ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= 2 &&
- (ie[3] &
- HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
- tmp = max_ht40_rate(snr, true) + 1;
- if (tmp > est)
- est = tmp;
- }
-
- /* Determine VHT BSS bandwidth based on IEEE Std
- * 802.11-2020, Table 11-23 (VHT BSs bandwidth) */
- ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
- if (ie && ie[1] >= 3) {
- u8 cw = ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK;
- u8 seg0 = ie[3];
- u8 seg1 = ie[4];
-
- if (cw)
- vht80 = true;
- if (cw == 2 ||
- (cw == 3 &&
- (seg1 > 0 && abs(seg1 - seg0) == 16)))
- vht160 = true;
- if (cw == 1 &&
- ((seg1 > 0 && abs(seg1 - seg0) == 8) ||
- (seg1 > 0 && abs(seg1 - seg0) == 16)))
- vht160 = true;
- }
-
- if (vht80) {
- tmp = max_vht80_rate(snr) + 1;
- if (tmp > est)
- est = tmp;
- }
-
- if (vht160 &&
- (hw_mode->vht_capab &
- (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
- VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
- tmp = max_vht160_rate(snr) + 1;
- if (tmp > est)
- est = tmp;
- }
- }
- }
-
- if (hw_mode && hw_mode->he_capab[IEEE80211_MODE_INFRA].he_supported) {
- /* Use +2 to assume HE is always faster than HT/VHT */
- struct ieee80211_he_capabilities *he;
- struct he_capabilities *own_he;
- u8 cw;
-
- ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_CAPABILITIES);
- if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
- return est;
- he = (struct ieee80211_he_capabilities *) &ie[3];
- own_he = &hw_mode->he_capab[IEEE80211_MODE_INFRA];
-
- tmp = max_he_rate(he20_table, snr) + 2;
- if (tmp > est)
- est = tmp;
-
- cw = he->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- own_he->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
- if (cw &
- (IS_2P4GHZ(freq) ? HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
- HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
- tmp = max_he_rate(he40_table, snr) + 2;
- if (tmp > est)
- est = tmp;
- }
-
- if (!IS_2P4GHZ(freq) &&
- (cw & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
- tmp = max_he_rate(he80_table, snr) + 2;
- if (tmp > est)
- est = tmp;
- }
-
- if (!IS_2P4GHZ(freq) &&
- (cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
- HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G))) {
- tmp = max_he_rate(he160_table, snr) + 2;
- if (tmp > est)
- est = tmp;
- }
- }
-
- return est;
-}
-
-
-void scan_est_throughput(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res)
-{
- int rate; /* max legacy rate in 500 kb/s units */
- int snr = res->snr;
- const u8 *ies = (const void *) (res + 1);
- size_t ie_len = res->ie_len;
-
- if (res->est_throughput)
- return;
-
- /* Get maximum legacy rate */
- rate = wpa_scan_get_max_rate(res);
-
- if (!ie_len)
- ie_len = res->beacon_ie_len;
- res->est_throughput =
- wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, res->freq);
-
- /* TODO: channel utilization and AP load (e.g., from AP Beacon) */
-}
-
-
-/**
- * wpa_supplicant_get_scan_results - Get scan results
- * @wpa_s: Pointer to wpa_supplicant data
- * @info: Information about what was scanned or %NULL if not available
- * @new_scan: Whether a new scan was performed
- * Returns: Scan results, %NULL on failure
- *
- * This function request the current scan results from the driver and updates
- * the local BSS list wpa_s->bss. The caller is responsible for freeing the
- * results with wpa_scan_results_free().
- */
-struct wpa_scan_results *
-wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
- struct scan_info *info, int new_scan)
-{
- struct wpa_scan_results *scan_res;
- size_t i;
- int (*compar)(const void *, const void *) = wpa_scan_result_compar;
-
- scan_res = wpa_drv_get_scan_results2(wpa_s);
- if (scan_res == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
- return NULL;
- }
- if (scan_res->fetch_time.sec == 0) {
- /*
- * Make sure we have a valid timestamp if the driver wrapper
- * does not set this.
- */
- os_get_reltime(&scan_res->fetch_time);
- }
- filter_scan_res(wpa_s, scan_res);
-
- for (i = 0; i < scan_res->num; i++) {
- struct wpa_scan_res *scan_res_item = scan_res->res[i];
-
- scan_snr(scan_res_item);
- scan_est_throughput(wpa_s, scan_res_item);
- }
-
-#ifdef CONFIG_WPS
- if (wpas_wps_searching(wpa_s)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
- "provisioning rules");
- compar = wpa_scan_result_wps_compar;
- }
-#endif /* CONFIG_WPS */
-
- if (scan_res->res) {
- qsort(scan_res->res, scan_res->num,
- sizeof(struct wpa_scan_res *), compar);
- }
- dump_scan_res(scan_res);
-
- if (wpa_s->ignore_post_flush_scan_res) {
- /* FLUSH command aborted an ongoing scan and these are the
- * results from the aborted scan. Do not process the results to
- * maintain flushed state. */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Do not update BSS table based on pending post-FLUSH scan results");
- wpa_s->ignore_post_flush_scan_res = 0;
- return scan_res;
- }
-
- wpa_bss_update_start(wpa_s);
- for (i = 0; i < scan_res->num; i++)
- wpa_bss_update_scan_res(wpa_s, scan_res->res[i],
- &scan_res->fetch_time);
- wpa_bss_update_end(wpa_s, info, new_scan);
-
- return scan_res;
-}
-
-
-/**
- * wpa_supplicant_update_scan_results - Update scan results from the driver
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success, -1 on failure
- *
- * This function updates the BSS table within wpa_supplicant based on the
- * currently available scan results from the driver without requesting a new
- * scan. This is used in cases where the driver indicates an association
- * (including roaming within ESS) and wpa_supplicant does not yet have the
- * needed information to complete the connection (e.g., to perform validation
- * steps in 4-way handshake).
- */
-int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
-{
- struct wpa_scan_results *scan_res;
- scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
- if (scan_res == NULL)
- return -1;
- wpa_scan_results_free(scan_res);
-
- return 0;
-}
-
-
-/**
- * scan_only_handler - Reports scan results
- */
-void scan_only_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received");
- if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
- wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
- wpa_s->manual_scan_id);
- wpa_s->manual_scan_use_id = 0;
- } else {
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
- }
- wpas_notify_scan_results(wpa_s);
- wpas_notify_scan_done(wpa_s, 1);
- if (wpa_s->scan_work) {
- struct wpa_radio_work *work = wpa_s->scan_work;
- wpa_s->scan_work = NULL;
- radio_work_done(work);
- }
-
- if (wpa_s->wpa_state == WPA_SCANNING)
- wpa_supplicant_set_state(wpa_s, wpa_s->scan_prev_wpa_state);
-}
-
-
-int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
-{
- return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
-}
-
-
-struct wpa_driver_scan_params *
-wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
-{
- struct wpa_driver_scan_params *params;
- size_t i;
- u8 *n;
-
- params = os_zalloc(sizeof(*params));
- if (params == NULL)
- return NULL;
-
- for (i = 0; i < src->num_ssids; i++) {
- if (src->ssids[i].ssid) {
- n = os_memdup(src->ssids[i].ssid,
- src->ssids[i].ssid_len);
- if (n == NULL)
- goto failed;
- params->ssids[i].ssid = n;
- params->ssids[i].ssid_len = src->ssids[i].ssid_len;
- }
- }
- params->num_ssids = src->num_ssids;
-
- if (src->extra_ies) {
- n = os_memdup(src->extra_ies, src->extra_ies_len);
- if (n == NULL)
- goto failed;
- params->extra_ies = n;
- params->extra_ies_len = src->extra_ies_len;
- }
-
- if (src->freqs) {
- int len = int_array_len(src->freqs);
- params->freqs = os_memdup(src->freqs, (len + 1) * sizeof(int));
- if (params->freqs == NULL)
- goto failed;
- }
-
- if (src->filter_ssids) {
- params->filter_ssids = os_memdup(src->filter_ssids,
- sizeof(*params->filter_ssids) *
- src->num_filter_ssids);
- if (params->filter_ssids == NULL)
- goto failed;
- params->num_filter_ssids = src->num_filter_ssids;
- }
-
- params->filter_rssi = src->filter_rssi;
- params->p2p_probe = src->p2p_probe;
- params->only_new_results = src->only_new_results;
- params->low_priority = src->low_priority;
- params->duration = src->duration;
- params->duration_mandatory = src->duration_mandatory;
- params->oce_scan = src->oce_scan;
-
- if (src->sched_scan_plans_num > 0) {
- params->sched_scan_plans =
- os_memdup(src->sched_scan_plans,
- sizeof(*src->sched_scan_plans) *
- src->sched_scan_plans_num);
- if (!params->sched_scan_plans)
- goto failed;
-
- params->sched_scan_plans_num = src->sched_scan_plans_num;
- }
-
- if (src->mac_addr_rand &&
- wpa_setup_mac_addr_rand_params(params, src->mac_addr))
- goto failed;
-
- if (src->bssid) {
- u8 *bssid;
-
- bssid = os_memdup(src->bssid, ETH_ALEN);
- if (!bssid)
- goto failed;
- params->bssid = bssid;
- }
-
- params->relative_rssi_set = src->relative_rssi_set;
- params->relative_rssi = src->relative_rssi;
- params->relative_adjust_band = src->relative_adjust_band;
- params->relative_adjust_rssi = src->relative_adjust_rssi;
- params->p2p_include_6ghz = src->p2p_include_6ghz;
- return params;
-
-failed:
- wpa_scan_free_params(params);
- return NULL;
-}
-
-
-void wpa_scan_free_params(struct wpa_driver_scan_params *params)
-{
- size_t i;
-
- if (params == NULL)
- return;
-
- for (i = 0; i < params->num_ssids; i++)
- os_free((u8 *) params->ssids[i].ssid);
- os_free((u8 *) params->extra_ies);
- os_free(params->freqs);
- os_free(params->filter_ssids);
- os_free(params->sched_scan_plans);
-
- /*
- * Note: params->mac_addr_mask points to same memory allocation and
- * must not be freed separately.
- */
- os_free((u8 *) params->mac_addr);
-
- os_free((u8 *) params->bssid);
-
- os_free(params);
-}
-
-
-int wpas_start_pno(struct wpa_supplicant *wpa_s)
-{
- int ret;
- size_t prio, i, num_ssid, num_match_ssid;
- struct wpa_ssid *ssid;
- struct wpa_driver_scan_params params;
- struct sched_scan_plan scan_plan;
- unsigned int max_sched_scan_ssids;
-
- if (!wpa_s->sched_scan_supported)
- return -1;
-
- if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
- max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
- else
- max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
- if (max_sched_scan_ssids < 1)
- return -1;
-
- if (wpa_s->pno || wpa_s->pno_sched_pending)
- return 0;
-
- if ((wpa_s->wpa_state > WPA_SCANNING) &&
- (wpa_s->wpa_state < WPA_COMPLETED)) {
- wpa_printf(MSG_ERROR, "PNO: In assoc process");
- return -EAGAIN;
- }
-
- if (wpa_s->wpa_state == WPA_SCANNING) {
- wpa_supplicant_cancel_scan(wpa_s);
- if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
- "ongoing sched scan");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_s->pno_sched_pending = 1;
- return 0;
- }
- }
-
- if (wpa_s->sched_scan_stop_req) {
- wpa_printf(MSG_DEBUG,
- "Schedule PNO after previous sched scan has stopped");
- wpa_s->pno_sched_pending = 1;
- return 0;
- }
-
- os_memset(&params, 0, sizeof(params));
-
- num_ssid = num_match_ssid = 0;
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- if (!wpas_network_disabled(wpa_s, ssid)) {
- num_match_ssid++;
- if (ssid->scan_ssid)
- num_ssid++;
- }
- ssid = ssid->next;
- }
-
- if (num_match_ssid == 0) {
- wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
- return -1;
- }
-
- if (num_match_ssid > num_ssid) {
- params.num_ssids++; /* wildcard */
- num_ssid++;
- }
-
- if (num_ssid > max_sched_scan_ssids) {
- wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
- "%u", max_sched_scan_ssids, (unsigned int) num_ssid);
- num_ssid = max_sched_scan_ssids;
- }
-
- if (num_match_ssid > wpa_s->max_match_sets) {
- num_match_ssid = wpa_s->max_match_sets;
- wpa_dbg(wpa_s, MSG_DEBUG, "PNO: Too many SSIDs to match");
- }
- params.filter_ssids = os_calloc(num_match_ssid,
- sizeof(struct wpa_driver_scan_filter));
- if (params.filter_ssids == NULL)
- return -1;
-
- i = 0;
- prio = 0;
- ssid = wpa_s->conf->pssid[prio];
- while (ssid) {
- if (!wpas_network_disabled(wpa_s, ssid)) {
- if (ssid->scan_ssid && params.num_ssids < num_ssid) {
- params.ssids[params.num_ssids].ssid =
- ssid->ssid;
- params.ssids[params.num_ssids].ssid_len =
- ssid->ssid_len;
- params.num_ssids++;
- }
- os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
- ssid->ssid_len);
- params.filter_ssids[i].ssid_len = ssid->ssid_len;
- params.num_filter_ssids++;
- i++;
- if (i == num_match_ssid)
- break;
- }
- if (ssid->pnext)
- ssid = ssid->pnext;
- else if (prio + 1 == wpa_s->conf->num_prio)
- break;
- else
- ssid = wpa_s->conf->pssid[++prio];
- }
-
- if (wpa_s->conf->filter_rssi)
- params.filter_rssi = wpa_s->conf->filter_rssi;
-
- if (wpa_s->sched_scan_plans_num) {
- params.sched_scan_plans = wpa_s->sched_scan_plans;
- params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
- } else {
- /* Set one scan plan that will run infinitely */
- if (wpa_s->conf->sched_scan_interval)
- scan_plan.interval = wpa_s->conf->sched_scan_interval;
- else
- scan_plan.interval = 10;
-
- scan_plan.iterations = 0;
- params.sched_scan_plans = &scan_plan;
- params.sched_scan_plans_num = 1;
- }
-
- params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
-
- if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels");
- params.freqs = wpa_s->manual_sched_scan_freqs;
- }
-
- if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) &&
- wpa_s->wpa_state <= WPA_SCANNING)
- wpa_setup_mac_addr_rand_params(&params, wpa_s->mac_addr_pno);
-
- wpa_scan_set_relative_rssi_params(wpa_s, &params);
-
- ret = wpa_supplicant_start_sched_scan(wpa_s, &params);
- os_free(params.filter_ssids);
- os_free(params.mac_addr);
- if (ret == 0)
- wpa_s->pno = 1;
- else
- wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
- return ret;
-}
-
-
-int wpas_stop_pno(struct wpa_supplicant *wpa_s)
-{
- int ret = 0;
-
- if (!wpa_s->pno)
- return 0;
-
- ret = wpa_supplicant_stop_sched_scan(wpa_s);
- wpa_s->sched_scan_stop_req = 1;
-
- wpa_s->pno = 0;
- wpa_s->pno_sched_pending = 0;
-
- if (wpa_s->wpa_state == WPA_SCANNING)
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-
- return ret;
-}
-
-
-void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
- unsigned int type)
-{
- type &= MAC_ADDR_RAND_ALL;
- wpa_s->mac_addr_rand_enable &= ~type;
-
- if (type & MAC_ADDR_RAND_SCAN) {
- os_free(wpa_s->mac_addr_scan);
- wpa_s->mac_addr_scan = NULL;
- }
-
- if (type & MAC_ADDR_RAND_SCHED_SCAN) {
- os_free(wpa_s->mac_addr_sched_scan);
- wpa_s->mac_addr_sched_scan = NULL;
- }
-
- if (type & MAC_ADDR_RAND_PNO) {
- os_free(wpa_s->mac_addr_pno);
- wpa_s->mac_addr_pno = NULL;
- }
-}
-
-
-int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
- unsigned int type, const u8 *addr,
- const u8 *mask)
-{
- u8 *tmp = NULL;
-
- if ((wpa_s->mac_addr_rand_supported & type) != type ) {
- wpa_printf(MSG_INFO,
- "scan: MAC randomization type %u != supported=%u",
- type, wpa_s->mac_addr_rand_supported);
- return -1;
- }
-
- wpas_mac_addr_rand_scan_clear(wpa_s, type);
-
- if (addr) {
- tmp = os_malloc(2 * ETH_ALEN);
- if (!tmp)
- return -1;
- os_memcpy(tmp, addr, ETH_ALEN);
- os_memcpy(tmp + ETH_ALEN, mask, ETH_ALEN);
- }
-
- if (type == MAC_ADDR_RAND_SCAN) {
- wpa_s->mac_addr_scan = tmp;
- } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
- wpa_s->mac_addr_sched_scan = tmp;
- } else if (type == MAC_ADDR_RAND_PNO) {
- wpa_s->mac_addr_pno = tmp;
- } else {
- wpa_printf(MSG_INFO,
- "scan: Invalid MAC randomization type=0x%x",
- type);
- os_free(tmp);
- return -1;
- }
-
- wpa_s->mac_addr_rand_enable |= type;
- return 0;
-}
-
-
-int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
- unsigned int type, u8 *mask)
-{
- const u8 *to_copy;
-
- if ((wpa_s->mac_addr_rand_enable & type) != type)
- return -1;
-
- if (type == MAC_ADDR_RAND_SCAN) {
- to_copy = wpa_s->mac_addr_scan;
- } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
- to_copy = wpa_s->mac_addr_sched_scan;
- } else if (type == MAC_ADDR_RAND_PNO) {
- to_copy = wpa_s->mac_addr_pno;
- } else {
- wpa_printf(MSG_DEBUG,
- "scan: Invalid MAC randomization type=0x%x",
- type);
- return -1;
- }
-
- os_memcpy(mask, to_copy + ETH_ALEN, ETH_ALEN);
- return 0;
-}
-
-
-int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s)
-{
- struct wpa_radio_work *work;
- struct wpa_radio *radio = wpa_s->radio;
-
- dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
- if (work->wpa_s != wpa_s || !work->started ||
- (os_strcmp(work->type, "scan") != 0 &&
- os_strcmp(work->type, "p2p-scan") != 0))
- continue;
- wpa_dbg(wpa_s, MSG_DEBUG, "Abort an ongoing scan");
- return wpa_drv_abort_scan(wpa_s, wpa_s->curr_scan_cookie);
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "No ongoing scan/p2p-scan found to abort");
- return -1;
-}
-
-
-int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd)
-{
- struct sched_scan_plan *scan_plans = NULL;
- const char *token, *context = NULL;
- unsigned int num = 0;
-
- if (!cmd)
- return -1;
-
- if (!cmd[0]) {
- wpa_printf(MSG_DEBUG, "Clear sched scan plans");
- os_free(wpa_s->sched_scan_plans);
- wpa_s->sched_scan_plans = NULL;
- wpa_s->sched_scan_plans_num = 0;
- return 0;
- }
-
- while ((token = cstr_token(cmd, " ", &context))) {
- int ret;
- struct sched_scan_plan *scan_plan, *n;
-
- n = os_realloc_array(scan_plans, num + 1, sizeof(*scan_plans));
- if (!n)
- goto fail;
-
- scan_plans = n;
- scan_plan = &scan_plans[num];
- num++;
-
- ret = sscanf(token, "%u:%u", &scan_plan->interval,
- &scan_plan->iterations);
- if (ret <= 0 || ret > 2 || !scan_plan->interval) {
- wpa_printf(MSG_ERROR,
- "Invalid sched scan plan input: %s", token);
- goto fail;
- }
-
- if (scan_plan->interval > wpa_s->max_sched_scan_plan_interval) {
- wpa_printf(MSG_WARNING,
- "scan plan %u: Scan interval too long(%u), use the maximum allowed(%u)",
- num, scan_plan->interval,
- wpa_s->max_sched_scan_plan_interval);
- scan_plan->interval =
- wpa_s->max_sched_scan_plan_interval;
- }
-
- if (ret == 1) {
- scan_plan->iterations = 0;
- break;
- }
-
- if (!scan_plan->iterations) {
- wpa_printf(MSG_ERROR,
- "scan plan %u: Number of iterations cannot be zero",
- num);
- goto fail;
- }
-
- if (scan_plan->iterations >
- wpa_s->max_sched_scan_plan_iterations) {
- wpa_printf(MSG_WARNING,
- "scan plan %u: Too many iterations(%u), use the maximum allowed(%u)",
- num, scan_plan->iterations,
- wpa_s->max_sched_scan_plan_iterations);
- scan_plan->iterations =
- wpa_s->max_sched_scan_plan_iterations;
- }
-
- wpa_printf(MSG_DEBUG,
- "scan plan %u: interval=%u iterations=%u",
- num, scan_plan->interval, scan_plan->iterations);
- }
-
- if (!scan_plans) {
- wpa_printf(MSG_ERROR, "Invalid scan plans entry");
- goto fail;
- }
-
- if (cstr_token(cmd, " ", &context) || scan_plans[num - 1].iterations) {
- wpa_printf(MSG_ERROR,
- "All scan plans but the last must specify a number of iterations");
- goto fail;
- }
-
- wpa_printf(MSG_DEBUG, "scan plan %u (last plan): interval=%u",
- num, scan_plans[num - 1].interval);
-
- if (num > wpa_s->max_sched_scan_plans) {
- wpa_printf(MSG_WARNING,
- "Too many scheduled scan plans (only %u supported)",
- wpa_s->max_sched_scan_plans);
- wpa_printf(MSG_WARNING,
- "Use only the first %u scan plans, and the last one (in infinite loop)",
- wpa_s->max_sched_scan_plans - 1);
- os_memcpy(&scan_plans[wpa_s->max_sched_scan_plans - 1],
- &scan_plans[num - 1], sizeof(*scan_plans));
- num = wpa_s->max_sched_scan_plans;
- }
-
- os_free(wpa_s->sched_scan_plans);
- wpa_s->sched_scan_plans = scan_plans;
- wpa_s->sched_scan_plans_num = num;
-
- return 0;
-
-fail:
- os_free(scan_plans);
- wpa_printf(MSG_ERROR, "invalid scan plans list");
- return -1;
-}
-
-
-/**
- * wpas_scan_reset_sched_scan - Reset sched_scan state
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to cancel a running scheduled scan and to reset an
- * internal scan state to continue with a regular scan on the following
- * wpa_supplicant_req_scan() calls.
- */
-void wpas_scan_reset_sched_scan(struct wpa_supplicant *wpa_s)
-{
- wpa_s->normal_scans = 0;
- if (wpa_s->sched_scanning) {
- wpa_s->sched_scan_timed_out = 0;
- wpa_s->prev_sched_ssid = NULL;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
-}
-
-
-void wpas_scan_restart_sched_scan(struct wpa_supplicant *wpa_s)
-{
- /* simulate timeout to restart the sched scan */
- wpa_s->sched_scan_timed_out = 1;
- wpa_s->prev_sched_ssid = NULL;
- wpa_supplicant_cancel_sched_scan(wpa_s);
-}
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
deleted file mode 100644
index d1780eb09979..000000000000
--- a/wpa_supplicant/scan.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * WPA Supplicant - Scanning
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SCAN_H
-#define SCAN_H
-
-/*
- * Noise floor values to use when we have signal strength
- * measurements, but no noise floor measurements. These values were
- * measured in an office environment with many APs.
- */
-#define DEFAULT_NOISE_FLOOR_2GHZ (-89)
-#define DEFAULT_NOISE_FLOOR_5GHZ (-92)
-#define DEFAULT_NOISE_FLOOR_6GHZ (-92)
-
-/*
- * Channels with a great SNR can operate at full rate. What is a great SNR?
- * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
- * rule of thumb is that any SNR above 20 is good." This one
- * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
- * recommends 25 as a minimum SNR for 54 Mbps data rate. The estimates used in
- * scan_est_throughput() allow even smaller SNR values for the maximum rates
- * (21 for 54 Mbps, 22 for VHT80 MCS9, 24 for HT40 and HT20 MCS7). Use 25 as a
- * somewhat conservative value here.
- */
-#define GREAT_SNR 25
-
-#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
-#define IS_5GHZ(n) (n > 4000 && n < 5895)
-
-int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
-int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
- int sec, int usec);
-int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
- int scanning);
-struct wpa_driver_scan_params;
-int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params);
-struct wpa_scan_results *
-wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
- struct scan_info *info, int new_scan);
-int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s);
-const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
-const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
- u32 vendor_type);
-const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
- u32 vendor_type);
-struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
- u32 vendor_type);
-int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
- const u8 *bssid);
-void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec);
-void scan_only_handler(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
-int wpas_scan_scheduled(struct wpa_supplicant *wpa_s);
-struct wpa_driver_scan_params *
-wpa_scan_clone_params(const struct wpa_driver_scan_params *src);
-void wpa_scan_free_params(struct wpa_driver_scan_params *params);
-int wpas_start_pno(struct wpa_supplicant *wpa_s);
-int wpas_stop_pno(struct wpa_supplicant *wpa_s);
-void wpas_scan_reset_sched_scan(struct wpa_supplicant *wpa_s);
-void wpas_scan_restart_sched_scan(struct wpa_supplicant *wpa_s);
-
-void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
- unsigned int type);
-int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
- unsigned int type, const u8 *addr,
- const u8 *mask);
-int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
- unsigned int type, u8 *mask);
-int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s);
-void filter_scan_res(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *res);
-void scan_snr(struct wpa_scan_res *res);
-void scan_est_throughput(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res);
-unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len, int rate,
- int snr, int freq);
-void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s);
-int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s,
- enum hostapd_hw_mode band,
- struct wpa_driver_scan_params *params,
- bool is_6ghz);
-
-#endif /* SCAN_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
deleted file mode 100644
index 1dc7001a7305..000000000000
--- a/wpa_supplicant/sme.c
+++ /dev/null
@@ -1,2945 +0,0 @@
-/*
- * wpa_supplicant - SME
- * Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/ocv.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "common/wpa_common.h"
-#include "common/sae.h"
-#include "common/dpp.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "wpas_glue.h"
-#include "wps_supplicant.h"
-#include "p2p_supplicant.h"
-#include "notify.h"
-#include "bss.h"
-#include "scan.h"
-#include "sme.h"
-#include "hs20_supplicant.h"
-
-#define SME_AUTH_TIMEOUT 5
-#define SME_ASSOC_TIMEOUT 5
-
-static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
-static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
-static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx);
-static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
-
-
-#ifdef CONFIG_SAE
-
-static int index_within_array(const int *array, int idx)
-{
- int i;
- for (i = 0; i < idx; i++) {
- if (array[i] <= 0)
- return 0;
- }
- return 1;
-}
-
-
-static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
-{
- int *groups = wpa_s->conf->sae_groups;
- int default_groups[] = { 19, 20, 21, 0 };
-
- if (!groups || groups[0] <= 0)
- groups = default_groups;
-
- /* Configuration may have changed, so validate current index */
- if (!index_within_array(groups, wpa_s->sme.sae_group_index))
- return -1;
-
- for (;;) {
- int group = groups[wpa_s->sme.sae_group_index];
- if (group <= 0)
- break;
- if (sae_set_group(&wpa_s->sme.sae, group) == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
- wpa_s->sme.sae.group);
- return 0;
- }
- wpa_s->sme.sae_group_index++;
- }
-
- return -1;
-}
-
-
-static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const u8 *bssid, int external,
- int reuse, int *ret_use_pt,
- bool *ret_use_pk)
-{
- struct wpabuf *buf;
- size_t len;
- const char *password;
- struct wpa_bss *bss;
- int use_pt = 0;
- bool use_pk = false;
- u8 rsnxe_capa = 0;
-
- if (ret_use_pt)
- *ret_use_pt = 0;
- if (ret_use_pk)
- *ret_use_pk = false;
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->sae_commit_override) {
- wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
- buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override));
- if (!buf)
- return NULL;
- if (!external) {
- wpabuf_put_le16(buf, 1); /* Transaction seq# */
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
- }
- wpabuf_put_buf(buf, wpa_s->sae_commit_override);
- return buf;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- password = ssid->sae_password;
- if (!password)
- password = ssid->passphrase;
- if (!password) {
- wpa_printf(MSG_DEBUG, "SAE: No password available");
- return NULL;
- }
-
- if (reuse && wpa_s->sme.sae.tmp &&
- os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
- wpa_printf(MSG_DEBUG,
- "SAE: Reuse previously generated PWE on a retry with the same AP");
- use_pt = wpa_s->sme.sae.h2e;
- use_pk = wpa_s->sme.sae.pk;
- goto reuse_data;
- }
- if (sme_set_sae_group(wpa_s) < 0) {
- wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
- return NULL;
- }
-
- bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- if (!bss) {
- wpa_printf(MSG_DEBUG,
- "SAE: BSS not available, update scan result to get BSS");
- wpa_supplicant_update_scan_results(wpa_s);
- bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- }
- if (bss) {
- const u8 *rsnxe;
-
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (rsnxe && rsnxe[1] >= 1)
- rsnxe_capa = rsnxe[2];
- }
-
- if (ssid->sae_password_id && wpa_s->conf->sae_pwe != 3)
- use_pt = 1;
-#ifdef CONFIG_SAE_PK
- if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
- ssid->sae_pk != SAE_PK_MODE_DISABLED &&
- ((ssid->sae_password &&
- sae_pk_valid_password(ssid->sae_password)) ||
- (!ssid->sae_password && ssid->passphrase &&
- sae_pk_valid_password(ssid->passphrase)))) {
- use_pt = 1;
- use_pk = true;
- }
-
- if (ssid->sae_pk == SAE_PK_MODE_ONLY && !use_pk) {
- wpa_printf(MSG_DEBUG,
- "SAE: Cannot use PK with the selected AP");
- return NULL;
- }
-#endif /* CONFIG_SAE_PK */
-
- if (use_pt || wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
- use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E));
-
- if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
- wpa_s->conf->sae_pwe != 3 &&
- !use_pt) {
- wpa_printf(MSG_DEBUG,
- "SAE: Cannot use H2E with the selected AP");
- return NULL;
- }
- }
-
- if (use_pt &&
- sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt,
- wpa_s->own_addr, bssid,
- wpa_s->sme.sae_rejected_groups, NULL) < 0)
- return NULL;
- if (!use_pt &&
- sae_prepare_commit(wpa_s->own_addr, bssid,
- (u8 *) password, os_strlen(password),
- &wpa_s->sme.sae) < 0) {
- wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
- return NULL;
- }
- if (wpa_s->sme.sae.tmp) {
- os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
- if (use_pt && use_pk)
- wpa_s->sme.sae.pk = 1;
-#ifdef CONFIG_SAE_PK
- os_memcpy(wpa_s->sme.sae.tmp->own_addr, wpa_s->own_addr,
- ETH_ALEN);
- os_memcpy(wpa_s->sme.sae.tmp->peer_addr, bssid, ETH_ALEN);
- sae_pk_set_password(&wpa_s->sme.sae, password);
-#endif /* CONFIG_SAE_PK */
- }
-
-reuse_data:
- len = wpa_s->sme.sae_token ? 3 + wpabuf_len(wpa_s->sme.sae_token) : 0;
- if (ssid->sae_password_id)
- len += 4 + os_strlen(ssid->sae_password_id);
- buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
- if (buf == NULL)
- return NULL;
- if (!external) {
- wpabuf_put_le16(buf, 1); /* Transaction seq# */
- if (use_pk)
- wpabuf_put_le16(buf, WLAN_STATUS_SAE_PK);
- else if (use_pt)
- wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
- else
- wpabuf_put_le16(buf,WLAN_STATUS_SUCCESS);
- }
- if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
- ssid->sae_password_id) < 0) {
- wpabuf_free(buf);
- return NULL;
- }
- if (ret_use_pt)
- *ret_use_pt = use_pt;
- if (ret_use_pk)
- *ret_use_pk = use_pk;
-
- return buf;
-}
-
-
-static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s,
- int external)
-{
- struct wpabuf *buf;
-
- buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN);
- if (buf == NULL)
- return NULL;
-
- if (!external) {
- wpabuf_put_le16(buf, 2); /* Transaction seq# */
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
- }
- sae_write_confirm(&wpa_s->sme.sae, buf);
-
- return buf;
-}
-
-#endif /* CONFIG_SAE */
-
-
-/**
- * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt
- * @wpa_s: Pointer to wpa_supplicant data
- * @bss: Pointer to the bss which is the target of authentication attempt
- */
-static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
- const u8 rrm_ie_len = 5;
- u8 *pos;
- const u8 *rrm_ie;
-
- wpa_s->rrm.rrm_used = 0;
-
- wpa_printf(MSG_DEBUG,
- "RRM: Determining whether RRM can be used - device support: 0x%x",
- wpa_s->drv_rrm_flags);
-
- rrm_ie = wpa_bss_get_ie(bss, WLAN_EID_RRM_ENABLED_CAPABILITIES);
- if (!rrm_ie || !(bss->caps & IEEE80211_CAP_RRM)) {
- wpa_printf(MSG_DEBUG, "RRM: No RRM in network");
- return;
- }
-
- if (!((wpa_s->drv_rrm_flags &
- WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) &&
- (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) &&
- !(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_RRM)) {
- wpa_printf(MSG_DEBUG,
- "RRM: Insufficient RRM support in driver - do not use RRM");
- return;
- }
-
- if (sizeof(wpa_s->sme.assoc_req_ie) <
- wpa_s->sme.assoc_req_ie_len + rrm_ie_len + 2) {
- wpa_printf(MSG_INFO,
- "RRM: Unable to use RRM, no room for RRM IE");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "RRM: Adding RRM IE to Association Request");
- pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
- os_memset(pos, 0, 2 + rrm_ie_len);
- *pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
- *pos++ = rrm_ie_len;
-
- /* Set supported capabilities flags */
- if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)
- *pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
-
- *pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
- WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
- WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
-
- if (wpa_s->lci)
- pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT;
-
- wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2;
- wpa_s->rrm.rrm_used = 1;
-}
-
-
-static void sme_send_authentication(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid,
- int start)
-{
- struct wpa_driver_auth_params params;
- struct wpa_ssid *old_ssid;
-#ifdef CONFIG_IEEE80211R
- const u8 *ie;
-#endif /* CONFIG_IEEE80211R */
-#if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
- const u8 *md = NULL;
-#endif /* CONFIG_IEEE80211R || CONFIG_FILS */
- int bssid_changed;
- struct wpabuf *resp = NULL;
- u8 ext_capab[18];
- int ext_capab_len;
- int skip_auth;
- u8 *wpa_ie;
- size_t wpa_ie_len;
-#ifdef CONFIG_MBO
- const u8 *mbo_ie;
-#endif /* CONFIG_MBO */
- int omit_rsnxe = 0;
-
- if (bss == NULL) {
- wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for "
- "the network");
- wpas_connect_work_done(wpa_s);
- return;
- }
-
- skip_auth = wpa_s->conf->reassoc_same_bss_optim &&
- wpa_s->reassoc_same_bss;
- wpa_s->current_bss = bss;
-
- os_memset(&params, 0, sizeof(params));
- wpa_s->reassociate = 0;
-
- params.freq = bss->freq;
- params.bssid = bss->bssid;
- params.ssid = bss->ssid;
- params.ssid_len = bss->ssid_len;
- params.p2p = ssid->p2p_group;
-
- if (wpa_s->sme.ssid_len != params.ssid_len ||
- os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
- wpa_s->sme.prev_bssid_set = 0;
-
- wpa_s->sme.freq = params.freq;
- os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
- wpa_s->sme.ssid_len = params.ssid_len;
-
- params.auth_alg = WPA_AUTH_ALG_OPEN;
-#ifdef IEEE8021X_EAPOL
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- if (ssid->leap) {
- if (ssid->non_leap == 0)
- params.auth_alg = WPA_AUTH_ALG_LEAP;
- else
- params.auth_alg |= WPA_AUTH_ALG_LEAP;
- }
- }
-#endif /* IEEE8021X_EAPOL */
- wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
- params.auth_alg);
- if (ssid->auth_alg) {
- params.auth_alg = ssid->auth_alg;
- wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
- "0x%x", params.auth_alg);
- }
-#ifdef CONFIG_SAE
- wpa_s->sme.sae_pmksa_caching = 0;
- if (wpa_key_mgmt_sae(ssid->key_mgmt)) {
- const u8 *rsn;
- struct wpa_ie_data ied;
-
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (!rsn) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SAE enabled, but target BSS does not advertise RSN");
-#ifdef CONFIG_DPP
- } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
- (ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
- (ied.key_mgmt & WPA_KEY_MGMT_DPP)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Prefer DPP over SAE when both are enabled");
-#endif /* CONFIG_DPP */
- } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
- wpa_key_mgmt_sae(ied.key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg");
- params.auth_alg = WPA_AUTH_ALG_SAE;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SAE enabled, but target BSS does not advertise SAE AKM for RSN");
- }
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_WEP
- {
- int i;
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i])
- params.wep_key[i] = ssid->wep_key[i];
- params.wep_key_len[i] = ssid->wep_key_len[i];
- }
- params.wep_tx_keyidx = ssid->wep_tx_keyidx;
- }
-#endif /* CONFIG_WEP */
-
- if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
- wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
- wpa_key_mgmt_wpa(ssid->key_mgmt)) {
- int try_opportunistic;
- const u8 *cache_id = NULL;
-
- try_opportunistic = (ssid->proactive_key_caching < 0 ?
- wpa_s->conf->okc :
- ssid->proactive_key_caching) &&
- (ssid->proto & WPA_PROTO_RSN);
-#ifdef CONFIG_FILS
- if (wpa_key_mgmt_fils(ssid->key_mgmt))
- cache_id = wpa_bss_get_fils_cache_id(bss);
-#endif /* CONFIG_FILS */
- if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
- wpa_s->current_ssid,
- try_opportunistic, cache_id,
- 0) == 0)
- eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
- wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
- if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
- wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
- "key management and encryption suites");
- wpas_connect_work_done(wpa_s);
- return;
- }
-#ifdef CONFIG_HS20
- } else if (wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE) &&
- (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)) {
- /* No PMKSA caching, but otherwise similar to RSN/WPA */
- wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
- if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
- wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
- "key management and encryption suites");
- wpas_connect_work_done(wpa_s);
- return;
- }
-#endif /* CONFIG_HS20 */
- } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
- wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
- /*
- * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
- * use non-WPA since the scan results did not indicate that the
- * AP is using WPA or WPA2.
- */
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- wpa_s->sme.assoc_req_ie_len = 0;
- } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
- wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
- if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
- wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
- "key management and encryption suites (no "
- "scan results)");
- wpas_connect_work_done(wpa_s);
- return;
- }
-#ifdef CONFIG_WPS
- } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- struct wpabuf *wps_ie;
- wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
- if (wps_ie && wpabuf_len(wps_ie) <=
- sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie);
- os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie),
- wpa_s->sme.assoc_req_ie_len);
- } else
- wpa_s->sme.assoc_req_ie_len = 0;
- wpabuf_free(wps_ie);
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
-#endif /* CONFIG_WPS */
- } else {
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- wpa_s->sme.assoc_req_ie_len = 0;
- }
-
- /* In case the WPA vendor IE is used, it should be placed after all the
- * non-vendor IEs, as the lower layer expects the IEs to be ordered as
- * defined in the standard. Store the WPA IE so it can later be
- * inserted at the correct location.
- */
- wpa_ie = NULL;
- wpa_ie_len = 0;
- if (wpa_s->wpa_proto == WPA_PROTO_WPA) {
- wpa_ie = os_memdup(wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- if (wpa_ie) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Storing WPA IE");
-
- wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
- wpa_s->sme.assoc_req_ie_len = 0;
- } else {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed copy WPA IE");
- wpas_connect_work_done(wpa_s);
- return;
- }
- }
-
-#ifdef CONFIG_IEEE80211R
- ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
- if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
- md = ie + 2;
- wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
- if (md && (!wpa_key_mgmt_ft(ssid->key_mgmt) ||
- !wpa_key_mgmt_ft(wpa_s->key_mgmt)))
- md = NULL;
- if (md) {
- /* Prepare for the next transition */
- wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
- }
-
- if (md) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
- md[0], md[1]);
-
- omit_rsnxe = !wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (wpa_s->sme.assoc_req_ie_len + 5 <
- sizeof(wpa_s->sme.assoc_req_ie)) {
- struct rsn_mdie *mdie;
- u8 *pos = wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len;
- *pos++ = WLAN_EID_MOBILITY_DOMAIN;
- *pos++ = sizeof(*mdie);
- mdie = (struct rsn_mdie *) pos;
- os_memcpy(mdie->mobility_domain, md,
- MOBILITY_DOMAIN_ID_LEN);
- mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN];
- wpa_s->sme.assoc_req_ie_len += 5;
- }
-
- if (wpa_s->sme.prev_bssid_set && wpa_s->sme.ft_used &&
- os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 &&
- wpa_sm_has_ptk(wpa_s->wpa)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT "
- "over-the-air");
- params.auth_alg = WPA_AUTH_ALG_FT;
- params.ie = wpa_s->sme.ft_ies;
- params.ie_len = wpa_s->sme.ft_ies_len;
- }
- }
-#endif /* CONFIG_IEEE80211R */
-
- wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
- if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
- const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- struct wpa_ie_data _ie;
- if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
- _ie.capabilities &
- (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports "
- "MFP: require MFP");
- wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
- }
- }
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p) {
- u8 *pos;
- size_t len;
- int res;
- pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
- len = sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len;
- res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
- ssid->p2p_group);
- if (res >= 0)
- wpa_s->sme.assoc_req_ie_len += res;
- }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_FST
- if (wpa_s->fst_ies) {
- int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
-
- if (wpa_s->sme.assoc_req_ie_len + fst_ies_len <=
- sizeof(wpa_s->sme.assoc_req_ie)) {
- os_memcpy(wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(wpa_s->fst_ies),
- fst_ies_len);
- wpa_s->sme.assoc_req_ie_len += fst_ies_len;
- }
- }
-#endif /* CONFIG_FST */
-
- sme_auth_handle_rrm(wpa_s, bss);
-
- wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie(
- wpa_s, ssid, bss,
- wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len);
-
- if (params.p2p)
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
- else
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
-
- ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
- if (ext_capab_len > 0) {
- u8 *pos = wpa_s->sme.assoc_req_ie;
- if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)
- pos += 2 + pos[1];
- os_memmove(pos + ext_capab_len, pos,
- wpa_s->sme.assoc_req_ie_len -
- (pos - wpa_s->sme.assoc_req_ie));
- wpa_s->sme.assoc_req_ie_len += ext_capab_len;
- os_memcpy(pos, ext_capab, ext_capab_len);
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->rsnxe_override_assoc &&
- wpabuf_len(wpa_s->rsnxe_override_assoc) <=
- sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len) {
- wpa_printf(MSG_DEBUG, "TESTING: RSNXE AssocReq override");
- os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(wpa_s->rsnxe_override_assoc),
- wpabuf_len(wpa_s->rsnxe_override_assoc));
- wpa_s->sme.assoc_req_ie_len +=
- wpabuf_len(wpa_s->rsnxe_override_assoc);
- } else
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_s->rsnxe_len > 0 &&
- wpa_s->rsnxe_len <=
- sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len &&
- !omit_rsnxe) {
- os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- wpa_s->rsnxe, wpa_s->rsnxe_len);
- wpa_s->sme.assoc_req_ie_len += wpa_s->rsnxe_len;
- }
-
-#ifdef CONFIG_HS20
- if (is_hs20_network(wpa_s, ssid, bss)) {
- struct wpabuf *hs20;
-
- hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
- if (hs20) {
- int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
- size_t len;
-
- wpas_hs20_add_indication(hs20, pps_mo_id,
- get_hs20_version(bss));
- wpas_hs20_add_roam_cons_sel(hs20, ssid);
- len = sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len;
- if (wpabuf_len(hs20) <= len) {
- os_memcpy(wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(hs20), wpabuf_len(hs20));
- wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20);
- }
- wpabuf_free(hs20);
- }
- }
-#endif /* CONFIG_HS20 */
-
- if (wpa_ie) {
- size_t len;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Reinsert WPA IE");
-
- len = sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len;
-
- if (len > wpa_ie_len) {
- os_memcpy(wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len,
- wpa_ie, wpa_ie_len);
- wpa_s->sme.assoc_req_ie_len += wpa_ie_len;
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Failed to add WPA IE");
- }
-
- os_free(wpa_ie);
- }
-
- if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
- struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
- size_t len;
-
- len = sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len;
- if (wpabuf_len(buf) <= len) {
- os_memcpy(wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(buf), wpabuf_len(buf));
- wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
- }
- }
-
-#ifdef CONFIG_MBO
- mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
- if (!wpa_s->disable_mbo_oce && mbo_ie) {
- int len;
-
- len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
- wpa_s->sme.assoc_req_ie_len,
- sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len,
- !!mbo_attr_from_mbo_ie(mbo_ie,
- OCE_ATTR_ID_CAPA_IND));
- if (len >= 0)
- wpa_s->sme.assoc_req_ie_len += len;
- }
-#endif /* CONFIG_MBO */
-
-#ifdef CONFIG_SAE
- if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE &&
- pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0,
- NULL,
- wpa_s->key_mgmt == WPA_KEY_MGMT_FT_SAE ?
- WPA_KEY_MGMT_FT_SAE :
- WPA_KEY_MGMT_SAE) == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
- wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
- params.auth_alg = WPA_AUTH_ALG_OPEN;
- wpa_s->sme.sae_pmksa_caching = 1;
- }
-
- if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
- if (start)
- resp = sme_auth_build_sae_commit(wpa_s, ssid,
- bss->bssid, 0,
- start == 2, NULL,
- NULL);
- else
- resp = sme_auth_build_sae_confirm(wpa_s, 0);
- if (resp == NULL) {
- wpas_connection_failed(wpa_s, bss->bssid);
- return;
- }
- params.auth_data = wpabuf_head(resp);
- params.auth_data_len = wpabuf_len(resp);
- wpa_s->sme.sae.state = start ? SAE_COMMITTED : SAE_CONFIRMED;
- }
-#endif /* CONFIG_SAE */
-
- bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
- os_memset(wpa_s->bssid, 0, ETH_ALEN);
- os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-
- old_ssid = wpa_s->current_ssid;
- wpa_s->current_ssid = ssid;
- wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
- wpa_supplicant_initiate_eapol(wpa_s);
-
-#ifdef CONFIG_FILS
- /* TODO: FILS operations can in some cases be done between different
- * network_ctx (i.e., same credentials can be used with multiple
- * networks). */
- if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
- wpa_key_mgmt_fils(ssid->key_mgmt)) {
- const u8 *indic;
- u16 fils_info;
- const u8 *realm, *username, *rrk;
- size_t realm_len, username_len, rrk_len;
- u16 next_seq_num;
-
- /*
- * Check FILS Indication element (FILS Information field) bits
- * indicating supported authentication algorithms against local
- * configuration (ssid->fils_dh_group). Try to use FILS
- * authentication only if the AP supports the combination in the
- * network profile. */
- indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
- if (!indic || indic[1] < 2) {
- wpa_printf(MSG_DEBUG, "SME: " MACSTR
- " does not include FILS Indication element - cannot use FILS authentication with it",
- MAC2STR(bss->bssid));
- goto no_fils;
- }
-
- fils_info = WPA_GET_LE16(indic + 2);
- if (ssid->fils_dh_group == 0 && !(fils_info & BIT(9))) {
- wpa_printf(MSG_DEBUG, "SME: " MACSTR
- " does not support FILS SK without PFS - cannot use FILS authentication with it",
- MAC2STR(bss->bssid));
- goto no_fils;
- }
- if (ssid->fils_dh_group != 0 && !(fils_info & BIT(10))) {
- wpa_printf(MSG_DEBUG, "SME: " MACSTR
- " does not support FILS SK with PFS - cannot use FILS authentication with it",
- MAC2STR(bss->bssid));
- goto no_fils;
- }
-
- if (wpa_s->last_con_fail_realm &&
- eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
- &username, &username_len,
- &realm, &realm_len, &next_seq_num,
- &rrk, &rrk_len) == 0 &&
- realm && realm_len == wpa_s->last_con_fail_realm_len &&
- os_memcmp(realm, wpa_s->last_con_fail_realm,
- realm_len) == 0) {
- wpa_printf(MSG_DEBUG,
- "SME: FILS authentication for this realm failed last time - try to regenerate ERP key hierarchy");
- goto no_fils;
- }
-
- if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
- ssid, 0,
- wpa_bss_get_fils_cache_id(bss),
- 0) == 0)
- wpa_printf(MSG_DEBUG,
- "SME: Try to use FILS with PMKSA caching");
- resp = fils_build_auth(wpa_s->wpa, ssid->fils_dh_group, md);
- if (resp) {
- int auth_alg;
-
- if (ssid->fils_dh_group)
- wpa_printf(MSG_DEBUG,
- "SME: Try to use FILS SK authentication with PFS (DH Group %u)",
- ssid->fils_dh_group);
- else
- wpa_printf(MSG_DEBUG,
- "SME: Try to use FILS SK authentication without PFS");
- auth_alg = ssid->fils_dh_group ?
- WPA_AUTH_ALG_FILS_SK_PFS : WPA_AUTH_ALG_FILS;
- params.auth_alg = auth_alg;
- params.auth_data = wpabuf_head(resp);
- params.auth_data_len = wpabuf_len(resp);
- wpa_s->sme.auth_alg = auth_alg;
- }
- }
-no_fils:
-#endif /* CONFIG_FILS */
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
-
- wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR
- " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
- wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
-
- eapol_sm_notify_portValid(wpa_s->eapol, false);
- wpa_clear_keys(wpa_s, bss->bssid);
- wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
- if (old_ssid != wpa_s->current_ssid)
- wpas_notify_network_changed(wpa_s);
-
-#ifdef CONFIG_HS20
- hs20_configure_frame_filters(wpa_s);
-#endif /* CONFIG_HS20 */
-
-#ifdef CONFIG_P2P
- /*
- * If multi-channel concurrency is not supported, check for any
- * frequency conflict. In case of any frequency conflict, remove the
- * least prioritized connection.
- */
- if (wpa_s->num_multichan_concurrent < 2) {
- int freq, num;
- num = get_shared_radio_freqs(wpa_s, &freq, 1);
- if (num > 0 && freq > 0 && freq != params.freq) {
- wpa_printf(MSG_DEBUG,
- "Conflicting frequency found (%d != %d)",
- freq, params.freq);
- if (wpas_p2p_handle_frequency_conflicts(wpa_s,
- params.freq,
- ssid) < 0) {
- wpas_connection_failed(wpa_s, bss->bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- wpabuf_free(resp);
- wpas_connect_work_done(wpa_s);
- return;
- }
- }
- }
-#endif /* CONFIG_P2P */
-
- if (skip_auth) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "SME: Skip authentication step on reassoc-to-same-BSS");
- wpabuf_free(resp);
- sme_associate(wpa_s, ssid->mode, bss->bssid, WLAN_AUTH_OPEN);
- return;
- }
-
-
- wpa_s->sme.auth_alg = params.auth_alg;
- if (wpa_drv_authenticate(wpa_s, &params) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
- "driver failed");
- wpas_connection_failed(wpa_s, bss->bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- wpabuf_free(resp);
- wpas_connect_work_done(wpa_s);
- return;
- }
-
- eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
- NULL);
-
- /*
- * Association will be started based on the authentication event from
- * the driver.
- */
-
- wpabuf_free(resp);
-}
-
-
-static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_connect_work *cwork = work->ctx;
- struct wpa_supplicant *wpa_s = work->wpa_s;
-
- wpa_s->roam_in_progress = false;
-
- if (deinit) {
- if (work->started)
- wpa_s->connect_work = NULL;
-
- wpas_connect_work_free(cwork);
- return;
- }
-
- wpa_s->connect_work = work;
-
- if (cwork->bss_removed ||
- !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid) ||
- wpas_network_disabled(wpa_s, cwork->ssid)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt");
- wpas_connect_work_done(wpa_s);
- return;
- }
-
- /* Starting new connection, so clear the possibly used WPA IE from the
- * previous association. */
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
- wpa_s->rsnxe_len = 0;
-
- sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
-}
-
-
-void sme_authenticate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid)
-{
- struct wpa_connect_work *cwork;
-
- if (bss == NULL || ssid == NULL)
- return;
- if (wpa_s->connect_work) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist");
- return;
- }
-
- if (wpa_s->roam_in_progress) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Reject sme_authenticate() in favor of explicit roam request");
- return;
- }
- if (radio_work_pending(wpa_s, "sme-connect")) {
- /*
- * The previous sme-connect work might no longer be valid due to
- * the fact that the BSS list was updated. In addition, it makes
- * sense to adhere to the 'newer' decision.
- */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Remove previous pending sme-connect");
- radio_remove_works(wpa_s, "sme-connect", 0);
- }
-
- wpas_abort_ongoing_scan(wpa_s);
-
- cwork = os_zalloc(sizeof(*cwork));
- if (cwork == NULL)
- return;
- cwork->bss = bss;
- cwork->ssid = ssid;
- cwork->sme = 1;
-
-#ifdef CONFIG_SAE
- wpa_s->sme.sae.state = SAE_NOTHING;
- wpa_s->sme.sae.send_confirm = 0;
- wpa_s->sme.sae_group_index = 0;
-#endif /* CONFIG_SAE */
-
- if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1,
- sme_auth_start_cb, cwork) < 0)
- wpas_connect_work_free(cwork);
-}
-
-
-#ifdef CONFIG_SAE
-
-static int sme_external_auth_build_buf(struct wpabuf *buf,
- struct wpabuf *params,
- const u8 *sa, const u8 *da,
- u16 auth_transaction, u16 seq_num,
- u16 status_code)
-{
- struct ieee80211_mgmt *resp;
-
- resp = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
- u.auth.variable));
-
- resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_AUTH << 4));
- os_memcpy(resp->da, da, ETH_ALEN);
- os_memcpy(resp->sa, sa, ETH_ALEN);
- os_memcpy(resp->bssid, da, ETH_ALEN);
- resp->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
- resp->seq_ctrl = host_to_le16(seq_num << 4);
- resp->u.auth.auth_transaction = host_to_le16(auth_transaction);
- resp->u.auth.status_code = host_to_le16(status_code);
- if (params)
- wpabuf_put_buf(buf, params);
-
- return 0;
-}
-
-
-static int sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
- const u8 *bssid,
- struct wpa_ssid *ssid)
-{
- struct wpabuf *resp, *buf;
- int use_pt;
- bool use_pk;
- u16 status;
-
- resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0, &use_pt,
- &use_pk);
- if (!resp) {
- wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
- return -1;
- }
-
- wpa_s->sme.sae.state = SAE_COMMITTED;
- buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
- if (!buf) {
- wpabuf_free(resp);
- return -1;
- }
-
- wpa_s->sme.seq_num++;
- if (use_pk)
- status = WLAN_STATUS_SAE_PK;
- else if (use_pt)
- status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
- else
- status = WLAN_STATUS_SUCCESS;
- sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
- bssid, 1, wpa_s->sme.seq_num, status);
- wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
- wpabuf_free(resp);
- wpabuf_free(buf);
-
- return 0;
-}
-
-
-static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
- u16 status)
-{
- struct external_auth params;
-
- os_memset(&params, 0, sizeof(params));
- params.status = status;
- params.ssid = wpa_s->sme.ext_auth_ssid;
- params.ssid_len = wpa_s->sme.ext_auth_ssid_len;
- params.bssid = wpa_s->sme.ext_auth_bssid;
- if (wpa_s->conf->sae_pmkid_in_assoc && status == WLAN_STATUS_SUCCESS)
- params.pmkid = wpa_s->sme.sae.pmkid;
- wpa_drv_send_external_auth_status(wpa_s, &params);
-}
-
-
-static int sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- struct wpa_ssid *ssid;
- size_t ssid_str_len = data->external_auth.ssid_len;
- const u8 *ssid_str = data->external_auth.ssid;
-
- /* Get the SSID conf from the ssid string obtained */
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (!wpas_network_disabled(wpa_s, ssid) &&
- ssid_str_len == ssid->ssid_len &&
- os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
- (ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)))
- break;
- }
- if (!ssid ||
- sme_external_auth_send_sae_commit(wpa_s, data->external_auth.bssid,
- ssid) < 0)
- return -1;
-
- return 0;
-}
-
-
-static void sme_external_auth_send_sae_confirm(struct wpa_supplicant *wpa_s,
- const u8 *da)
-{
- struct wpabuf *resp, *buf;
-
- resp = sme_auth_build_sae_confirm(wpa_s, 1);
- if (!resp) {
- wpa_printf(MSG_DEBUG, "SAE: Confirm message buf alloc failure");
- return;
- }
-
- wpa_s->sme.sae.state = SAE_CONFIRMED;
- buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp));
- if (!buf) {
- wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
- wpabuf_free(resp);
- return;
- }
- wpa_s->sme.seq_num++;
- sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
- da, 2, wpa_s->sme.seq_num,
- WLAN_STATUS_SUCCESS);
- wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
- wpabuf_free(resp);
- wpabuf_free(buf);
-}
-
-
-void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- if (RSN_SELECTOR_GET(&data->external_auth.key_mgmt_suite) !=
- RSN_AUTH_KEY_MGMT_SAE)
- return;
-
- if (data->external_auth.action == EXT_AUTH_START) {
- if (!data->external_auth.bssid || !data->external_auth.ssid)
- return;
- os_memcpy(wpa_s->sme.ext_auth_bssid, data->external_auth.bssid,
- ETH_ALEN);
- os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
- data->external_auth.ssid_len);
- wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
- wpa_s->sme.seq_num = 0;
- wpa_s->sme.sae.state = SAE_NOTHING;
- wpa_s->sme.sae.send_confirm = 0;
- wpa_s->sme.sae_group_index = 0;
- if (sme_handle_external_auth_start(wpa_s, data) < 0)
- sme_send_external_auth_status(wpa_s,
- WLAN_STATUS_UNSPECIFIED_FAILURE);
- } else if (data->external_auth.action == EXT_AUTH_ABORT) {
- /* Report failure to driver for the wrong trigger */
- sme_send_external_auth_status(wpa_s,
- WLAN_STATUS_UNSPECIFIED_FAILURE);
- }
-}
-
-
-static int sme_sae_is_group_enabled(struct wpa_supplicant *wpa_s, int group)
-{
- int *groups = wpa_s->conf->sae_groups;
- int default_groups[] = { 19, 20, 21, 0 };
- int i;
-
- if (!groups)
- groups = default_groups;
-
- for (i = 0; groups[i] > 0; i++) {
- if (groups[i] == group)
- return 1;
- }
-
- return 0;
-}
-
-
-static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
- const struct wpabuf *groups)
-{
- size_t i, count;
- const u8 *pos;
-
- if (!groups)
- return 0;
-
- pos = wpabuf_head(groups);
- count = wpabuf_len(groups) / 2;
- for (i = 0; i < count; i++) {
- int enabled;
- u16 group;
-
- group = WPA_GET_LE16(pos);
- pos += 2;
- enabled = sme_sae_is_group_enabled(wpa_s, group);
- wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
- group, enabled ? "enabled" : "disabled");
- if (enabled)
- return 1;
- }
-
- return 0;
-}
-
-
-static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
- u16 status_code, const u8 *data, size_t len,
- int external, const u8 *sa)
-{
- int *groups;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
- "status code %u", auth_transaction, status_code);
-
- if (auth_transaction == 1 &&
- status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
- wpa_s->sme.sae.state == SAE_COMMITTED &&
- (external || wpa_s->current_bss) && wpa_s->current_ssid) {
- int default_groups[] = { 19, 20, 21, 0 };
- u16 group;
- const u8 *token_pos;
- size_t token_len;
- int h2e = 0;
-
- groups = wpa_s->conf->sae_groups;
- if (!groups || groups[0] <= 0)
- groups = default_groups;
-
- wpa_hexdump(MSG_DEBUG, "SME: SAE anti-clogging token request",
- data, len);
- if (len < sizeof(le16)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Too short SAE anti-clogging token request");
- return -1;
- }
- group = WPA_GET_LE16(data);
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: SAE anti-clogging token requested (group %u)",
- group);
- if (sae_group_allowed(&wpa_s->sme.sae, groups, group) !=
- WLAN_STATUS_SUCCESS) {
- wpa_dbg(wpa_s, MSG_ERROR,
- "SME: SAE group %u of anti-clogging request is invalid",
- group);
- return -1;
- }
- wpabuf_free(wpa_s->sme.sae_token);
- token_pos = data + sizeof(le16);
- token_len = len - sizeof(le16);
- h2e = wpa_s->sme.sae.h2e;
- if (h2e) {
- if (token_len < 3) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Too short SAE anti-clogging token container");
- return -1;
- }
- if (token_pos[0] != WLAN_EID_EXTENSION ||
- token_pos[1] == 0 ||
- token_pos[1] > token_len - 2 ||
- token_pos[2] != WLAN_EID_EXT_ANTI_CLOGGING_TOKEN) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Invalid SAE anti-clogging token container header");
- return -1;
- }
- token_len = token_pos[1] - 1;
- token_pos += 3;
- }
- wpa_s->sme.sae_token = wpabuf_alloc_copy(token_pos, token_len);
- wpa_hexdump_buf(MSG_DEBUG, "SME: Requested anti-clogging token",
- wpa_s->sme.sae_token);
- if (!external)
- sme_send_authentication(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, 2);
- else
- sme_external_auth_send_sae_commit(
- wpa_s, wpa_s->sme.ext_auth_bssid,
- wpa_s->current_ssid);
- return 0;
- }
-
- if (auth_transaction == 1 &&
- status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
- wpa_s->sme.sae.state == SAE_COMMITTED &&
- (external || wpa_s->current_bss) && wpa_s->current_ssid) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
- int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
- wpa_s->sme.sae.group);
- wpa_s->sme.sae_group_index++;
- if (sme_set_sae_group(wpa_s) < 0)
- return -1; /* no other groups enabled */
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
- if (!external)
- sme_send_authentication(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, 1);
- else
- sme_external_auth_send_sae_commit(
- wpa_s, wpa_s->sme.ext_auth_bssid,
- wpa_s->current_ssid);
- return 0;
- }
-
- if (auth_transaction == 1 &&
- status_code == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
- const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
-
- wpa_msg(wpa_s, MSG_INFO,
- WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER MACSTR,
- MAC2STR(bssid));
- return -1;
- }
-
- if (status_code != WLAN_STATUS_SUCCESS &&
- status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
- status_code != WLAN_STATUS_SAE_PK) {
- const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
- " auth_type=%u auth_transaction=%u status_code=%u",
- MAC2STR(bssid), WLAN_AUTH_SAE,
- auth_transaction, status_code);
- return -1;
- }
-
- if (auth_transaction == 1) {
- u16 res;
-
- groups = wpa_s->conf->sae_groups;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
- if ((!external && wpa_s->current_bss == NULL) ||
- wpa_s->current_ssid == NULL)
- return -1;
- if (wpa_s->sme.sae.state != SAE_COMMITTED) {
- wpa_printf(MSG_DEBUG,
- "SAE: Ignore commit message while waiting for confirm");
- return 0;
- }
- if (wpa_s->sme.sae.h2e && status_code == WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_DEBUG,
- "SAE: Unexpected use of status code 0 in SAE commit when H2E was expected");
- return -1;
- }
- if ((!wpa_s->sme.sae.h2e || wpa_s->sme.sae.pk) &&
- status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
- wpa_printf(MSG_DEBUG,
- "SAE: Unexpected use of status code for H2E in SAE commit when H2E was not expected");
- return -1;
- }
- if (!wpa_s->sme.sae.pk &&
- status_code == WLAN_STATUS_SAE_PK) {
- wpa_printf(MSG_DEBUG,
- "SAE: Unexpected use of status code for PK in SAE commit when PK was not expected");
- return -1;
- }
-
- if (groups && groups[0] <= 0)
- groups = NULL;
- res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
- groups, status_code ==
- WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
- status_code == WLAN_STATUS_SAE_PK);
- if (res == SAE_SILENTLY_DISCARD) {
- wpa_printf(MSG_DEBUG,
- "SAE: Drop commit message due to reflection attack");
- return 0;
- }
- if (res != WLAN_STATUS_SUCCESS)
- return -1;
-
- if (wpa_s->sme.sae.tmp &&
- sme_check_sae_rejected_groups(
- wpa_s,
- wpa_s->sme.sae.tmp->peer_rejected_groups))
- return -1;
-
- if (sae_process_commit(&wpa_s->sme.sae) < 0) {
- wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
- "commit");
- return -1;
- }
-
- wpabuf_free(wpa_s->sme.sae_token);
- wpa_s->sme.sae_token = NULL;
- if (!external)
- sme_send_authentication(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, 0);
- else
- sme_external_auth_send_sae_confirm(wpa_s, sa);
- return 0;
- } else if (auth_transaction == 2) {
- if (status_code != WLAN_STATUS_SUCCESS)
- return -1;
- wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
- if (wpa_s->sme.sae.state != SAE_CONFIRMED)
- return -1;
- if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0)
- return -1;
- wpa_s->sme.sae.state = SAE_ACCEPTED;
- sae_clear_temp_data(&wpa_s->sme.sae);
-
- if (external) {
- /* Report success to driver */
- sme_send_external_auth_status(wpa_s,
- WLAN_STATUS_SUCCESS);
- }
-
- return 1;
- }
-
- return -1;
-}
-
-
-static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- wpa_printf(MSG_DEBUG,
- "SME: SAE completed - setting PMK for 4-way handshake");
- wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
- wpa_s->sme.sae.pmkid, bssid);
- if (wpa_s->conf->sae_pmkid_in_assoc) {
- /* Update the own RSNE contents now that we have set the PMK
- * and added a PMKSA cache entry based on the successfully
- * completed SAE exchange. In practice, this will add the PMKID
- * into RSNE. */
- if (wpa_s->sme.assoc_req_ie_len + 2 + PMKID_LEN >
- sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_msg(wpa_s, MSG_WARNING,
- "RSN: Not enough room for inserting own PMKID into RSNE");
- return -1;
- }
- if (wpa_insert_pmkid(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- wpa_s->sme.sae.pmkid) < 0)
- return -1;
- wpa_hexdump(MSG_DEBUG,
- "SME: Updated Association Request IEs",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- }
-
- return 0;
-}
-
-
-void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
- const u8 *auth_frame, size_t len)
-{
- const struct ieee80211_mgmt *header;
- size_t auth_length;
-
- header = (const struct ieee80211_mgmt *) auth_frame;
- auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
-
- if (len < auth_length) {
- /* Notify failure to the driver */
- sme_send_external_auth_status(wpa_s,
- WLAN_STATUS_UNSPECIFIED_FAILURE);
- return;
- }
-
- if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
- int res;
-
- res = sme_sae_auth(
- wpa_s, le_to_host16(header->u.auth.auth_transaction),
- le_to_host16(header->u.auth.status_code),
- header->u.auth.variable,
- len - auth_length, 1, header->sa);
- if (res < 0) {
- /* Notify failure to the driver */
- sme_send_external_auth_status(
- wpa_s, WLAN_STATUS_UNSPECIFIED_FAILURE);
- return;
- }
- if (res != 1)
- return;
-
- if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
- return;
- }
-}
-
-#endif /* CONFIG_SAE */
-
-
-void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (ssid == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
- "when network is not selected");
- return;
- }
-
- if (wpa_s->wpa_state != WPA_AUTHENTICATING) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
- "when not in authenticating state");
- return;
- }
-
- if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with "
- "unexpected peer " MACSTR,
- MAC2STR(data->auth.peer));
- return;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR
- " auth_type=%d auth_transaction=%d status_code=%d",
- MAC2STR(data->auth.peer), data->auth.auth_type,
- data->auth.auth_transaction, data->auth.status_code);
- wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
- data->auth.ies, data->auth.ies_len);
-
- eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
-
-#ifdef CONFIG_SAE
- if (data->auth.auth_type == WLAN_AUTH_SAE) {
- int res;
- res = sme_sae_auth(wpa_s, data->auth.auth_transaction,
- data->auth.status_code, data->auth.ies,
- data->auth.ies_len, 0, data->auth.peer);
- if (res < 0) {
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
-
- }
- if (res != 1)
- return;
-
- if (sme_sae_set_pmk(wpa_s, wpa_s->pending_bssid) < 0)
- return;
- }
-#endif /* CONFIG_SAE */
-
- if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
- char *ie_txt = NULL;
-
- if (data->auth.ies && data->auth.ies_len) {
- size_t buflen = 2 * data->auth.ies_len + 1;
- ie_txt = os_malloc(buflen);
- if (ie_txt) {
- wpa_snprintf_hex(ie_txt, buflen, data->auth.ies,
- data->auth.ies_len);
- }
- }
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
- " auth_type=%u auth_transaction=%u status_code=%u%s%s",
- MAC2STR(data->auth.peer), data->auth.auth_type,
- data->auth.auth_transaction, data->auth.status_code,
- ie_txt ? " ie=" : "",
- ie_txt ? ie_txt : "");
- os_free(ie_txt);
-
-#ifdef CONFIG_FILS
- if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
- wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS)
- fils_connection_failure(wpa_s);
-#endif /* CONFIG_FILS */
-
- if (data->auth.status_code !=
- WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
- wpa_s->sme.auth_alg == data->auth.auth_type ||
- wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- return;
- }
-
- wpas_connect_work_done(wpa_s);
-
- switch (data->auth.auth_type) {
- case WLAN_AUTH_OPEN:
- wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth");
- wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid);
- return;
-
- case WLAN_AUTH_SHARED_KEY:
- wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth");
- wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid);
- return;
-
- default:
- return;
- }
- }
-
-#ifdef CONFIG_IEEE80211R
- if (data->auth.auth_type == WLAN_AUTH_FT) {
- const u8 *ric_ies = NULL;
- size_t ric_ies_len = 0;
-
- if (wpa_s->ric_ies) {
- ric_ies = wpabuf_head(wpa_s->ric_ies);
- ric_ies_len = wpabuf_len(wpa_s->ric_ies);
- }
- if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies,
- data->auth.ies_len, 0,
- data->auth.peer,
- ric_ies, ric_ies_len) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: FT Authentication response processing failed");
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
- MACSTR
- " reason=%d locally_generated=1",
- MAC2STR(wpa_s->pending_bssid),
- WLAN_REASON_DEAUTH_LEAVING);
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- return;
- }
- }
-#endif /* CONFIG_IEEE80211R */
-
-#ifdef CONFIG_FILS
- if (data->auth.auth_type == WLAN_AUTH_FILS_SK ||
- data->auth.auth_type == WLAN_AUTH_FILS_SK_PFS) {
- u16 expect_auth_type;
-
- expect_auth_type = wpa_s->sme.auth_alg ==
- WPA_AUTH_ALG_FILS_SK_PFS ? WLAN_AUTH_FILS_SK_PFS :
- WLAN_AUTH_FILS_SK;
- if (data->auth.auth_type != expect_auth_type) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: FILS Authentication response used different auth alg (%u; expected %u)",
- data->auth.auth_type, expect_auth_type);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
- MACSTR
- " reason=%d locally_generated=1",
- MAC2STR(wpa_s->pending_bssid),
- WLAN_REASON_DEAUTH_LEAVING);
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- return;
- }
-
- if (fils_process_auth(wpa_s->wpa, wpa_s->pending_bssid,
- data->auth.ies, data->auth.ies_len) < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: FILS Authentication response processing failed");
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
- MACSTR
- " reason=%d locally_generated=1",
- MAC2STR(wpa_s->pending_bssid),
- WLAN_REASON_DEAUTH_LEAVING);
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
- return;
- }
- }
-#endif /* CONFIG_FILS */
-
- sme_associate(wpa_s, ssid->mode, data->auth.peer,
- data->auth.auth_type);
-}
-
-
-#ifdef CONFIG_IEEE80211R
-static void remove_ie(u8 *buf, size_t *len, u8 eid)
-{
- u8 *pos, *next, *end;
-
- pos = (u8 *) get_ie(buf, *len, eid);
- if (pos) {
- next = pos + 2 + pos[1];
- end = buf + *len;
- *len -= 2 + pos[1];
- os_memmove(pos, next, end - next);
- }
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
- const u8 *bssid, u16 auth_type)
-{
- struct wpa_driver_associate_params params;
- struct ieee802_11_elems elems;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-#ifdef CONFIG_FILS
- u8 nonces[2 * FILS_NONCE_LEN];
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_HT_OVERRIDES
- struct ieee80211_ht_capabilities htcaps;
- struct ieee80211_ht_capabilities htcaps_mask;
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- struct ieee80211_vht_capabilities vhtcaps;
- struct ieee80211_vht_capabilities vhtcaps_mask;
-#endif /* CONFIG_VHT_OVERRIDES */
-
- os_memset(&params, 0, sizeof(params));
-
-#ifdef CONFIG_FILS
- if (auth_type == WLAN_AUTH_FILS_SK ||
- auth_type == WLAN_AUTH_FILS_SK_PFS) {
- struct wpabuf *buf;
- const u8 *snonce, *anonce;
- const unsigned int max_hlp = 20;
- struct wpabuf *hlp[max_hlp];
- unsigned int i, num_hlp = 0;
- struct fils_hlp_req *req;
-
- dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
- list) {
- hlp[num_hlp] = wpabuf_alloc(2 * ETH_ALEN + 6 +
- wpabuf_len(req->pkt));
- if (!hlp[num_hlp])
- break;
- wpabuf_put_data(hlp[num_hlp], req->dst, ETH_ALEN);
- wpabuf_put_data(hlp[num_hlp], wpa_s->own_addr,
- ETH_ALEN);
- wpabuf_put_data(hlp[num_hlp],
- "\xaa\xaa\x03\x00\x00\x00", 6);
- wpabuf_put_buf(hlp[num_hlp], req->pkt);
- num_hlp++;
- if (num_hlp >= max_hlp)
- break;
- }
-
- buf = fils_build_assoc_req(wpa_s->wpa, &params.fils_kek,
- &params.fils_kek_len, &snonce,
- &anonce,
- (const struct wpabuf **) hlp,
- num_hlp);
- for (i = 0; i < num_hlp; i++)
- wpabuf_free(hlp[i]);
- if (!buf)
- return;
- wpa_hexdump(MSG_DEBUG, "FILS: assoc_req before FILS elements",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
-#ifdef CONFIG_IEEE80211R
- if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
- /* Remove RSNE and MDE to allow them to be overridden
- * with FILS+FT specific values from
- * fils_build_assoc_req(). */
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_RSN);
- wpa_hexdump(MSG_DEBUG,
- "FILS: assoc_req after RSNE removal",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_MOBILITY_DOMAIN);
- wpa_hexdump(MSG_DEBUG,
- "FILS: assoc_req after MDE removal",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- }
-#endif /* CONFIG_IEEE80211R */
- /* TODO: Make wpa_s->sme.assoc_req_ie use dynamic allocation */
- if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(buf) >
- sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_printf(MSG_ERROR,
- "FILS: Not enough buffer room for own AssocReq elements");
- wpabuf_free(buf);
- return;
- }
- os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(buf), wpabuf_len(buf));
- wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
- wpabuf_free(buf);
- wpa_hexdump(MSG_DEBUG, "FILS: assoc_req after FILS elements",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
-
- os_memcpy(nonces, snonce, FILS_NONCE_LEN);
- os_memcpy(nonces + FILS_NONCE_LEN, anonce, FILS_NONCE_LEN);
- params.fils_nonces = nonces;
- params.fils_nonces_len = sizeof(nonces);
- }
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_OWE
-#ifdef CONFIG_TESTING_OPTIONS
- if (get_ie_ext(wpa_s->sme.assoc_req_ie, wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_EXT_OWE_DH_PARAM)) {
- wpa_printf(MSG_INFO, "TESTING: Override OWE DH element");
- } else
-#endif /* CONFIG_TESTING_OPTIONS */
- if (auth_type == WLAN_AUTH_OPEN &&
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
- struct wpabuf *owe_ie;
- u16 group;
-
- if (ssid && ssid->owe_group) {
- group = ssid->owe_group;
- } else if (wpa_s->assoc_status_code ==
- WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
- if (wpa_s->last_owe_group == 19)
- group = 20;
- else if (wpa_s->last_owe_group == 20)
- group = 21;
- else
- group = OWE_DH_GROUP;
- } else {
- group = OWE_DH_GROUP;
- }
-
- wpa_s->last_owe_group = group;
- wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group);
- owe_ie = owe_build_assoc_req(wpa_s->wpa, group);
- if (!owe_ie) {
- wpa_printf(MSG_ERROR,
- "OWE: Failed to build IE for Association Request frame");
- return;
- }
- if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(owe_ie) >
- sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_printf(MSG_ERROR,
- "OWE: Not enough buffer room for own Association Request frame elements");
- wpabuf_free(owe_ie);
- return;
- }
- os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(owe_ie), wpabuf_len(owe_ie));
- wpa_s->sme.assoc_req_ie_len += wpabuf_len(owe_ie);
- wpabuf_free(owe_ie);
- }
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_DPP2
- if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid &&
- ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 &&
- !ssid->dpp_pfs_fallback) {
- struct rsn_pmksa_cache_entry *pmksa;
-
- pmksa = pmksa_cache_get_current(wpa_s->wpa);
- if (!pmksa || !pmksa->dpp_pfs)
- goto pfs_fail;
-
- dpp_pfs_free(wpa_s->dpp_pfs);
- wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
- ssid->dpp_netaccesskey_len);
- if (!wpa_s->dpp_pfs) {
- wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
- /* Try to continue without PFS */
- goto pfs_fail;
- }
- if (wpa_s->sme.assoc_req_ie_len +
- wpabuf_len(wpa_s->dpp_pfs->ie) >
- sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_printf(MSG_ERROR,
- "DPP: Not enough buffer room for own Association Request frame elements");
- dpp_pfs_free(wpa_s->dpp_pfs);
- wpa_s->dpp_pfs = NULL;
- goto pfs_fail;
- }
- os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- wpabuf_head(wpa_s->dpp_pfs->ie),
- wpabuf_len(wpa_s->dpp_pfs->ie));
- wpa_s->sme.assoc_req_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
- }
-pfs_fail:
-#endif /* CONFIG_DPP2 */
-
- wpa_s->mscs_setup_done = false;
- if (wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS) &&
- wpa_s->robust_av.valid_config) {
- struct wpabuf *mscs_ie;
- size_t mscs_ie_len, buf_len, *wpa_ie_len, max_ie_len;
-
- buf_len = 3 + /* MSCS descriptor IE header */
- 1 + /* Request type */
- 2 + /* User priority control */
- 4 + /* Stream timeout */
- 3 + /* TCLAS Mask IE header */
- wpa_s->robust_av.frame_classifier_len;
- mscs_ie = wpabuf_alloc(buf_len);
- if (!mscs_ie) {
- wpa_printf(MSG_INFO,
- "MSCS: Failed to allocate MSCS IE");
- goto mscs_fail;
- }
-
- wpa_ie_len = &wpa_s->sme.assoc_req_ie_len;
- max_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
- wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, mscs_ie);
- if ((*wpa_ie_len + wpabuf_len(mscs_ie)) <= max_ie_len) {
- wpa_hexdump_buf(MSG_MSGDUMP, "MSCS IE", mscs_ie);
- mscs_ie_len = wpabuf_len(mscs_ie);
- os_memcpy(wpa_s->sme.assoc_req_ie + *wpa_ie_len,
- wpabuf_head(mscs_ie), mscs_ie_len);
- *wpa_ie_len += mscs_ie_len;
- }
-
- wpabuf_free(mscs_ie);
- }
-mscs_fail:
-
- if (ssid && ssid->multi_ap_backhaul_sta) {
- size_t multi_ap_ie_len;
-
- multi_ap_ie_len = add_multi_ap_ie(
- wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
- sizeof(wpa_s->sme.assoc_req_ie) -
- wpa_s->sme.assoc_req_ie_len,
- MULTI_AP_BACKHAUL_STA);
- if (multi_ap_ie_len == 0) {
- wpa_printf(MSG_ERROR,
- "Multi-AP: Failed to build Multi-AP IE");
- return;
- }
- wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
- }
-
- params.bssid = bssid;
- params.ssid = wpa_s->sme.ssid;
- params.ssid_len = wpa_s->sme.ssid_len;
- params.freq.freq = wpa_s->sme.freq;
- params.bg_scan_period = ssid ? ssid->bg_scan_period : -1;
- params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
- wpa_s->sme.assoc_req_ie : NULL;
- params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
- wpa_hexdump(MSG_DEBUG, "SME: Association Request IEs",
- params.wpa_ie, params.wpa_ie_len);
- params.pairwise_suite = wpa_s->pairwise_cipher;
- params.group_suite = wpa_s->group_cipher;
- params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
- params.key_mgmt_suite = wpa_s->key_mgmt;
- params.wpa_proto = wpa_s->wpa_proto;
-#ifdef CONFIG_HT_OVERRIDES
- os_memset(&htcaps, 0, sizeof(htcaps));
- os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
- params.htcaps = (u8 *) &htcaps;
- params.htcaps_mask = (u8 *) &htcaps_mask;
- wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- os_memset(&vhtcaps, 0, sizeof(vhtcaps));
- os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
- params.vhtcaps = &vhtcaps;
- params.vhtcaps_mask = &vhtcaps_mask;
- wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_VHT_OVERRIDES */
-#ifdef CONFIG_HE_OVERRIDES
- wpa_supplicant_apply_he_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_HE_OVERRIDES */
-#ifdef CONFIG_IEEE80211R
- if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies &&
- get_ie(wpa_s->sme.ft_ies, wpa_s->sme.ft_ies_len,
- WLAN_EID_RIC_DATA)) {
- /* There seems to be a pretty inconvenient bug in the Linux
- * kernel IE splitting functionality when RIC is used. For now,
- * skip correct behavior in IE construction here (i.e., drop the
- * additional non-FT-specific IEs) to avoid kernel issues. This
- * is fine since RIC is used only for testing purposes in the
- * current implementation. */
- wpa_printf(MSG_INFO,
- "SME: Linux kernel workaround - do not try to include additional IEs with RIC");
- params.wpa_ie = wpa_s->sme.ft_ies;
- params.wpa_ie_len = wpa_s->sme.ft_ies_len;
- } else if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
- const u8 *rm_en, *pos, *end;
- size_t rm_en_len = 0;
- u8 *rm_en_dup = NULL, *wpos;
-
- /* Remove RSNE, MDE, FTE to allow them to be overridden with
- * FT specific values */
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_RSN);
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_MOBILITY_DOMAIN);
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_FAST_BSS_TRANSITION);
- rm_en = get_ie(wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_RRM_ENABLED_CAPABILITIES);
- if (rm_en) {
- /* Need to remove RM Enabled Capabilities element as
- * well temporarily, so that it can be placed between
- * RSNE and MDE. */
- rm_en_len = 2 + rm_en[1];
- rm_en_dup = os_memdup(rm_en, rm_en_len);
- remove_ie(wpa_s->sme.assoc_req_ie,
- &wpa_s->sme.assoc_req_ie_len,
- WLAN_EID_RRM_ENABLED_CAPABILITIES);
- }
- wpa_hexdump(MSG_DEBUG,
- "SME: Association Request IEs after FT IE removal",
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- if (wpa_s->sme.assoc_req_ie_len + wpa_s->sme.ft_ies_len +
- rm_en_len > sizeof(wpa_s->sme.assoc_req_ie)) {
- wpa_printf(MSG_ERROR,
- "SME: Not enough buffer room for FT IEs in Association Request frame");
- os_free(rm_en_dup);
- return;
- }
-
- os_memmove(wpa_s->sme.assoc_req_ie + wpa_s->sme.ft_ies_len +
- rm_en_len,
- wpa_s->sme.assoc_req_ie,
- wpa_s->sme.assoc_req_ie_len);
- pos = wpa_s->sme.ft_ies;
- end = pos + wpa_s->sme.ft_ies_len;
- wpos = wpa_s->sme.assoc_req_ie;
- if (*pos == WLAN_EID_RSN) {
- os_memcpy(wpos, pos, 2 + pos[1]);
- wpos += 2 + pos[1];
- pos += 2 + pos[1];
- }
- if (rm_en_dup) {
- os_memcpy(wpos, rm_en_dup, rm_en_len);
- wpos += rm_en_len;
- os_free(rm_en_dup);
- }
- os_memcpy(wpos, pos, end - pos);
- wpa_s->sme.assoc_req_ie_len += wpa_s->sme.ft_ies_len +
- rm_en_len;
- params.wpa_ie = wpa_s->sme.assoc_req_ie;
- params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
- wpa_hexdump(MSG_DEBUG,
- "SME: Association Request IEs after FT override",
- params.wpa_ie, params.wpa_ie_len);
- }
-#endif /* CONFIG_IEEE80211R */
- params.mode = mode;
- params.mgmt_frame_protection = wpa_s->sme.mfp;
- params.rrm_used = wpa_s->rrm.rrm_used;
- if (wpa_s->sme.prev_bssid_set)
- params.prev_bssid = wpa_s->sme.prev_bssid;
-
- wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
- " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
- params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
- params.freq.freq);
-
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
-
- if (params.wpa_ie == NULL ||
- ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
- < 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
- os_memset(&elems, 0, sizeof(elems));
- }
- if (elems.rsn_ie) {
- params.wpa_proto = WPA_PROTO_RSN;
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
- elems.rsn_ie_len + 2);
- } else if (elems.wpa_ie) {
- params.wpa_proto = WPA_PROTO_WPA;
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
- elems.wpa_ie_len + 2);
- } else if (elems.osen) {
- params.wpa_proto = WPA_PROTO_OSEN;
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.osen - 2,
- elems.osen_len + 2);
- } else
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- if (elems.rsnxe)
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, elems.rsnxe - 2,
- elems.rsnxe_len + 2);
- else
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
- if (ssid && ssid->p2p_group)
- params.p2p = 1;
-
- if (wpa_s->p2pdev->set_sta_uapsd)
- params.uapsd = wpa_s->p2pdev->sta_uapsd;
- else
- params.uapsd = -1;
-
- if (wpa_drv_associate(wpa_s, &params) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
- "driver failed");
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- return;
- }
-
- eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s,
- NULL);
-
-#ifdef CONFIG_TESTING_OPTIONS
- wpabuf_free(wpa_s->last_assoc_req_wpa_ie);
- wpa_s->last_assoc_req_wpa_ie = NULL;
- if (params.wpa_ie)
- wpa_s->last_assoc_req_wpa_ie =
- wpabuf_alloc_copy(params.wpa_ie, params.wpa_ie_len);
-#endif /* CONFIG_TESTING_OPTIONS */
-}
-
-
-int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- if (md == NULL || ies == NULL) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain");
- os_free(wpa_s->sme.ft_ies);
- wpa_s->sme.ft_ies = NULL;
- wpa_s->sme.ft_ies_len = 0;
- wpa_s->sme.ft_used = 0;
- return 0;
- }
-
- os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN);
- wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len);
- os_free(wpa_s->sme.ft_ies);
- wpa_s->sme.ft_ies = os_memdup(ies, ies_len);
- if (wpa_s->sme.ft_ies == NULL)
- return -1;
- wpa_s->sme.ft_ies_len = ies_len;
- return 0;
-}
-
-
-static void sme_deauth(struct wpa_supplicant *wpa_s)
-{
- int bssid_changed;
-
- bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
-
- if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
- WLAN_REASON_DEAUTH_LEAVING) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver "
- "failed");
- }
- wpa_s->sme.prev_bssid_set = 0;
-
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- os_memset(wpa_s->bssid, 0, ETH_ALEN);
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-}
-
-
-void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: "
- "status code %d", MAC2STR(wpa_s->pending_bssid),
- data->assoc_reject.status_code);
-
- eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
-
-#ifdef CONFIG_SAE
- if (wpa_s->sme.sae_pmksa_caching && wpa_s->current_ssid &&
- wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication");
- wpa_sm_aborted_cached(wpa_s->wpa);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
- if (wpa_s->current_bss) {
- struct wpa_bss *bss = wpa_s->current_bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
- WLAN_REASON_DEAUTH_LEAVING);
- wpas_connect_work_done(wpa_s);
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_supplicant_connect(wpa_s, bss, ssid);
- return;
- }
- }
-#endif /* CONFIG_SAE */
-
- /*
- * For now, unconditionally terminate the previous authentication. In
- * theory, this should not be needed, but mac80211 gets quite confused
- * if the authentication is left pending.. Some roaming cases might
- * benefit from using the previous authentication, so this could be
- * optimized in the future.
- */
- sme_deauth(wpa_s);
-}
-
-
-void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
-}
-
-
-void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
-}
-
-
-void sme_event_disassoc(struct wpa_supplicant *wpa_s,
- struct disassoc_info *info)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received");
- if (wpa_s->sme.prev_bssid_set) {
- /*
- * cfg80211/mac80211 can get into somewhat confused state if
- * the AP only disassociates us and leaves us in authenticated
- * state. For now, force the state to be cleared to avoid
- * confusing errors if we try to associate with the AP again.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear "
- "driver state");
- wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid,
- WLAN_REASON_DEAUTH_LEAVING);
- }
-}
-
-
-static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
- wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
- sme_deauth(wpa_s);
- }
-}
-
-
-static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- if (wpa_s->wpa_state == WPA_ASSOCIATING) {
- wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
- sme_deauth(wpa_s);
- }
-}
-
-
-void sme_state_changed(struct wpa_supplicant *wpa_s)
-{
- /* Make sure timers are cleaned up appropriately. */
- if (wpa_s->wpa_state != WPA_ASSOCIATING)
- eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
- if (wpa_s->wpa_state != WPA_AUTHENTICATING)
- eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
-}
-
-
-void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
- const u8 *prev_pending_bssid)
-{
- /*
- * mac80211-workaround to force deauth on failed auth cmd,
- * requires us to remain in authenticating state to allow the
- * second authentication attempt to be continued properly.
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication "
- "to proceed after disconnection event");
- wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
- os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
-
- /*
- * Re-arm authentication timer in case auth fails for whatever reason.
- */
- eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
- eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
- NULL);
-}
-
-
-void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
-{
- wpa_s->sme.prev_bssid_set = 0;
-#ifdef CONFIG_SAE
- wpabuf_free(wpa_s->sme.sae_token);
- wpa_s->sme.sae_token = NULL;
- sae_clear_data(&wpa_s->sme.sae);
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_IEEE80211R
- if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
- sme_update_ft_ies(wpa_s, NULL, NULL, 0);
-#endif /* CONFIG_IEEE80211R */
- sme_stop_sa_query(wpa_s);
-}
-
-
-void sme_deinit(struct wpa_supplicant *wpa_s)
-{
- sme_clear_on_disassoc(wpa_s);
-#ifdef CONFIG_SAE
- os_free(wpa_s->sme.sae_rejected_groups);
- wpa_s->sme.sae_rejected_groups = NULL;
-#endif /* CONFIG_SAE */
-
- eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
- eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
- eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
-}
-
-
-static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s,
- const u8 *chan_list, u8 num_channels,
- u8 num_intol)
-{
- struct ieee80211_2040_bss_coex_ie *bc_ie;
- struct ieee80211_2040_intol_chan_report *ic_report;
- struct wpabuf *buf;
-
- wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR
- " (num_channels=%u num_intol=%u)",
- MAC2STR(wpa_s->bssid), num_channels, num_intol);
- wpa_hexdump(MSG_DEBUG, "SME: 20/40 BSS Intolerant Channels",
- chan_list, num_channels);
-
- buf = wpabuf_alloc(2 + /* action.category + action_code */
- sizeof(struct ieee80211_2040_bss_coex_ie) +
- sizeof(struct ieee80211_2040_intol_chan_report) +
- num_channels);
- if (buf == NULL)
- return;
-
- wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
- wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX);
-
- bc_ie = wpabuf_put(buf, sizeof(*bc_ie));
- bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE;
- bc_ie->length = 1;
- if (num_intol)
- bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ;
-
- if (num_channels > 0) {
- ic_report = wpabuf_put(buf, sizeof(*ic_report));
- ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT;
- ic_report->length = num_channels + 1;
- ic_report->op_class = 0;
- os_memcpy(wpabuf_put(buf, num_channels), chan_list,
- num_channels);
- }
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "SME: Failed to send 20/40 BSS Coexistence frame");
- }
-
- wpabuf_free(buf);
-}
-
-
-int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
- const u8 *ie;
- u16 ht_cap;
- u8 chan_list[P2P_MAX_CHANNELS], channel;
- u8 num_channels = 0, num_intol = 0, i;
-
- if (!wpa_s->sme.sched_obss_scan)
- return 0;
-
- wpa_s->sme.sched_obss_scan = 0;
- if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED)
- return 1;
-
- /*
- * Check whether AP uses regulatory triplet or channel triplet in
- * country info. Right now the operating class of the BSS channel
- * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12),
- * based on the assumption that operating class triplet is not used in
- * beacon frame. If the First Channel Number/Operating Extension
- * Identifier octet has a positive integer value of 201 or greater,
- * then its operating class triplet.
- *
- * TODO: If Supported Operating Classes element is present in beacon
- * frame, have to lookup operating class in Annex E and fill them in
- * 2040 coex frame.
- */
- ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
- if (ie && (ie[1] >= 6) && (ie[5] >= 201))
- return 1;
-
- os_memset(chan_list, 0, sizeof(chan_list));
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- /* Skip other band bss */
- enum hostapd_hw_mode mode;
- mode = ieee80211_freq_to_chan(bss->freq, &channel);
- if (mode != HOSTAPD_MODE_IEEE80211G &&
- mode != HOSTAPD_MODE_IEEE80211B)
- continue;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP);
- ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0;
- wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR
- " freq=%u chan=%u ht_cap=0x%x",
- MAC2STR(bss->bssid), bss->freq, channel, ht_cap);
-
- if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) {
- if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)
- num_intol++;
-
- /* Check whether the channel is already considered */
- for (i = 0; i < num_channels; i++) {
- if (channel == chan_list[i])
- break;
- }
- if (i != num_channels)
- continue;
-
- chan_list[num_channels++] = channel;
- }
- }
-
- sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol);
- return 1;
-}
-
-
-static void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
-{
- /* Include only affected channels */
- struct hostapd_hw_modes *mode;
- int count, i;
- int start, end;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
- HOSTAPD_MODE_IEEE80211G, false);
- if (mode == NULL) {
- /* No channels supported in this band - use empty list */
- params->freqs = os_zalloc(sizeof(int));
- return;
- }
-
- if (wpa_s->sme.ht_sec_chan == HT_SEC_CHAN_UNKNOWN &&
- wpa_s->current_bss) {
- const u8 *ie;
-
- ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= 2) {
- u8 o;
-
- o = ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
- if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE;
- else if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW;
- }
- }
-
- start = wpa_s->assoc_freq - 10;
- end = wpa_s->assoc_freq + 10;
- switch (wpa_s->sme.ht_sec_chan) {
- case HT_SEC_CHAN_UNKNOWN:
- /* HT40+ possible on channels 1..9 */
- if (wpa_s->assoc_freq <= 2452)
- start -= 20;
- /* HT40- possible on channels 5-13 */
- if (wpa_s->assoc_freq >= 2432)
- end += 20;
- break;
- case HT_SEC_CHAN_ABOVE:
- end += 20;
- break;
- case HT_SEC_CHAN_BELOW:
- start -= 20;
- break;
- }
- wpa_printf(MSG_DEBUG,
- "OBSS: assoc_freq %d possible affected range %d-%d",
- wpa_s->assoc_freq, start, end);
-
- params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
- if (params->freqs == NULL)
- return;
- for (count = 0, i = 0; i < mode->num_channels; i++) {
- int freq;
-
- if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
- continue;
- freq = mode->channels[i].freq;
- if (freq - 10 >= end || freq + 10 <= start)
- continue; /* not affected */
- params->freqs[count++] = freq;
- }
-}
-
-
-static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_driver_scan_params params;
-
- if (!wpa_s->current_bss) {
- wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request");
- return;
- }
-
- os_memset(&params, 0, sizeof(params));
- wpa_obss_scan_freqs_list(wpa_s, &params);
- params.low_priority = 1;
- wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
-
- if (wpa_supplicant_trigger_scan(wpa_s, &params))
- wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
- else
- wpa_s->sme.sched_obss_scan = 1;
- os_free(params.freqs);
-
- eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
- sme_obss_scan_timeout, wpa_s, NULL);
-}
-
-
-void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
-{
- const u8 *ie;
- struct wpa_bss *bss = wpa_s->current_bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct hostapd_hw_modes *hw_mode = NULL;
- int i;
-
- eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
- wpa_s->sme.sched_obss_scan = 0;
- wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN;
- if (!enable)
- return;
-
- /*
- * Schedule OBSS scan if driver is using station SME in wpa_supplicant
- * or it expects OBSS scan to be performed by wpa_supplicant.
- */
- if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
- ssid == NULL || ssid->mode != WPAS_MODE_INFRA)
- return;
-
-#ifdef CONFIG_HT_OVERRIDES
- /* No need for OBSS scan if HT40 is explicitly disabled */
- if (ssid->disable_ht40)
- return;
-#endif /* CONFIG_HT_OVERRIDES */
-
- if (!wpa_s->hw.modes)
- return;
-
- /* only HT caps in 11g mode are relevant */
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- hw_mode = &wpa_s->hw.modes[i];
- if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G)
- break;
- }
-
- /* Driver does not support HT40 for 11g or doesn't have 11g. */
- if (i == wpa_s->hw.num_modes || !hw_mode ||
- !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
- return;
-
- if (bss == NULL || bss->freq < 2400 || bss->freq > 2500)
- return; /* Not associated on 2.4 GHz band */
-
- /* Check whether AP supports HT40 */
- ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP);
- if (!ie || ie[1] < 2 ||
- !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
- return; /* AP does not support HT40 */
-
- ie = wpa_bss_get_ie(wpa_s->current_bss,
- WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS);
- if (!ie || ie[1] < 14)
- return; /* AP does not request OBSS scans */
-
- wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6);
- if (wpa_s->sme.obss_scan_int < 10) {
- wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u "
- "replaced with the minimum 10 sec",
- wpa_s->sme.obss_scan_int);
- wpa_s->sme.obss_scan_int = 10;
- }
- wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec",
- wpa_s->sme.obss_scan_int);
- eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
- sme_obss_scan_timeout, wpa_s, NULL);
-}
-
-
-static const unsigned int sa_query_max_timeout = 1000;
-static const unsigned int sa_query_retry_timeout = 201;
-static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
-
-static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s)
-{
- u32 tu;
- struct os_reltime now, passed;
- os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->sme.sa_query_start, &passed);
- tu = (passed.sec * 1000000 + passed.usec) / 1024;
- if (sa_query_max_timeout < tu) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out");
- sme_stop_sa_query(wpa_s);
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID);
- return 1;
- }
-
- return 0;
-}
-
-
-static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
- const u8 *trans_id)
-{
- u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
- u8 req_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to "
- MACSTR, MAC2STR(wpa_s->bssid));
- wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID",
- trans_id, WLAN_SA_QUERY_TR_ID_LEN);
- req[0] = WLAN_ACTION_SA_QUERY;
- req[1] = WLAN_SA_QUERY_REQUEST;
- os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN);
-
-#ifdef CONFIG_OCV
- if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
- struct wpa_channel_info ci;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "Failed to get channel info for OCI element in SA Query Request frame");
- return;
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->oci_freq_override_saquery_req) {
- wpa_printf(MSG_INFO,
- "TEST: Override SA Query Request OCI frequency %d -> %d MHz",
- ci.frequency,
- wpa_s->oci_freq_override_saquery_req);
- ci.frequency = wpa_s->oci_freq_override_saquery_req;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (ocv_insert_extended_oci(&ci, req + req_len) < 0)
- return;
-
- req_len += OCV_OCI_EXTENDED_LEN;
- }
-#endif /* CONFIG_OCV */
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- req, req_len, 0) < 0)
- wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query "
- "Request");
-}
-
-
-static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- unsigned int timeout, sec, usec;
- u8 *trans_id, *nbuf;
-
- if (wpa_s->sme.sa_query_count > 0 &&
- sme_check_sa_query_timeout(wpa_s))
- return;
-
- nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id,
- wpa_s->sme.sa_query_count + 1,
- WLAN_SA_QUERY_TR_ID_LEN);
- if (nbuf == NULL) {
- sme_stop_sa_query(wpa_s);
- return;
- }
- if (wpa_s->sme.sa_query_count == 0) {
- /* Starting a new SA Query procedure */
- os_get_reltime(&wpa_s->sme.sa_query_start);
- }
- trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
- wpa_s->sme.sa_query_trans_id = nbuf;
- wpa_s->sme.sa_query_count++;
-
- if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) {
- wpa_printf(MSG_DEBUG, "Could not generate SA Query ID");
- sme_stop_sa_query(wpa_s);
- return;
- }
-
- timeout = sa_query_retry_timeout;
- sec = ((timeout / 1000) * 1024) / 1000;
- usec = (timeout % 1000) * 1024;
- eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL);
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d",
- wpa_s->sme.sa_query_count);
-
- sme_send_sa_query_req(wpa_s, trans_id);
-}
-
-
-static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
-{
- sme_sa_query_timer(wpa_s, NULL);
-}
-
-
-static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->sme.sa_query_trans_id)
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Stop SA Query");
- eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
- os_free(wpa_s->sme.sa_query_trans_id);
- wpa_s->sme.sa_query_trans_id = NULL;
- wpa_s->sme.sa_query_count = 0;
-}
-
-
-void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
- const u8 *da, u16 reason_code)
-{
- struct wpa_ssid *ssid;
- struct os_reltime now;
-
- if (wpa_s->wpa_state != WPA_COMPLETED)
- return;
- ssid = wpa_s->current_ssid;
- if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
- return;
- if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
- return;
- if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA &&
- reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)
- return;
- if (wpa_s->sme.sa_query_count > 0)
- return;
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->disable_sa_query)
- return;
-#endif /* CONFIG_TESTING_OPTIONS */
-
- os_get_reltime(&now);
- if (wpa_s->sme.last_unprot_disconnect.sec &&
- !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10))
- return; /* limit SA Query procedure frequency */
- wpa_s->sme.last_unprot_disconnect = now;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - "
- "possible AP/STA state mismatch - trigger SA Query");
- sme_start_sa_query(wpa_s);
-}
-
-
-void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
-{
- unsigned int usec;
- u32 _rand;
-
- if (wpa_s->wpa_state != WPA_COMPLETED ||
- !wpa_sm_ocv_enabled(wpa_s->wpa))
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Channel switch completed - trigger new SA Query to verify new operating channel");
- sme_stop_sa_query(wpa_s);
-
- if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
- _rand = os_random();
- usec = _rand % (sa_query_ch_switch_max_delay + 1);
- eloop_register_timeout(0, usec, sme_sa_query_timer, wpa_s, NULL);
-}
-
-
-static void sme_process_sa_query_request(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *data,
- size_t len)
-{
- u8 resp[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
- u8 resp_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Response to "
- MACSTR, MAC2STR(wpa_s->bssid));
-
- resp[0] = WLAN_ACTION_SA_QUERY;
- resp[1] = WLAN_SA_QUERY_RESPONSE;
- os_memcpy(resp + 2, data + 1, WLAN_SA_QUERY_TR_ID_LEN);
-
-#ifdef CONFIG_OCV
- if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
- struct wpa_channel_info ci;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "Failed to get channel info for OCI element in SA Query Response frame");
- return;
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->oci_freq_override_saquery_resp) {
- wpa_printf(MSG_INFO,
- "TEST: Override SA Query Response OCI frequency %d -> %d MHz",
- ci.frequency,
- wpa_s->oci_freq_override_saquery_resp);
- ci.frequency = wpa_s->oci_freq_override_saquery_resp;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (ocv_insert_extended_oci(&ci, resp + resp_len) < 0)
- return;
-
- resp_len += OCV_OCI_EXTENDED_LEN;
- }
-#endif /* CONFIG_OCV */
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- resp, resp_len, 0) < 0)
- wpa_msg(wpa_s, MSG_INFO,
- "SME: Failed to send SA Query Response");
-}
-
-
-static void sme_process_sa_query_response(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *data,
- size_t len)
-{
- int i;
-
- if (!wpa_s->sme.sa_query_trans_id)
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from "
- MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
-
- if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
- return;
-
- for (i = 0; i < wpa_s->sme.sa_query_count; i++) {
- if (os_memcmp(wpa_s->sme.sa_query_trans_id +
- i * WLAN_SA_QUERY_TR_ID_LEN,
- data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0)
- break;
- }
-
- if (i >= wpa_s->sme.sa_query_count) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query "
- "transaction identifier found");
- return;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received "
- "from " MACSTR, MAC2STR(sa));
- sme_stop_sa_query(wpa_s);
-}
-
-
-void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *da, const u8 *sa,
- const u8 *data, size_t len)
-{
- if (len < 1 + WLAN_SA_QUERY_TR_ID_LEN)
- return;
- if (is_multicast_ether_addr(da)) {
- wpa_printf(MSG_DEBUG,
- "IEEE 802.11: Ignore group-addressed SA Query frame (A1=" MACSTR " A2=" MACSTR ")",
- MAC2STR(da), MAC2STR(sa));
- return;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query frame from "
- MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
-
-#ifdef CONFIG_OCV
- if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
- struct ieee802_11_elems elems;
- struct wpa_channel_info ci;
-
- if (ieee802_11_parse_elems(data + 1 + WLAN_SA_QUERY_TR_ID_LEN,
- len - 1 - WLAN_SA_QUERY_TR_ID_LEN,
- &elems, 1) == ParseFailed) {
- wpa_printf(MSG_DEBUG,
- "SA Query: Failed to parse elements");
- return;
- }
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "Failed to get channel info to validate received OCI in SA Query Action frame");
- return;
- }
-
- if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
- channel_width_to_int(ci.chanwidth),
- ci.seg1_idx) != OCI_SUCCESS) {
- wpa_msg(wpa_s, MSG_INFO, OCV_FAILURE "addr=" MACSTR
- " frame=saquery%s error=%s",
- MAC2STR(sa), data[0] == WLAN_SA_QUERY_REQUEST ?
- "req" : "resp", ocv_errorstr);
- return;
- }
- }
-#endif /* CONFIG_OCV */
-
- if (data[0] == WLAN_SA_QUERY_REQUEST)
- sme_process_sa_query_request(wpa_s, sa, data, len);
- else if (data[0] == WLAN_SA_QUERY_RESPONSE)
- sme_process_sa_query_response(wpa_s, sa, data, len);
-}
diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h
deleted file mode 100644
index c797d2e9e796..000000000000
--- a/wpa_supplicant/sme.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * wpa_supplicant - SME
- * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SME_H
-#define SME_H
-
-#ifdef CONFIG_SME
-
-void sme_authenticate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid);
-void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
- const u8 *bssid, u16 auth_type);
-void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data);
-int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len);
-void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data);
-void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data);
-void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data);
-void sme_event_disassoc(struct wpa_supplicant *wpa_s,
- struct disassoc_info *info);
-void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
- const u8 *da, u16 reason_code);
-void sme_event_ch_switch(struct wpa_supplicant *wpa_s);
-void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *da, const u8 *sa,
- const u8 *data, size_t len);
-void sme_state_changed(struct wpa_supplicant *wpa_s);
-void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
- const u8 *prev_pending_bssid);
-void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s);
-void sme_deinit(struct wpa_supplicant *wpa_s);
-
-int sme_proc_obss_scan(struct wpa_supplicant *wpa_s);
-void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable);
-void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data);
-void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
- const u8 *auth_frame, size_t len);
-
-#else /* CONFIG_SME */
-
-static inline void sme_authenticate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_ssid *ssid)
-{
-}
-
-static inline void sme_event_auth(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-}
-
-static inline int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- return -1;
-}
-
-
-static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-}
-
-static inline void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-}
-
-static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-}
-
-static inline void sme_event_disassoc(struct wpa_supplicant *wpa_s,
- struct disassoc_info *info)
-{
-}
-
-static inline void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *da,
- u16 reason_code)
-{
-}
-
-static inline void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void sme_state_changed(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void
-sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
- const u8 *prev_pending_bssid)
-{
-}
-
-static inline void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void sme_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void sme_sched_obss_scan(struct wpa_supplicant *wpa_s,
- int enable)
-{
-}
-
-static inline void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
-{
-}
-
-static inline void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
- const u8 *auth_frame, size_t len)
-{
-}
-
-#endif /* CONFIG_SME */
-
-#endif /* SME_H */
diff --git a/wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in
deleted file mode 100644
index da69a8705ce8..000000000000
--- a/wpa_supplicant/systemd/wpa_supplicant-nl80211.service.arg.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=WPA supplicant daemon (interface- and nl80211 driver-specific version)
-Requires=sys-subsystem-net-devices-%i.device
-After=sys-subsystem-net-devices-%i.device
-Before=network.target
-Wants=network.target
-
-# NetworkManager users will probably want the dbus version instead.
-
-[Service]
-Type=simple
-ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-nl80211-%I.conf -Dnl80211 -i%I
-
-[Install]
-WantedBy=multi-user.target
diff --git a/wpa_supplicant/systemd/wpa_supplicant-wired.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant-wired.service.arg.in
deleted file mode 100644
index ca3054bc6d55..000000000000
--- a/wpa_supplicant/systemd/wpa_supplicant-wired.service.arg.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=WPA supplicant daemon (interface- and wired driver-specific version)
-Requires=sys-subsystem-net-devices-%i.device
-After=sys-subsystem-net-devices-%i.device
-Before=network.target
-Wants=network.target
-
-# NetworkManager users will probably want the dbus version instead.
-
-[Service]
-Type=simple
-ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-wired-%I.conf -Dwired -i%I
-
-[Install]
-WantedBy=multi-user.target
diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in
deleted file mode 100644
index 55d2b9c81712..000000000000
--- a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=WPA supplicant daemon (interface-specific version)
-Requires=sys-subsystem-net-devices-%i.device
-After=sys-subsystem-net-devices-%i.device
-Before=network.target
-Wants=network.target
-
-# NetworkManager users will probably want the dbus version instead.
-
-[Service]
-Type=simple
-ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I
-
-[Install]
-WantedBy=multi-user.target
diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in
deleted file mode 100644
index 58a622887cd9..000000000000
--- a/wpa_supplicant/systemd/wpa_supplicant.service.in
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=WPA supplicant
-Before=network.target
-After=dbus.service
-Wants=network.target
-
-[Service]
-Type=dbus
-BusName=fi.w1.wpa_supplicant1
-ExecStart=@BINDIR@/wpa_supplicant -u
-
-[Install]
-WantedBy=multi-user.target
-Alias=dbus-fi.w1.wpa_supplicant1.service
diff --git a/wpa_supplicant/todo.txt b/wpa_supplicant/todo.txt
deleted file mode 100644
index 4c9f98e9c7ab..000000000000
--- a/wpa_supplicant/todo.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-To do:
-- add support for WPA with ap_scan=0 (update selected cipher etc. based on
- AssocInfo; make sure these match with configuration)
-- consider closing smart card / PCSC connection when EAP-SIM/EAP-AKA
- authentication has been completed (cache scard data based on serial#(?)
- and try to optimize next connection if the same card is present for next
- auth)
-- if driver/hw is not WPA2 capable, must remove WPA_PROTO_RSN flag from
- ssid->proto fields to avoid detecting downgrade attacks when the driver
- is not reporting RSN IE, but msg 3/4 has one
-- Cisco AP and non-zero keyidx for unicast -> map to broadcast
- (actually, this already works with driver_ndis; so maybe just change
- driver_*.c to do the mapping for drivers that cannot handle non-zero keyidx
- for unicast); worked also with Host AP driver and madwifi
-- IEEE 802.1X and key update with driver_ndis?? wpa_supplicant did not seem
- to see unencrypted EAPOL-Key frames at all..
-- EAP-PAX with PAX_SEC
-- EAP (RFC 3748)
- * OTP Extended Responses (Sect. 5.5)
-- test what happens if authenticator sends EAP-Success before real EAP
- authentication ("canned" Success); this should be ignored based on
- RFC 3748 Sect. 4.2
-- test compilation with gcc -W options (more warnings?)
- (Done once; number of unused function arguments still present)
-- ctrl_iface: get/remove blob
-- use doc/docbook/*.sgml and docbook2{txt,html,pdf} to replace README and
- web pages including the same information.. i.e., have this information only
- in one page; how to build a PDF file with all the SGML included?
-- EAP-POTP/RSA SecurID profile (RFC 4793)
-- document wpa_gui build and consider adding it to 'make install'
-- consider merging hostapd and wpa_supplicant PMKSA cache implementations
-- consider redesigning pending EAP requests (identity/password/otp from
- ctrl_iface) by moving the retrying of the previous request into EAP
- state machine so that EAPOL state machine is not needed for this
-- rfc4284.txt (network selection for eap)
-- www pages about configuring wpa_supplicant:
- * global options (ap_scan, ctrl_interfaces) based on OS/driver
- * network block
- * key_mgmt selection
- * WPA parameters
- * EAP options (one page for each method)
- * "configuration wizard" (step 1: select OS, step 2: select driver, ...) to
- generate example configuration
-- error path in rsn_preauth_init: should probably deinit l2_packet handlers
- if something fails; does something else need deinit?
-- consider moving SIM card functionality (IMSI fetching) away from eap.c;
- this should likely happen before EAP is initialized for authentication;
- now IMSI is read only after receiving EAP-Identity/Request, but since it is
- really needed for all cases, reading IMSI and generating Identity string
- could very well be done before EAP has been started
-- try to work around race in receiving association event and first EAPOL
- message
-- try to work around race in configuring PTK and sending msg 4/4 (some NDIS
- drivers with ndiswrapper end up not being able to complete 4-way handshake
- in some cases; extra delay before setting the key seems to help)
-- make sure that TLS session cache is not shared between EAP types or if it
- is, that the cache entries are bound to only one EAP type; e.g., cache entry
- created with EAP-TLS must not be allowed to do fast re-auth with EAP-TTLS
-- consider moving eap_peer_tls_build_ack() call into
- eap_peer_tls_process_helper()
- (it seems to be called always if helper returns 1)
- * could need to modify eap_{ttls,peap,fast}_decrypt to do same
-- add support for fetching full user cert chain from Windows certificate
- stores even when there are intermediate CA certs that are not in the
- configured ca_cert store (e.g., ROOT) (they could be, e.g., in CA store)
-- clean up common.[ch]
-- change TLS/crypto library interface to use a structure of function
- pointers and helper inline functions (like driver_ops) instead of
- requiring every TLS wrapper to implement all functions
-- add support for encrypted configuration fields (e.g., password, psk,
- passphrase, pin)
-- wpa_gui: add support for setting and showing priority
-- cleanup TLS/PEAP/TTLS/FAST fragmentation: both the handshake and Appl. Data
- phases should be able to use the same functions for this;
- the last step in processing sent should be this code and rest of the code
- should not need to care about fragmentation at all
-- test EAP-FAST peer with OpenSSL and verify that fallback to full handshake
- (ServerHello followed by something else than ChangeCipherSpec)
diff --git a/wpa_supplicant/twt.c b/wpa_supplicant/twt.c
deleted file mode 100644
index 8ec2c85acb8d..000000000000
--- a/wpa_supplicant/twt.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * wpa_supplicant - TWT
- * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "utils/common.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-
-/**
- * wpas_twt_send_setup - Send TWT Setup frame (Request) to our AP
- * @wpa_s: Pointer to wpa_supplicant
- * @dtok: Dialog token
- * @exponent: Wake-interval exponent
- * @mantissa: Wake-interval mantissa
- * @min_twt: Minimum TWT wake duration in units of 256 usec
- * @setup_cmd: 0 == request, 1 == suggest, etc. Table 9-297
- * Returns: 0 in case of success, negative error code otherwise
- *
- */
-int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
- int mantissa, u8 min_twt, int setup_cmd, u64 twt,
- bool requestor, bool trigger, bool implicit,
- bool flow_type, u8 flow_id, bool protection,
- u8 twt_channel, u8 control)
-{
- struct wpabuf *buf;
- u16 req_type = 0;
- int ret = 0;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG,
- "TWT: No connection - cannot send TWT Setup frame");
- return -ENOTCONN;
- }
-
- /* 3 = Action category + Action code + Dialog token */
- /* 17 = TWT element */
- buf = wpabuf_alloc(3 + 17);
- if (!buf) {
- wpa_printf(MSG_DEBUG,
- "TWT: Failed to allocate TWT Setup frame (Request)");
- return -ENOMEM;
- }
-
- wpa_printf(MSG_DEBUG,
- "TWT: Setup request, dtok: %d exponent: %d mantissa: %d min-twt: %d",
- dtok, exponent, mantissa, min_twt);
-
- wpabuf_put_u8(buf, WLAN_ACTION_S1G);
- wpabuf_put_u8(buf, S1G_ACT_TWT_SETUP);
- wpabuf_put_u8(buf, dtok);
-
- wpabuf_put_u8(buf, WLAN_EID_TWT);
- wpabuf_put_u8(buf, 15); /* len */
-
- wpabuf_put_u8(buf, control);
-
- if (requestor)
- req_type |= BIT(0); /* This STA is a TWT Requesting STA */
- /* TWT Setup Command field */
- req_type |= (setup_cmd & 0x7) << 1;
- if (trigger)
- req_type |= BIT(4); /* TWT SP includes trigger frames */
- if (implicit)
- req_type |= BIT(5); /* Implicit TWT */
- if (flow_type)
- req_type |= BIT(6); /* Flow Type: Unannounced TWT */
- req_type |= (flow_id & 0x7) << 7;
- req_type |= (exponent & 0x1f) << 10; /* TWT Wake Interval Exponent */
- if (protection)
- req_type |= BIT(15);
- wpabuf_put_le16(buf, req_type);
- wpabuf_put_le64(buf, twt);
- wpabuf_put_u8(buf, min_twt); /* Nominal Minimum TWT Wake Duration */
- wpabuf_put_le16(buf, mantissa); /* TWT Wake Interval Mantissa */
- wpabuf_put_u8(buf, twt_channel); /* TWT Channel */
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
- wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Setup Request");
- ret = -ECANCELED;
- }
-
- wpabuf_free(buf);
- return ret;
-}
-
-
-/**
- * wpas_twt_send_teardown - Send TWT teardown request to our AP
- * @wpa_s: Pointer to wpa_supplicant
- * @flags: The byte that goes inside the TWT Teardown element
- * Returns: 0 in case of success, negative error code otherwise
- *
- */
-int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags)
-{
- struct wpabuf *buf;
- int ret = 0;
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG,
- "TWT: No connection - cannot send TWT Teardown frame");
- return -ENOTCONN;
- }
-
- /* 3 = Action category + Action code + flags */
- buf = wpabuf_alloc(3);
- if (!buf) {
- wpa_printf(MSG_DEBUG,
- "TWT: Failed to allocate TWT Teardown frame");
- return -ENOMEM;
- }
-
- wpa_printf(MSG_DEBUG, "TWT: Teardown request, flags: 0x%x", flags);
-
- wpabuf_put_u8(buf, WLAN_ACTION_S1G);
- wpabuf_put_u8(buf, S1G_ACT_TWT_TEARDOWN);
- wpabuf_put_u8(buf, flags);
-
- if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
- wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Teardown frame");
- ret = -ECANCELED;
- }
-
- wpabuf_free(buf);
- return ret;
-}
-
-#endif /* CONFIG_TESTING_OPTIONS */
diff --git a/wpa_supplicant/utils/log2pcap.py b/wpa_supplicant/utils/log2pcap.py
deleted file mode 100755
index 141aecbe5178..000000000000
--- a/wpa_supplicant/utils/log2pcap.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012, Intel Corporation
-#
-# Author: Johannes Berg <johannes@sipsolutions.net>
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-
-import sys, struct, re
-
-def write_pcap_header(pcap_file):
- pcap_file.write(
- struct.pack('<IHHIIII',
- 0xa1b2c3d4, 2, 4, 0, 0, 65535,
- 105 # raw 802.11 format
- ))
-
-def pcap_addpacket(pcap_file, ts, data):
- # ts in seconds, float
- pcap_file.write(struct.pack('<IIII',
- int(ts), int(1000000 * ts) % 1000000,
- len(data), len(data)))
- pcap_file.write(data)
-
-if __name__ == "__main__":
- try:
- input = sys.argv[1]
- pcap = sys.argv[2]
- except IndexError:
- print("Usage: %s <log file> <pcap file>" % sys.argv[0])
- sys.exit(2)
-
- input_file = open(input, 'r')
- pcap_file = open(pcap, 'w')
- frame_re = re.compile(r'(([0-9]+.[0-9]{6}):\s*)?nl80211: MLME event frame - hexdump\(len=[0-9]*\):((\s*[0-9a-fA-F]{2})*)')
-
- write_pcap_header(pcap_file)
-
- for line in input_file:
- m = frame_re.match(line)
- if m is None:
- continue
- if m.group(2):
- ts = float(m.group(2))
- else:
- ts = 0
- hexdata = m.group(3)
- hexdata = hexdata.split()
- data = ''.join([chr(int(x, 16)) for x in hexdata])
- pcap_addpacket(pcap_file, ts, data)
-
- input_file.close()
- pcap_file.close()
diff --git a/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj b/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
deleted file mode 100755
index c92b8fd89d6c..000000000000
--- a/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
+++ /dev/null
@@ -1,477 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="eapol_test"
- ProjectGUID="{0E3F2C6D-1372-48D6-BCAB-E584917C4DE3}"
- RootNamespace="eapol_test"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="2"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="1"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\crypto\aes-cbc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-ctr.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-eax.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-encblock.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-omac1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-unwrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-wrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\base64.c"
- >
- </File>
- <File
- RelativePath="..\..\bssid_ignore.c"
- >
- </File>
- <File
- RelativePath="..\..\bss.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\chap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config_file.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\crypto_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface_named_pipe.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_aka.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_gtc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_leap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_methods.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_otp.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_peap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_peap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\eap_register.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_sim.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_sim_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tnc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_ttls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
- >
- </File>
- <File
- RelativePath="..\..\eapol_test.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\eloop_win.c"
- >
- </File>
- <File
- RelativePath="..\..\events.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\fips_prf_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\ip_addr.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\l2_packet\l2_packet_winpcap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\ms_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\notify.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\os_win32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\pcsc_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\peerkey.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\pmksa_cache.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\preauth.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\radius\radius.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\radius\radius_client.c"
- >
- </File>
- <File
- RelativePath="..\..\scan.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-pbkdf2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-prf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-tlsprf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\tls_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\tncc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\common\wpa_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpa_debug.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa_ie.c"
- >
- </File>
- <File
- RelativePath="..\..\wpa_supplicant.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpabuf.c"
- >
- </File>
- <File
- RelativePath="..\..\wpas_glue.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/vs2005/win_if_list/win_if_list.vcproj b/wpa_supplicant/vs2005/win_if_list/win_if_list.vcproj
deleted file mode 100755
index e79fc0f4666f..000000000000
--- a/wpa_supplicant/vs2005/win_if_list/win_if_list.vcproj
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="win_if_list"
- ProjectGUID="{9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}"
- RootNamespace="win_if_list"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\src\utils;C:\dev\WpdPack\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wpcap.lib"
- LinkIncremental="2"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\src\utils;C:\dev\WpdPack\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wpcap.lib"
- LinkIncremental="1"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\win_if_list.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/vs2005/wpa_cli/wpa_cli.vcproj b/wpa_supplicant/vs2005/wpa_cli/wpa_cli.vcproj
deleted file mode 100755
index d2de768e7cdc..000000000000
--- a/wpa_supplicant/vs2005/wpa_cli/wpa_cli.vcproj
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="wpa_cli"
- ProjectGUID="{E3A7B181-22CC-4DA3-8410-6AD69879A9EC}"
- RootNamespace="wpa_cli"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\src;..\..\..\src\utils"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- DisableSpecificWarnings="4244;4267"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\src;..\..\..\src\utils"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4267"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\utils\common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\os_win32.c"
- >
- </File>
- <File
- RelativePath="..\..\wpa_cli.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\common\wpa_ctrl.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/vs2005/wpa_passphrase/wpa_passphrase.vcproj b/wpa_supplicant/vs2005/wpa_passphrase/wpa_passphrase.vcproj
deleted file mode 100755
index 97aa2c5aecb5..000000000000
--- a/wpa_supplicant/vs2005/wpa_passphrase/wpa_passphrase.vcproj
+++ /dev/null
@@ -1,236 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="wpa_passphrase"
- ProjectGUID="{ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}"
- RootNamespace="wpa_passphrase"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\src;..\..\..\src\utils;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- DisableSpecificWarnings="4244;4267"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- LinkIncremental="2"
- AdditionalLibraryDirectories=""
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\src;..\..\..\src\utils;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4267"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\utils\common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\md5-internal.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\os_win32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-internal.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-prf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-pbkdf2.c"
- >
- </File>
- <File
- RelativePath="..\..\wpa_passphrase.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/vs2005/wpa_supplicant.sln b/wpa_supplicant/vs2005/wpa_supplicant.sln
deleted file mode 100755
index df89e3198d2f..000000000000
--- a/wpa_supplicant/vs2005/wpa_supplicant.sln
+++ /dev/null
@@ -1,52 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpa_supplicant", "wpa_supplicant\wpa_supplicant.vcproj", "{8BCFDA77-AEDC-4168-8897-5B73105BBB87}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpa_cli", "wpa_cli\wpa_cli.vcproj", "{E3A7B181-22CC-4DA3-8410-6AD69879A9EC}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpasvc", "wpasvc\wpasvc.vcproj", "{E2A4A85F-CA77-406D-8ABF-63EF94545ACC}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpa_passphrase", "wpa_passphrase\wpa_passphrase.vcproj", "{ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win_if_list", "win_if_list\win_if_list.vcproj", "{9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eapol_test", "eapol_test\eapol_test.vcproj", "{0E3F2C6D-1372-48D6-BCAB-E584917C4DE3}"
-EndProject
-Global
- GlobalSection(DPCodeReviewSolutionGUID) = preSolution
- DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {8BCFDA77-AEDC-4168-8897-5B73105BBB87}.Debug|Win32.ActiveCfg = Debug|Win32
- {8BCFDA77-AEDC-4168-8897-5B73105BBB87}.Debug|Win32.Build.0 = Debug|Win32
- {8BCFDA77-AEDC-4168-8897-5B73105BBB87}.Release|Win32.ActiveCfg = Release|Win32
- {8BCFDA77-AEDC-4168-8897-5B73105BBB87}.Release|Win32.Build.0 = Release|Win32
- {E3A7B181-22CC-4DA3-8410-6AD69879A9EC}.Debug|Win32.ActiveCfg = Debug|Win32
- {E3A7B181-22CC-4DA3-8410-6AD69879A9EC}.Debug|Win32.Build.0 = Debug|Win32
- {E3A7B181-22CC-4DA3-8410-6AD69879A9EC}.Release|Win32.ActiveCfg = Release|Win32
- {E3A7B181-22CC-4DA3-8410-6AD69879A9EC}.Release|Win32.Build.0 = Release|Win32
- {E2A4A85F-CA77-406D-8ABF-63EF94545ACC}.Debug|Win32.ActiveCfg = Debug|Win32
- {E2A4A85F-CA77-406D-8ABF-63EF94545ACC}.Debug|Win32.Build.0 = Debug|Win32
- {E2A4A85F-CA77-406D-8ABF-63EF94545ACC}.Release|Win32.ActiveCfg = Release|Win32
- {E2A4A85F-CA77-406D-8ABF-63EF94545ACC}.Release|Win32.Build.0 = Release|Win32
- {ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}.Debug|Win32.ActiveCfg = Debug|Win32
- {ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}.Debug|Win32.Build.0 = Debug|Win32
- {ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}.Release|Win32.ActiveCfg = Release|Win32
- {ADBE4EA8-F0C5-40C2-AE89-C56D0F2EC1DF}.Release|Win32.Build.0 = Release|Win32
- {9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}.Debug|Win32.ActiveCfg = Debug|Win32
- {9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}.Debug|Win32.Build.0 = Debug|Win32
- {9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}.Release|Win32.ActiveCfg = Release|Win32
- {9E87CD9C-60CE-4533-85CF-85CA3A9BF26A}.Release|Win32.Build.0 = Release|Win32
- {0E3F2C6D-1372-48D6-BCAB-E584917C4DE3}.Debug|Win32.ActiveCfg = Debug|Win32
- {0E3F2C6D-1372-48D6-BCAB-E584917C4DE3}.Debug|Win32.Build.0 = Debug|Win32
- {0E3F2C6D-1372-48D6-BCAB-E584917C4DE3}.Release|Win32.ActiveCfg = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj b/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
deleted file mode 100755
index 10c05b565597..000000000000
--- a/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
+++ /dev/null
@@ -1,465 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="wpa_supplicant"
- ProjectGUID="{8BCFDA77-AEDC-4168-8897-5B73105BBB87}"
- RootNamespace="wpa_supplicant"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wbemuuid.lib ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="2"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wbemuuid.lib ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="1"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\crypto\aes-cbc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-ctr.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-eax.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-encblock.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-omac1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-unwrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-wrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\base64.c"
- >
- </File>
- <File
- RelativePath="..\..\bssid_ignore.c"
- >
- </File>
- <File
- RelativePath="..\..\bss.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\chap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config_file.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\crypto_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface_named_pipe.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_ndis.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_ndis_.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\drivers.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_gtc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_leap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_methods.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_otp.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_peap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_peap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\eap_register.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tnc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_ttls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\eloop_win.c"
- >
- </File>
- <File
- RelativePath="..\..\events.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\l2_packet\l2_packet_winpcap.c"
- >
- </File>
- <File
- RelativePath="..\..\main.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\ms_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\ndis_events.c"
- >
- </File>
- <File
- RelativePath="..\..\notify.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\os_win32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\pcsc_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\peerkey.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\pmksa_cache.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\preauth.c"
- >
- </File>
- <File
- RelativePath="..\..\scan.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-pbkdf2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-prf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-tlsprf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\tls_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\tncc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\common\wpa_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpa_debug.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa_ie.c"
- >
- </File>
- <File
- RelativePath="..\..\wpa_supplicant.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpabuf.c"
- >
- </File>
- <File
- RelativePath="..\..\wpas_glue.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj b/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
deleted file mode 100755
index 82d9033ffe8e..000000000000
--- a/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
+++ /dev/null
@@ -1,465 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="wpasvc"
- ProjectGUID="{E2A4A85F-CA77-406D-8ABF-63EF94545ACC}"
- RootNamespace="wpasvc"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wbemuuid.lib ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="2"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="1"
- CharacterSet="0"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..;..\..\..\src;..\..\..\src\utils;C:\dev\WpdPack\include;C:\dev\openssl\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;CONFIG_WIN32_DEFAULTS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4267;4311"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="wbemuuid.lib ws2_32.lib Crypt32.lib Winscard.lib Packet.lib wpcap.lib libeay32MT.lib ssleay32Mt.lib"
- LinkIncremental="1"
- AdditionalLibraryDirectories="C:\dev\WpdPack\lib;C:\dev\openssl\lib"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\src\crypto\aes-cbc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-ctr.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-eax.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-encblock.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-omac1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-unwrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\aes-wrap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\base64.c"
- >
- </File>
- <File
- RelativePath="..\..\bssid_ignore.c"
- >
- </File>
- <File
- RelativePath="..\..\bss.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\chap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config.c"
- >
- </File>
- <File
- RelativePath="..\..\config_winreg.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\crypto_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface.c"
- >
- </File>
- <File
- RelativePath="..\..\ctrl_iface_named_pipe.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_ndis.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\driver_ndis_.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\drivers.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_gtc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_leap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_methods.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_otp.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_peap.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_common\eap_peap_common.c"
- >
- </File>
- <File
- RelativePath="..\..\eap_register.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tls_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_tnc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\eap_ttls.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\eloop_win.c"
- >
- </File>
- <File
- RelativePath="..\..\events.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\l2_packet\l2_packet_winpcap.c"
- >
- </File>
- <File
- RelativePath="..\..\main_winsvc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\md5.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\ms_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\mschapv2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\drivers\ndis_events.c"
- >
- </File>
- <File
- RelativePath="..\..\notify.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\os_win32.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\pcsc_funcs.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\peerkey.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\pmksa_cache.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\preauth.c"
- >
- </File>
- <File
- RelativePath="..\..\scan.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-pbkdf2.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-prf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\sha1-tlsprf.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\crypto\tls_openssl.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\eap_peer\tncc.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\common\wpa_common.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpa_debug.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\rsn_supp\wpa_ie.c"
- >
- </File>
- <File
- RelativePath="..\..\wpa_supplicant.c"
- >
- </File>
- <File
- RelativePath="..\..\..\src\utils\wpabuf.c"
- >
- </File>
- <File
- RelativePath="..\..\wpas_glue.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/wpa_supplicant/wifi_display.c b/wpa_supplicant/wifi_display.c
deleted file mode 100644
index c94e4610893a..000000000000
--- a/wpa_supplicant/wifi_display.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * wpa_supplicant - Wi-Fi Display
- * Copyright (c) 2011, Atheros Communications, Inc.
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "p2p/p2p.h"
-#include "common/ieee802_11_defs.h"
-#include "wpa_supplicant_i.h"
-#include "wifi_display.h"
-
-
-#define WIFI_DISPLAY_SUBELEM_HEADER_LEN 3
-
-
-int wifi_display_init(struct wpa_global *global)
-{
- global->wifi_display = 1;
- return 0;
-}
-
-
-void wifi_display_deinit(struct wpa_global *global)
-{
- int i;
- for (i = 0; i < MAX_WFD_SUBELEMS; i++) {
- wpabuf_free(global->wfd_subelem[i]);
- global->wfd_subelem[i] = NULL;
- }
-}
-
-
-struct wpabuf * wifi_display_get_wfd_ie(struct wpa_global *global)
-{
- struct wpabuf *ie;
- size_t len;
- int i;
-
- if (global->p2p == NULL)
- return NULL;
-
- len = 0;
- for (i = 0; i < MAX_WFD_SUBELEMS; i++) {
- if (global->wfd_subelem[i])
- len += wpabuf_len(global->wfd_subelem[i]);
- }
-
- ie = wpabuf_alloc(len);
- if (ie == NULL)
- return NULL;
-
- for (i = 0; i < MAX_WFD_SUBELEMS; i++) {
- if (global->wfd_subelem[i])
- wpabuf_put_buf(ie, global->wfd_subelem[i]);
- }
-
- return ie;
-}
-
-
-static int wifi_display_update_wfd_ie(struct wpa_global *global)
-{
- struct wpabuf *ie, *buf;
- size_t len, plen;
-
- if (global->p2p == NULL)
- return 0;
-
- wpa_printf(MSG_DEBUG, "WFD: Update WFD IE");
-
- if (!global->wifi_display) {
- wpa_printf(MSG_DEBUG, "WFD: Wi-Fi Display disabled - do not "
- "include WFD IE");
- p2p_set_wfd_ie_beacon(global->p2p, NULL);
- p2p_set_wfd_ie_probe_req(global->p2p, NULL);
- p2p_set_wfd_ie_probe_resp(global->p2p, NULL);
- p2p_set_wfd_ie_assoc_req(global->p2p, NULL);
- p2p_set_wfd_ie_invitation(global->p2p, NULL);
- p2p_set_wfd_ie_prov_disc_req(global->p2p, NULL);
- p2p_set_wfd_ie_prov_disc_resp(global->p2p, NULL);
- p2p_set_wfd_ie_go_neg(global->p2p, NULL);
- p2p_set_wfd_dev_info(global->p2p, NULL);
- p2p_set_wfd_r2_dev_info(global->p2p, NULL);
- p2p_set_wfd_assoc_bssid(global->p2p, NULL);
- p2p_set_wfd_coupled_sink_info(global->p2p, NULL);
- return 0;
- }
-
- p2p_set_wfd_dev_info(global->p2p,
- global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]);
- p2p_set_wfd_r2_dev_info(
- global->p2p, global->wfd_subelem[WFD_SUBELEM_R2_DEVICE_INFO]);
- p2p_set_wfd_assoc_bssid(
- global->p2p,
- global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID]);
- p2p_set_wfd_coupled_sink_info(
- global->p2p, global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]);
-
- /*
- * WFD IE is included in number of management frames. Two different
- * sets of subelements are included depending on the frame:
- *
- * Beacon, (Re)Association Request, GO Negotiation Req/Resp/Conf,
- * Provision Discovery Req:
- * WFD Device Info
- * [Associated BSSID]
- * [Coupled Sink Info]
- *
- * Probe Request:
- * WFD Device Info
- * [Associated BSSID]
- * [Coupled Sink Info]
- * [WFD Extended Capability]
- *
- * Probe Response:
- * WFD Device Info
- * [Associated BSSID]
- * [Coupled Sink Info]
- * [WFD Extended Capability]
- * [WFD Session Info]
- *
- * (Re)Association Response, P2P Invitation Req/Resp,
- * Provision Discovery Resp:
- * WFD Device Info
- * [Associated BSSID]
- * [Coupled Sink Info]
- * [WFD Session Info]
- */
- len = 0;
- if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO])
- len += wpabuf_len(global->wfd_subelem[
- WFD_SUBELEM_DEVICE_INFO]);
-
- if (global->wfd_subelem[WFD_SUBELEM_R2_DEVICE_INFO])
- len += wpabuf_len(global->wfd_subelem[
- WFD_SUBELEM_R2_DEVICE_INFO]);
-
- if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID])
- len += wpabuf_len(global->wfd_subelem[
- WFD_SUBELEM_ASSOCIATED_BSSID]);
- if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK])
- len += wpabuf_len(global->wfd_subelem[
- WFD_SUBELEM_COUPLED_SINK]);
- if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO])
- len += wpabuf_len(global->wfd_subelem[
- WFD_SUBELEM_SESSION_INFO]);
- if (global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB])
- len += wpabuf_len(global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]);
- buf = wpabuf_alloc(len);
- if (buf == NULL)
- return -1;
-
- if (global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_DEVICE_INFO]);
-
- if (global->wfd_subelem[WFD_SUBELEM_R2_DEVICE_INFO])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_R2_DEVICE_INFO]);
-
- if (global->wfd_subelem[WFD_SUBELEM_ASSOCIATED_BSSID])
- wpabuf_put_buf(buf, global->wfd_subelem[
- WFD_SUBELEM_ASSOCIATED_BSSID]);
- if (global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_COUPLED_SINK]);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Beacon", ie);
- p2p_set_wfd_ie_beacon(global->p2p, ie);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for (Re)Association Request",
- ie);
- p2p_set_wfd_ie_assoc_req(global->p2p, ie);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for GO Negotiation", ie);
- p2p_set_wfd_ie_go_neg(global->p2p, ie);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Provision Discovery "
- "Request", ie);
- p2p_set_wfd_ie_prov_disc_req(global->p2p, ie);
-
- plen = buf->used;
- if (global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_EXT_CAPAB]);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Request", ie);
- p2p_set_wfd_ie_probe_req(global->p2p, ie);
-
- if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]);
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Probe Response", ie);
- p2p_set_wfd_ie_probe_resp(global->p2p, ie);
-
- /* Remove WFD Extended Capability from buffer */
- buf->used = plen;
- if (global->wfd_subelem[WFD_SUBELEM_SESSION_INFO])
- wpabuf_put_buf(buf,
- global->wfd_subelem[WFD_SUBELEM_SESSION_INFO]);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for P2P Invitation", ie);
- p2p_set_wfd_ie_invitation(global->p2p, ie);
-
- ie = wifi_display_encaps(buf);
- wpa_hexdump_buf(MSG_DEBUG, "WFD: WFD IE for Provision Discovery "
- "Response", ie);
- p2p_set_wfd_ie_prov_disc_resp(global->p2p, ie);
-
- wpabuf_free(buf);
-
- return 0;
-}
-
-
-void wifi_display_enable(struct wpa_global *global, int enabled)
-{
- wpa_printf(MSG_DEBUG, "WFD: Wi-Fi Display %s",
- enabled ? "enabled" : "disabled");
- global->wifi_display = enabled;
- wifi_display_update_wfd_ie(global);
-}
-
-
-int wifi_display_subelem_set(struct wpa_global *global, char *cmd)
-{
- char *pos;
- int subelem;
- size_t len;
- struct wpabuf *e;
-
- pos = os_strchr(cmd, ' ');
- if (pos == NULL)
- return -1;
- *pos++ = '\0';
-
- len = os_strlen(pos);
- if (len & 1)
- return -1;
- len /= 2;
-
- if (os_strcmp(cmd, "all") == 0) {
- int res;
-
- e = wpabuf_alloc(len);
- if (e == NULL)
- return -1;
- if (hexstr2bin(pos, wpabuf_put(e, len), len) < 0) {
- wpabuf_free(e);
- return -1;
- }
- res = wifi_display_subelem_set_from_ies(global, e);
- wpabuf_free(e);
- return res;
- }
-
- subelem = atoi(cmd);
- if (subelem < 0 || subelem >= MAX_WFD_SUBELEMS)
- return -1;
-
- if (len == 0) {
- /* Clear subelement */
- e = NULL;
- wpa_printf(MSG_DEBUG, "WFD: Clear subelement %d", subelem);
- } else {
- e = wpabuf_alloc(1 + len);
- if (e == NULL)
- return -1;
- wpabuf_put_u8(e, subelem);
- if (hexstr2bin(pos, wpabuf_put(e, len), len) < 0) {
- wpabuf_free(e);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "WFD: Set subelement %d", subelem);
- }
-
- wpabuf_free(global->wfd_subelem[subelem]);
- global->wfd_subelem[subelem] = e;
- wifi_display_update_wfd_ie(global);
-
- return 0;
-}
-
-
-int wifi_display_subelem_set_from_ies(struct wpa_global *global,
- struct wpabuf *ie)
-{
- int subelements[MAX_WFD_SUBELEMS] = {};
- const u8 *pos, *end;
- unsigned int len, subelem;
- struct wpabuf *e;
-
- wpa_printf(MSG_DEBUG, "WFD IEs set: %p - %lu",
- ie, ie ? (unsigned long) wpabuf_len(ie) : 0);
-
- if (ie == NULL || wpabuf_len(ie) < 6)
- return -1;
-
- pos = wpabuf_head(ie);
- end = pos + wpabuf_len(ie);
-
- while (end > pos) {
- if (pos + 3 > end)
- break;
-
- len = WPA_GET_BE16(pos + 1) + 3;
-
- wpa_printf(MSG_DEBUG, "WFD Sub-Element ID %d - len %d",
- *pos, len - 3);
-
- if (len > (unsigned int) (end - pos))
- break;
-
- subelem = *pos;
- if (subelem < MAX_WFD_SUBELEMS && subelements[subelem] == 0) {
- e = wpabuf_alloc_copy(pos, len);
- if (e == NULL)
- return -1;
-
- wpabuf_free(global->wfd_subelem[subelem]);
- global->wfd_subelem[subelem] = e;
- subelements[subelem] = 1;
- }
-
- pos += len;
- }
-
- for (subelem = 0; subelem < MAX_WFD_SUBELEMS; subelem++) {
- if (subelements[subelem] == 0) {
- wpabuf_free(global->wfd_subelem[subelem]);
- global->wfd_subelem[subelem] = NULL;
- }
- }
-
- return wifi_display_update_wfd_ie(global);
-}
-
-
-int wifi_display_subelem_get(struct wpa_global *global, char *cmd,
- char *buf, size_t buflen)
-{
- int subelem;
-
- if (os_strcmp(cmd, "all") == 0) {
- struct wpabuf *ie;
- int res;
-
- ie = wifi_display_get_wfd_ie(global);
- if (ie == NULL)
- return 0;
- res = wpa_snprintf_hex(buf, buflen, wpabuf_head(ie),
- wpabuf_len(ie));
- wpabuf_free(ie);
- return res;
- }
-
- subelem = atoi(cmd);
- if (subelem < 0 || subelem >= MAX_WFD_SUBELEMS)
- return -1;
-
- if (global->wfd_subelem[subelem] == NULL)
- return 0;
-
- return wpa_snprintf_hex(buf, buflen,
- wpabuf_head_u8(global->wfd_subelem[subelem]) +
- 1,
- wpabuf_len(global->wfd_subelem[subelem]) - 1);
-}
-
-
-char * wifi_display_subelem_hex(const struct wpabuf *wfd_subelems, u8 id)
-{
- char *subelem = NULL;
- const u8 *buf;
- size_t buflen;
- size_t i = 0;
- u16 elen;
-
- if (!wfd_subelems)
- return NULL;
-
- buf = wpabuf_head_u8(wfd_subelems);
- if (!buf)
- return NULL;
-
- buflen = wpabuf_len(wfd_subelems);
-
- while (i + WIFI_DISPLAY_SUBELEM_HEADER_LEN < buflen) {
- elen = WPA_GET_BE16(buf + i + 1);
- if (i + WIFI_DISPLAY_SUBELEM_HEADER_LEN + elen > buflen)
- break; /* truncated subelement */
-
- if (buf[i] == id) {
- /*
- * Limit explicitly to an arbitrary length to avoid
- * unnecessarily large allocations. In practice, this
- * is limited to maximum frame length anyway, so the
- * maximum memory allocation here is not really that
- * large. Anyway, the Wi-Fi Display subelements that
- * are fetched with this function are even shorter.
- */
- if (elen > 1000)
- break;
- subelem = os_zalloc(2 * elen + 1);
- if (!subelem)
- return NULL;
- wpa_snprintf_hex(subelem, 2 * elen + 1,
- buf + i +
- WIFI_DISPLAY_SUBELEM_HEADER_LEN,
- elen);
- break;
- }
-
- i += elen + WIFI_DISPLAY_SUBELEM_HEADER_LEN;
- }
-
- return subelem;
-}
diff --git a/wpa_supplicant/wifi_display.h b/wpa_supplicant/wifi_display.h
deleted file mode 100644
index 0966bdb93bef..000000000000
--- a/wpa_supplicant/wifi_display.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * wpa_supplicant - Wi-Fi Display
- * Copyright (c) 2011, Atheros Communications, Inc.
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WIFI_DISPLAY_H
-#define WIFI_DISPLAY_H
-
-int wifi_display_init(struct wpa_global *global);
-void wifi_display_deinit(struct wpa_global *global);
-void wifi_display_enable(struct wpa_global *global, int enabled);
-struct wpabuf *wifi_display_get_wfd_ie(struct wpa_global *global);
-int wifi_display_subelem_set(struct wpa_global *global, char *cmd);
-int wifi_display_subelem_set_from_ies(struct wpa_global *global,
- struct wpabuf *ie);
-int wifi_display_subelem_get(struct wpa_global *global, char *cmd,
- char *buf, size_t buflen);
-char * wifi_display_subelem_hex(const struct wpabuf *wfd_subelems, u8 id);
-
-#endif /* WIFI_DISPLAY_H */
diff --git a/wpa_supplicant/win_example.reg b/wpa_supplicant/win_example.reg
deleted file mode 100755
index 875d4ef28046..000000000000
--- a/wpa_supplicant/win_example.reg
+++ /dev/null
@@ -1,42 +0,0 @@
-REGEDIT4
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant]
-"debug_level"=dword:00000000
-"debug_show_keys"=dword:00000001
-"debug_timestamp"=dword:00000000
-"debug_use_file"=dword:00000000
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs]
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test]
-"ap_scan"=dword:00000002
-"update_config"=dword:00000001
-"uuid"="12345678-9abc-def0-1234-56789abcdef0"
-"device_name"="Wireless Client"
-"manufacturer"="Company"
-"model_name"="cmodel"
-"serial_number"="12345"
-"device_type"="1-0050F204-1"
-"os_version"="01020300"
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\blobs]
-"testblob"=hex:01,02,03,04,05
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks]
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000]
-"ssid"="\"example network\""
-"key_mgmt"="WPA-PSK"
-"psk"="\"secret password\""
-"pairwise"="CCMP"
-"group"="CCMP"
-"proto"="WPA"
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\interfaces]
-
-[HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\interfaces\0000]
-"adapter"="{A7627643-C310-49E5-BD89-7E77709C04AB}"
-"config"="test"
-"ctrl_interface"=""
-"skip_on_error"=dword:00000000
-
diff --git a/wpa_supplicant/win_if_list.c b/wpa_supplicant/win_if_list.c
deleted file mode 100644
index 39634d92f0dc..000000000000
--- a/wpa_supplicant/win_if_list.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * win_if_list - Display network interfaces with description (for Windows)
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * This small tool is for the Windows build to provide an easy way of fetching
- * a list of available network interfaces.
- */
-
-#include "includes.h"
-#include <stdio.h>
-#ifdef CONFIG_USE_NDISUIO
-#include <winsock2.h>
-#include <ntddndis.h>
-#else /* CONFIG_USE_NDISUIO */
-#include "pcap.h"
-#include <winsock.h>
-#endif /* CONFIG_USE_NDISUIO */
-
-#ifdef CONFIG_USE_NDISUIO
-
-/* from nuiouser.h */
-#define FSCTL_NDISUIO_BASE FILE_DEVICE_NETWORK
-
-#define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \
- CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access)
-
-#define IOCTL_NDISUIO_QUERY_BINDING \
- _NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \
- FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#define IOCTL_NDISUIO_BIND_WAIT \
- _NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \
- FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-typedef struct _NDISUIO_QUERY_BINDING
-{
- ULONG BindingIndex;
- ULONG DeviceNameOffset;
- ULONG DeviceNameLength;
- ULONG DeviceDescrOffset;
- ULONG DeviceDescrLength;
-} NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING;
-
-
-static HANDLE ndisuio_open(void)
-{
- DWORD written;
- HANDLE h;
-
- h = CreateFile(TEXT("\\\\.\\\\Ndisuio"),
- GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- INVALID_HANDLE_VALUE);
- if (h == INVALID_HANDLE_VALUE)
- return h;
-
-#ifndef _WIN32_WCE
- if (!DeviceIoControl(h, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, NULL, 0,
- &written, NULL)) {
- printf("IOCTL_NDISUIO_BIND_WAIT failed: %d",
- (int) GetLastError());
- CloseHandle(h);
- return INVALID_HANDLE_VALUE;
- }
-#endif /* _WIN32_WCE */
-
- return h;
-}
-
-
-static void ndisuio_query_bindings(HANDLE ndisuio)
-{
- NDISUIO_QUERY_BINDING *b;
- size_t blen = sizeof(*b) + 1024;
- int i, error;
- DWORD written;
- char name[256], desc[256];
- WCHAR *pos;
- size_t j, len;
-
- b = malloc(blen);
- if (b == NULL)
- return;
-
- for (i = 0; ; i++) {
- memset(b, 0, blen);
- b->BindingIndex = i;
- if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
- b, sizeof(NDISUIO_QUERY_BINDING), b,
- (DWORD) blen, &written, NULL)) {
- error = (int) GetLastError();
- if (error == ERROR_NO_MORE_ITEMS)
- break;
- printf("IOCTL_NDISUIO_QUERY_BINDING failed: %d",
- error);
- break;
- }
-
- pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
- len = b->DeviceNameLength;
- if (len >= sizeof(name))
- len = sizeof(name) - 1;
- for (j = 0; j < len; j++)
- name[j] = (char) pos[j];
- name[len] = '\0';
-
- pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
- len = b->DeviceDescrLength;
- if (len >= sizeof(desc))
- len = sizeof(desc) - 1;
- for (j = 0; j < len; j++)
- desc[j] = (char) pos[j];
- desc[len] = '\0';
-
- printf("ifname: %s\ndescription: %s\n\n", name, desc);
- }
-
- free(b);
-}
-
-
-static void ndisuio_enum_bindings(void)
-{
- HANDLE ndisuio = ndisuio_open();
- if (ndisuio == INVALID_HANDLE_VALUE)
- return;
-
- ndisuio_query_bindings(ndisuio);
- CloseHandle(ndisuio);
-}
-
-#else /* CONFIG_USE_NDISUIO */
-
-static void show_dev(pcap_if_t *dev)
-{
- printf("ifname: %s\ndescription: %s\n\n",
- dev->name, dev->description);
-}
-
-
-static void pcap_enum_devs(void)
-{
- pcap_if_t *devs, *dev;
- char err[PCAP_ERRBUF_SIZE + 1];
-
- if (pcap_findalldevs(&devs, err) < 0) {
- fprintf(stderr, "Error - pcap_findalldevs: %s\n", err);
- return;
- }
-
- for (dev = devs; dev; dev = dev->next) {
- show_dev(dev);
- }
-
- pcap_freealldevs(devs);
-}
-
-#endif /* CONFIG_USE_NDISUIO */
-
-
-int main(int argc, char *argv[])
-{
-#ifdef CONFIG_USE_NDISUIO
- ndisuio_enum_bindings();
-#else /* CONFIG_USE_NDISUIO */
- pcap_enum_devs();
-#endif /* CONFIG_USE_NDISUIO */
-
- return 0;
-}
diff --git a/wpa_supplicant/wmm_ac.c b/wpa_supplicant/wmm_ac.c
deleted file mode 100644
index d0fdd55d30fc..000000000000
--- a/wpa_supplicant/wmm_ac.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * Wi-Fi Multimedia Admission Control (WMM-AC)
- * Copyright(c) 2014, Intel Mobile Communication GmbH.
- * Copyright(c) 2014, Intel Corporation. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "utils/common.h"
-#include "utils/list.h"
-#include "utils/eloop.h"
-#include "common/ieee802_11_common.h"
-#include "wpa_supplicant_i.h"
-#include "bss.h"
-#include "driver_i.h"
-#include "wmm_ac.h"
-
-static void wmm_ac_addts_req_timeout(void *eloop_ctx, void *timeout_ctx);
-
-static const enum wmm_ac up_to_ac[8] = {
- WMM_AC_BK,
- WMM_AC_BE,
- WMM_AC_BE,
- WMM_AC_BK,
- WMM_AC_VI,
- WMM_AC_VI,
- WMM_AC_VO,
- WMM_AC_VO
-};
-
-
-static inline u8 wmm_ac_get_tsid(const struct wmm_tspec_element *tspec)
-{
- return (tspec->ts_info[0] >> 1) & 0x0f;
-}
-
-
-static u8 wmm_ac_get_direction(const struct wmm_tspec_element *tspec)
-{
- return (tspec->ts_info[0] >> 5) & 0x03;
-}
-
-
-static u8 wmm_ac_get_user_priority(const struct wmm_tspec_element *tspec)
-{
- return (tspec->ts_info[1] >> 3) & 0x07;
-}
-
-
-static u8 wmm_ac_direction_to_idx(u8 direction)
-{
- switch (direction) {
- case WMM_AC_DIR_UPLINK:
- return TS_DIR_IDX_UPLINK;
- case WMM_AC_DIR_DOWNLINK:
- return TS_DIR_IDX_DOWNLINK;
- case WMM_AC_DIR_BIDIRECTIONAL:
- return TS_DIR_IDX_BIDI;
- default:
- wpa_printf(MSG_ERROR, "Invalid direction: %d", direction);
- return WMM_AC_DIR_UPLINK;
- }
-}
-
-
-static int wmm_ac_add_ts(struct wpa_supplicant *wpa_s, const u8 *addr,
- const struct wmm_tspec_element *tspec)
-{
- struct wmm_tspec_element *_tspec;
- int ret;
- u16 admitted_time = le_to_host16(tspec->medium_time);
- u8 up = wmm_ac_get_user_priority(tspec);
- u8 ac = up_to_ac[up];
- u8 dir = wmm_ac_get_direction(tspec);
- u8 tsid = wmm_ac_get_tsid(tspec);
- enum ts_dir_idx idx = wmm_ac_direction_to_idx(dir);
-
- /* should have been verified before, but double-check here */
- if (wpa_s->tspecs[ac][idx]) {
- wpa_printf(MSG_ERROR,
- "WMM AC: tspec (ac=%d, dir=%d) already exists!",
- ac, dir);
- return -1;
- }
-
- /* copy tspec */
- _tspec = os_memdup(tspec, sizeof(*_tspec));
- if (!_tspec)
- return -1;
-
- if (dir != WMM_AC_DIR_DOWNLINK) {
- ret = wpa_drv_add_ts(wpa_s, tsid, addr, up, admitted_time);
- wpa_printf(MSG_DEBUG,
- "WMM AC: Add TS: addr=" MACSTR
- " TSID=%u admitted time=%u, ret=%d",
- MAC2STR(addr), tsid, admitted_time, ret);
- if (ret < 0) {
- os_free(_tspec);
- return -1;
- }
- }
-
- wpa_s->tspecs[ac][idx] = _tspec;
-
- wpa_printf(MSG_DEBUG, "Traffic stream was created successfully");
-
- wpa_msg(wpa_s, MSG_INFO, WMM_AC_EVENT_TSPEC_ADDED
- "tsid=%d addr=" MACSTR " admitted_time=%d",
- tsid, MAC2STR(addr), admitted_time);
-
- return 0;
-}
-
-
-static void wmm_ac_del_ts_idx(struct wpa_supplicant *wpa_s, u8 ac,
- enum ts_dir_idx dir)
-{
- struct wmm_tspec_element *tspec = wpa_s->tspecs[ac][dir];
- u8 tsid;
-
- if (!tspec)
- return;
-
- tsid = wmm_ac_get_tsid(tspec);
- wpa_printf(MSG_DEBUG, "WMM AC: Del TS ac=%d tsid=%d", ac, tsid);
-
- /* update the driver in case of uplink/bidi */
- if (wmm_ac_get_direction(tspec) != WMM_AC_DIR_DOWNLINK)
- wpa_drv_del_ts(wpa_s, tsid, wpa_s->bssid);
-
- wpa_msg(wpa_s, MSG_INFO, WMM_AC_EVENT_TSPEC_REMOVED
- "tsid=%d addr=" MACSTR, tsid, MAC2STR(wpa_s->bssid));
-
- os_free(wpa_s->tspecs[ac][dir]);
- wpa_s->tspecs[ac][dir] = NULL;
-}
-
-
-static void wmm_ac_del_req(struct wpa_supplicant *wpa_s, int failed)
-{
- struct wmm_ac_addts_request *req = wpa_s->addts_request;
-
- if (!req)
- return;
-
- if (failed)
- wpa_msg(wpa_s, MSG_INFO, WMM_AC_EVENT_TSPEC_REQ_FAILED
- "tsid=%u", wmm_ac_get_tsid(&req->tspec));
-
- eloop_cancel_timeout(wmm_ac_addts_req_timeout, wpa_s, req);
- wpa_s->addts_request = NULL;
- os_free(req);
-}
-
-
-static void wmm_ac_addts_req_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wmm_ac_addts_request *addts_req = timeout_ctx;
-
- wpa_printf(MSG_DEBUG,
- "Timeout getting ADDTS response (tsid=%d up=%d)",
- wmm_ac_get_tsid(&addts_req->tspec),
- wmm_ac_get_user_priority(&addts_req->tspec));
-
- wmm_ac_del_req(wpa_s, 1);
-}
-
-
-static int wmm_ac_send_addts_request(struct wpa_supplicant *wpa_s,
- const struct wmm_ac_addts_request *req)
-{
- struct wpabuf *buf;
- int ret;
-
- wpa_printf(MSG_DEBUG, "Sending ADDTS Request to " MACSTR,
- MAC2STR(req->address));
-
- /* category + action code + dialog token + status + sizeof(tspec) */
- buf = wpabuf_alloc(4 + sizeof(req->tspec));
- if (!buf) {
- wpa_printf(MSG_ERROR, "WMM AC: Allocation error");
- return -1;
- }
-
- wpabuf_put_u8(buf, WLAN_ACTION_WMM);
- wpabuf_put_u8(buf, WMM_ACTION_CODE_ADDTS_REQ);
- wpabuf_put_u8(buf, req->dialog_token);
- wpabuf_put_u8(buf, 0); /* status code */
- wpabuf_put_data(buf, &req->tspec, sizeof(req->tspec));
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, req->address,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret) {
- wpa_printf(MSG_WARNING,
- "WMM AC: Failed to send ADDTS Request");
- }
-
- wpabuf_free(buf);
- return ret;
-}
-
-
-static int wmm_ac_send_delts(struct wpa_supplicant *wpa_s,
- const struct wmm_tspec_element *tspec,
- const u8 *address)
-{
- struct wpabuf *buf;
- int ret;
-
- /* category + action code + dialog token + status + sizeof(tspec) */
- buf = wpabuf_alloc(4 + sizeof(*tspec));
- if (!buf)
- return -1;
-
- wpa_printf(MSG_DEBUG, "Sending DELTS to " MACSTR, MAC2STR(address));
-
- /* category + action code + dialog token + status + sizeof(tspec) */
- wpabuf_put_u8(buf, WLAN_ACTION_WMM);
- wpabuf_put_u8(buf, WMM_ACTION_CODE_DELTS);
- wpabuf_put_u8(buf, 0); /* Dialog Token (not used) */
- wpabuf_put_u8(buf, 0); /* Status Code (not used) */
- wpabuf_put_data(buf, tspec, sizeof(*tspec));
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, address,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(buf), wpabuf_len(buf), 0);
- if (ret)
- wpa_printf(MSG_WARNING, "Failed to send DELTS frame");
-
- wpabuf_free(buf);
- return ret;
-}
-
-
-/* return the AC using the given TSPEC tid */
-static int wmm_ac_find_tsid(struct wpa_supplicant *wpa_s, u8 tsid,
- enum ts_dir_idx *dir)
-{
- int ac;
- enum ts_dir_idx idx;
-
- for (ac = 0; ac < WMM_AC_NUM; ac++) {
- for (idx = 0; idx < TS_DIR_IDX_COUNT; idx++) {
- if (wpa_s->tspecs[ac][idx] &&
- wmm_ac_get_tsid(wpa_s->tspecs[ac][idx]) == tsid) {
- if (dir)
- *dir = idx;
- return ac;
- }
- }
- }
-
- return -1;
-}
-
-
-static struct wmm_ac_addts_request *
-wmm_ac_build_addts_req(struct wpa_supplicant *wpa_s,
- const struct wmm_ac_ts_setup_params *params,
- const u8 *address)
-{
- struct wmm_ac_addts_request *addts_req;
- struct wmm_tspec_element *tspec;
- u8 ac = up_to_ac[params->user_priority];
- u8 uapsd = wpa_s->wmm_ac_assoc_info->ac_params[ac].uapsd;
-
- addts_req = os_zalloc(sizeof(*addts_req));
- if (!addts_req)
- return NULL;
-
- tspec = &addts_req->tspec;
- os_memcpy(addts_req->address, address, ETH_ALEN);
-
- /* The dialog token cannot be zero */
- if (++wpa_s->wmm_ac_last_dialog_token == 0)
- wpa_s->wmm_ac_last_dialog_token++;
-
- addts_req->dialog_token = wpa_s->wmm_ac_last_dialog_token;
- tspec->eid = WLAN_EID_VENDOR_SPECIFIC;
- tspec->length = sizeof(*tspec) - 2; /* reduce eid and length */
- tspec->oui[0] = 0x00;
- tspec->oui[1] = 0x50;
- tspec->oui[2] = 0xf2;
- tspec->oui_type = WMM_OUI_TYPE;
- tspec->oui_subtype = WMM_OUI_SUBTYPE_TSPEC_ELEMENT;
- tspec->version = WMM_VERSION;
-
- tspec->ts_info[0] = params->tsid << 1;
- tspec->ts_info[0] |= params->direction << 5;
- tspec->ts_info[0] |= WMM_AC_ACCESS_POLICY_EDCA << 7;
- tspec->ts_info[1] = uapsd << 2;
- tspec->ts_info[1] |= params->user_priority << 3;
- tspec->ts_info[2] = 0;
-
- tspec->nominal_msdu_size = host_to_le16(params->nominal_msdu_size);
- if (params->fixed_nominal_msdu)
- tspec->nominal_msdu_size |=
- host_to_le16(WMM_AC_FIXED_MSDU_SIZE);
-
- tspec->mean_data_rate = host_to_le32(params->mean_data_rate);
- tspec->minimum_phy_rate = host_to_le32(params->minimum_phy_rate);
- tspec->surplus_bandwidth_allowance =
- host_to_le16(params->surplus_bandwidth_allowance);
-
- return addts_req;
-}
-
-
-static int param_in_range(const char *name, long value,
- long min_val, long max_val)
-{
- if (value < min_val || (max_val >= 0 && value > max_val)) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: param %s (%ld) is out of range (%ld-%ld)",
- name, value, min_val, max_val);
- return 0;
- }
-
- return 1;
-}
-
-
-static int wmm_ac_should_replace_ts(struct wpa_supplicant *wpa_s,
- u8 tsid, u8 ac, u8 dir)
-{
- enum ts_dir_idx idx;
- int cur_ac, existing_ts = 0, replace_ts = 0;
-
- cur_ac = wmm_ac_find_tsid(wpa_s, tsid, &idx);
- if (cur_ac >= 0) {
- if (cur_ac != ac) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: TSID %i already exists on different ac (%d)",
- tsid, cur_ac);
- return -1;
- }
-
- /* same tsid - this tspec will replace the current one */
- replace_ts |= BIT(idx);
- }
-
- for (idx = 0; idx < TS_DIR_IDX_COUNT; idx++) {
- if (wpa_s->tspecs[ac][idx])
- existing_ts |= BIT(idx);
- }
-
- switch (dir) {
- case WMM_AC_DIR_UPLINK:
- /* replace existing uplink/bidi tspecs */
- replace_ts |= existing_ts & (BIT(TS_DIR_IDX_UPLINK) |
- BIT(TS_DIR_IDX_BIDI));
- break;
- case WMM_AC_DIR_DOWNLINK:
- /* replace existing downlink/bidi tspecs */
- replace_ts |= existing_ts & (BIT(TS_DIR_IDX_DOWNLINK) |
- BIT(TS_DIR_IDX_BIDI));
- break;
- case WMM_AC_DIR_BIDIRECTIONAL:
- /* replace all existing tspecs */
- replace_ts |= existing_ts;
- break;
- default:
- return -1;
- }
-
- return replace_ts;
-}
-
-
-static int wmm_ac_ts_req_is_valid(struct wpa_supplicant *wpa_s,
- const struct wmm_ac_ts_setup_params *params)
-{
- enum wmm_ac req_ac;
-
-#define PARAM_IN_RANGE(field, min_value, max_value) \
- param_in_range(#field, params->field, min_value, max_value)
-
- if (!PARAM_IN_RANGE(tsid, 0, WMM_AC_MAX_TID) ||
- !PARAM_IN_RANGE(user_priority, 0, WMM_AC_MAX_USER_PRIORITY) ||
- !PARAM_IN_RANGE(nominal_msdu_size, 1, WMM_AC_MAX_NOMINAL_MSDU) ||
- !PARAM_IN_RANGE(mean_data_rate, 1, -1) ||
- !PARAM_IN_RANGE(minimum_phy_rate, 1, -1) ||
- !PARAM_IN_RANGE(surplus_bandwidth_allowance, WMM_AC_MIN_SBA_UNITY,
- -1))
- return 0;
-#undef PARAM_IN_RANGE
-
- if (!(params->direction == WMM_TSPEC_DIRECTION_UPLINK ||
- params->direction == WMM_TSPEC_DIRECTION_DOWNLINK ||
- params->direction == WMM_TSPEC_DIRECTION_BI_DIRECTIONAL)) {
- wpa_printf(MSG_DEBUG, "WMM AC: invalid TS direction: %d",
- params->direction);
- return 0;
- }
-
- req_ac = up_to_ac[params->user_priority];
-
- /* Requested access category must have acm */
- if (!wpa_s->wmm_ac_assoc_info->ac_params[req_ac].acm) {
- wpa_printf(MSG_DEBUG, "WMM AC: AC %d is not ACM", req_ac);
- return 0;
- }
-
- if (wmm_ac_should_replace_ts(wpa_s, params->tsid, req_ac,
- params->direction) < 0)
- return 0;
-
- return 1;
-}
-
-
-static struct wmm_ac_assoc_data *
-wmm_ac_process_param_elem(struct wpa_supplicant *wpa_s, const u8 *ies,
- size_t ies_len)
-{
- struct ieee802_11_elems elems;
- struct wmm_parameter_element *wmm_params;
- struct wmm_ac_assoc_data *assoc_data;
- int i;
-
- /* Parsing WMM Parameter Element */
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
- wpa_printf(MSG_DEBUG, "WMM AC: could not parse assoc ies");
- return NULL;
- }
-
- if (!elems.wmm) {
- wpa_printf(MSG_DEBUG, "WMM AC: No WMM IE");
- return NULL;
- }
-
- if (elems.wmm_len != sizeof(*wmm_params)) {
- wpa_printf(MSG_DEBUG, "WMM AC: Invalid WMM ie length");
- return NULL;
- }
-
- wmm_params = (struct wmm_parameter_element *)(elems.wmm);
-
- assoc_data = os_zalloc(sizeof(*assoc_data));
- if (!assoc_data)
- return NULL;
-
- for (i = 0; i < WMM_AC_NUM; i++)
- assoc_data->ac_params[i].acm =
- !!(wmm_params->ac[i].aci_aifsn & WMM_AC_ACM);
-
- wpa_printf(MSG_DEBUG,
- "WMM AC: AC mandatory: AC_BE=%u AC_BK=%u AC_VI=%u AC_VO=%u",
- assoc_data->ac_params[WMM_AC_BE].acm,
- assoc_data->ac_params[WMM_AC_BK].acm,
- assoc_data->ac_params[WMM_AC_VI].acm,
- assoc_data->ac_params[WMM_AC_VO].acm);
-
- return assoc_data;
-}
-
-
-static int wmm_ac_init(struct wpa_supplicant *wpa_s, const u8 *ies,
- size_t ies_len, const struct wmm_params *wmm_params)
-{
- struct wmm_ac_assoc_data *assoc_data;
- u8 ac;
-
- if (wpa_s->wmm_ac_assoc_info) {
- wpa_printf(MSG_ERROR, "WMM AC: Already initialized");
- return -1;
- }
-
- if (!ies || !(wmm_params->info_bitmap & WMM_PARAMS_UAPSD_QUEUES_INFO)) {
- /* WMM AC not in use for this connection */
- return -1;
- }
-
- os_memset(wpa_s->tspecs, 0, sizeof(wpa_s->tspecs));
- wpa_s->wmm_ac_last_dialog_token = 0;
- wpa_s->addts_request = NULL;
-
- assoc_data = wmm_ac_process_param_elem(wpa_s, ies, ies_len);
- if (!assoc_data)
- return -1;
-
- wpa_printf(MSG_DEBUG, "WMM AC: U-APSD queues=0x%x",
- wmm_params->uapsd_queues);
-
- for (ac = 0; ac < WMM_AC_NUM; ac++) {
- assoc_data->ac_params[ac].uapsd =
- !!(wmm_params->uapsd_queues & BIT(ac));
- }
-
- wpa_s->wmm_ac_assoc_info = assoc_data;
- return 0;
-}
-
-
-static void wmm_ac_del_ts(struct wpa_supplicant *wpa_s, u8 ac, int dir_bitmap)
-{
- enum ts_dir_idx idx;
-
- for (idx = 0; idx < TS_DIR_IDX_COUNT; idx++) {
- if (!(dir_bitmap & BIT(idx)))
- continue;
-
- wmm_ac_del_ts_idx(wpa_s, ac, idx);
- }
-}
-
-
-static void wmm_ac_deinit(struct wpa_supplicant *wpa_s)
-{
- int i;
-
- for (i = 0; i < WMM_AC_NUM; i++)
- wmm_ac_del_ts(wpa_s, i, TS_DIR_IDX_ALL);
-
- /* delete pending add_ts request */
- wmm_ac_del_req(wpa_s, 1);
-
- os_free(wpa_s->wmm_ac_assoc_info);
- wpa_s->wmm_ac_assoc_info = NULL;
-}
-
-
-void wmm_ac_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *ies,
- size_t ies_len, const struct wmm_params *wmm_params)
-{
- if (wmm_ac_init(wpa_s, ies, ies_len, wmm_params))
- return;
-
- wpa_printf(MSG_DEBUG,
- "WMM AC: Valid WMM association, WMM AC is enabled");
-}
-
-
-void wmm_ac_notify_disassoc(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->wmm_ac_assoc_info)
- return;
-
- wmm_ac_deinit(wpa_s);
- wpa_printf(MSG_DEBUG, "WMM AC: WMM AC is disabled");
-}
-
-
-int wpas_wmm_ac_delts(struct wpa_supplicant *wpa_s, u8 tsid)
-{
- struct wmm_tspec_element tspec;
- int ac;
- enum ts_dir_idx dir;
-
- if (!wpa_s->wmm_ac_assoc_info) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Failed to delete TS, WMM AC is disabled");
- return -1;
- }
-
- ac = wmm_ac_find_tsid(wpa_s, tsid, &dir);
- if (ac < 0) {
- wpa_printf(MSG_DEBUG, "WMM AC: TS does not exist");
- return -1;
- }
-
- tspec = *wpa_s->tspecs[ac][dir];
-
- wmm_ac_del_ts_idx(wpa_s, ac, dir);
-
- wmm_ac_send_delts(wpa_s, &tspec, wpa_s->bssid);
-
- return 0;
-}
-
-
-int wpas_wmm_ac_addts(struct wpa_supplicant *wpa_s,
- struct wmm_ac_ts_setup_params *params)
-{
- struct wmm_ac_addts_request *addts_req;
-
- if (!wpa_s->wmm_ac_assoc_info) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Cannot add TS - missing assoc data");
- return -1;
- }
-
- if (wpa_s->addts_request) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: can't add TS - ADDTS request is already pending");
- return -1;
- }
-
- /*
- * we can setup downlink TS even without driver support.
- * however, we need driver support for the other directions.
- */
- if (params->direction != WMM_AC_DIR_DOWNLINK &&
- !wpa_s->wmm_ac_supported) {
- wpa_printf(MSG_DEBUG,
- "Cannot set uplink/bidi TS without driver support");
- return -1;
- }
-
- if (!wmm_ac_ts_req_is_valid(wpa_s, params))
- return -1;
-
- wpa_printf(MSG_DEBUG, "WMM AC: TS setup request (addr=" MACSTR
- " tsid=%u user priority=%u direction=%d)",
- MAC2STR(wpa_s->bssid), params->tsid,
- params->user_priority, params->direction);
-
- addts_req = wmm_ac_build_addts_req(wpa_s, params, wpa_s->bssid);
- if (!addts_req)
- return -1;
-
- if (wmm_ac_send_addts_request(wpa_s, addts_req))
- goto err;
-
- /* save as pending and set ADDTS resp timeout to 1 second */
- wpa_s->addts_request = addts_req;
- eloop_register_timeout(1, 0, wmm_ac_addts_req_timeout,
- wpa_s, addts_req);
- return 0;
-err:
- os_free(addts_req);
- return -1;
-}
-
-
-static void wmm_ac_handle_delts(struct wpa_supplicant *wpa_s, const u8 *sa,
- const struct wmm_tspec_element *tspec)
-{
- int ac;
- u8 tsid;
- enum ts_dir_idx idx;
-
- tsid = wmm_ac_get_tsid(tspec);
-
- wpa_printf(MSG_DEBUG,
- "WMM AC: DELTS frame has been received TSID=%u addr="
- MACSTR, tsid, MAC2STR(sa));
-
- ac = wmm_ac_find_tsid(wpa_s, tsid, &idx);
- if (ac < 0) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Ignoring DELTS frame - TSID does not exist");
- return;
- }
-
- wmm_ac_del_ts_idx(wpa_s, ac, idx);
-
- wpa_printf(MSG_DEBUG,
- "TS was deleted successfully (tsid=%u address=" MACSTR ")",
- tsid, MAC2STR(sa));
-}
-
-
-static void wmm_ac_handle_addts_resp(struct wpa_supplicant *wpa_s, const u8 *sa,
- const u8 resp_dialog_token, const u8 status_code,
- const struct wmm_tspec_element *tspec)
-{
- struct wmm_ac_addts_request *req = wpa_s->addts_request;
- u8 ac, tsid, up, dir;
- int replace_tspecs;
-
- tsid = wmm_ac_get_tsid(tspec);
- dir = wmm_ac_get_direction(tspec);
- up = wmm_ac_get_user_priority(tspec);
- ac = up_to_ac[up];
-
- /* make sure we have a matching addts request */
- if (!req || req->dialog_token != resp_dialog_token) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: no req with dialog=%u, ignoring frame",
- resp_dialog_token);
- return;
- }
-
- /* make sure the params are the same */
- if (os_memcmp(req->address, sa, ETH_ALEN) != 0 ||
- tsid != wmm_ac_get_tsid(&req->tspec) ||
- up != wmm_ac_get_user_priority(&req->tspec) ||
- dir != wmm_ac_get_direction(&req->tspec)) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: ADDTS params do not match, ignoring frame");
- return;
- }
-
- /* delete pending request */
- wmm_ac_del_req(wpa_s, 0);
-
- wpa_printf(MSG_DEBUG,
- "ADDTS response status=%d tsid=%u up=%u direction=%u",
- status_code, tsid, up, dir);
-
- if (status_code != WMM_ADDTS_STATUS_ADMISSION_ACCEPTED) {
- wpa_printf(MSG_INFO, "WMM AC: ADDTS request was rejected");
- goto err_msg;
- }
-
- replace_tspecs = wmm_ac_should_replace_ts(wpa_s, tsid, ac, dir);
- if (replace_tspecs < 0)
- goto err_delts;
-
- wpa_printf(MSG_DEBUG, "ts idx replace bitmap: 0x%x", replace_tspecs);
-
- /* when replacing tspecs - delete first */
- wmm_ac_del_ts(wpa_s, ac, replace_tspecs);
-
- /* Creating a new traffic stream */
- wpa_printf(MSG_DEBUG,
- "WMM AC: adding a new TS with TSID=%u address="MACSTR
- " medium time=%u access category=%d dir=%d ",
- tsid, MAC2STR(sa),
- le_to_host16(tspec->medium_time), ac, dir);
-
- if (wmm_ac_add_ts(wpa_s, sa, tspec))
- goto err_delts;
-
- return;
-
-err_delts:
- /* ask the ap to delete the tspec */
- wmm_ac_send_delts(wpa_s, tspec, sa);
-err_msg:
- wpa_msg(wpa_s, MSG_INFO, WMM_AC_EVENT_TSPEC_REQ_FAILED "tsid=%u",
- tsid);
-}
-
-
-void wmm_ac_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
- const u8 *sa, const u8 *data, size_t len)
-{
- u8 action;
- u8 dialog_token;
- u8 status_code;
- struct ieee802_11_elems elems;
- struct wmm_tspec_element *tspec;
-
- if (wpa_s->wmm_ac_assoc_info == NULL) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: WMM AC is disabled, ignoring action frame");
- return;
- }
-
- action = data[0];
-
- if (action != WMM_ACTION_CODE_ADDTS_RESP &&
- action != WMM_ACTION_CODE_DELTS) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Unknown action (%d), ignoring action frame",
- action);
- return;
- }
-
- /* WMM AC action frame */
- if (os_memcmp(da, wpa_s->own_addr, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "WMM AC: frame destination addr="MACSTR
- " is other than ours, ignoring frame", MAC2STR(da));
- return;
- }
-
- if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "WMM AC: ignore frame with sa " MACSTR
- " different other than our bssid", MAC2STR(da));
- return;
- }
-
- if (len < 2 + sizeof(struct wmm_tspec_element)) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Short ADDTS response ignored (len=%lu)",
- (unsigned long) len);
- return;
- }
-
- data++;
- len--;
- dialog_token = data[0];
- status_code = data[1];
-
- if (ieee802_11_parse_elems(data + 2, len - 2, &elems, 1) != ParseOK) {
- wpa_printf(MSG_DEBUG,
- "WMM AC: Could not parse WMM AC action from " MACSTR,
- MAC2STR(sa));
- return;
- }
-
- /* the struct also contains the type and value, so decrease it */
- if (elems.wmm_tspec_len != sizeof(struct wmm_tspec_element) - 2) {
- wpa_printf(MSG_DEBUG, "WMM AC: missing or wrong length TSPEC");
- return;
- }
-
- tspec = (struct wmm_tspec_element *)(elems.wmm_tspec - 2);
-
- wpa_printf(MSG_DEBUG, "WMM AC: RX WMM AC Action from " MACSTR,
- MAC2STR(sa));
- wpa_hexdump(MSG_MSGDUMP, "WMM AC: WMM AC Action content", data, len);
-
- switch (action) {
- case WMM_ACTION_CODE_ADDTS_RESP:
- wmm_ac_handle_addts_resp(wpa_s, sa, dialog_token, status_code,
- tspec);
- break;
- case WMM_ACTION_CODE_DELTS:
- wmm_ac_handle_delts(wpa_s, sa, tspec);
- break;
- default:
- break;
- }
-}
-
-
-static const char * get_ac_str(u8 ac)
-{
- switch (ac) {
- case WMM_AC_BE:
- return "BE";
- case WMM_AC_BK:
- return "BK";
- case WMM_AC_VI:
- return "VI";
- case WMM_AC_VO:
- return "VO";
- default:
- return "N/A";
- }
-}
-
-
-static const char * get_direction_str(u8 direction)
-{
- switch (direction) {
- case WMM_AC_DIR_DOWNLINK:
- return "Downlink";
- case WMM_AC_DIR_UPLINK:
- return "Uplink";
- case WMM_AC_DIR_BIDIRECTIONAL:
- return "Bi-directional";
- default:
- return "N/A";
- }
-}
-
-
-int wpas_wmm_ac_status(struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
-{
- struct wmm_ac_assoc_data *assoc_info = wpa_s->wmm_ac_assoc_info;
- enum ts_dir_idx idx;
- int pos = 0;
- u8 ac, up;
-
- if (!assoc_info) {
- return wpa_scnprintf(buf, buflen - pos,
- "Not associated to a WMM AP, WMM AC is Disabled\n");
- }
-
- pos += wpa_scnprintf(buf + pos, buflen - pos, "WMM AC is Enabled\n");
-
- for (ac = 0; ac < WMM_AC_NUM; ac++) {
- int ts_count = 0;
-
- pos += wpa_scnprintf(buf + pos, buflen - pos,
- "%s: acm=%d uapsd=%d\n",
- get_ac_str(ac),
- assoc_info->ac_params[ac].acm,
- assoc_info->ac_params[ac].uapsd);
-
- for (idx = 0; idx < TS_DIR_IDX_COUNT; idx++) {
- struct wmm_tspec_element *tspec;
- u8 dir, tsid;
- const char *dir_str;
-
- tspec = wpa_s->tspecs[ac][idx];
- if (!tspec)
- continue;
-
- ts_count++;
-
- dir = wmm_ac_get_direction(tspec);
- dir_str = get_direction_str(dir);
- tsid = wmm_ac_get_tsid(tspec);
- up = wmm_ac_get_user_priority(tspec);
-
- pos += wpa_scnprintf(buf + pos, buflen - pos,
- "\tTSID=%u UP=%u\n"
- "\tAddress = "MACSTR"\n"
- "\tWMM AC dir = %s\n"
- "\tTotal admitted time = %u\n\n",
- tsid, up,
- MAC2STR(wpa_s->bssid),
- dir_str,
- le_to_host16(tspec->medium_time));
- }
-
- if (!ts_count) {
- pos += wpa_scnprintf(buf + pos, buflen - pos,
- "\t(No Traffic Stream)\n\n");
- }
- }
-
- return pos;
-}
-
-
-static u8 wmm_ac_get_tspecs_count(struct wpa_supplicant *wpa_s)
-{
- int ac, dir, tspecs_count = 0;
-
- for (ac = 0; ac < WMM_AC_NUM; ac++) {
- for (dir = 0; dir < TS_DIR_IDX_COUNT; dir++) {
- if (wpa_s->tspecs[ac][dir])
- tspecs_count++;
- }
- }
-
- return tspecs_count;
-}
-
-
-void wmm_ac_save_tspecs(struct wpa_supplicant *wpa_s)
-{
- int ac, dir, tspecs_count;
-
- wpa_printf(MSG_DEBUG, "WMM AC: Save last configured tspecs");
-
- if (!wpa_s->wmm_ac_assoc_info)
- return;
-
- tspecs_count = wmm_ac_get_tspecs_count(wpa_s);
- if (!tspecs_count) {
- wpa_printf(MSG_DEBUG, "WMM AC: No configured TSPECs");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "WMM AC: Saving tspecs");
-
- wmm_ac_clear_saved_tspecs(wpa_s);
- wpa_s->last_tspecs = os_calloc(tspecs_count,
- sizeof(*wpa_s->last_tspecs));
- if (!wpa_s->last_tspecs) {
- wpa_printf(MSG_ERROR, "WMM AC: Failed to save tspecs!");
- return;
- }
-
- for (ac = 0; ac < WMM_AC_NUM; ac++) {
- for (dir = 0; dir < TS_DIR_IDX_COUNT; dir++) {
- if (!wpa_s->tspecs[ac][dir])
- continue;
-
- wpa_s->last_tspecs[wpa_s->last_tspecs_count++] =
- *wpa_s->tspecs[ac][dir];
- }
- }
-
- wpa_printf(MSG_DEBUG, "WMM AC: Successfully saved %d TSPECs",
- wpa_s->last_tspecs_count);
-}
-
-
-void wmm_ac_clear_saved_tspecs(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->last_tspecs) {
- wpa_printf(MSG_DEBUG, "WMM AC: Clear saved tspecs");
- os_free(wpa_s->last_tspecs);
- wpa_s->last_tspecs = NULL;
- wpa_s->last_tspecs_count = 0;
- }
-}
-
-
-int wmm_ac_restore_tspecs(struct wpa_supplicant *wpa_s)
-{
- unsigned int i;
-
- if (!wpa_s->wmm_ac_assoc_info || !wpa_s->last_tspecs_count)
- return 0;
-
- wpa_printf(MSG_DEBUG, "WMM AC: Restore %u saved tspecs",
- wpa_s->last_tspecs_count);
-
- for (i = 0; i < wpa_s->last_tspecs_count; i++)
- wmm_ac_add_ts(wpa_s, wpa_s->bssid, &wpa_s->last_tspecs[i]);
-
- return 0;
-}
diff --git a/wpa_supplicant/wmm_ac.h b/wpa_supplicant/wmm_ac.h
deleted file mode 100644
index 0d15ad01cc58..000000000000
--- a/wpa_supplicant/wmm_ac.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Wi-Fi Multimedia Admission Control (WMM-AC)
- * Copyright(c) 2014, Intel Mobile Communication GmbH.
- * Copyright(c) 2014, Intel Corporation. All rights reserved.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WMM_AC_H
-#define WMM_AC_H
-
-#include "common/ieee802_11_defs.h"
-#include "drivers/driver.h"
-
-struct wpa_supplicant;
-
-#define WMM_AC_ACCESS_POLICY_EDCA 1
-#define WMM_AC_FIXED_MSDU_SIZE BIT(15)
-
-#define WMM_AC_MAX_TID 7
-#define WMM_AC_MAX_USER_PRIORITY 7
-#define WMM_AC_MIN_SBA_UNITY 0x2000
-#define WMM_AC_MAX_NOMINAL_MSDU 32767
-
-/**
- * struct wmm_ac_assoc_data - WMM Admission Control Association Data
- *
- * This struct will store any relevant WMM association data needed by WMM AC.
- * In case there is a valid WMM association, an instance of this struct will be
- * created. In case there is no instance of this struct, the station is not
- * associated to a valid WMM BSS and hence, WMM AC will not be used.
- */
-struct wmm_ac_assoc_data {
- struct {
- /*
- * acm - Admission Control Mandatory
- * In case an access category is ACM, the traffic will have
- * to be admitted by WMM-AC's admission mechanism before use.
- */
- unsigned int acm:1;
-
- /*
- * uapsd_queues - Unscheduled Automatic Power Save Delivery
- * queues.
- * Indicates whether ACs are configured for U-APSD (or legacy
- * PS). Storing this value is necessary in order to set the
- * Power Save Bit (PSB) in ADDTS request Action frames (if not
- * given).
- */
- unsigned int uapsd:1;
- } ac_params[WMM_AC_NUM];
-};
-
-/**
- * wmm_ac_dir - WMM Admission Control Direction
- */
-enum wmm_ac_dir {
- WMM_AC_DIR_UPLINK = 0,
- WMM_AC_DIR_DOWNLINK = 1,
- WMM_AC_DIR_BIDIRECTIONAL = 3
-};
-
-/**
- * ts_dir_idx - indices of internally saved tspecs
- *
- * we can have multiple tspecs (downlink + uplink) per ac.
- * save them in array, and use the enum to directly access
- * the respective tspec slot (according to the direction).
- */
-enum ts_dir_idx {
- TS_DIR_IDX_UPLINK,
- TS_DIR_IDX_DOWNLINK,
- TS_DIR_IDX_BIDI,
-
- TS_DIR_IDX_COUNT
-};
-#define TS_DIR_IDX_ALL (BIT(TS_DIR_IDX_COUNT) - 1)
-
-/**
- * struct wmm_ac_addts_request - ADDTS Request Information
- *
- * The last sent ADDTS request(s) will be saved as element(s) of this struct in
- * order to be compared with the received ADDTS response in ADDTS response
- * action frame handling and should be stored until that point.
- * In case a new traffic stream will be created/replaced/updated, only its
- * relevant traffic stream information will be stored as a wmm_ac_ts struct.
- */
-struct wmm_ac_addts_request {
- /*
- * dialog token - Used to link the received ADDTS response with this
- * saved ADDTS request when ADDTS response is being handled
- */
- u8 dialog_token;
-
- /*
- * address - The alleged traffic stream's receiver/transmitter address
- * Address and TID are used to identify the TS (TID is contained in
- * TSPEC)
- */
- u8 address[ETH_ALEN];
-
- /*
- * tspec - Traffic Stream Specification, will be used to compare the
- * sent TSPEC in ADDTS request to the received TSPEC in ADDTS response
- * and act accordingly in ADDTS response handling
- */
- struct wmm_tspec_element tspec;
-};
-
-
-/**
- * struct wmm_ac_ts_setup_params - TS setup parameters
- *
- * This struct holds parameters which should be provided
- * to wmm_ac_ts_setup in order to setup a traffic stream
- */
-struct wmm_ac_ts_setup_params {
- /*
- * tsid - Traffic ID
- * TID and address are used to identify the TS
- */
- int tsid;
-
- /*
- * direction - Traffic Stream's direction
- */
- enum wmm_ac_dir direction;
-
- /*
- * user_priority - Traffic Stream's user priority
- */
- int user_priority;
-
- /*
- * nominal_msdu_size - Nominal MAC service data unit size
- */
- int nominal_msdu_size;
-
- /*
- * fixed_nominal_msdu - Whether the size is fixed
- * 0 = Nominal MSDU size is not fixed
- * 1 = Nominal MSDU size is fixed
- */
- int fixed_nominal_msdu;
-
- /*
- * surplus_bandwidth_allowance - Specifies excess time allocation
- */
- int mean_data_rate;
-
- /*
- * minimum_phy_rate - Specifies the minimum supported PHY rate in bps
- */
- int minimum_phy_rate;
-
- /*
- * surplus_bandwidth_allowance - Specifies excess time allocation
- */
- int surplus_bandwidth_allowance;
-};
-
-void wmm_ac_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *ies,
- size_t ies_len, const struct wmm_params *wmm_params);
-void wmm_ac_notify_disassoc(struct wpa_supplicant *wpa_s);
-int wpas_wmm_ac_addts(struct wpa_supplicant *wpa_s,
- struct wmm_ac_ts_setup_params *params);
-int wpas_wmm_ac_delts(struct wpa_supplicant *wpa_s, u8 tsid);
-void wmm_ac_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
- const u8 *sa, const u8 *data, size_t len);
-int wpas_wmm_ac_status(struct wpa_supplicant *wpa_s, char *buf, size_t buflen);
-void wmm_ac_save_tspecs(struct wpa_supplicant *wpa_s);
-void wmm_ac_clear_saved_tspecs(struct wpa_supplicant *wpa_s);
-int wmm_ac_restore_tspecs(struct wpa_supplicant *wpa_s);
-
-#endif /* WMM_AC_H */
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
deleted file mode 100644
index 8a1a44690ba5..000000000000
--- a/wpa_supplicant/wnm_sta.c
+++ /dev/null
@@ -1,1970 +0,0 @@
-/*
- * wpa_supplicant - WNM
- * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/wpa_ctrl.h"
-#include "common/ocv.h"
-#include "rsn_supp/wpa.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "scan.h"
-#include "ctrl_iface.h"
-#include "bss.h"
-#include "wnm_sta.h"
-#include "notify.h"
-#include "hs20_supplicant.h"
-
-#define MAX_TFS_IE_LEN 1024
-#define WNM_MAX_NEIGHBOR_REPORT 10
-
-#define WNM_SCAN_RESULT_AGE 2 /* 2 seconds */
-
-/* get the TFS IE from driver */
-static int ieee80211_11_get_tfs_ie(struct wpa_supplicant *wpa_s, u8 *buf,
- u16 *buf_len, enum wnm_oper oper)
-{
- wpa_printf(MSG_DEBUG, "%s: TFS get operation %d", __func__, oper);
-
- return wpa_drv_wnm_oper(wpa_s, oper, wpa_s->bssid, buf, buf_len);
-}
-
-
-/* set the TFS IE to driver */
-static int ieee80211_11_set_tfs_ie(struct wpa_supplicant *wpa_s,
- const u8 *addr, const u8 *buf, u16 buf_len,
- enum wnm_oper oper)
-{
- u16 len = buf_len;
-
- wpa_printf(MSG_DEBUG, "%s: TFS set operation %d", __func__, oper);
-
- return wpa_drv_wnm_oper(wpa_s, oper, addr, (u8 *) buf, &len);
-}
-
-
-/* MLME-SLEEPMODE.request */
-int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
- u8 action, u16 intval, struct wpabuf *tfs_req)
-{
- struct ieee80211_mgmt *mgmt;
- int res;
- size_t len;
- struct wnm_sleep_element *wnmsleep_ie;
- u8 *wnmtfs_ie, *oci_ie;
- u8 wnmsleep_ie_len, oci_ie_len;
- u16 wnmtfs_ie_len; /* possibly multiple IE(s) */
- enum wnm_oper tfs_oper = action == 0 ? WNM_SLEEP_TFS_REQ_IE_ADD :
- WNM_SLEEP_TFS_REQ_IE_NONE;
-
- wpa_printf(MSG_DEBUG, "WNM: Request to send WNM-Sleep Mode Request "
- "action=%s to " MACSTR,
- action == 0 ? "enter" : "exit",
- MAC2STR(wpa_s->bssid));
-
- /* WNM-Sleep Mode IE */
- wnmsleep_ie_len = sizeof(struct wnm_sleep_element);
- wnmsleep_ie = os_zalloc(sizeof(struct wnm_sleep_element));
- if (wnmsleep_ie == NULL)
- return -1;
- wnmsleep_ie->eid = WLAN_EID_WNMSLEEP;
- wnmsleep_ie->len = wnmsleep_ie_len - 2;
- wnmsleep_ie->action_type = action;
- wnmsleep_ie->status = WNM_STATUS_SLEEP_ACCEPT;
- wnmsleep_ie->intval = host_to_le16(intval);
- wpa_hexdump(MSG_DEBUG, "WNM: WNM-Sleep Mode element",
- (u8 *) wnmsleep_ie, wnmsleep_ie_len);
-
- /* TFS IE(s) */
- if (tfs_req) {
- wnmtfs_ie_len = wpabuf_len(tfs_req);
- wnmtfs_ie = os_memdup(wpabuf_head(tfs_req), wnmtfs_ie_len);
- if (wnmtfs_ie == NULL) {
- os_free(wnmsleep_ie);
- return -1;
- }
- } else {
- wnmtfs_ie = os_zalloc(MAX_TFS_IE_LEN);
- if (wnmtfs_ie == NULL) {
- os_free(wnmsleep_ie);
- return -1;
- }
- if (ieee80211_11_get_tfs_ie(wpa_s, wnmtfs_ie, &wnmtfs_ie_len,
- tfs_oper)) {
- wnmtfs_ie_len = 0;
- os_free(wnmtfs_ie);
- wnmtfs_ie = NULL;
- }
- }
- wpa_hexdump(MSG_DEBUG, "WNM: TFS Request element",
- (u8 *) wnmtfs_ie, wnmtfs_ie_len);
-
- oci_ie = NULL;
- oci_ie_len = 0;
-#ifdef CONFIG_OCV
- if (action == WNM_SLEEP_MODE_EXIT && wpa_sm_ocv_enabled(wpa_s->wpa)) {
- struct wpa_channel_info ci;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_printf(MSG_WARNING,
- "Failed to get channel info for OCI element in WNM-Sleep Mode frame");
- os_free(wnmsleep_ie);
- os_free(wnmtfs_ie);
- return -1;
- }
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->oci_freq_override_wnm_sleep) {
- wpa_printf(MSG_INFO,
- "TEST: Override OCI KDE frequency %d -> %d MHz",
- ci.frequency,
- wpa_s->oci_freq_override_wnm_sleep);
- ci.frequency = wpa_s->oci_freq_override_wnm_sleep;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- oci_ie_len = OCV_OCI_EXTENDED_LEN;
- oci_ie = os_zalloc(oci_ie_len);
- if (!oci_ie) {
- wpa_printf(MSG_WARNING,
- "Failed to allocate buffer for for OCI element in WNM-Sleep Mode frame");
- os_free(wnmsleep_ie);
- os_free(wnmtfs_ie);
- return -1;
- }
-
- if (ocv_insert_extended_oci(&ci, oci_ie) < 0) {
- os_free(wnmsleep_ie);
- os_free(wnmtfs_ie);
- os_free(oci_ie);
- return -1;
- }
- }
-#endif /* CONFIG_OCV */
-
- mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len +
- oci_ie_len);
- if (mgmt == NULL) {
- wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
- "WNM-Sleep Request action frame");
- os_free(wnmsleep_ie);
- os_free(wnmtfs_ie);
- return -1;
- }
-
- os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
- os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_ACTION);
- mgmt->u.action.category = WLAN_ACTION_WNM;
- mgmt->u.action.u.wnm_sleep_req.action = WNM_SLEEP_MODE_REQ;
- mgmt->u.action.u.wnm_sleep_req.dialogtoken = 1;
- os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable, wnmsleep_ie,
- wnmsleep_ie_len);
- /* copy TFS IE here */
- if (wnmtfs_ie_len > 0) {
- os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable +
- wnmsleep_ie_len, wnmtfs_ie, wnmtfs_ie_len);
- }
-
-#ifdef CONFIG_OCV
- /* copy OCV OCI here */
- if (oci_ie_len > 0) {
- os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable +
- wnmsleep_ie_len + wnmtfs_ie_len, oci_ie, oci_ie_len);
- }
-#endif /* CONFIG_OCV */
-
- len = 1 + sizeof(mgmt->u.action.u.wnm_sleep_req) + wnmsleep_ie_len +
- wnmtfs_ie_len + oci_ie_len;
-
- res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- &mgmt->u.action.category, len, 0);
- if (res < 0)
- wpa_printf(MSG_DEBUG, "Failed to send WNM-Sleep Request "
- "(action=%d, intval=%d)", action, intval);
- else
- wpa_s->wnmsleep_used = 1;
-
- os_free(wnmsleep_ie);
- os_free(wnmtfs_ie);
- os_free(oci_ie);
- os_free(mgmt);
-
- return res;
-}
-
-
-static void wnm_sleep_mode_enter_success(struct wpa_supplicant *wpa_s,
- const u8 *tfsresp_ie_start,
- const u8 *tfsresp_ie_end)
-{
- wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_ENTER_CONFIRM,
- wpa_s->bssid, NULL, NULL);
- /* remove GTK/IGTK ?? */
-
- /* set the TFS Resp IE(s) */
- if (tfsresp_ie_start && tfsresp_ie_end &&
- tfsresp_ie_end - tfsresp_ie_start >= 0) {
- u16 tfsresp_ie_len;
- tfsresp_ie_len = (tfsresp_ie_end + tfsresp_ie_end[1] + 2) -
- tfsresp_ie_start;
- wpa_printf(MSG_DEBUG, "TFS Resp IE(s) found");
- /* pass the TFS Resp IE(s) to driver for processing */
- if (ieee80211_11_set_tfs_ie(wpa_s, wpa_s->bssid,
- tfsresp_ie_start,
- tfsresp_ie_len,
- WNM_SLEEP_TFS_RESP_IE_SET))
- wpa_printf(MSG_DEBUG, "WNM: Fail to set TFS Resp IE");
- }
-}
-
-
-static void wnm_sleep_mode_exit_success(struct wpa_supplicant *wpa_s,
- const u8 *frm, u16 key_len_total)
-{
- u8 *ptr, *end;
- u8 gtk_len;
-
- wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_EXIT_CONFIRM, wpa_s->bssid,
- NULL, NULL);
-
- /* Install GTK/IGTK */
-
- /* point to key data field */
- ptr = (u8 *) frm + 1 + 2;
- end = ptr + key_len_total;
- wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total);
-
- if (key_len_total && !wpa_sm_pmf_enabled(wpa_s->wpa)) {
- wpa_msg(wpa_s, MSG_INFO,
- "WNM: Ignore Key Data in WNM-Sleep Mode Response - PMF not enabled");
- return;
- }
-
- while (end - ptr > 1) {
- if (2 + ptr[1] > end - ptr) {
- wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element "
- "length");
- if (end > ptr) {
- wpa_hexdump(MSG_DEBUG, "WNM: Remaining data",
- ptr, end - ptr);
- }
- break;
- }
- if (*ptr == WNM_SLEEP_SUBELEM_GTK) {
- if (ptr[1] < 11 + 5) {
- wpa_printf(MSG_DEBUG, "WNM: Too short GTK "
- "subelem");
- break;
- }
- gtk_len = *(ptr + 4);
- if (ptr[1] < 11 + gtk_len ||
- gtk_len < 5 || gtk_len > 32) {
- wpa_printf(MSG_DEBUG, "WNM: Invalid GTK "
- "subelem");
- break;
- }
- wpa_wnmsleep_install_key(
- wpa_s->wpa,
- WNM_SLEEP_SUBELEM_GTK,
- ptr);
- ptr += 13 + gtk_len;
- } else if (*ptr == WNM_SLEEP_SUBELEM_IGTK) {
- if (ptr[1] < 2 + 6 + WPA_IGTK_LEN) {
- wpa_printf(MSG_DEBUG, "WNM: Too short IGTK "
- "subelem");
- break;
- }
- wpa_wnmsleep_install_key(wpa_s->wpa,
- WNM_SLEEP_SUBELEM_IGTK, ptr);
- ptr += 10 + WPA_IGTK_LEN;
- } else if (*ptr == WNM_SLEEP_SUBELEM_BIGTK) {
- if (ptr[1] < 2 + 6 + WPA_BIGTK_LEN) {
- wpa_printf(MSG_DEBUG,
- "WNM: Too short BIGTK subelem");
- break;
- }
- wpa_wnmsleep_install_key(wpa_s->wpa,
- WNM_SLEEP_SUBELEM_BIGTK, ptr);
- ptr += 10 + WPA_BIGTK_LEN;
- } else
- break; /* skip the loop */
- }
-}
-
-
-static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
- const u8 *frm, int len)
-{
- /*
- * Action [1] | Dialog Token [1] | Key Data Len [2] | Key Data |
- * WNM-Sleep Mode IE | TFS Response IE
- */
- const u8 *pos = frm; /* point to payload after the action field */
- u16 key_len_total;
- struct wnm_sleep_element *wnmsleep_ie = NULL;
- /* multiple TFS Resp IE (assuming consecutive) */
- const u8 *tfsresp_ie_start = NULL;
- const u8 *tfsresp_ie_end = NULL;
-#ifdef CONFIG_OCV
- const u8 *oci_ie = NULL;
- u8 oci_ie_len = 0;
-#endif /* CONFIG_OCV */
- size_t left;
-
- if (!wpa_s->wnmsleep_used) {
- wpa_printf(MSG_DEBUG,
- "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested");
- return;
- }
-
- if (len < 3)
- return;
- key_len_total = WPA_GET_LE16(frm + 1);
-
- wpa_printf(MSG_DEBUG, "WNM-Sleep Mode Response token=%u key_len_total=%d",
- frm[0], key_len_total);
- left = len - 3;
- if (key_len_total > left) {
- wpa_printf(MSG_INFO, "WNM: Too short frame for Key Data field");
- return;
- }
- pos += 3 + key_len_total;
- while (pos - frm + 1 < len) {
- u8 ie_len = *(pos + 1);
- if (2 + ie_len > frm + len - pos) {
- wpa_printf(MSG_INFO, "WNM: Invalid IE len %u", ie_len);
- break;
- }
- wpa_hexdump(MSG_DEBUG, "WNM: Element", pos, 2 + ie_len);
- if (*pos == WLAN_EID_WNMSLEEP && ie_len >= 4)
- wnmsleep_ie = (struct wnm_sleep_element *) pos;
- else if (*pos == WLAN_EID_TFS_RESP) {
- if (!tfsresp_ie_start)
- tfsresp_ie_start = pos;
- tfsresp_ie_end = pos;
-#ifdef CONFIG_OCV
- } else if (*pos == WLAN_EID_EXTENSION && ie_len >= 1 &&
- pos[2] == WLAN_EID_EXT_OCV_OCI) {
- oci_ie = pos + 3;
- oci_ie_len = ie_len - 1;
-#endif /* CONFIG_OCV */
- } else
- wpa_printf(MSG_DEBUG, "EID %d not recognized", *pos);
- pos += ie_len + 2;
- }
-
- if (!wnmsleep_ie) {
- wpa_printf(MSG_DEBUG, "No WNM-Sleep IE found");
- return;
- }
-
-#ifdef CONFIG_OCV
- if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_EXIT &&
- wpa_sm_ocv_enabled(wpa_s->wpa)) {
- struct wpa_channel_info ci;
-
- if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
- wpa_msg(wpa_s, MSG_WARNING,
- "Failed to get channel info to validate received OCI in WNM-Sleep Mode frame");
- return;
- }
-
- if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci,
- channel_width_to_int(ci.chanwidth),
- ci.seg1_idx) != OCI_SUCCESS) {
- wpa_msg(wpa_s, MSG_WARNING, "WNM: OCV failed: %s",
- ocv_errorstr);
- return;
- }
- }
-#endif /* CONFIG_OCV */
-
- wpa_s->wnmsleep_used = 0;
-
- if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT ||
- wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) {
- wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response "
- "frame (action=%d, intval=%d)",
- wnmsleep_ie->action_type, wnmsleep_ie->intval);
- if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_ENTER) {
- wnm_sleep_mode_enter_success(wpa_s, tfsresp_ie_start,
- tfsresp_ie_end);
- } else if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_EXIT) {
- wnm_sleep_mode_exit_success(wpa_s, frm, key_len_total);
- }
- } else {
- wpa_printf(MSG_DEBUG, "Reject recv WNM-Sleep Response frame "
- "(action=%d, intval=%d)",
- wnmsleep_ie->action_type, wnmsleep_ie->intval);
- if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_ENTER)
- wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_ENTER_FAIL,
- wpa_s->bssid, NULL, NULL);
- else if (wnmsleep_ie->action_type == WNM_SLEEP_MODE_EXIT)
- wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_EXIT_FAIL,
- wpa_s->bssid, NULL, NULL);
- }
-}
-
-
-void wnm_deallocate_memory(struct wpa_supplicant *wpa_s)
-{
- int i;
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- os_free(wpa_s->wnm_neighbor_report_elements[i].meas_pilot);
- os_free(wpa_s->wnm_neighbor_report_elements[i].mul_bssid);
- }
-
- wpa_s->wnm_num_neighbor_report = 0;
- os_free(wpa_s->wnm_neighbor_report_elements);
- wpa_s->wnm_neighbor_report_elements = NULL;
-
- wpabuf_free(wpa_s->coloc_intf_elems);
- wpa_s->coloc_intf_elems = NULL;
-}
-
-
-static void wnm_parse_neighbor_report_elem(struct neighbor_report *rep,
- u8 id, u8 elen, const u8 *pos)
-{
- switch (id) {
- case WNM_NEIGHBOR_TSF:
- if (elen < 2 + 2) {
- wpa_printf(MSG_DEBUG, "WNM: Too short TSF");
- break;
- }
- rep->tsf_offset = WPA_GET_LE16(pos);
- rep->beacon_int = WPA_GET_LE16(pos + 2);
- rep->tsf_present = 1;
- break;
- case WNM_NEIGHBOR_CONDENSED_COUNTRY_STRING:
- if (elen < 2) {
- wpa_printf(MSG_DEBUG, "WNM: Too short condensed "
- "country string");
- break;
- }
- os_memcpy(rep->country, pos, 2);
- rep->country_present = 1;
- break;
- case WNM_NEIGHBOR_BSS_TRANSITION_CANDIDATE:
- if (elen < 1) {
- wpa_printf(MSG_DEBUG, "WNM: Too short BSS transition "
- "candidate");
- break;
- }
- rep->preference = pos[0];
- rep->preference_present = 1;
- break;
- case WNM_NEIGHBOR_BSS_TERMINATION_DURATION:
- if (elen < 10) {
- wpa_printf(MSG_DEBUG,
- "WNM: Too short BSS termination duration");
- break;
- }
- rep->bss_term_tsf = WPA_GET_LE64(pos);
- rep->bss_term_dur = WPA_GET_LE16(pos + 8);
- rep->bss_term_present = 1;
- break;
- case WNM_NEIGHBOR_BEARING:
- if (elen < 8) {
- wpa_printf(MSG_DEBUG, "WNM: Too short neighbor "
- "bearing");
- break;
- }
- rep->bearing = WPA_GET_LE16(pos);
- rep->distance = WPA_GET_LE32(pos + 2);
- rep->rel_height = WPA_GET_LE16(pos + 2 + 4);
- rep->bearing_present = 1;
- break;
- case WNM_NEIGHBOR_MEASUREMENT_PILOT:
- if (elen < 1) {
- wpa_printf(MSG_DEBUG, "WNM: Too short measurement "
- "pilot");
- break;
- }
- os_free(rep->meas_pilot);
- rep->meas_pilot = os_zalloc(sizeof(struct measurement_pilot));
- if (rep->meas_pilot == NULL)
- break;
- rep->meas_pilot->measurement_pilot = pos[0];
- rep->meas_pilot->subelem_len = elen - 1;
- os_memcpy(rep->meas_pilot->subelems, pos + 1, elen - 1);
- break;
- case WNM_NEIGHBOR_RRM_ENABLED_CAPABILITIES:
- if (elen < 5) {
- wpa_printf(MSG_DEBUG, "WNM: Too short RRM enabled "
- "capabilities");
- break;
- }
- os_memcpy(rep->rm_capab, pos, 5);
- rep->rm_capab_present = 1;
- break;
- case WNM_NEIGHBOR_MULTIPLE_BSSID:
- if (elen < 1) {
- wpa_printf(MSG_DEBUG, "WNM: Too short multiple BSSID");
- break;
- }
- os_free(rep->mul_bssid);
- rep->mul_bssid = os_zalloc(sizeof(struct multiple_bssid));
- if (rep->mul_bssid == NULL)
- break;
- rep->mul_bssid->max_bssid_indicator = pos[0];
- rep->mul_bssid->subelem_len = elen - 1;
- os_memcpy(rep->mul_bssid->subelems, pos + 1, elen - 1);
- break;
- }
-}
-
-
-static int wnm_nei_get_chan(struct wpa_supplicant *wpa_s, u8 op_class, u8 chan)
-{
- struct wpa_bss *bss = wpa_s->current_bss;
- const char *country = NULL;
- int freq;
-
- if (bss) {
- const u8 *elem = wpa_bss_get_ie(bss, WLAN_EID_COUNTRY);
-
- if (elem && elem[1] >= 2)
- country = (const char *) (elem + 2);
- }
-
- freq = ieee80211_chan_to_freq(country, op_class, chan);
- if (freq <= 0 && op_class == 0) {
- /*
- * Some APs do not advertise correct operating class
- * information. Try to determine the most likely operating
- * frequency based on the channel number.
- */
- if (chan >= 1 && chan <= 13)
- freq = 2407 + chan * 5;
- else if (chan == 14)
- freq = 2484;
- else if (chan >= 36 && chan <= 177)
- freq = 5000 + chan * 5;
- }
- return freq;
-}
-
-
-static void wnm_parse_neighbor_report(struct wpa_supplicant *wpa_s,
- const u8 *pos, u8 len,
- struct neighbor_report *rep)
-{
- u8 left = len;
-
- if (left < 13) {
- wpa_printf(MSG_DEBUG, "WNM: Too short neighbor report");
- return;
- }
-
- os_memcpy(rep->bssid, pos, ETH_ALEN);
- rep->bssid_info = WPA_GET_LE32(pos + ETH_ALEN);
- rep->regulatory_class = *(pos + 10);
- rep->channel_number = *(pos + 11);
- rep->phy_type = *(pos + 12);
-
- pos += 13;
- left -= 13;
-
- while (left >= 2) {
- u8 id, elen;
-
- id = *pos++;
- elen = *pos++;
- wpa_printf(MSG_DEBUG, "WNM: Subelement id=%u len=%u", id, elen);
- left -= 2;
- if (elen > left) {
- wpa_printf(MSG_DEBUG,
- "WNM: Truncated neighbor report subelement");
- break;
- }
- wnm_parse_neighbor_report_elem(rep, id, elen, pos);
- left -= elen;
- pos += elen;
- }
-
- rep->freq = wnm_nei_get_chan(wpa_s, rep->regulatory_class,
- rep->channel_number);
-}
-
-
-static void wnm_clear_acceptable(struct wpa_supplicant *wpa_s)
-{
- unsigned int i;
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++)
- wpa_s->wnm_neighbor_report_elements[i].acceptable = 0;
-}
-
-
-static struct wpa_bss * get_first_acceptable(struct wpa_supplicant *wpa_s)
-{
- unsigned int i;
- struct neighbor_report *nei;
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- nei = &wpa_s->wnm_neighbor_report_elements[i];
- if (nei->acceptable)
- return wpa_bss_get_bssid(wpa_s, nei->bssid);
- }
-
- return NULL;
-}
-
-
-#ifdef CONFIG_MBO
-static struct wpa_bss *
-get_mbo_transition_candidate(struct wpa_supplicant *wpa_s,
- enum mbo_transition_reject_reason *reason)
-{
- struct wpa_bss *target = NULL;
- struct wpa_bss_trans_info params;
- struct wpa_bss_candidate_info *info = NULL;
- struct neighbor_report *nei = wpa_s->wnm_neighbor_report_elements;
- u8 *first_candidate_bssid = NULL, *pos;
- unsigned int i;
-
- params.mbo_transition_reason = wpa_s->wnm_mbo_transition_reason;
- params.n_candidates = 0;
- params.bssid = os_calloc(wpa_s->wnm_num_neighbor_report, ETH_ALEN);
- if (!params.bssid)
- return NULL;
-
- pos = params.bssid;
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; nei++, i++) {
- if (nei->is_first)
- first_candidate_bssid = nei->bssid;
- if (!nei->acceptable)
- continue;
- os_memcpy(pos, nei->bssid, ETH_ALEN);
- pos += ETH_ALEN;
- params.n_candidates++;
- }
-
- if (!params.n_candidates)
- goto end;
-
- info = wpa_drv_get_bss_trans_status(wpa_s, &params);
- if (!info) {
- /* If failed to get candidate BSS transition status from driver,
- * get the first acceptable candidate from wpa_supplicant.
- */
- target = wpa_bss_get_bssid(wpa_s, params.bssid);
- goto end;
- }
-
- /* Get the first acceptable candidate from driver */
- for (i = 0; i < info->num; i++) {
- if (info->candidates[i].is_accept) {
- target = wpa_bss_get_bssid(wpa_s,
- info->candidates[i].bssid);
- goto end;
- }
- }
-
- /* If Disassociation Imminent is set and driver rejects all the
- * candidate select first acceptable candidate which has
- * rssi > disassoc_imminent_rssi_threshold
- */
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
- for (i = 0; i < info->num; i++) {
- target = wpa_bss_get_bssid(wpa_s,
- info->candidates[i].bssid);
- if (target &&
- (target->level <
- wpa_s->conf->disassoc_imminent_rssi_threshold))
- continue;
- goto end;
- }
- }
-
- /* While sending BTM reject use reason code of the first candidate
- * received in BTM request frame
- */
- if (reason) {
- for (i = 0; i < info->num; i++) {
- if (first_candidate_bssid &&
- os_memcmp(first_candidate_bssid,
- info->candidates[i].bssid, ETH_ALEN) == 0)
- {
- *reason = info->candidates[i].reject_reason;
- break;
- }
- }
- }
-
- target = NULL;
-
-end:
- os_free(params.bssid);
- if (info) {
- os_free(info->candidates);
- os_free(info);
- }
- return target;
-}
-#endif /* CONFIG_MBO */
-
-
-static struct wpa_bss *
-compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
- enum mbo_transition_reject_reason *reason)
-{
- u8 i;
- struct wpa_bss *bss = wpa_s->current_bss;
- struct wpa_bss *target;
-
- if (!bss)
- return NULL;
-
- wpa_printf(MSG_DEBUG, "WNM: Current BSS " MACSTR " RSSI %d",
- MAC2STR(wpa_s->bssid), bss->level);
-
- wnm_clear_acceptable(wpa_s);
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- struct neighbor_report *nei;
-
- nei = &wpa_s->wnm_neighbor_report_elements[i];
- if (nei->preference_present && nei->preference == 0) {
- wpa_printf(MSG_DEBUG, "Skip excluded BSS " MACSTR,
- MAC2STR(nei->bssid));
- continue;
- }
-
- target = wpa_bss_get_bssid(wpa_s, nei->bssid);
- if (!target) {
- wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
- " (pref %d) not found in scan results",
- MAC2STR(nei->bssid),
- nei->preference_present ? nei->preference :
- -1);
- continue;
- }
-
- if (age_secs) {
- struct os_reltime now;
-
- if (os_get_reltime(&now) == 0 &&
- os_reltime_expired(&now, &target->last_update,
- age_secs)) {
- wpa_printf(MSG_DEBUG,
- "Candidate BSS is more than %ld seconds old",
- age_secs);
- continue;
- }
- }
-
- if (bss->ssid_len != target->ssid_len ||
- os_memcmp(bss->ssid, target->ssid, bss->ssid_len) != 0) {
- /*
- * TODO: Could consider allowing transition to another
- * ESS if PMF was enabled for the association.
- */
- wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
- " (pref %d) in different ESS",
- MAC2STR(nei->bssid),
- nei->preference_present ? nei->preference :
- -1);
- continue;
- }
-
- if (wpa_s->current_ssid &&
- !wpa_scan_res_match(wpa_s, 0, target, wpa_s->current_ssid,
- 1, 0)) {
- wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
- " (pref %d) does not match the current network profile",
- MAC2STR(nei->bssid),
- nei->preference_present ? nei->preference :
- -1);
- continue;
- }
-
- if (wpa_is_bss_tmp_disallowed(wpa_s, target)) {
- wpa_printf(MSG_DEBUG,
- "MBO: Candidate BSS " MACSTR
- " retry delay is not over yet",
- MAC2STR(nei->bssid));
- continue;
- }
-
- if (target->level < bss->level && target->level < -80) {
- wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
- " (pref %d) does not have sufficient signal level (%d)",
- MAC2STR(nei->bssid),
- nei->preference_present ? nei->preference :
- -1,
- target->level);
- continue;
- }
-
- nei->acceptable = 1;
- }
-
-#ifdef CONFIG_MBO
- if (wpa_s->wnm_mbo_trans_reason_present)
- target = get_mbo_transition_candidate(wpa_s, reason);
- else
- target = get_first_acceptable(wpa_s);
-#else /* CONFIG_MBO */
- target = get_first_acceptable(wpa_s);
-#endif /* CONFIG_MBO */
-
- if (target) {
- wpa_printf(MSG_DEBUG,
- "WNM: Found an acceptable preferred transition candidate BSS "
- MACSTR " (RSSI %d)",
- MAC2STR(target->bssid), target->level);
- }
-
- return target;
-}
-
-
-static int wpa_bss_ies_eq(struct wpa_bss *a, struct wpa_bss *b, u8 eid)
-{
- const u8 *ie_a, *ie_b;
-
- if (!a || !b)
- return 0;
-
- ie_a = wpa_bss_get_ie(a, eid);
- ie_b = wpa_bss_get_ie(b, eid);
-
- if (!ie_a || !ie_b || ie_a[1] != ie_b[1])
- return 0;
-
- return os_memcmp(ie_a, ie_b, ie_a[1]) == 0;
-}
-
-
-static u32 wnm_get_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
- u32 info = 0;
-
- info |= NEI_REP_BSSID_INFO_AP_UNKNOWN_REACH;
-
- /*
- * Leave the security and key scope bits unset to indicate that the
- * security information is not available.
- */
-
- if (bss->caps & WLAN_CAPABILITY_SPECTRUM_MGMT)
- info |= NEI_REP_BSSID_INFO_SPECTRUM_MGMT;
- if (bss->caps & WLAN_CAPABILITY_QOS)
- info |= NEI_REP_BSSID_INFO_QOS;
- if (bss->caps & WLAN_CAPABILITY_APSD)
- info |= NEI_REP_BSSID_INFO_APSD;
- if (bss->caps & WLAN_CAPABILITY_RADIO_MEASUREMENT)
- info |= NEI_REP_BSSID_INFO_RM;
- if (bss->caps & WLAN_CAPABILITY_DELAYED_BLOCK_ACK)
- info |= NEI_REP_BSSID_INFO_DELAYED_BA;
- if (bss->caps & WLAN_CAPABILITY_IMM_BLOCK_ACK)
- info |= NEI_REP_BSSID_INFO_IMM_BA;
- if (wpa_bss_ies_eq(bss, wpa_s->current_bss, WLAN_EID_MOBILITY_DOMAIN))
- info |= NEI_REP_BSSID_INFO_MOBILITY_DOMAIN;
- if (wpa_bss_ies_eq(bss, wpa_s->current_bss, WLAN_EID_HT_CAP))
- info |= NEI_REP_BSSID_INFO_HT;
-
- return info;
-}
-
-
-static int wnm_add_nei_rep(struct wpabuf **buf, const u8 *bssid,
- u32 bss_info, u8 op_class, u8 chan, u8 phy_type,
- u8 pref)
-{
- if (wpabuf_len(*buf) + 18 >
- IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN) {
- wpa_printf(MSG_DEBUG,
- "WNM: No room in frame for Neighbor Report element");
- return -1;
- }
-
- if (wpabuf_resize(buf, 18) < 0) {
- wpa_printf(MSG_DEBUG,
- "WNM: Failed to allocate memory for Neighbor Report element");
- return -1;
- }
-
- wpabuf_put_u8(*buf, WLAN_EID_NEIGHBOR_REPORT);
- /* length: 13 for basic neighbor report + 3 for preference subelement */
- wpabuf_put_u8(*buf, 16);
- wpabuf_put_data(*buf, bssid, ETH_ALEN);
- wpabuf_put_le32(*buf, bss_info);
- wpabuf_put_u8(*buf, op_class);
- wpabuf_put_u8(*buf, chan);
- wpabuf_put_u8(*buf, phy_type);
- wpabuf_put_u8(*buf, WNM_NEIGHBOR_BSS_TRANSITION_CANDIDATE);
- wpabuf_put_u8(*buf, 1);
- wpabuf_put_u8(*buf, pref);
- return 0;
-}
-
-
-static int wnm_nei_rep_add_bss(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpabuf **buf,
- u8 pref)
-{
- const u8 *ie;
- u8 op_class, chan;
- int sec_chan = 0, vht = 0;
- enum phy_type phy_type;
- u32 info;
- struct ieee80211_ht_operation *ht_oper = NULL;
- struct ieee80211_vht_operation *vht_oper = NULL;
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= 2) {
- ht_oper = (struct ieee80211_ht_operation *) (ie + 2);
-
- if (ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
- sec_chan = 1;
- else if (ht_oper->ht_param &
- HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
- sec_chan = -1;
- }
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_VHT_OPERATION);
- if (ie && ie[1] >= 1) {
- vht_oper = (struct ieee80211_vht_operation *) (ie + 2);
-
- if (vht_oper->vht_op_info_chwidth == CHANWIDTH_80MHZ ||
- vht_oper->vht_op_info_chwidth == CHANWIDTH_160MHZ ||
- vht_oper->vht_op_info_chwidth == CHANWIDTH_80P80MHZ)
- vht = vht_oper->vht_op_info_chwidth;
- }
-
- if (ieee80211_freq_to_channel_ext(bss->freq, sec_chan, vht, &op_class,
- &chan) == NUM_HOSTAPD_MODES) {
- wpa_printf(MSG_DEBUG,
- "WNM: Cannot determine operating class and channel");
- return -2;
- }
-
- phy_type = ieee80211_get_phy_type(bss->freq, (ht_oper != NULL),
- (vht_oper != NULL));
- if (phy_type == PHY_TYPE_UNSPECIFIED) {
- wpa_printf(MSG_DEBUG,
- "WNM: Cannot determine BSS phy type for Neighbor Report");
- return -2;
- }
-
- info = wnm_get_bss_info(wpa_s, bss);
-
- return wnm_add_nei_rep(buf, bss->bssid, info, op_class, chan, phy_type,
- pref);
-}
-
-
-static void wnm_add_cand_list(struct wpa_supplicant *wpa_s, struct wpabuf **buf)
-{
- unsigned int i, pref = 255;
- struct os_reltime now;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
- if (!ssid)
- return;
-
- /*
- * TODO: Define when scan results are no longer valid for the candidate
- * list.
- */
- os_get_reltime(&now);
- if (os_reltime_expired(&now, &wpa_s->last_scan, 10))
- return;
-
- wpa_printf(MSG_DEBUG,
- "WNM: Add candidate list to BSS Transition Management Response frame");
- for (i = 0; i < wpa_s->last_scan_res_used && pref; i++) {
- struct wpa_bss *bss = wpa_s->last_scan_res[i];
- int res;
-
- if (wpa_scan_res_match(wpa_s, i, bss, ssid, 1, 0)) {
- res = wnm_nei_rep_add_bss(wpa_s, bss, buf, pref--);
- if (res == -2)
- continue; /* could not build entry for BSS */
- if (res < 0)
- break; /* no more room for candidates */
- if (pref == 1)
- break;
- }
- }
-
- wpa_hexdump_buf(MSG_DEBUG,
- "WNM: BSS Transition Management Response candidate list",
- *buf);
-}
-
-
-#define BTM_RESP_MIN_SIZE 5 + ETH_ALEN
-
-static void wnm_send_bss_transition_mgmt_resp(
- struct wpa_supplicant *wpa_s, u8 dialog_token,
- enum bss_trans_mgmt_status_code status,
- enum mbo_transition_reject_reason reason,
- u8 delay, const u8 *target_bssid)
-{
- struct wpabuf *buf;
- int res;
-
- wpa_printf(MSG_DEBUG,
- "WNM: Send BSS Transition Management Response to " MACSTR
- " dialog_token=%u status=%u reason=%u delay=%d",
- MAC2STR(wpa_s->bssid), dialog_token, status, reason, delay);
- if (!wpa_s->current_bss) {
- wpa_printf(MSG_DEBUG,
- "WNM: Current BSS not known - drop response");
- return;
- }
-
- buf = wpabuf_alloc(BTM_RESP_MIN_SIZE);
- if (!buf) {
- wpa_printf(MSG_DEBUG,
- "WNM: Failed to allocate memory for BTM response");
- return;
- }
-
- wpa_s->bss_tm_status = status;
- wpas_notify_bss_tm_status(wpa_s);
-
- wpabuf_put_u8(buf, WLAN_ACTION_WNM);
- wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_RESP);
- wpabuf_put_u8(buf, dialog_token);
- wpabuf_put_u8(buf, status);
- wpabuf_put_u8(buf, delay);
- if (target_bssid) {
- wpabuf_put_data(buf, target_bssid, ETH_ALEN);
- } else if (status == WNM_BSS_TM_ACCEPT) {
- /*
- * P802.11-REVmc clarifies that the Target BSSID field is always
- * present when status code is zero, so use a fake value here if
- * no BSSID is yet known.
- */
- wpabuf_put_data(buf, "\0\0\0\0\0\0", ETH_ALEN);
- }
-
- if (status == WNM_BSS_TM_ACCEPT)
- wnm_add_cand_list(wpa_s, &buf);
-
-#ifdef CONFIG_MBO
- if (status != WNM_BSS_TM_ACCEPT &&
- wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE)) {
- u8 mbo[10];
- size_t ret;
-
- ret = wpas_mbo_ie_bss_trans_reject(wpa_s, mbo, sizeof(mbo),
- reason);
- if (ret) {
- if (wpabuf_resize(&buf, ret) < 0) {
- wpabuf_free(buf);
- wpa_printf(MSG_DEBUG,
- "WNM: Failed to allocate memory for MBO IE");
- return;
- }
-
- wpabuf_put_data(buf, mbo, ret);
- }
- }
-#endif /* CONFIG_MBO */
-
- res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head_u8(buf), wpabuf_len(buf), 0);
- if (res < 0) {
- wpa_printf(MSG_DEBUG,
- "WNM: Failed to send BSS Transition Management Response");
- }
-
- wpabuf_free(buf);
-}
-
-
-static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid,
- int after_new_scan)
-{
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Transition to BSS " MACSTR
- " based on BSS Transition Management Request (old BSSID "
- MACSTR " after_new_scan=%d)",
- MAC2STR(bss->bssid), MAC2STR(wpa_s->bssid), after_new_scan);
-
- /* Send the BSS Management Response - Accept */
- if (wpa_s->wnm_reply) {
- wpa_s->wnm_reply = 0;
- wpa_printf(MSG_DEBUG,
- "WNM: Sending successful BSS Transition Management Response");
- wnm_send_bss_transition_mgmt_resp(
- wpa_s, wpa_s->wnm_dialog_token, WNM_BSS_TM_ACCEPT,
- MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
- bss->bssid);
- }
-
- if (bss == wpa_s->current_bss) {
- wpa_printf(MSG_DEBUG,
- "WNM: Already associated with the preferred candidate");
- wnm_deallocate_memory(wpa_s);
- return;
- }
-
- wpa_s->reassociate = 1;
- wpa_printf(MSG_DEBUG, "WNM: Issuing connect");
- wpa_supplicant_connect(wpa_s, bss, ssid);
- wnm_deallocate_memory(wpa_s);
-}
-
-
-int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
-{
- struct wpa_bss *bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- enum bss_trans_mgmt_status_code status = WNM_BSS_TM_REJECT_UNSPECIFIED;
- enum mbo_transition_reject_reason reason =
- MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
-
- if (!wpa_s->wnm_neighbor_report_elements)
- return 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Process scan results for BSS Transition Management");
- if (os_reltime_before(&wpa_s->wnm_cand_valid_until,
- &wpa_s->scan_trigger_time)) {
- wpa_printf(MSG_DEBUG, "WNM: Previously stored BSS transition candidate list is not valid anymore - drop it");
- wnm_deallocate_memory(wpa_s);
- return 0;
- }
-
- if (!wpa_s->current_bss ||
- os_memcmp(wpa_s->wnm_cand_from_bss, wpa_s->current_bss->bssid,
- ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "WNM: Stored BSS transition candidate list not from the current BSS - ignore it");
- return 0;
- }
-
- /* Compare the Neighbor Report and scan results */
- bss = compare_scan_neighbor_results(wpa_s, 0, &reason);
- if (!bss) {
- wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found");
- status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
- goto send_bss_resp_fail;
- }
-
- /* Associate to the network */
- wnm_bss_tm_connect(wpa_s, bss, ssid, 1);
- return 1;
-
-send_bss_resp_fail:
- if (!reply_on_fail)
- return 0;
-
- /* Send reject response for all the failures */
-
- if (wpa_s->wnm_reply) {
- wpa_s->wnm_reply = 0;
- wnm_send_bss_transition_mgmt_resp(wpa_s,
- wpa_s->wnm_dialog_token,
- status, reason, 0, NULL);
- }
- wnm_deallocate_memory(wpa_s);
-
- return 0;
-}
-
-
-static int cand_pref_compar(const void *a, const void *b)
-{
- const struct neighbor_report *aa = a;
- const struct neighbor_report *bb = b;
-
- if (!aa->preference_present && !bb->preference_present)
- return 0;
- if (!aa->preference_present)
- return 1;
- if (!bb->preference_present)
- return -1;
- if (bb->preference > aa->preference)
- return 1;
- if (bb->preference < aa->preference)
- return -1;
- return 0;
-}
-
-
-static void wnm_sort_cand_list(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->wnm_neighbor_report_elements)
- return;
- qsort(wpa_s->wnm_neighbor_report_elements,
- wpa_s->wnm_num_neighbor_report, sizeof(struct neighbor_report),
- cand_pref_compar);
-}
-
-
-static void wnm_dump_cand_list(struct wpa_supplicant *wpa_s)
-{
- unsigned int i;
-
- wpa_printf(MSG_DEBUG, "WNM: BSS Transition Candidate List");
- if (!wpa_s->wnm_neighbor_report_elements)
- return;
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- struct neighbor_report *nei;
-
- nei = &wpa_s->wnm_neighbor_report_elements[i];
- wpa_printf(MSG_DEBUG, "%u: " MACSTR
- " info=0x%x op_class=%u chan=%u phy=%u pref=%d freq=%d",
- i, MAC2STR(nei->bssid), nei->bssid_info,
- nei->regulatory_class,
- nei->channel_number, nei->phy_type,
- nei->preference_present ? nei->preference : -1,
- nei->freq);
- }
-}
-
-
-static int chan_supported(struct wpa_supplicant *wpa_s, int freq)
-{
- unsigned int i;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
- int j;
-
- for (j = 0; j < mode->num_channels; j++) {
- struct hostapd_channel_data *chan;
-
- chan = &mode->channels[j];
- if (chan->freq == freq &&
- !(chan->flag & HOSTAPD_CHAN_DISABLED))
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static void wnm_set_scan_freqs(struct wpa_supplicant *wpa_s)
-{
- int *freqs;
- int num_freqs = 0;
- unsigned int i;
-
- if (!wpa_s->wnm_neighbor_report_elements)
- return;
-
- if (wpa_s->hw.modes == NULL)
- return;
-
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = NULL;
-
- freqs = os_calloc(wpa_s->wnm_num_neighbor_report + 1, sizeof(int));
- if (freqs == NULL)
- return;
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- struct neighbor_report *nei;
-
- nei = &wpa_s->wnm_neighbor_report_elements[i];
- if (nei->freq <= 0) {
- wpa_printf(MSG_DEBUG,
- "WNM: Unknown neighbor operating frequency for "
- MACSTR " - scan all channels",
- MAC2STR(nei->bssid));
- os_free(freqs);
- return;
- }
- if (chan_supported(wpa_s, nei->freq))
- add_freq(freqs, &num_freqs, nei->freq);
- }
-
- if (num_freqs == 0) {
- os_free(freqs);
- return;
- }
-
- wpa_printf(MSG_DEBUG,
- "WNM: Scan %d frequencies based on transition candidate list",
- num_freqs);
- wpa_s->next_scan_freqs = freqs;
-}
-
-
-static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s)
-{
- struct wpa_scan_results *scan_res;
- struct wpa_bss *bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- u8 i, found = 0;
- size_t j;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Fetch current scan results from the driver for checking transition candidates");
- scan_res = wpa_drv_get_scan_results2(wpa_s);
- if (!scan_res) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Failed to get scan results");
- return 0;
- }
-
- if (scan_res->fetch_time.sec == 0)
- os_get_reltime(&scan_res->fetch_time);
-
- filter_scan_res(wpa_s, scan_res);
-
- for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
- struct neighbor_report *nei;
-
- nei = &wpa_s->wnm_neighbor_report_elements[i];
- if (nei->preference_present && nei->preference == 0)
- continue;
-
- for (j = 0; j < scan_res->num; j++) {
- struct wpa_scan_res *res;
- const u8 *ssid_ie;
-
- res = scan_res->res[j];
- if (os_memcmp(nei->bssid, res->bssid, ETH_ALEN) != 0 ||
- res->age > WNM_SCAN_RESULT_AGE * 1000)
- continue;
- bss = wpa_s->current_bss;
- ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
- if (bss && ssid_ie && ssid_ie[1] &&
- (bss->ssid_len != ssid_ie[1] ||
- os_memcmp(bss->ssid, ssid_ie + 2,
- bss->ssid_len) != 0))
- continue; /* Skip entries for other ESSs */
-
- /* Potential candidate found */
- found = 1;
- scan_snr(res);
- scan_est_throughput(wpa_s, res);
- wpa_bss_update_scan_res(wpa_s, res,
- &scan_res->fetch_time);
- }
- }
-
- wpa_scan_results_free(scan_res);
- if (!found) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: No transition candidate matches existing scan results");
- return 0;
- }
-
- bss = compare_scan_neighbor_results(wpa_s, WNM_SCAN_RESULT_AGE, NULL);
- if (!bss) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Comparison of scan results against transition candidates did not find matches");
- return 0;
- }
-
- /* Associate to the network */
- wnm_bss_tm_connect(wpa_s, bss, ssid, 0);
- return 1;
-}
-
-
-static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
- const u8 *pos, const u8 *end,
- int reply)
-{
- unsigned int beacon_int;
- u8 valid_int;
-#ifdef CONFIG_MBO
- const u8 *vendor;
-#endif /* CONFIG_MBO */
-
- if (wpa_s->disable_mbo_oce || wpa_s->conf->disable_btm)
- return;
-
- if (end - pos < 5)
- return;
-
-#ifdef CONFIG_MBO
- wpa_s->wnm_mbo_trans_reason_present = 0;
- wpa_s->wnm_mbo_transition_reason = 0;
-#endif /* CONFIG_MBO */
-
- if (wpa_s->current_bss)
- beacon_int = wpa_s->current_bss->beacon_int;
- else
- beacon_int = 100; /* best guess */
-
- wpa_s->wnm_dialog_token = pos[0];
- wpa_s->wnm_mode = pos[1];
- wpa_s->wnm_dissoc_timer = WPA_GET_LE16(pos + 2);
- valid_int = pos[4];
- wpa_s->wnm_reply = reply;
-
- wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management Request: "
- "dialog_token=%u request_mode=0x%x "
- "disassoc_timer=%u validity_interval=%u",
- wpa_s->wnm_dialog_token, wpa_s->wnm_mode,
- wpa_s->wnm_dissoc_timer, valid_int);
-
-#if defined(CONFIG_MBO) && defined(CONFIG_TESTING_OPTIONS)
- if (wpa_s->reject_btm_req_reason) {
- wpa_printf(MSG_INFO,
- "WNM: Testing - reject BSS Transition Management Request: reject_btm_req_reason=%d",
- wpa_s->reject_btm_req_reason);
- wnm_send_bss_transition_mgmt_resp(
- wpa_s, wpa_s->wnm_dialog_token,
- wpa_s->reject_btm_req_reason,
- MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0, NULL);
- return;
- }
-#endif /* CONFIG_MBO && CONFIG_TESTING_OPTIONS */
-
- pos += 5;
-
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
- if (end - pos < 12) {
- wpa_printf(MSG_DEBUG, "WNM: Too short BSS TM Request");
- return;
- }
- os_memcpy(wpa_s->wnm_bss_termination_duration, pos, 12);
- pos += 12; /* BSS Termination Duration */
- }
-
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
- char url[256];
-
- if (end - pos < 1 || 1 + pos[0] > end - pos) {
- wpa_printf(MSG_DEBUG, "WNM: Invalid BSS Transition "
- "Management Request (URL)");
- return;
- }
- os_memcpy(url, pos + 1, pos[0]);
- url[pos[0]] = '\0';
- pos += 1 + pos[0];
-
- wpa_msg(wpa_s, MSG_INFO, ESS_DISASSOC_IMMINENT "%d %u %s",
- wpa_sm_pmf_enabled(wpa_s->wpa),
- wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125, url);
- }
-
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
- wpa_msg(wpa_s, MSG_INFO, "WNM: Disassociation Imminent - "
- "Disassociation Timer %u", wpa_s->wnm_dissoc_timer);
- if (wpa_s->wnm_dissoc_timer && !wpa_s->scanning) {
- /* TODO: mark current BSS less preferred for
- * selection */
- wpa_printf(MSG_DEBUG, "Trying to find another BSS");
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
- }
-
-#ifdef CONFIG_MBO
- vendor = get_ie(pos, end - pos, WLAN_EID_VENDOR_SPECIFIC);
- if (vendor)
- wpas_mbo_ie_trans_req(wpa_s, vendor + 2, vendor[1]);
-#endif /* CONFIG_MBO */
-
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
- unsigned int valid_ms;
-
- wpa_msg(wpa_s, MSG_INFO, "WNM: Preferred List Available");
- wnm_deallocate_memory(wpa_s);
- wpa_s->wnm_neighbor_report_elements = os_calloc(
- WNM_MAX_NEIGHBOR_REPORT,
- sizeof(struct neighbor_report));
- if (wpa_s->wnm_neighbor_report_elements == NULL)
- return;
-
- while (end - pos >= 2 &&
- wpa_s->wnm_num_neighbor_report < WNM_MAX_NEIGHBOR_REPORT)
- {
- u8 tag = *pos++;
- u8 len = *pos++;
-
- wpa_printf(MSG_DEBUG, "WNM: Neighbor report tag %u",
- tag);
- if (len > end - pos) {
- wpa_printf(MSG_DEBUG, "WNM: Truncated request");
- return;
- }
- if (tag == WLAN_EID_NEIGHBOR_REPORT) {
- struct neighbor_report *rep;
- rep = &wpa_s->wnm_neighbor_report_elements[
- wpa_s->wnm_num_neighbor_report];
- wnm_parse_neighbor_report(wpa_s, pos, len, rep);
- wpa_s->wnm_num_neighbor_report++;
-#ifdef CONFIG_MBO
- if (wpa_s->wnm_mbo_trans_reason_present &&
- wpa_s->wnm_num_neighbor_report == 1) {
- rep->is_first = 1;
- wpa_printf(MSG_DEBUG,
- "WNM: First transition candidate is "
- MACSTR, MAC2STR(rep->bssid));
- }
-#endif /* CONFIG_MBO */
- }
-
- pos += len;
- }
-
- if (!wpa_s->wnm_num_neighbor_report) {
- wpa_printf(MSG_DEBUG,
- "WNM: Candidate list included bit is set, but no candidates found");
- wnm_send_bss_transition_mgmt_resp(
- wpa_s, wpa_s->wnm_dialog_token,
- WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES,
- MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0,
- NULL);
- return;
- }
-
- wnm_sort_cand_list(wpa_s);
- wnm_dump_cand_list(wpa_s);
- valid_ms = valid_int * beacon_int * 128 / 125;
- wpa_printf(MSG_DEBUG, "WNM: Candidate list valid for %u ms",
- valid_ms);
- os_get_reltime(&wpa_s->wnm_cand_valid_until);
- wpa_s->wnm_cand_valid_until.sec += valid_ms / 1000;
- wpa_s->wnm_cand_valid_until.usec += (valid_ms % 1000) * 1000;
- wpa_s->wnm_cand_valid_until.sec +=
- wpa_s->wnm_cand_valid_until.usec / 1000000;
- wpa_s->wnm_cand_valid_until.usec %= 1000000;
- os_memcpy(wpa_s->wnm_cand_from_bss, wpa_s->bssid, ETH_ALEN);
-
- /*
- * Fetch the latest scan results from the kernel and check for
- * candidates based on those results first. This can help in
- * finding more up-to-date information should the driver has
- * done some internal scanning operations after the last scan
- * result update in wpa_supplicant.
- */
- if (wnm_fetch_scan_results(wpa_s) > 0)
- return;
-
- /*
- * Try to use previously received scan results, if they are
- * recent enough to use for a connection.
- */
- if (wpa_s->last_scan_res_used > 0) {
- struct os_reltime now;
-
- os_get_reltime(&now);
- if (!os_reltime_expired(&now, &wpa_s->last_scan, 10)) {
- wpa_printf(MSG_DEBUG,
- "WNM: Try to use recent scan results");
- if (wnm_scan_process(wpa_s, 0) > 0)
- return;
- wpa_printf(MSG_DEBUG,
- "WNM: No match in previous scan results - try a new scan");
- }
- }
-
- wnm_set_scan_freqs(wpa_s);
- if (wpa_s->wnm_num_neighbor_report == 1) {
- os_memcpy(wpa_s->next_scan_bssid,
- wpa_s->wnm_neighbor_report_elements[0].bssid,
- ETH_ALEN);
- wpa_printf(MSG_DEBUG,
- "WNM: Scan only for a specific BSSID since there is only a single candidate "
- MACSTR, MAC2STR(wpa_s->next_scan_bssid));
- }
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- } else if (reply) {
- enum bss_trans_mgmt_status_code status;
- if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT)
- status = WNM_BSS_TM_ACCEPT;
- else {
- wpa_msg(wpa_s, MSG_INFO, "WNM: BSS Transition Management Request did not include candidates");
- status = WNM_BSS_TM_REJECT_UNSPECIFIED;
- }
- wnm_send_bss_transition_mgmt_resp(
- wpa_s, wpa_s->wnm_dialog_token, status,
- MBO_TRANSITION_REJECT_REASON_UNSPECIFIED, 0, NULL);
- }
-}
-
-
-#define BTM_QUERY_MIN_SIZE 4
-
-int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
- u8 query_reason,
- const char *btm_candidates,
- int cand_list)
-{
- struct wpabuf *buf;
- int ret;
-
- wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Query to "
- MACSTR " query_reason=%u%s",
- MAC2STR(wpa_s->bssid), query_reason,
- cand_list ? " candidate list" : "");
-
- buf = wpabuf_alloc(BTM_QUERY_MIN_SIZE);
- if (!buf)
- return -1;
-
- wpabuf_put_u8(buf, WLAN_ACTION_WNM);
- wpabuf_put_u8(buf, WNM_BSS_TRANS_MGMT_QUERY);
- wpabuf_put_u8(buf, 1);
- wpabuf_put_u8(buf, query_reason);
-
- if (cand_list)
- wnm_add_cand_list(wpa_s, &buf);
-
- if (btm_candidates) {
- const size_t max_len = 1000;
-
- ret = wpabuf_resize(&buf, max_len);
- if (ret < 0) {
- wpabuf_free(buf);
- return ret;
- }
-
- ret = ieee802_11_parse_candidate_list(btm_candidates,
- wpabuf_put(buf, 0),
- max_len);
- if (ret < 0) {
- wpabuf_free(buf);
- return ret;
- }
-
- wpabuf_put(buf, ret);
- }
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head_u8(buf), wpabuf_len(buf), 0);
-
- wpabuf_free(buf);
- return ret;
-}
-
-
-static void ieee802_11_rx_wnm_notif_req_wfa(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *data,
- int len)
-{
- const u8 *pos, *end, *next;
- u8 ie, ie_len;
-
- pos = data;
- end = data + len;
-
- while (end - pos > 1) {
- ie = *pos++;
- ie_len = *pos++;
- wpa_printf(MSG_DEBUG, "WNM: WFA subelement %u len %u",
- ie, ie_len);
- if (ie_len > end - pos) {
- wpa_printf(MSG_DEBUG, "WNM: Not enough room for "
- "subelement");
- break;
- }
- next = pos + ie_len;
- if (ie_len < 4) {
- pos = next;
- continue;
- }
- wpa_printf(MSG_DEBUG, "WNM: Subelement OUI %06x type %u",
- WPA_GET_BE24(pos), pos[3]);
-
-#ifdef CONFIG_HS20
- if (ie == WLAN_EID_VENDOR_SPECIFIC && ie_len >= 5 &&
- WPA_GET_BE24(pos) == OUI_WFA &&
- pos[3] == HS20_WNM_SUB_REM_NEEDED) {
- /* Subscription Remediation subelement */
- const u8 *ie_end;
- u8 url_len;
- char *url;
- u8 osu_method;
-
- wpa_printf(MSG_DEBUG, "WNM: Subscription Remediation "
- "subelement");
- ie_end = pos + ie_len;
- pos += 4;
- url_len = *pos++;
- if (url_len == 0) {
- wpa_printf(MSG_DEBUG, "WNM: No Server URL included");
- url = NULL;
- osu_method = 1;
- } else {
- if (url_len + 1 > ie_end - pos) {
- wpa_printf(MSG_DEBUG, "WNM: Not enough room for Server URL (len=%u) and Server Method (left %d)",
- url_len,
- (int) (ie_end - pos));
- break;
- }
- url = os_malloc(url_len + 1);
- if (url == NULL)
- break;
- os_memcpy(url, pos, url_len);
- url[url_len] = '\0';
- osu_method = pos[url_len];
- }
- hs20_rx_subscription_remediation(wpa_s, url,
- osu_method);
- os_free(url);
- pos = next;
- continue;
- }
-
- if (ie == WLAN_EID_VENDOR_SPECIFIC && ie_len >= 8 &&
- WPA_GET_BE24(pos) == OUI_WFA &&
- pos[3] == HS20_WNM_DEAUTH_IMMINENT_NOTICE) {
- const u8 *ie_end;
- u8 url_len;
- char *url;
- u8 code;
- u16 reauth_delay;
-
- ie_end = pos + ie_len;
- pos += 4;
- code = *pos++;
- reauth_delay = WPA_GET_LE16(pos);
- pos += 2;
- url_len = *pos++;
- wpa_printf(MSG_DEBUG, "WNM: HS 2.0 Deauthentication "
- "Imminent - Reason Code %u "
- "Re-Auth Delay %u URL Length %u",
- code, reauth_delay, url_len);
- if (url_len > ie_end - pos)
- break;
- url = os_malloc(url_len + 1);
- if (url == NULL)
- break;
- os_memcpy(url, pos, url_len);
- url[url_len] = '\0';
- hs20_rx_deauth_imminent_notice(wpa_s, code,
- reauth_delay, url);
- os_free(url);
- pos = next;
- continue;
- }
-
- if (ie == WLAN_EID_VENDOR_SPECIFIC && ie_len >= 5 &&
- WPA_GET_BE24(pos) == OUI_WFA &&
- pos[3] == HS20_WNM_T_C_ACCEPTANCE) {
- const u8 *ie_end;
- u8 url_len;
- char *url;
-
- ie_end = pos + ie_len;
- pos += 4;
- url_len = *pos++;
- wpa_printf(MSG_DEBUG,
- "WNM: HS 2.0 Terms and Conditions Acceptance (URL Length %u)",
- url_len);
- if (url_len > ie_end - pos)
- break;
- url = os_malloc(url_len + 1);
- if (!url)
- break;
- os_memcpy(url, pos, url_len);
- url[url_len] = '\0';
- hs20_rx_t_c_acceptance(wpa_s, url);
- os_free(url);
- pos = next;
- continue;
- }
-#endif /* CONFIG_HS20 */
-
- pos = next;
- }
-}
-
-
-static void ieee802_11_rx_wnm_notif_req(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *frm, int len)
-{
- const u8 *pos, *end;
- u8 dialog_token, type;
-
- /* Dialog Token [1] | Type [1] | Subelements */
-
- if (len < 2 || sa == NULL)
- return;
- end = frm + len;
- pos = frm;
- dialog_token = *pos++;
- type = *pos++;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Received WNM-Notification Request "
- "(dialog_token %u type %u sa " MACSTR ")",
- dialog_token, type, MAC2STR(sa));
- wpa_hexdump(MSG_DEBUG, "WNM-Notification Request subelements",
- pos, end - pos);
-
- if (wpa_s->wpa_state != WPA_COMPLETED ||
- os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WNM: WNM-Notification frame not "
- "from our AP - ignore it");
- return;
- }
-
- switch (type) {
- case 1:
- ieee802_11_rx_wnm_notif_req_wfa(wpa_s, sa, pos, end - pos);
- break;
- default:
- wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Ignore unknown "
- "WNM-Notification type %u", type);
- break;
- }
-}
-
-
-static void ieee802_11_rx_wnm_coloc_intf_req(struct wpa_supplicant *wpa_s,
- const u8 *sa, const u8 *frm,
- int len)
-{
- u8 dialog_token, req_info, auto_report, timeout;
-
- if (!wpa_s->conf->coloc_intf_reporting)
- return;
-
- /* Dialog Token [1] | Request Info [1] */
-
- if (len < 2)
- return;
- dialog_token = frm[0];
- req_info = frm[1];
- auto_report = req_info & 0x03;
- timeout = req_info >> 2;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Received Collocated Interference Request (dialog_token %u auto_report %u timeout %u sa " MACSTR ")",
- dialog_token, auto_report, timeout, MAC2STR(sa));
-
- if (dialog_token == 0)
- return; /* only nonzero values are used for request */
-
- if (wpa_s->wpa_state != WPA_COMPLETED ||
- os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WNM: Collocated Interference Request frame not from current AP - ignore it");
- return;
- }
-
- wpa_msg(wpa_s, MSG_INFO, COLOC_INTF_REQ "%u %u %u",
- dialog_token, auto_report, timeout);
- wpa_s->coloc_intf_dialog_token = dialog_token;
- wpa_s->coloc_intf_auto_report = auto_report;
- wpa_s->coloc_intf_timeout = timeout;
-}
-
-
-void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len)
-{
- const u8 *pos, *end;
- u8 act;
-
- if (len < IEEE80211_HDRLEN + 2)
- return;
-
- pos = ((const u8 *) mgmt) + IEEE80211_HDRLEN + 1;
- act = *pos++;
- end = ((const u8 *) mgmt) + len;
-
- wpa_printf(MSG_DEBUG, "WNM: RX action %u from " MACSTR,
- act, MAC2STR(mgmt->sa));
- if (wpa_s->wpa_state < WPA_ASSOCIATED ||
- os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "WNM: Ignore unexpected WNM Action "
- "frame");
- return;
- }
-
- switch (act) {
- case WNM_BSS_TRANS_MGMT_REQ:
- ieee802_11_rx_bss_trans_mgmt_req(wpa_s, pos, end,
- !(mgmt->da[0] & 0x01));
- break;
- case WNM_SLEEP_MODE_RESP:
- ieee802_11_rx_wnmsleep_resp(wpa_s, pos, end - pos);
- break;
- case WNM_NOTIFICATION_REQ:
- ieee802_11_rx_wnm_notif_req(wpa_s, mgmt->sa, pos, end - pos);
- break;
- case WNM_COLLOCATED_INTERFERENCE_REQ:
- ieee802_11_rx_wnm_coloc_intf_req(wpa_s, mgmt->sa, pos,
- end - pos);
- break;
- default:
- wpa_printf(MSG_ERROR, "WNM: Unknown request");
- break;
- }
-}
-
-
-int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8 dialog_token,
- const struct wpabuf *elems)
-{
- struct wpabuf *buf;
- int ret;
-
- if (wpa_s->wpa_state < WPA_ASSOCIATED || !elems)
- return -1;
-
- wpa_printf(MSG_DEBUG, "WNM: Send Collocated Interference Report to "
- MACSTR " (dialog token %u)",
- MAC2STR(wpa_s->bssid), dialog_token);
-
- buf = wpabuf_alloc(3 + wpabuf_len(elems));
- if (!buf)
- return -1;
-
- wpabuf_put_u8(buf, WLAN_ACTION_WNM);
- wpabuf_put_u8(buf, WNM_COLLOCATED_INTERFERENCE_REPORT);
- wpabuf_put_u8(buf, dialog_token);
- wpabuf_put_buf(buf, elems);
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head_u8(buf), wpabuf_len(buf), 0);
- wpabuf_free(buf);
- return ret;
-}
-
-
-void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
- struct wpabuf *elems)
-{
- wpabuf_free(wpa_s->coloc_intf_elems);
- if (elems && wpabuf_len(elems) == 0) {
- wpabuf_free(elems);
- elems = NULL;
- }
- wpa_s->coloc_intf_elems = elems;
-
- if (wpa_s->conf->coloc_intf_reporting && wpa_s->coloc_intf_elems &&
- wpa_s->coloc_intf_dialog_token &&
- (wpa_s->coloc_intf_auto_report == 1 ||
- wpa_s->coloc_intf_auto_report == 3)) {
- /* TODO: Check that there has not been less than
- * wpa_s->coloc_intf_timeout * 200 TU from the last report.
- */
- wnm_send_coloc_intf_report(wpa_s,
- wpa_s->coloc_intf_dialog_token,
- wpa_s->coloc_intf_elems);
- }
-}
-
-
-void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WNM
- wpa_s->coloc_intf_dialog_token = 0;
- wpa_s->coloc_intf_auto_report = 0;
-#endif /* CONFIG_WNM */
-}
diff --git a/wpa_supplicant/wnm_sta.h b/wpa_supplicant/wnm_sta.h
deleted file mode 100644
index 29625f8ca943..000000000000
--- a/wpa_supplicant/wnm_sta.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * IEEE 802.11v WNM related functions and structures
- * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WNM_STA_H
-#define WNM_STA_H
-
-struct measurement_pilot {
- u8 measurement_pilot;
- u8 subelem_len;
- u8 subelems[255];
-};
-
-struct multiple_bssid {
- u8 max_bssid_indicator;
- u8 subelem_len;
- u8 subelems[255];
-};
-
-struct neighbor_report {
- u8 bssid[ETH_ALEN];
- u32 bssid_info;
- u8 regulatory_class;
- u8 channel_number;
- u8 phy_type;
- u8 preference; /* valid if preference_present=1 */
- u16 tsf_offset; /* valid if tsf_present=1 */
- u16 beacon_int; /* valid if tsf_present=1 */
- char country[2]; /* valid if country_present=1 */
- u8 rm_capab[5]; /* valid if rm_capab_present=1 */
- u16 bearing; /* valid if bearing_present=1 */
- u16 rel_height; /* valid if bearing_present=1 */
- u32 distance; /* valid if bearing_present=1 */
- u64 bss_term_tsf; /* valid if bss_term_present=1 */
- u16 bss_term_dur; /* valid if bss_term_present=1 */
- unsigned int preference_present:1;
- unsigned int tsf_present:1;
- unsigned int country_present:1;
- unsigned int rm_capab_present:1;
- unsigned int bearing_present:1;
- unsigned int bss_term_present:1;
- unsigned int acceptable:1;
-#ifdef CONFIG_MBO
- unsigned int is_first:1;
-#endif /* CONFIG_MBO */
- struct measurement_pilot *meas_pilot;
- struct multiple_bssid *mul_bssid;
- int freq;
-};
-
-
-int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
- u8 action, u16 intval, struct wpabuf *tfs_req);
-
-void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len);
-
-int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
- u8 query_reason,
- const char *btm_candidates,
- int cand_list);
-
-void wnm_deallocate_memory(struct wpa_supplicant *wpa_s);
-int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8 dialog_token,
- const struct wpabuf *elems);
-void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
- struct wpabuf *elems);
-
-
-#ifdef CONFIG_WNM
-
-int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail);
-void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s);
-
-#else /* CONFIG_WNM */
-
-static inline int wnm_scan_process(struct wpa_supplicant *wpa_s,
- int reply_on_fail)
-{
- return 0;
-}
-
-static inline void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s)
-{
-}
-
-#endif /* CONFIG_WNM */
-
-#endif /* WNM_STA_H */
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
deleted file mode 100644
index 17b14c824ddb..000000000000
--- a/wpa_supplicant/wpa_cli.c
+++ /dev/null
@@ -1,5083 +0,0 @@
-/*
- * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#ifdef CONFIG_CTRL_IFACE
-
-#ifdef CONFIG_CTRL_IFACE_UNIX
-#include <dirent.h>
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-
-#include "common/cli.h"
-#include "common/wpa_ctrl.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/edit.h"
-#include "utils/list.h"
-#include "common/version.h"
-#include "common/ieee802_11_defs.h"
-#ifdef ANDROID
-#include <cutils/properties.h>
-#endif /* ANDROID */
-
-
-static const char *const wpa_cli_version =
-"wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors";
-
-#define VENDOR_ELEM_FRAME_ID \
- " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
- "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
- "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
- "11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
-
-static struct wpa_ctrl *ctrl_conn;
-static struct wpa_ctrl *mon_conn;
-static int wpa_cli_quit = 0;
-static int wpa_cli_attached = 0;
-static int wpa_cli_connected = -1;
-static int wpa_cli_last_id = 0;
-#ifndef CONFIG_CTRL_IFACE_DIR
-#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
-#endif /* CONFIG_CTRL_IFACE_DIR */
-static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
-static const char *client_socket_dir = NULL;
-static char *ctrl_ifname = NULL;
-static const char *global = NULL;
-static const char *pid_file = NULL;
-static const char *action_file = NULL;
-static int reconnect = 0;
-static int ping_interval = 5;
-static int interactive = 0;
-static char *ifname_prefix = NULL;
-
-static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
-static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
-static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
-static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
-static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */
-static DEFINE_DL_LIST(creds); /* struct cli_txt_entry */
-#ifdef CONFIG_AP
-static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */
-#endif /* CONFIG_AP */
-
-
-static void print_help(const char *cmd);
-static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
-static void wpa_cli_close_connection(void);
-static char * wpa_cli_get_default_ifname(void);
-static char ** wpa_list_cmd_list(void);
-static void update_creds(struct wpa_ctrl *ctrl);
-static void update_networks(struct wpa_ctrl *ctrl);
-static void update_stations(struct wpa_ctrl *ctrl);
-static void update_ifnames(struct wpa_ctrl *ctrl);
-
-
-static void usage(void)
-{
- printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvBr] "
- "[-a<action file>] \\\n"
- " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
- "\\\n"
- " [-s<wpa_client_socket_file_path>] "
- "[command..]\n"
- " -h = help (show this usage text)\n"
- " -v = shown version information\n"
- " -a = run in daemon mode executing the action file based on "
- "events from\n"
- " wpa_supplicant\n"
- " -r = try to reconnect when client socket is disconnected.\n"
- " This is useful only when used with -a.\n"
- " -B = run a daemon in the background\n"
- " default path: " CONFIG_CTRL_IFACE_DIR "\n"
- " default interface: first interface found in socket path\n");
- print_help(NULL);
-}
-
-
-static int wpa_cli_show_event(const char *event)
-{
- const char *start;
-
- start = os_strchr(event, '>');
- if (start == NULL)
- return 1;
-
- start++;
- /*
- * Skip BSS added/removed events since they can be relatively frequent
- * and are likely of not much use for an interactive user.
- */
- if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
- str_starts(start, WPA_EVENT_BSS_REMOVED))
- return 0;
-
- return 1;
-}
-
-
-static int wpa_cli_open_connection(const char *ifname, int attach)
-{
-#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
- ctrl_conn = wpa_ctrl_open(ifname);
- if (ctrl_conn == NULL)
- return -1;
-
- if (attach && interactive)
- mon_conn = wpa_ctrl_open(ifname);
- else
- mon_conn = NULL;
-#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
- char *cfile = NULL;
- int flen, res;
-
- if (ifname == NULL)
- return -1;
-
-#ifdef ANDROID
- if (access(ctrl_iface_dir, F_OK) < 0) {
- cfile = os_strdup(ifname);
- if (cfile == NULL)
- return -1;
- }
-#endif /* ANDROID */
-
- if (client_socket_dir && client_socket_dir[0] &&
- access(client_socket_dir, F_OK) < 0) {
- perror(client_socket_dir);
- os_free(cfile);
- return -1;
- }
-
- if (cfile == NULL) {
- flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
- cfile = os_malloc(flen);
- if (cfile == NULL)
- return -1;
- res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
- ifname);
- if (os_snprintf_error(flen, res)) {
- os_free(cfile);
- return -1;
- }
- }
-
- ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir);
- if (ctrl_conn == NULL) {
- os_free(cfile);
- return -1;
- }
-
- if (attach && interactive)
- mon_conn = wpa_ctrl_open2(cfile, client_socket_dir);
- else
- mon_conn = NULL;
- os_free(cfile);
-#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
-
- if (mon_conn) {
- if (wpa_ctrl_attach(mon_conn) == 0) {
- wpa_cli_attached = 1;
- if (interactive)
- eloop_register_read_sock(
- wpa_ctrl_get_fd(mon_conn),
- wpa_cli_mon_receive, NULL, NULL);
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- wpa_cli_close_connection();
- return -1;
- }
- }
-
- return 0;
-}
-
-
-static void wpa_cli_close_connection(void)
-{
- if (ctrl_conn == NULL)
- return;
-
- if (wpa_cli_attached) {
- wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
- wpa_cli_attached = 0;
- }
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- if (mon_conn) {
- eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
- wpa_ctrl_close(mon_conn);
- mon_conn = NULL;
- }
-}
-
-
-static void wpa_cli_msg_cb(char *msg, size_t len)
-{
- printf("%s\n", msg);
-}
-
-
-static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print)
-{
- char buf[4096];
- size_t len;
- int ret;
-
- if (ctrl_conn == NULL) {
- printf("Not connected to wpa_supplicant - command dropped.\n");
- return -1;
- }
- if (ifname_prefix) {
- os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
- ifname_prefix, cmd);
- buf[sizeof(buf) - 1] = '\0';
- cmd = buf;
- }
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
- wpa_cli_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- return -2;
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- return -1;
- }
- if (print) {
- buf[len] = '\0';
- printf("%s", buf);
- if (interactive && len > 0 && buf[len - 1] != '\n')
- printf("\n");
- }
- return 0;
-}
-
-
-static int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd)
-{
- return _wpa_ctrl_command(ctrl, cmd, 1);
-}
-
-
-static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
- int argc, char *argv[])
-{
- char buf[4096];
- if (argc < min_args) {
- printf("Invalid %s command - at least %d argument%s "
- "required.\n", cmd, min_args,
- min_args > 1 ? "s are" : " is");
- return -1;
- }
- if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
- return -1;
- return wpa_ctrl_command(ctrl, buf);
-}
-
-
-static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "IFNAME");
-}
-
-
-static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
- return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
- if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
- return wpa_ctrl_command(ctrl, "STATUS-WPS");
- if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
- return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
-#ifdef ANDROID
- if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
- return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
-#endif /* ANDROID */
- return wpa_ctrl_command(ctrl, "STATUS");
-}
-
-
-static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "PING");
-}
-
-
-static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "RELOG");
-}
-
-
-static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "MIB");
-}
-
-
-static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "PMKSA");
-}
-
-
-static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
-}
-
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-
-static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv);
-}
-
-
-#ifdef CONFIG_MESH
-
-static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv);
-}
-
-
-static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv);
-}
-
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
-
-static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- print_help(argc > 0 ? argv[0] : NULL);
- return 0;
-}
-
-
-static char ** wpa_cli_complete_help(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = wpa_list_cmd_list();
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- printf("%s\n\n%s\n", wpa_cli_version, cli_full_license);
- return 0;
-}
-
-
-static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- wpa_cli_quit = 1;
- if (interactive)
- eloop_terminate();
- return 0;
-}
-
-
-static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256];
- int res;
-
- if (argc == 1) {
- res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
- if (os_snprintf_error(sizeof(cmd), res)) {
- printf("Too long SET command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
-
- return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_set(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- const char *fields[] = {
- /* runtime values */
- "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
- "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
- "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
- "wps_fragment_size", "wps_version_number", "ampdu",
- "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
- "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
- "no_keep_alive",
- /* global configuration parameters */
-#ifdef CONFIG_CTRL_IFACE
- "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
-#endif /* CONFIG_CTRL_IFACE */
- "eapol_version", "ap_scan", "bgscan",
-#ifdef CONFIG_MESH
- "user_mpm", "max_peer_links", "mesh_max_inactivity",
- "dot11RSNASAERetransPeriod",
-#endif /* CONFIG_MESH */
- "disable_scan_offload", "fast_reauth", "opensc_engine_path",
- "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
- "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
- "dot11RSNAConfigPMKLifetime",
- "dot11RSNAConfigPMKReauthThreshold",
- "dot11RSNAConfigSATimeout",
-#ifndef CONFIG_NO_CONFIG_WRITE
- "update_config",
-#endif /* CONFIG_NO_CONFIG_WRITE */
- "load_dynamic_eap",
-#ifdef CONFIG_WPS
- "uuid", "device_name", "manufacturer", "model_name",
- "model_number", "serial_number", "device_type", "os_version",
- "config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- "sec_device_type",
- "p2p_listen_reg_class", "p2p_listen_channel",
- "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
- "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
- "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
- "p2p_no_go_freq", "p2p_add_cli_chan",
- "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
- "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
- "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
- "ip_addr_start", "ip_addr_end", "p2p_go_edmg",
-#endif /* CONFIG_P2P */
- "country", "bss_max_count", "bss_expiration_age",
- "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
- "max_num_sta", "disassoc_low_ack", "ap_isolate",
-#ifdef CONFIG_HS20
- "hs20",
-#endif /* CONFIG_HS20 */
- "interworking", "hessid", "access_network_type", "pbc_in_m1",
- "go_interworking", "go_access_network_type", "go_internet",
- "go_venue_group", "go_venue_type",
- "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
- "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
- "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
- "sae_groups", "dtim_period", "beacon_int",
- "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
- "scan_cur_freq", "scan_res_valid_for_connect",
- "sched_scan_interval",
- "tdls_external_control", "osu_dir", "wowlan_triggers",
- "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
- "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
- "reassoc_same_bss_optim", "wps_priority",
- "ap_assocresp_elements",
-#ifdef CONFIG_TESTING_OPTIONS
- "ignore_auth_resp",
-#endif /* CONFIG_TESTING_OPTIONS */
- "relative_rssi", "relative_band_adjust",
- "extended_key_id",
- };
- int i, num_fields = ARRAY_SIZE(fields);
-
- if (arg == 1) {
- char **res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(fields[i]);
- if (res[i] == NULL)
- return res;
- }
- return res;
- }
-
- if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
- return cli_txt_list_array(&bsses);
-
- return NULL;
-}
-
-static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DUMP");
-}
-
-
-static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DRIVER_FLAGS");
-}
-
-
-static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_get(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- const char *fields[] = {
-#ifdef CONFIG_CTRL_IFACE
- "ctrl_interface", "ctrl_interface_group",
-#endif /* CONFIG_CTRL_IFACE */
- "eapol_version", "ap_scan",
-#ifdef CONFIG_MESH
- "user_mpm", "max_peer_links", "mesh_max_inactivity",
-#endif /* CONFIG_MESH */
- "disable_scan_offload", "fast_reauth", "opensc_engine_path",
- "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
- "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
- "dot11RSNAConfigPMKLifetime",
- "dot11RSNAConfigPMKReauthThreshold",
- "dot11RSNAConfigSATimeout",
-#ifndef CONFIG_NO_CONFIG_WRITE
- "update_config",
-#endif /* CONFIG_NO_CONFIG_WRITE */
-#ifdef CONFIG_WPS
- "device_name", "manufacturer", "model_name", "model_number",
- "serial_number", "config_methods", "wps_cred_processing",
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
- "p2p_listen_reg_class", "p2p_listen_channel",
- "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
- "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
- "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
- "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
- "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
- "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
- "ip_addr_start", "ip_addr_end",
-#endif /* CONFIG_P2P */
- "bss_max_count", "bss_expiration_age",
- "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
- "max_num_sta", "disassoc_low_ack", "ap_isolate",
-#ifdef CONFIG_HS20
- "hs20",
-#endif /* CONFIG_HS20 */
- "interworking", "access_network_type", "pbc_in_m1", "autoscan",
- "go_interworking", "go_access_network_type", "go_internet",
- "go_venue_group", "go_venue_type",
- "wps_nfc_dev_pw_id", "ext_password_backend",
- "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
- "dtim_period", "beacon_int", "ignore_old_scan_res",
- "scan_cur_freq", "scan_res_valid_for_connect",
- "sched_scan_interval",
- "sched_scan_start_delay",
- "tdls_external_control", "osu_dir", "wowlan_triggers",
- "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
- "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
- "reassoc_same_bss_optim", "extended_key_id"
- };
- int i, num_fields = ARRAY_SIZE(fields);
-
- if (arg == 1) {
- char **res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(fields[i]);
- if (res[i] == NULL)
- return res;
- }
- return res;
- }
-
- return NULL;
-}
-
-
-static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "LOGOFF");
-}
-
-
-static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "LOGON");
-}
-
-
-static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "REASSOCIATE");
-}
-
-
-static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "REATTACH");
-}
-
-
-static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256];
- int res;
-
- if (argc < 1)
- res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
- else
- res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
- if (os_snprintf_error(sizeof(cmd), res)) {
- printf("Too long BSS_FLUSH command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc == 0) {
- printf("Invalid WPS_PIN command: need one or two arguments:\n"
- "- BSSID: use 'any' to select any\n"
- "- PIN: optional, used only with devices that have no "
- "display\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "WPS_CANCEL");
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- int ret;
- char *buf;
- size_t buflen;
-
- if (argc != 1) {
- printf("Invalid 'wps_nfc_tag_read' command - one argument "
- "is required.\n");
- return -1;
- }
-
- buflen = 18 + os_strlen(argv[0]);
- buf = os_malloc(buflen);
- if (buf == NULL)
- return -1;
- os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
-
- ret = wpa_ctrl_command(ctrl, buf);
- os_free(buf);
-
- return ret;
-}
-
-
-static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
-}
-
-#endif /* CONFIG_WPS_NFC */
-
-
-static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256];
- int res;
-
- if (argc == 2)
- res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
- argv[0], argv[1]);
- else if (argc == 5 || argc == 6) {
- char ssid_hex[2 * SSID_MAX_LEN + 1];
- char key_hex[2 * 64 + 1];
- int i;
-
- ssid_hex[0] = '\0';
- for (i = 0; i < SSID_MAX_LEN; i++) {
- if (argv[2][i] == '\0')
- break;
- os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
- }
-
- key_hex[0] = '\0';
- if (argc == 6) {
- for (i = 0; i < 64; i++) {
- if (argv[5][i] == '\0')
- break;
- os_snprintf(&key_hex[i * 2], 3, "%02x",
- argv[5][i]);
- }
- }
-
- res = os_snprintf(cmd, sizeof(cmd),
- "WPS_REG %s %s %s %s %s %s",
- argv[0], argv[1], ssid_hex, argv[3], argv[4],
- key_hex);
- } else {
- printf("Invalid WPS_REG command: need two arguments:\n"
- "- BSSID of the target AP\n"
- "- AP PIN\n");
- printf("Alternatively, six arguments can be used to "
- "reconfigure the AP:\n"
- "- BSSID of the target AP\n"
- "- AP PIN\n"
- "- new SSID\n"
- "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
- "- new encr (NONE, WEP, TKIP, CCMP)\n"
- "- new key\n");
- return -1;
- }
-
- if (os_snprintf_error(sizeof(cmd), res)) {
- printf("Too long WPS_REG command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
-
-}
-
-
-static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc < 2) {
- printf("Invalid WPS_ER_PIN command: need at least two "
- "arguments:\n"
- "- UUID: use 'any' to select any\n"
- "- PIN: Enrollee PIN\n"
- "optional: - Enrollee MAC address\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 2) {
- printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
- "- UUID: specify which AP to use\n"
- "- PIN: AP PIN\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 2) {
- printf("Invalid WPS_ER_SET_CONFIG command: need two "
- "arguments:\n"
- "- UUID: specify which AP to use\n"
- "- Network configuration id\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[256];
- int res;
-
- if (argc == 5 || argc == 6) {
- char ssid_hex[2 * SSID_MAX_LEN + 1];
- char key_hex[2 * 64 + 1];
- int i;
-
- ssid_hex[0] = '\0';
- for (i = 0; i < SSID_MAX_LEN; i++) {
- if (argv[2][i] == '\0')
- break;
- os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
- }
-
- key_hex[0] = '\0';
- if (argc == 6) {
- for (i = 0; i < 64; i++) {
- if (argv[5][i] == '\0')
- break;
- os_snprintf(&key_hex[i * 2], 3, "%02x",
- argv[5][i]);
- }
- }
-
- res = os_snprintf(cmd, sizeof(cmd),
- "WPS_ER_CONFIG %s %s %s %s %s %s",
- argv[0], argv[1], ssid_hex, argv[3], argv[4],
- key_hex);
- } else {
- printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
- "- AP UUID\n"
- "- AP PIN\n"
- "- new SSID\n"
- "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
- "- new encr (NONE, WEP, TKIP, CCMP)\n"
- "- new key\n");
- return -1;
- }
-
- if (os_snprintf_error(sizeof(cmd), res)) {
- printf("Too long WPS_ER_CONFIG command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-#ifdef CONFIG_WPS_NFC
-static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 2) {
- printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
- "arguments:\n"
- "- WPS/NDEF: token format\n"
- "- UUID: specify which AP to use\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
-}
-#endif /* CONFIG_WPS_NFC */
-
-
-static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid IDENTITY command: needs two arguments "
- "(network id and identity)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long IDENTITY command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long IDENTITY command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid PASSWORD command: needs two arguments "
- "(network id and password)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid NEW_PASSWORD command: needs two arguments "
- "(network id and password)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long NEW_PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long NEW_PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid PIN command: needs two arguments "
- "(network id and pin)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PIN command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PIN command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid OTP command: needs two arguments (network "
- "id and password)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long OTP command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long OTP command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid SIM command: needs two arguments "
- "(network id and SIM operation response)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long SIM command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long SIM command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PSK_PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PSK_PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[256], *pos, *end;
- int i, ret;
-
- if (argc < 2) {
- printf("Invalid PASSPHRASE command: needs two arguments "
- "(network id and passphrase)\n");
- return -1;
- }
-
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
- argv[0], argv[1]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (os_snprintf_error(end - pos, ret)) {
- printf("Too long PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- }
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc < 2) {
- printf("Invalid BSSID command: needs two arguments (network "
- "id and BSSID)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_bssid_ignore(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "BSSID_IGNORE", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "LIST_NETWORKS", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
- if (interactive)
- update_networks(ctrl);
- return res;
-}
-
-
-static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
- if (interactive)
- update_networks(ctrl);
- return res;
-}
-
-
-static void wpa_cli_show_network_variables(void)
-{
- printf("set_network variables:\n"
- " ssid (network name, SSID)\n"
- " psk (WPA passphrase or pre-shared key)\n"
- " key_mgmt (key management protocol)\n"
- " identity (EAP identity)\n"
- " password (EAP password)\n"
- " ...\n"
- "\n"
- "Note: Values are entered in the same format as the "
- "configuration file is using,\n"
- "i.e., strings values need to be inside double quotation "
- "marks.\n"
- "For example: set_network 1 ssid \"network name\"\n"
- "\n"
- "Please see wpa_supplicant.conf documentation for full list "
- "of\navailable variables.\n");
-}
-
-
-static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc == 0) {
- wpa_cli_show_network_variables();
- return 0;
- }
-
- if (argc < 3) {
- printf("Invalid SET_NETWORK command: needs three arguments\n"
- "(network id, variable name, and value)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
-}
-
-
-static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc == 0) {
- wpa_cli_show_network_variables();
- return 0;
- }
-
- if (argc != 2) {
- printf("Invalid GET_NETWORK command: needs two arguments\n"
- "(network id and variable name)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
-}
-
-
-static const char *network_fields[] = {
- "ssid", "scan_ssid", "bssid", "bssid_ignore",
- "bssid_accept", "psk", "proto", "key_mgmt",
- "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
- "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1",
- "vht_center_freq2", "ht", "edmg",
-#ifdef IEEE8021X_EAPOL
- "eap", "identity", "anonymous_identity", "password", "ca_cert",
- "ca_path", "client_cert", "private_key", "private_key_passwd",
- "dh_file", "subject_match", "altsubject_match",
- "check_cert_subject",
- "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
- "client_cert2", "private_key2", "private_key2_passwd",
- "dh_file2", "subject_match2", "altsubject_match2",
- "check_cert_subject2",
- "domain_suffix_match2", "domain_match2", "phase1", "phase2",
- "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
- "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
- "engine", "engine2", "eapol_flags", "sim_num",
- "openssl_ciphers", "erp",
-#endif /* IEEE8021X_EAPOL */
- "wep_key0", "wep_key1", "wep_key2", "wep_key3",
- "wep_tx_keyidx", "priority",
-#ifdef IEEE8021X_EAPOL
- "eap_workaround", "pac_file", "fragment_size", "ocsp",
-#endif /* IEEE8021X_EAPOL */
- "mode",
- "proactive_key_caching", "disabled", "id_str",
- "ieee80211w",
- "mixed_cell", "frequency", "fixed_freq",
-#ifdef CONFIG_MESH
- "no_auto_peer", "mesh_rssi_threshold",
- "mesh_basic_rates", "dot11MeshMaxRetries",
- "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
- "dot11MeshHoldingTimeout",
-#endif /* CONFIG_MESH */
- "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
- "wpa_deny_ptk0_rekey",
- "enable_edmg", "edmg_channel",
-#ifdef CONFIG_P2P
- "go_p2p_dev_addr", "p2p_client_list", "psk_list",
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_HT_OVERRIDES
- "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
- "ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
- "ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc",
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
- "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
- "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
- "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
- "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
- "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
-#endif /* CONFIG_VHT_OVERRIDES */
-#ifdef CONFIG_HE_OVERRIDES
- "disable_he",
-#endif /* CONFIG_HE_OVERRIDES */
- "ap_max_inactivity", "dtim_period", "beacon_int",
-#ifdef CONFIG_MACSEC
- "macsec_policy",
- "macsec_integ_only",
- "macsec_replay_protect",
- "macsec_replay_window",
- "macsec_port",
- "mka_priority",
-#endif /* CONFIG_MACSEC */
-#ifdef CONFIG_HS20
- "update_identifier",
-#endif /* CONFIG_HS20 */
- "mac_addr", "pbss", "wps_disabled"
-};
-
-
-static char ** wpa_cli_complete_network(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- int i, num_fields = ARRAY_SIZE(network_fields);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&networks);
- break;
- case 2:
- res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(network_fields[i]);
- if (res[i] == NULL)
- break;
- }
- }
- return res;
-}
-
-
-static char ** wpa_cli_complete_network_id(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- if (arg == 1)
- return cli_txt_list_array(&networks);
- return NULL;
-}
-
-
-static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc == 0) {
- wpa_cli_show_network_variables();
- return 0;
- }
-
- if (argc < 3) {
- printf("Invalid DUP_NETWORK command: needs three arguments\n"
- "(src netid, dest netid, and variable name)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_dup_network(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- int i, num_fields = ARRAY_SIZE(network_fields);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- case 2:
- res = cli_txt_list_array(&networks);
- break;
- case 3:
- res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(network_fields[i]);
- if (res[i] == NULL)
- break;
- }
- }
- return res;
-}
-
-
-static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "LIST_CREDS");
-}
-
-
-static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- int res = wpa_ctrl_command(ctrl, "ADD_CRED");
- if (interactive)
- update_creds(ctrl);
- return res;
-}
-
-
-static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- int res = wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
- if (interactive)
- update_creds(ctrl);
- return res;
-}
-
-
-static const char * const cred_fields[] = {
- "temporary", "priority", "sp_priority", "pcsc", "eap",
- "update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home",
- "min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load",
- "req_conn_capab", "ocsp", "sim_num", "realm", "username", "password",
- "ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi",
- "ca_cert_id", "cert_id", "key_id", "engine_id", "engine",
- "milenage", "domain_suffix_match", "domain", "phase1", "phase2",
- "roaming_consortium", "required_roaming_consortium", "excluded_ssid",
- "roaming_partner", "provisioning_sp"
-};
-
-
-static char ** wpa_cli_complete_cred(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- int i, num_fields = ARRAY_SIZE(cred_fields);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&creds);
- break;
- case 2:
- res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(cred_fields[i]);
- if (res[i] == NULL)
- break;
- }
- }
- return res;
-}
-
-
-static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc != 3) {
- printf("Invalid SET_CRED command: needs three arguments\n"
- "(cred id, variable name, and value)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
-}
-
-
-static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc != 2) {
- printf("Invalid GET_CRED command: needs two arguments\n"
- "(cred id, variable name)\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DISCONNECT");
-}
-
-
-static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "RECONNECT");
-}
-
-
-static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
-}
-
-
-static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
-}
-
-
-static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "ABORT_SCAN");
-}
-
-
-static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_bss(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&bsses);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc < 1 || argc > 3) {
- printf("Invalid GET_CAPABILITY command: need at least one argument and max three arguments\n");
- return -1;
- }
-
- if (argc > 1 && os_strcmp(argv[0], "key_mgmt") != 0 &&
- os_strncmp(argv[1], "iftype=", 7) == 0) {
- printf("Invalid GET_CAPABILITY command: 'iftype=' param is allowed only for 'key_mgmt'\n");
- return -1;
- }
-
- if (argc == 2 && os_strcmp(argv[1], "strict") != 0 &&
- os_strncmp(argv[1], "iftype=", 7) != 0) {
- printf("Invalid GET_CAPABILITY command: the second argument, if any, must be 'strict' OR 'iftype=<iftype_name>'\n");
- return -1;
- }
-
- if (argc == 3 && os_strcmp(argv[2], "strict") != 0) {
- printf("Invalid GET_CAPABILITY command: the third argument, if any, must be 'strict'\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_get_capability(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- const char *fields[] = {
- "eap", "pairwise", "group", "group_mgmt", "key_mgmt",
- "proto", "auth_alg", "modes", "channels", "freq",
-#ifdef CONFIG_TDLS
- "tdls",
-#endif /* CONFIG_TDLS */
-#ifdef CONFIG_ERP
- "erp",
-#endif /* CONFIG_ERP */
-#ifdef CONFIG_FIPS
- "fips",
-#endif /* CONFIG_FIPS */
-#ifdef CONFIG_ACS
- "acs",
-#endif /* CONFIG_ACS */
- };
- const char *iftypes[] = {
- "iftype=STATION", "iftype=AP", "iftype=P2P_CLIENT",
- "iftype=P2P_GO", "iftype=AP_VLAN", "iftype=IBSS", "iftype=NAN",
- "iftype=P2P_DEVICE", "iftype=MESH",
- };
- int i, num_fields = ARRAY_SIZE(fields);
- int num_iftypes = ARRAY_SIZE(iftypes);
- char **res = NULL;
-
- if (arg == 1) {
- res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(fields[i]);
- if (res[i] == NULL)
- return res;
- }
- }
- if (arg == 2) {
- /* the second argument can be "iftype=<iftype_name>" OR
- * "strict" */
- res = os_calloc(num_iftypes + 2, sizeof(char *));
- if (!res)
- return NULL;
- res[0] = os_strdup("strict");
- if (!res[0])
- return res;
- for (i = 0; i < num_iftypes; i++) {
- res[i + 1] = os_strdup(iftypes[i]);
- if (!res[i + 1])
- return res;
- }
- }
- if (arg == 3) {
- res = os_calloc(1 + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- res[0] = os_strdup("strict");
- }
- return res;
-}
-
-
-static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
-{
- printf("Available interfaces:\n");
- return wpa_ctrl_command(ctrl, "INTERFACES");
-}
-
-
-static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc < 1) {
- wpa_cli_list_interfaces(ctrl);
- return 0;
- }
-
- wpa_cli_close_connection();
- os_free(ctrl_ifname);
- ctrl_ifname = os_strdup(argv[0]);
- if (!ctrl_ifname) {
- printf("Failed to allocate memory\n");
- return 0;
- }
-
- if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
- printf("Connected to interface '%s'.\n", ctrl_ifname);
- } else {
- printf("Could not connect to interface '%s' - re-trying\n",
- ctrl_ifname);
- }
- return 0;
-}
-
-
-static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "RECONFIGURE");
-}
-
-
-static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "TERMINATE");
-}
-
-
-static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[256];
- int res;
-
- if (argc < 1) {
- printf("Invalid INTERFACE_ADD command: needs at least one "
- "argument (interface name)\n"
- "All arguments: ifname confname driver ctrl_interface "
- "driver_param bridge_name [create]\n");
- return -1;
- }
-
- /*
- * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
- * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
- */
- res = os_snprintf(cmd, sizeof(cmd),
- "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
- argv[0],
- argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
- argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
- argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
- argc > 7 ? argv[7] : "");
- if (os_snprintf_error(sizeof(cmd), res))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
-}
-
-
-#ifdef CONFIG_AP
-static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_sta(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&stations);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd,
- char *addr, size_t addr_len, int print)
-{
- char buf[4096], *pos;
- size_t len;
- int ret;
-
- if (ctrl_conn == NULL) {
- printf("Not connected to hostapd - command dropped.\n");
- return -1;
- }
- if (ifname_prefix) {
- os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
- ifname_prefix, cmd);
- buf[sizeof(buf) - 1] = '\0';
- cmd = buf;
- }
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
- wpa_cli_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- return -2;
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- return -1;
- }
-
- buf[len] = '\0';
- if (os_memcmp(buf, "FAIL", 4) == 0 ||
- os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0)
- return -1;
- if (print)
- printf("%s", buf);
-
- pos = buf;
- while (*pos != '\0' && *pos != '\n')
- pos++;
- *pos = '\0';
- os_strlcpy(addr, buf, addr_len);
- return 0;
-}
-
-
-static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char addr[32], cmd[64];
-
- if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1))
- return 0;
- do {
- os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
- } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0);
-
- return -1;
-}
-
-
-static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char addr[32], cmd[64];
-
- if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0))
- return 0;
- do {
- if (os_strcmp(addr, "") != 0)
- printf("%s\n", addr);
- os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
- } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0);
-
- return 0;
-}
-
-
-static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_deauthenticate(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&stations);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_disassociate(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&stations);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
-}
-
-#endif /* CONFIG_AP */
-
-
-static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "SUSPEND");
-}
-
-
-static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "RESUME");
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DROP_SA");
-}
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
-}
-
-
-#ifdef CONFIG_MESH
-
-static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv);
-}
-
-#endif /* CONFIG_MESH */
-
-
-#ifdef CONFIG_P2P
-
-static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
-{
- char **res = NULL;
- int arg = get_cmd_arg_num(str, pos);
-
- res = os_calloc(6, sizeof(char *));
- if (res == NULL)
- return NULL;
- res[0] = os_strdup("type=social");
- if (res[0] == NULL) {
- os_free(res);
- return NULL;
- }
- res[1] = os_strdup("type=progressive");
- if (res[1] == NULL)
- return res;
- res[2] = os_strdup("delay=");
- if (res[2] == NULL)
- return res;
- res[3] = os_strdup("dev_id=");
- if (res[3] == NULL)
- return res;
- if (arg == 1)
- res[4] = os_strdup("[timeout]");
-
- return res;
-}
-
-
-static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
-}
-
-
-static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&p2p_peers);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&p2p_groups);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 2 && argc != 3) {
- printf("Invalid P2P_PROV_DISC command: needs at least "
- "two arguments, address and config method\n"
- "(display, keypad, or pbc) and an optional join\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
-}
-
-
-static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[4096];
-
- if (argc < 2) {
- printf("Invalid P2P_SERV_DISC_REQ command: needs two "
- "or more arguments (address and TLVs)\n");
- return -1;
- }
-
- if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
- return -1;
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
- int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[4096];
- int res;
-
- if (argc != 4) {
- printf("Invalid P2P_SERV_DISC_RESP command: needs four "
- "arguments (freq, address, dialog token, and TLVs)\n");
- return -1;
- }
-
- res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
- argv[0], argv[1], argv[2], argv[3]);
- if (os_snprintf_error(sizeof(cmd), res))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
-}
-
-
-static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
- int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
-}
-
-
-static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc < 3) {
- printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc < 5 || argc > 6) {
- printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
- "arguments\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[4096];
- int res;
-
- if (argc != 2 && argc != 3) {
- printf("Invalid P2P_SERVICE_DEL command: needs two or three "
- "arguments\n");
- return -1;
- }
-
- if (argc == 3)
- res = os_snprintf(cmd, sizeof(cmd),
- "P2P_SERVICE_DEL %s %s %s",
- argv[0], argv[1], argv[2]);
- else
- res = os_snprintf(cmd, sizeof(cmd),
- "P2P_SERVICE_DEL %s %s",
- argv[0], argv[1]);
- if (os_snprintf_error(sizeof(cmd), res))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
- int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
- int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = cli_txt_list_array(&p2p_peers);
- break;
- }
-
- return res;
-}
-
-
-static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd,
- char *addr, size_t addr_len,
- int discovered)
-{
- char buf[4096], *pos;
- size_t len;
- int ret;
-
- if (ctrl_conn == NULL)
- return -1;
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
- wpa_cli_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- return -2;
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- return -1;
- }
-
- buf[len] = '\0';
- if (os_memcmp(buf, "FAIL", 4) == 0)
- return -1;
-
- pos = buf;
- while (*pos != '\0' && *pos != '\n')
- pos++;
- *pos++ = '\0';
- os_strlcpy(addr, buf, addr_len);
- if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
- printf("%s\n", addr);
- return 0;
-}
-
-
-static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char addr[32], cmd[64];
- int discovered;
-
- discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
-
- if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
- addr, sizeof(addr), discovered))
- return -1;
- do {
- os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
- } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
- discovered) == 0);
-
- return 0;
-}
-
-
-static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
-}
-
-
-static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- const char *fields[] = {
- "discoverability",
- "managed",
- "listen_channel",
- "ssid_postfix",
- "noa",
- "ps",
- "oppps",
- "ctwindow",
- "disabled",
- "conc_pref",
- "force_long_sd",
- "peer_filter",
- "cross_connect",
- "go_apsd",
- "client_apsd",
- "disallow_freq",
- "disc_int",
- "per_sta_psk",
- };
- int i, num_fields = ARRAY_SIZE(fields);
-
- if (arg == 1) {
- char **res = os_calloc(num_fields + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < num_fields; i++) {
- res[i] = os_strdup(fields[i]);
- if (res[i] == NULL)
- return res;
- }
- return res;
- }
-
- if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
- return cli_txt_list_array(&p2p_peers);
-
- return NULL;
-}
-
-
-static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_FLUSH");
-}
-
-
-static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "P2P_CANCEL");
-}
-
-
-static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 0 && argc != 2 && argc != 4) {
- printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
- "(preferred duration, interval; in microsecods).\n"
- "Optional second pair can be used to provide "
- "acceptable values.\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- if (argc != 0 && argc != 2) {
- printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
- "(availability period, availability interval; in "
- "millisecods).\n"
- "Extended Listen Timing can be cancelled with this "
- "command when used without parameters.\n");
- return -1;
- }
-
- return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
-}
-
-#endif /* CONFIG_P2P */
-
-
-static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
-}
-
-
-#ifdef CONFIG_WIFI_DISPLAY
-
-static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[100];
- int res;
-
- if (argc != 1 && argc != 2) {
- printf("Invalid WFD_SUBELEM_SET command: needs one or two "
- "arguments (subelem, hexdump)\n");
- return -1;
- }
-
- res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
- argv[0], argc > 1 ? argv[1] : "");
- if (os_snprintf_error(sizeof(cmd), res))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[100];
- int res;
-
- if (argc != 1) {
- printf("Invalid WFD_SUBELEM_GET command: needs one "
- "argument (subelem)\n");
- return -1;
- }
-
- res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
- argv[0]);
- if (os_snprintf_error(sizeof(cmd), res))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
-}
-#endif /* CONFIG_WIFI_DISPLAY */
-
-
-#ifdef CONFIG_INTERWORKING
-static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "FETCH_ANQP");
-}
-
-
-static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
-}
-
-
-static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
-}
-#endif /* CONFIG_INTERWORKING */
-
-
-#ifdef CONFIG_HS20
-
-static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[512];
-
- if (argc == 0) {
- printf("Command needs one or two arguments (dst mac addr and "
- "optional home realm)\n");
- return -1;
- }
-
- if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
- argc, argv) < 0)
- return -1;
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- char cmd[512];
-
- if (argc < 2) {
- printf("Command needs two arguments (dst mac addr and "
- "icon name)\n");
- return -1;
- }
-
- if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
- return -1;
-
- return wpa_ctrl_command(ctrl, cmd);
-}
-
-
-static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "FETCH_OSU");
-}
-
-
-static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
-}
-
-#endif /* CONFIG_HS20 */
-
-
-static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
-}
-
-
-static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
-}
-
-
-static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
-}
-
-
-static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
-}
-
-
-#ifdef CONFIG_AUTOSCAN
-
-static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc == 0)
- return wpa_ctrl_command(ctrl, "AUTOSCAN ");
-
- return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
-}
-
-#endif /* CONFIG_AUTOSCAN */
-
-
-#ifdef CONFIG_WNM
-
-static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
-}
-
-#endif /* CONFIG_WNM */
-
-
-static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- if (argc == 0)
- return -1;
- return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
-}
-
-
-#ifdef ANDROID
-static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
-}
-#endif /* ANDROID */
-
-
-static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "FLUSH");
-}
-
-
-static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_twt_teardown(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "TWT_TEARDOWN", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_ctrl_command(ctrl, "ERP_FLUSH");
-}
-
-
-static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv);
-}
-
-
-static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv);
-}
-
-
-#ifdef CONFIG_DPP
-
-static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_SET", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN");
-}
-
-
-static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv);
-}
-
-
-#ifdef CONFIG_DPP2
-
-static int wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DPP_CONTROLLER_STOP");
-}
-
-
-static int wpa_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DPP_CHIRP", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_ctrl_command(ctrl, "DPP_STOP_CHIRP");
-}
-
-#endif /* CONFIG_DPP2 */
-#endif /* CONFIG_DPP */
-
-
-static int wpa_ctrl_command_bss(struct wpa_ctrl *ctrl, const char *cmd)
-{
- char buf[512], *pos, *bssid = NULL, *freq = NULL, *level = NULL,
- *flags = NULL, *ssid = NULL;
- size_t len;
- int ret, id = -1;
-
- if (!ctrl_conn)
- return -1;
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
- wpa_cli_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- return -2;
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- return -1;
- }
-
- buf[len] = '\0';
- if (os_memcmp(buf, "FAIL", 4) == 0)
- return -1;
-
- pos = buf;
- while (*pos != '\0') {
- if (str_starts(pos, "id="))
- id = atoi(pos + 3);
- if (str_starts(pos, "bssid="))
- bssid = pos + 6;
- if (str_starts(pos, "freq="))
- freq = pos + 5;
- if (str_starts(pos, "level="))
- level = pos + 6;
- if (str_starts(pos, "flags="))
- flags = pos + 6;
- if (str_starts(pos, "ssid="))
- ssid = pos + 5;
-
- while (*pos != '\0' && *pos != '\n')
- pos++;
- *pos++ = '\0';
- }
- if (id != -1)
- printf("%s\t%s\t%s\t%s\t%s\n", bssid ? bssid : "N/A",
- freq ? freq : "N/A", level ? level : "N/A",
- flags ? flags : "N/A", ssid ? ssid : "N/A");
- return id;
-}
-
-
-static int wpa_cli_cmd_all_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- char cmd[64];
- int id = -1;
- unsigned int mask;
-
- printf("bssid / frequency / signal level / flags / ssid\n");
-
- mask = WPA_BSS_MASK_ID | WPA_BSS_MASK_BSSID | WPA_BSS_MASK_FREQ |
- WPA_BSS_MASK_LEVEL | WPA_BSS_MASK_FLAGS | WPA_BSS_MASK_SSID;
- do {
- if (id < 0)
- os_snprintf(cmd, sizeof(cmd), "BSS FIRST MASK=0x%x",
- mask);
- else
- os_snprintf(cmd, sizeof(cmd), "BSS NEXT-%d MASK=0x%x",
- id, mask);
- id = wpa_ctrl_command_bss(ctrl, cmd);
- } while (id >= 0);
-
- return 0;
-}
-
-
-#ifdef CONFIG_PASN
-
-static int wpa_cli_cmd_pasn_auth_start(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PASN_AUTH_START", 4, argc, argv);
-}
-
-
-static int wpa_cli_cmd_pasn_auth_stop(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PASN_AUTH_STOP", 0, argc, argv);
-}
-
-static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
-}
-
-
-static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
-{
- return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
-}
-
-#endif /* CONFIG_PASN */
-
-
-static int wpa_cli_cmd_mscs(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "MSCS", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_scs(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "SCS", 2, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dscp_resp(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DSCP_RESP", 1, argc, argv);
-}
-
-
-static int wpa_cli_cmd_dscp_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- return wpa_cli_cmd(ctrl, "DSCP_QUERY", 1, argc, argv);
-}
-
-
-enum wpa_cli_cmd_flags {
- cli_cmd_flag_none = 0x00,
- cli_cmd_flag_sensitive = 0x01
-};
-
-struct wpa_cli_cmd {
- const char *cmd;
- int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
- char ** (*completion)(const char *str, int pos);
- enum wpa_cli_cmd_flags flags;
- const char *usage;
-};
-
-static const struct wpa_cli_cmd wpa_cli_commands[] = {
- { "status", wpa_cli_cmd_status, NULL,
- cli_cmd_flag_none,
- "[verbose] = get current WPA/EAPOL/EAP status" },
- { "ifname", wpa_cli_cmd_ifname, NULL,
- cli_cmd_flag_none,
- "= get current interface name" },
- { "ping", wpa_cli_cmd_ping, NULL,
- cli_cmd_flag_none,
- "= pings wpa_supplicant" },
- { "relog", wpa_cli_cmd_relog, NULL,
- cli_cmd_flag_none,
- "= re-open log-file (allow rolling logs)" },
- { "note", wpa_cli_cmd_note, NULL,
- cli_cmd_flag_none,
- "<text> = add a note to wpa_supplicant debug log" },
- { "mib", wpa_cli_cmd_mib, NULL,
- cli_cmd_flag_none,
- "= get MIB variables (dot1x, dot11)" },
- { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
- cli_cmd_flag_none,
- "[command] = show usage help" },
- { "interface", wpa_cli_cmd_interface, NULL,
- cli_cmd_flag_none,
- "[ifname] = show interfaces/select interface" },
- { "level", wpa_cli_cmd_level, NULL,
- cli_cmd_flag_none,
- "<debug level> = change debug level" },
- { "license", wpa_cli_cmd_license, NULL,
- cli_cmd_flag_none,
- "= show full wpa_cli license" },
- { "quit", wpa_cli_cmd_quit, NULL,
- cli_cmd_flag_none,
- "= exit wpa_cli" },
- { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
- cli_cmd_flag_none,
- "= set variables (shows list of variables when run without "
- "arguments)" },
- { "dump", wpa_cli_cmd_dump, NULL,
- cli_cmd_flag_none,
- "= dump config variables" },
- { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
- cli_cmd_flag_none,
- "<name> = get information" },
- { "driver_flags", wpa_cli_cmd_driver_flags, NULL,
- cli_cmd_flag_none,
- "= list driver flags" },
- { "logon", wpa_cli_cmd_logon, NULL,
- cli_cmd_flag_none,
- "= IEEE 802.1X EAPOL state machine logon" },
- { "logoff", wpa_cli_cmd_logoff, NULL,
- cli_cmd_flag_none,
- "= IEEE 802.1X EAPOL state machine logoff" },
- { "pmksa", wpa_cli_cmd_pmksa, NULL,
- cli_cmd_flag_none,
- "= show PMKSA cache" },
- { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
- cli_cmd_flag_none,
- "= flush PMKSA cache entries" },
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL,
- cli_cmd_flag_none,
- "<network_id> = fetch all stored PMKSA cache entries" },
- { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL,
- cli_cmd_flag_sensitive,
- "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" },
-#ifdef CONFIG_MESH
- { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL,
- cli_cmd_flag_none,
- "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" },
- { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL,
- cli_cmd_flag_sensitive,
- "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" },
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
- { "reassociate", wpa_cli_cmd_reassociate, NULL,
- cli_cmd_flag_none,
- "= force reassociation" },
- { "reattach", wpa_cli_cmd_reattach, NULL,
- cli_cmd_flag_none,
- "= force reassociation back to the same BSS" },
- { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<BSSID> = force preauthentication" },
- { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> <identity> = configure identity for an SSID" },
- { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id,
- cli_cmd_flag_sensitive,
- "<network id> <password> = configure password for an SSID" },
- { "new_password", wpa_cli_cmd_new_password,
- wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
- "<network id> <password> = change password for an SSID" },
- { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id,
- cli_cmd_flag_sensitive,
- "<network id> <pin> = configure pin for an SSID" },
- { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id,
- cli_cmd_flag_sensitive,
- "<network id> <password> = configure one-time-password for an SSID"
- },
- { "psk_passphrase", wpa_cli_cmd_psk_passphrase,
- wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
- "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" },
- { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id,
- cli_cmd_flag_sensitive,
- "<network id> <passphrase> = configure private key passphrase\n"
- " for an SSID" },
- { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id,
- cli_cmd_flag_sensitive,
- "<network id> <pin> = report SIM operation result" },
- { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> <BSSID> = set preferred BSSID for an SSID" },
- { "bssid_ignore", wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<BSSID> = add a BSSID to the list of temporarily ignored BSSs\n"
- "bssid_ignore clear = clear the list of temporarily ignored BSSIDs\n"
- "bssid_ignore = display the list of temporarily ignored BSSIDs" },
- { "blacklist", /* deprecated alias for bssid_ignore */
- wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "= deprecated alias for bssid_ignore" },
- { "log_level", wpa_cli_cmd_log_level, NULL,
- cli_cmd_flag_none,
- "<level> [<timestamp>] = update the log level/timestamp\n"
- "log_level = display the current log level and log options" },
- { "list_networks", wpa_cli_cmd_list_networks, NULL,
- cli_cmd_flag_none,
- "= list configured networks" },
- { "select_network", wpa_cli_cmd_select_network,
- wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> = select a network (disable others)" },
- { "enable_network", wpa_cli_cmd_enable_network,
- wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> = enable a network" },
- { "disable_network", wpa_cli_cmd_disable_network,
- wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> = disable a network" },
- { "add_network", wpa_cli_cmd_add_network, NULL,
- cli_cmd_flag_none,
- "= add a network" },
- { "remove_network", wpa_cli_cmd_remove_network,
- wpa_cli_complete_network_id,
- cli_cmd_flag_none,
- "<network id> = remove a network" },
- { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
- cli_cmd_flag_sensitive,
- "<network id> <variable> <value> = set network variables (shows\n"
- " list of variables when run without arguments)" },
- { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
- cli_cmd_flag_none,
- "<network id> <variable> = get network variables" },
- { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
- cli_cmd_flag_none,
- "<src network id> <dst network id> <variable> = duplicate network variables"
- },
- { "list_creds", wpa_cli_cmd_list_creds, NULL,
- cli_cmd_flag_none,
- "= list configured credentials" },
- { "add_cred", wpa_cli_cmd_add_cred, NULL,
- cli_cmd_flag_none,
- "= add a credential" },
- { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
- cli_cmd_flag_none,
- "<cred id> = remove a credential" },
- { "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred,
- cli_cmd_flag_sensitive,
- "<cred id> <variable> <value> = set credential variables" },
- { "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred,
- cli_cmd_flag_none,
- "<cred id> <variable> = get credential variables" },
- { "save_config", wpa_cli_cmd_save_config, NULL,
- cli_cmd_flag_none,
- "= save the current configuration" },
- { "disconnect", wpa_cli_cmd_disconnect, NULL,
- cli_cmd_flag_none,
- "= disconnect and wait for reassociate/reconnect command before\n"
- " connecting" },
- { "reconnect", wpa_cli_cmd_reconnect, NULL,
- cli_cmd_flag_none,
- "= like reassociate, but only takes effect if already disconnected"
- },
- { "scan", wpa_cli_cmd_scan, NULL,
- cli_cmd_flag_none,
- "= request new BSS scan" },
- { "scan_results", wpa_cli_cmd_scan_results, NULL,
- cli_cmd_flag_none,
- "= get latest scan results" },
- { "abort_scan", wpa_cli_cmd_abort_scan, NULL,
- cli_cmd_flag_none,
- "= request ongoing scan to be aborted" },
- { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<<idx> | <bssid>> = get detailed scan result info" },
- { "get_capability", wpa_cli_cmd_get_capability,
- wpa_cli_complete_get_capability, cli_cmd_flag_none,
- "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
- "= get capabilities" },
- { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
- cli_cmd_flag_none,
- "= force wpa_supplicant to re-read its configuration file" },
- { "terminate", wpa_cli_cmd_terminate, NULL,
- cli_cmd_flag_none,
- "= terminate wpa_supplicant" },
- { "interface_add", wpa_cli_cmd_interface_add, NULL,
- cli_cmd_flag_none,
- "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
- " <bridge_name> <create> <type> = adds new interface, all "
- "parameters but\n"
- " <ifname> are optional. Supported types are station ('sta') and "
- "AP ('ap')" },
- { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
- cli_cmd_flag_none,
- "<ifname> = removes the interface" },
- { "interface_list", wpa_cli_cmd_interface_list, NULL,
- cli_cmd_flag_none,
- "= list available interfaces" },
- { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
- cli_cmd_flag_none,
- "<value> = set ap_scan parameter" },
- { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
- cli_cmd_flag_none,
- "<value> = set scan_interval parameter (in seconds)" },
- { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
- cli_cmd_flag_none,
- "<value> = set BSS expiration age parameter" },
- { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
- cli_cmd_flag_none,
- "<value> = set BSS expiration scan count parameter" },
- { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
- cli_cmd_flag_none,
- "<value> = set BSS flush age (0 by default)" },
- { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<addr> = request over-the-DS FT with <addr>" },
- { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
- { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
- cli_cmd_flag_sensitive,
- "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
- "hardcoded)" },
- { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
- cli_cmd_flag_sensitive,
- "<PIN> = verify PIN checksum" },
- { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
- "Cancels the pending WPS operation" },
-#ifdef CONFIG_WPS_NFC
- { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "[BSSID] = start Wi-Fi Protected Setup: NFC" },
- { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
- cli_cmd_flag_none,
- "<WPS|NDEF> = build configuration token" },
- { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
- cli_cmd_flag_none,
- "<WPS|NDEF> = create password token" },
- { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
- cli_cmd_flag_sensitive,
- "<hexdump of payload> = report read NFC tag with WPS data" },
- { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
- cli_cmd_flag_none,
- "<NDEF> <WPS> = create NFC handover request" },
- { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
- cli_cmd_flag_none,
- "<NDEF> <WPS> = create NFC handover select" },
- { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
- cli_cmd_flag_none,
- "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
- "NFC handover" },
-#endif /* CONFIG_WPS_NFC */
- { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
- cli_cmd_flag_sensitive,
- "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
- { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
- cli_cmd_flag_sensitive,
- "[params..] = enable/disable AP PIN" },
- { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
- cli_cmd_flag_none,
- "[IP address] = start Wi-Fi Protected Setup External Registrar" },
- { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
- cli_cmd_flag_none,
- "= stop Wi-Fi Protected Setup External Registrar" },
- { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
- cli_cmd_flag_sensitive,
- "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
- { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
- cli_cmd_flag_none,
- "<UUID> = accept an Enrollee PBC using External Registrar" },
- { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
- cli_cmd_flag_sensitive,
- "<UUID> <PIN> = learn AP configuration" },
- { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
- cli_cmd_flag_none,
- "<UUID> <network id> = set AP configuration for enrolling" },
- { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
- cli_cmd_flag_sensitive,
- "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
-#ifdef CONFIG_WPS_NFC
- { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
- cli_cmd_flag_none,
- "<WPS/NDEF> <UUID> = build NFC configuration token" },
-#endif /* CONFIG_WPS_NFC */
- { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
- cli_cmd_flag_none,
- "<addr> = request RSN authentication with <addr> in IBSS" },
-#ifdef CONFIG_AP
- { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta,
- cli_cmd_flag_none,
- "<addr> = get information about an associated station (AP)" },
- { "all_sta", wpa_cli_cmd_all_sta, NULL,
- cli_cmd_flag_none,
- "= get information about all associated stations (AP)" },
- { "list_sta", wpa_cli_cmd_list_sta, NULL,
- cli_cmd_flag_none,
- "= list all stations (AP)" },
- { "deauthenticate", wpa_cli_cmd_deauthenticate,
- wpa_cli_complete_deauthenticate, cli_cmd_flag_none,
- "<addr> = deauthenticate a station" },
- { "disassociate", wpa_cli_cmd_disassociate,
- wpa_cli_complete_disassociate, cli_cmd_flag_none,
- "<addr> = disassociate a station" },
- { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
- cli_cmd_flag_none,
- "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
- " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
- " = CSA parameters" },
- { "update_beacon", wpa_cli_cmd_update_beacon, NULL,
- cli_cmd_flag_none,
- "= update Beacon frame contents"},
-#endif /* CONFIG_AP */
- { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
- "= notification of suspend/hibernate" },
- { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
- "= notification of resume/thaw" },
-#ifdef CONFIG_TESTING_OPTIONS
- { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
- "= drop SA without deauth/disassoc (test command)" },
-#endif /* CONFIG_TESTING_OPTIONS */
- { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<addr> = roam to the specified BSS" },
-#ifdef CONFIG_MESH
- { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
- cli_cmd_flag_none,
- "[ifname] = Create a new mesh interface" },
- { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
- cli_cmd_flag_none,
- "<network id> = join a mesh network (disable others)" },
- { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
- cli_cmd_flag_none,
- "<ifname> = Remove mesh group interface" },
- { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
- cli_cmd_flag_none,
- "<addr> = Remove a mesh peer" },
- { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
- cli_cmd_flag_none,
- "<addr> [duration=<seconds>] = Add a mesh peer" },
- { "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL,
- cli_cmd_flag_none,
- "<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." },
-#endif /* CONFIG_MESH */
-#ifdef CONFIG_P2P
- { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
- cli_cmd_flag_none,
- "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
- { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
- "= stop P2P Devices search" },
- { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
- cli_cmd_flag_none,
- "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
- { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
- cli_cmd_flag_none,
- "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
- { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
- cli_cmd_flag_none,
- "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
- { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
- "[timeout] = listen for P2P Devices for up-to timeout seconds" },
- { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
- wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
- "<ifname> = remove P2P group interface (terminate group if GO)" },
- { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
- "[ht40] = add a new P2P group (local end as GO)" },
- { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
- cli_cmd_flag_none,
- "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
- { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
- wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
- "<addr> <method> = request provisioning discovery" },
- { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
- cli_cmd_flag_none,
- "= get the passphrase for a group (GO only)" },
- { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
- wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
- "<addr> <TLVs> = schedule service discovery request" },
- { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
- NULL, cli_cmd_flag_none,
- "<id> = cancel pending service discovery request" },
- { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
- cli_cmd_flag_none,
- "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
- { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
- cli_cmd_flag_none,
- "= indicate change in local services" },
- { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
- cli_cmd_flag_none,
- "<external> = set external processing of service discovery" },
- { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
- cli_cmd_flag_none,
- "= remove all stored service entries" },
- { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
- cli_cmd_flag_none,
- "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
- "service" },
- { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
- cli_cmd_flag_none,
- "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
- "local ASP service" },
- { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
- cli_cmd_flag_none,
- "<bonjour|upnp> <query|version> [|service] = remove a local "
- "service" },
- { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
- cli_cmd_flag_none,
- "<addr> = reject connection attempts from a specific peer" },
- { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
- cli_cmd_flag_none,
- "<cmd> [peer=addr] = invite peer" },
- { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
- "[discovered] = list known (optionally, only fully discovered) P2P "
- "peers" },
- { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
- cli_cmd_flag_none,
- "<address> = show information about known P2P peer" },
- { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
- cli_cmd_flag_none,
- "<field> <value> = set a P2P parameter" },
- { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
- "= flush P2P state" },
- { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
- "= cancel P2P group formation" },
- { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
- wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
- "<address> = unauthorize a peer" },
- { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
- cli_cmd_flag_none,
- "[<duration> <interval>] [<duration> <interval>] = request GO "
- "presence" },
- { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
- cli_cmd_flag_none,
- "[<period> <interval>] = set extended listen timing" },
- { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
- wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
- "<address|iface=address> = remove a peer from all groups" },
-#endif /* CONFIG_P2P */
- { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
- cli_cmd_flag_none,
- "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
- VENDOR_ELEM_FRAME_ID },
- { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
- cli_cmd_flag_none,
- "<frame id> = get vendor specific IE(s) to frame(s)\n"
- VENDOR_ELEM_FRAME_ID },
- { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
- cli_cmd_flag_none,
- "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
- VENDOR_ELEM_FRAME_ID },
-#ifdef CONFIG_WIFI_DISPLAY
- { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
- cli_cmd_flag_none,
- "<subelem> [contents] = set Wi-Fi Display subelement" },
- { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
- cli_cmd_flag_none,
- "<subelem> = get Wi-Fi Display subelement" },
-#endif /* CONFIG_WIFI_DISPLAY */
-#ifdef CONFIG_INTERWORKING
- { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
- "= fetch ANQP information for all APs" },
- { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
- cli_cmd_flag_none,
- "= stop fetch_anqp operation" },
- { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
- cli_cmd_flag_none,
- "[auto] = perform Interworking network selection" },
- { "interworking_connect", wpa_cli_cmd_interworking_connect,
- wpa_cli_complete_bss, cli_cmd_flag_none,
- "<BSSID> = connect using Interworking credentials" },
- { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
- wpa_cli_complete_bss, cli_cmd_flag_none,
- "<BSSID> = connect using Interworking credentials" },
- { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<addr> <info id>[,<info id>]... = request ANQP information" },
- { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<addr> <AdvProtoID> [QueryReq] = GAS request" },
- { "gas_response_get", wpa_cli_cmd_gas_response_get,
- wpa_cli_complete_bss, cli_cmd_flag_none,
- "<addr> <dialog token> [start,len] = Fetch last GAS response" },
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_HS20
- { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
- cli_cmd_flag_none,
- "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
- },
- { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
- wpa_cli_complete_bss, cli_cmd_flag_none,
- "<addr> <home realm> = get HS20 nai home realm list" },
- { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
- wpa_cli_complete_bss, cli_cmd_flag_none,
- "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
- { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
- "= fetch OSU provider information from all APs" },
- { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
- cli_cmd_flag_none,
- "= cancel fetch_osu command" },
-#endif /* CONFIG_HS20 */
- { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
- cli_cmd_flag_none,
- "<0/1> = disable/enable automatic reconnection" },
- { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
- cli_cmd_flag_none,
- "<addr> = request TDLS discovery with <addr>" },
- { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
- cli_cmd_flag_none,
- "<addr> = request TDLS setup with <addr>" },
- { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
- cli_cmd_flag_none,
- "<addr> = tear down TDLS with <addr>" },
- { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
- cli_cmd_flag_none,
- "<addr> = TDLS link status with <addr>" },
- { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
- cli_cmd_flag_none,
- "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
- "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
- "= add WMM-AC traffic stream" },
- { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
- cli_cmd_flag_none,
- "<tsid> = delete WMM-AC traffic stream" },
- { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
- cli_cmd_flag_none,
- "= show status for Wireless Multi-Media Admission-Control" },
- { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
- cli_cmd_flag_none,
- "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
- "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
- "with TDLS peer" },
- { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
- cli_cmd_flag_none,
- "<addr> = disable channel switching with TDLS peer <addr>" },
- { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
- cli_cmd_flag_none,
- "= get signal parameters" },
- { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
- cli_cmd_flag_none,
- "= set signal monitor parameters" },
- { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
- cli_cmd_flag_none,
- "= get TX/RX packet counters" },
- { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
- cli_cmd_flag_none,
- "= trigger IEEE 802.1X/EAPOL reauthentication" },
-#ifdef CONFIG_AUTOSCAN
- { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
- "[params] = Set or unset (if none) autoscan parameters" },
-#endif /* CONFIG_AUTOSCAN */
-#ifdef CONFIG_WNM
- { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
- "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
- { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
- "<query reason> [list]"
- " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]"
- " = Send BSS Transition Management Query" },
-#endif /* CONFIG_WNM */
- { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
- "<params..> = Sent unprocessed command" },
- { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
- "= flush wpa_supplicant state" },
-#ifdef ANDROID
- { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
- "<command> = driver private commands" },
-#endif /* ANDROID */
- { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
- "= radio_work <show/add/done>" },
- { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
- "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
- },
- { "neighbor_rep_request",
- wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
- "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
- },
- { "twt_setup",
- wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
- "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>] [min_twt=<Min TWT>] [setup_cmd=<setup-cmd>] [twt=<u64>] [requestor=0|1] [trigger=0|1] [implicit=0|1] [flow_type=0|1] [flow_id=<3-bit-id>] [protection=0|1] [twt_channel=<twt chanel id>] [control=<control-u8>] = Send TWT Setup frame"
- },
- { "twt_teardown",
- wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
- "[flags=<value>] = Send TWT Teardown frame"
- },
- { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
- "= flush ERP keys" },
- { "mac_rand_scan",
- wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
- "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
- "mask=mac-address-mask] = scan MAC randomization"
- },
- { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
- cli_cmd_flag_none,
- "<interface type> = retrieve preferred freq list for the specified interface type" },
- { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL,
- cli_cmd_flag_none,
- "<freq> <period> <interval> <count> = start P2P listen offload" },
- { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL,
- cli_cmd_flag_none,
- "= stop P2P listen offload" },
-#ifdef CONFIG_DPP
- { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none,
- "report a scanned DPP URI from a QR Code" },
- { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL,
- cli_cmd_flag_sensitive,
- "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" },
- { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL,
- cli_cmd_flag_none,
- "*|<id> = remove DPP bootstrap information" },
- { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL,
- cli_cmd_flag_none,
- "<id> = get DPP bootstrap URI" },
- { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL,
- cli_cmd_flag_none,
- "<id> = show DPP bootstrap information" },
- { "dpp_bootstrap_set", wpa_cli_cmd_dpp_bootstrap_set, NULL,
- cli_cmd_flag_none,
- "<id> [conf=..] [ssid=<SSID>] [ssid_charset=#] [psk=<PSK>] [pass=<passphrase>] [configurator=<id>] [conn_status=#] [akm_use_selector=<0|1>] [group_id=..] [expiry=#] [csrattrs=..] = set DPP configurator parameters" },
- { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none,
- "peer=<id> [own=<id>] = initiate DPP bootstrapping" },
- { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none,
- "<freq in MHz> = start DPP listen" },
- { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL,
- cli_cmd_flag_none,
- "= stop DPP listen" },
- { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL,
- cli_cmd_flag_sensitive,
- "[curve=..] [key=..] = add DPP configurator" },
- { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL,
- cli_cmd_flag_none,
- "*|<id> = remove DPP configurator" },
- { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key,
- NULL, cli_cmd_flag_none,
- "<id> = Get DPP configurator's private key" },
- { "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL,
- cli_cmd_flag_none,
- "conf=<role> configurator=<id> = generate self DPP configuration" },
- { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL,
- cli_cmd_flag_sensitive,
- "add PKEX code" },
- { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL,
- cli_cmd_flag_none,
- "*|<id> = remove DPP pkex information" },
-#ifdef CONFIG_DPP2
- { "dpp_controller_start", wpa_cli_cmd_dpp_controller_start, NULL,
- cli_cmd_flag_none,
- "[tcp_port=<port>] [role=..] = start DPP controller" },
- { "dpp_controller_stop", wpa_cli_cmd_dpp_controller_stop, NULL,
- cli_cmd_flag_none,
- "= stop DPP controller" },
- { "dpp_chirp", wpa_cli_cmd_dpp_chirp, NULL,
- cli_cmd_flag_none,
- "own=<BI ID> iter=<count> = start DPP chirp" },
- { "dpp_stop_chirp", wpa_cli_cmd_dpp_stop_chirp, NULL,
- cli_cmd_flag_none,
- "= stop DPP chirp" },
-#endif /* CONFIG_DPP2 */
-#endif /* CONFIG_DPP */
- { "all_bss", wpa_cli_cmd_all_bss, NULL, cli_cmd_flag_none,
- "= list all BSS entries (scan results)" },
-#ifdef CONFIG_PASN
- { "pasn_auth_start", wpa_cli_cmd_pasn_auth_start, NULL,
- cli_cmd_flag_none,
- "bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> nid=<network id> = Start PASN authentication" },
- { "pasn_auth_stop", wpa_cli_cmd_pasn_auth_stop, NULL,
- cli_cmd_flag_none,
- "= Stop PASN authentication" },
- { "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
- cli_cmd_flag_none,
- "= Get the PTKSA Cache" },
- { "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
- cli_cmd_flag_none,
- "bssid=<BSSID> = Remove PASN PTKSA state" },
-#endif /* CONFIG_PASN */
- { "mscs", wpa_cli_cmd_mscs, NULL,
- cli_cmd_flag_none,
- "<add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>] [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>] = Configure MSCS request" },
- { "scs", wpa_cli_cmd_scs, NULL,
- cli_cmd_flag_none,
- "[scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>] [classifier_type=<4|10>] [classifier params based on classifier type] [tclas_processing=<0|1>] [scs_id=<decimal number>] ... = Send SCS request" },
- { "dscp_resp", wpa_cli_cmd_dscp_resp, NULL,
- cli_cmd_flag_none,
- "<[reset]>/<[solicited] [policy_id=1 status=0...]> [more] = Send DSCP response" },
- { "dscp_query", wpa_cli_cmd_dscp_query, NULL,
- cli_cmd_flag_none,
- "wildcard/domain_name=<string> = Send DSCP Query" },
- { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
-};
-
-
-/*
- * Prints command usage, lines are padded with the specified string.
- */
-static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
-{
- char c;
- size_t n;
-
- printf("%s%s ", pad, cmd->cmd);
- for (n = 0; (c = cmd->usage[n]); n++) {
- printf("%c", c);
- if (c == '\n')
- printf("%s", pad);
- }
- printf("\n");
-}
-
-
-static void print_help(const char *cmd)
-{
- int n;
- printf("commands:\n");
- for (n = 0; wpa_cli_commands[n].cmd; n++) {
- if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
- print_cmd_help(&wpa_cli_commands[n], " ");
- }
-}
-
-
-static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
-{
- const char *c, *delim;
- int n;
- size_t len;
-
- delim = os_strchr(cmd, ' ');
- if (delim)
- len = delim - cmd;
- else
- len = os_strlen(cmd);
-
- for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
- if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
- return (wpa_cli_commands[n].flags &
- cli_cmd_flag_sensitive);
- }
- return 0;
-}
-
-
-static char ** wpa_list_cmd_list(void)
-{
- char **res;
- int i, count;
- struct cli_txt_entry *e;
-
- count = ARRAY_SIZE(wpa_cli_commands);
- count += dl_list_len(&p2p_groups);
- count += dl_list_len(&ifnames);
- res = os_calloc(count + 1, sizeof(char *));
- if (res == NULL)
- return NULL;
-
- for (i = 0; wpa_cli_commands[i].cmd; i++) {
- res[i] = os_strdup(wpa_cli_commands[i].cmd);
- if (res[i] == NULL)
- break;
- }
-
- dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
- size_t len = 8 + os_strlen(e->txt);
- res[i] = os_malloc(len);
- if (res[i] == NULL)
- break;
- os_snprintf(res[i], len, "ifname=%s", e->txt);
- i++;
- }
-
- dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
- res[i] = os_strdup(e->txt);
- if (res[i] == NULL)
- break;
- i++;
- }
-
- return res;
-}
-
-
-static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
- int pos)
-{
- int i;
-
- for (i = 0; wpa_cli_commands[i].cmd; i++) {
- if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
- if (wpa_cli_commands[i].completion)
- return wpa_cli_commands[i].completion(str,
- pos);
- edit_clear_line();
- printf("\r%s\n", wpa_cli_commands[i].usage);
- edit_redraw();
- break;
- }
- }
-
- return NULL;
-}
-
-
-static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
-{
- char **res;
- const char *end;
- char *cmd;
-
- if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
- end = os_strchr(str, ' ');
- if (end && pos > end - str) {
- pos -= end - str + 1;
- str = end + 1;
- }
- }
-
- end = os_strchr(str, ' ');
- if (end == NULL || str + pos < end)
- return wpa_list_cmd_list();
-
- cmd = os_malloc(pos + 1);
- if (cmd == NULL)
- return NULL;
- os_memcpy(cmd, str, pos);
- cmd[end - str] = '\0';
- res = wpa_cli_cmd_completion(cmd, str, pos);
- os_free(cmd);
- return res;
-}
-
-
-static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
- const struct wpa_cli_cmd *cmd, *match = NULL;
- int count;
- int ret = 0;
-
- if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
- ifname_prefix = argv[0] + 7;
- argv = &argv[1];
- argc--;
- } else
- ifname_prefix = NULL;
-
- if (argc == 0)
- return -1;
-
- count = 0;
- cmd = wpa_cli_commands;
- while (cmd->cmd) {
- if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
- {
- match = cmd;
- if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
- /* we have an exact match */
- count = 1;
- break;
- }
- count++;
- }
- cmd++;
- }
-
- if (count > 1) {
- printf("Ambiguous command '%s'; possible commands:", argv[0]);
- cmd = wpa_cli_commands;
- while (cmd->cmd) {
- if (os_strncasecmp(cmd->cmd, argv[0],
- os_strlen(argv[0])) == 0) {
- printf(" %s", cmd->cmd);
- }
- cmd++;
- }
- printf("\n");
- ret = 1;
- } else if (count == 0) {
- printf("Unknown command '%s'\n", argv[0]);
- ret = 1;
- } else {
- ret = match->handler(ctrl, argc - 1, &argv[1]);
- }
-
- return ret;
-}
-
-
-static int wpa_cli_exec(const char *program, const char *arg1,
- const char *arg2)
-{
- char *arg;
- size_t len;
- int res;
-
- /* If no interface is specified, set the global */
- if (!arg1)
- arg1 = "global";
-
- len = os_strlen(arg1) + os_strlen(arg2) + 2;
- arg = os_malloc(len);
- if (arg == NULL)
- return -1;
- os_snprintf(arg, len, "%s %s", arg1, arg2);
- res = os_exec(program, arg, 1);
- os_free(arg);
-
- return res;
-}
-
-
-static void wpa_cli_action_process(const char *msg)
-{
- const char *pos;
- char *copy = NULL, *id, *pos2;
- const char *ifname = ctrl_ifname;
- char ifname_buf[100];
-
- if (eloop_terminated())
- return;
-
- pos = msg;
- if (os_strncmp(pos, "IFNAME=", 7) == 0) {
- const char *end;
- end = os_strchr(pos + 7, ' ');
- if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
- pos += 7;
- os_memcpy(ifname_buf, pos, end - pos);
- ifname_buf[end - pos] = '\0';
- ifname = ifname_buf;
- pos = end + 1;
- }
- }
- if (*pos == '<') {
- const char *prev = pos;
- /* skip priority */
- pos = os_strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = prev;
- }
-
- if (str_starts(pos, WPA_EVENT_CONNECTED)) {
- int new_id = -1;
- os_unsetenv("WPA_ID");
- os_unsetenv("WPA_ID_STR");
- os_unsetenv("WPA_CTRL_DIR");
-
- pos = os_strstr(pos, "[id=");
- if (pos)
- copy = os_strdup(pos + 4);
-
- if (copy) {
- pos2 = id = copy;
- while (*pos2 && *pos2 != ' ')
- pos2++;
- *pos2++ = '\0';
- new_id = atoi(id);
- os_setenv("WPA_ID", id, 1);
- while (*pos2 && *pos2 != '=')
- pos2++;
- if (*pos2 == '=')
- pos2++;
- id = pos2;
- while (*pos2 && *pos2 != ']')
- pos2++;
- *pos2 = '\0';
- os_setenv("WPA_ID_STR", id, 1);
- os_free(copy);
- }
-
- os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
-
- if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
- wpa_cli_connected = 1;
- wpa_cli_last_id = new_id;
- wpa_cli_exec(action_file, ifname, "CONNECTED");
- }
- } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) {
- if (wpa_cli_connected) {
- wpa_cli_connected = 0;
- wpa_cli_exec(action_file, ifname, "DISCONNECTED");
- }
- } else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH_STARTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, AP_EVENT_ENABLED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, AP_EVENT_DISABLED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, MESH_GROUP_STARTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, MESH_GROUP_REMOVED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, MESH_PEER_CONNECTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) {
- wpa_cli_exec(action_file, ctrl_ifname, pos);
- } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_SUCCESS)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_ACTIVE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_OVERLAP)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_PIN_ACTIVE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_CANCEL)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPS_EVENT_FAIL)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, AP_STA_CONNECTED)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, AP_STA_DISCONNECTED)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONF_RECEIVED)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONFOBJ_AKM)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONFOBJ_SSID)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONNECTOR)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PASS)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PSK)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_C_SIGN_KEY)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, DPP_EVENT_NET_ACCESS_KEY)) {
- wpa_cli_exec(action_file, ifname, pos);
- } else if (str_starts(pos, WPA_EVENT_TERMINATING)) {
- printf("wpa_supplicant is terminating - stop monitoring\n");
- if (!reconnect)
- wpa_cli_quit = 1;
- }
-}
-
-
-#ifndef CONFIG_ANSI_C_EXTRA
-static void wpa_cli_action_cb(char *msg, size_t len)
-{
- wpa_cli_action_process(msg);
-}
-#endif /* CONFIG_ANSI_C_EXTRA */
-
-
-static int wpa_cli_open_global_ctrl(void)
-{
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- ctrl_conn = wpa_ctrl_open(NULL);
-#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- ctrl_conn = wpa_ctrl_open(global);
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- if (!ctrl_conn) {
- fprintf(stderr,
- "Failed to connect to wpa_supplicant global interface: %s error: %s\n",
- global, strerror(errno));
- return -1;
- }
-
- if (interactive) {
- update_ifnames(ctrl_conn);
- mon_conn = wpa_ctrl_open(global);
- if (mon_conn) {
- if (wpa_ctrl_attach(mon_conn) == 0) {
- wpa_cli_attached = 1;
- eloop_register_read_sock(
- wpa_ctrl_get_fd(mon_conn),
- wpa_cli_mon_receive,
- NULL, NULL);
- } else {
- printf("Failed to open monitor connection through global control interface\n");
- }
- }
- update_stations(ctrl_conn);
- }
-
- return 0;
-}
-
-
-static void wpa_cli_reconnect(void)
-{
- wpa_cli_close_connection();
- if ((global && wpa_cli_open_global_ctrl() < 0) ||
- (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0))
- return;
-
- if (interactive) {
- edit_clear_line();
- printf("\rConnection to wpa_supplicant re-established\n");
- edit_redraw();
- update_stations(ctrl_conn);
- }
-}
-
-
-static void cli_event(const char *str)
-{
- const char *start, *s;
-
- start = os_strchr(str, '>');
- if (start == NULL)
- return;
-
- start++;
-
- if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
- s = os_strchr(start, ' ');
- if (s == NULL)
- return;
- s = os_strchr(s + 1, ' ');
- if (s == NULL)
- return;
- cli_txt_list_add(&bsses, s + 1);
- return;
- }
-
- if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
- s = os_strchr(start, ' ');
- if (s == NULL)
- return;
- s = os_strchr(s + 1, ' ');
- if (s == NULL)
- return;
- cli_txt_list_del_addr(&bsses, s + 1);
- return;
- }
-
-#ifdef CONFIG_P2P
- if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
- s = os_strstr(start, " p2p_dev_addr=");
- if (s == NULL)
- return;
- cli_txt_list_add_addr(&p2p_peers, s + 14);
- return;
- }
-
- if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
- s = os_strstr(start, " p2p_dev_addr=");
- if (s == NULL)
- return;
- cli_txt_list_del_addr(&p2p_peers, s + 14);
- return;
- }
-
- if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
- s = os_strchr(start, ' ');
- if (s == NULL)
- return;
- cli_txt_list_add_word(&p2p_groups, s + 1, ' ');
- return;
- }
-
- if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
- s = os_strchr(start, ' ');
- if (s == NULL)
- return;
- cli_txt_list_del_word(&p2p_groups, s + 1, ' ');
- return;
- }
-#endif /* CONFIG_P2P */
-}
-
-
-static int check_terminating(const char *msg)
-{
- const char *pos = msg;
-
- if (*pos == '<') {
- /* skip priority */
- pos = os_strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = msg;
- }
-
- if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
- edit_clear_line();
- printf("\rConnection to wpa_supplicant lost - trying to "
- "reconnect\n");
- edit_redraw();
- wpa_cli_attached = 0;
- wpa_cli_close_connection();
- return 1;
- }
-
- return 0;
-}
-
-
-static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
-{
- if (ctrl_conn == NULL) {
- wpa_cli_reconnect();
- return;
- }
- while (wpa_ctrl_pending(ctrl) > 0) {
- char buf[4096];
- size_t len = sizeof(buf) - 1;
- if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
- buf[len] = '\0';
- if (action_monitor)
- wpa_cli_action_process(buf);
- else {
- cli_event(buf);
- if (wpa_cli_show_event(buf)) {
- edit_clear_line();
- printf("\r%s\n", buf);
- edit_redraw();
- }
-
- if (interactive && check_terminating(buf) > 0)
- return;
- }
- } else {
- printf("Could not read pending message.\n");
- break;
- }
- }
-
- if (wpa_ctrl_pending(ctrl) < 0) {
- printf("Connection to wpa_supplicant lost - trying to "
- "reconnect\n");
- if (reconnect) {
- eloop_terminate();
- return;
- }
- wpa_cli_reconnect();
- }
-}
-
-
-static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
-{
- if (ctrl_conn) {
- int res;
- char *prefix = ifname_prefix;
-
- ifname_prefix = NULL;
- res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
- ifname_prefix = prefix;
- if (res) {
- printf("Connection to wpa_supplicant lost - trying to "
- "reconnect\n");
- wpa_cli_close_connection();
- }
- }
- if (!ctrl_conn)
- wpa_cli_reconnect();
- eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
-}
-
-
-static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
-{
- wpa_cli_recv_pending(mon_conn, 0);
-}
-
-
-static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
-{
- char *argv[max_args];
- int argc;
- argc = tokenize_cmd(cmd, argv);
- if (argc)
- wpa_request(ctrl_conn, argc, argv);
-}
-
-
-static void wpa_cli_edit_eof_cb(void *ctx)
-{
- eloop_terminate();
-}
-
-
-static int warning_displayed = 0;
-static char *hfile = NULL;
-static int edit_started = 0;
-
-static void start_edit(void)
-{
- char *home;
- char *ps = NULL;
-
-#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
- ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
-#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
-
-#ifdef CONFIG_WPA_CLI_HISTORY_DIR
- home = CONFIG_WPA_CLI_HISTORY_DIR;
-#else /* CONFIG_WPA_CLI_HISTORY_DIR */
- home = getenv("HOME");
-#endif /* CONFIG_WPA_CLI_HISTORY_DIR */
- if (home) {
- const char *fname = ".wpa_cli_history";
- int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
- hfile = os_malloc(hfile_len);
- if (hfile)
- os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
- }
-
- if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
- wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
- eloop_terminate();
- return;
- }
-
- edit_started = 1;
- eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
-}
-
-
-static void update_bssid_list(struct wpa_ctrl *ctrl)
-{
- char buf[4096];
- size_t len = sizeof(buf);
- int ret;
- const char *cmd = "BSS RANGE=ALL MASK=0x2";
- char *pos, *end;
-
- if (ctrl == NULL)
- return;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
- if (ret < 0)
- return;
- buf[len] = '\0';
-
- pos = buf;
- while (pos) {
- pos = os_strstr(pos, "bssid=");
- if (pos == NULL)
- break;
- pos += 6;
- end = os_strchr(pos, '\n');
- if (end == NULL)
- break;
- *end = '\0';
- cli_txt_list_add(&bsses, pos);
- pos = end + 1;
- }
-}
-
-
-static void update_ifnames(struct wpa_ctrl *ctrl)
-{
- char buf[4096];
- size_t len = sizeof(buf);
- int ret;
- const char *cmd = "INTERFACES";
- char *pos, *end;
- char txt[200];
-
- cli_txt_list_flush(&ifnames);
-
- if (ctrl == NULL)
- return;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
- if (ret < 0)
- return;
- buf[len] = '\0';
-
- pos = buf;
- while (pos) {
- end = os_strchr(pos, '\n');
- if (end == NULL)
- break;
- *end = '\0';
- ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
- if (!os_snprintf_error(sizeof(txt), ret))
- cli_txt_list_add(&ifnames, txt);
- pos = end + 1;
- }
-}
-
-
-static void update_creds(struct wpa_ctrl *ctrl)
-{
- char buf[4096];
- size_t len = sizeof(buf);
- int ret;
- const char *cmd = "LIST_CREDS";
- char *pos, *end;
- int header = 1;
-
- cli_txt_list_flush(&creds);
-
- if (ctrl == NULL)
- return;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
- if (ret < 0)
- return;
- buf[len] = '\0';
-
- pos = buf;
- while (pos) {
- end = os_strchr(pos, '\n');
- if (end == NULL)
- break;
- *end = '\0';
- if (!header)
- cli_txt_list_add_word(&creds, pos, '\t');
- header = 0;
- pos = end + 1;
- }
-}
-
-
-static void update_networks(struct wpa_ctrl *ctrl)
-{
- char buf[4096];
- size_t len = sizeof(buf);
- int ret;
- const char *cmd = "LIST_NETWORKS";
- char *pos, *end;
- int header = 1;
-
- cli_txt_list_flush(&networks);
-
- if (ctrl == NULL)
- return;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
- if (ret < 0)
- return;
- buf[len] = '\0';
-
- pos = buf;
- while (pos) {
- end = os_strchr(pos, '\n');
- if (end == NULL)
- break;
- *end = '\0';
- if (!header)
- cli_txt_list_add_word(&networks, pos, '\t');
- header = 0;
- pos = end + 1;
- }
-}
-
-
-static void update_stations(struct wpa_ctrl *ctrl)
-{
-#ifdef CONFIG_AP
- char addr[32], cmd[64];
-
- if (!ctrl || !interactive)
- return;
-
- cli_txt_list_flush(&stations);
-
- if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0))
- return;
- do {
- if (os_strcmp(addr, "") != 0)
- cli_txt_list_add(&stations, addr);
- os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
- } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0);
-#endif /* CONFIG_AP */
-}
-
-
-static void try_connection(void *eloop_ctx, void *timeout_ctx)
-{
- if (ctrl_conn)
- goto done;
-
- if (ctrl_ifname == NULL)
- ctrl_ifname = wpa_cli_get_default_ifname();
-
- if (wpa_cli_open_connection(ctrl_ifname, 1)) {
- if (!warning_displayed) {
- printf("Could not connect to wpa_supplicant: "
- "%s - re-trying\n",
- ctrl_ifname ? ctrl_ifname : "(nil)");
- warning_displayed = 1;
- }
- eloop_register_timeout(1, 0, try_connection, NULL, NULL);
- return;
- }
-
- update_bssid_list(ctrl_conn);
- update_creds(ctrl_conn);
- update_networks(ctrl_conn);
- update_stations(ctrl_conn);
-
- if (warning_displayed)
- printf("Connection established.\n");
-
-done:
- start_edit();
-}
-
-
-static void wpa_cli_interactive(void)
-{
- printf("\nInteractive mode\n\n");
-
- eloop_register_timeout(0, 0, try_connection, NULL, NULL);
- eloop_run();
- eloop_cancel_timeout(try_connection, NULL, NULL);
-
- cli_txt_list_flush(&p2p_peers);
- cli_txt_list_flush(&p2p_groups);
- cli_txt_list_flush(&bsses);
- cli_txt_list_flush(&ifnames);
- cli_txt_list_flush(&creds);
- cli_txt_list_flush(&networks);
- if (edit_started)
- edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
- os_free(hfile);
- eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
- wpa_cli_close_connection();
-}
-
-
-static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_ctrl *ctrl = eloop_ctx;
- char buf[256];
- size_t len;
-
- /* verify that connection is still working */
- len = sizeof(buf) - 1;
- if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
- wpa_cli_action_cb) < 0 ||
- len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
- printf("wpa_supplicant did not reply to PING command - exiting\n");
- eloop_terminate();
- return;
- }
- eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
- ctrl, NULL);
-}
-
-
-static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_ctrl *ctrl = eloop_ctx;
-
- wpa_cli_recv_pending(ctrl, 1);
-}
-
-
-static void wpa_cli_action(struct wpa_ctrl *ctrl)
-{
-#ifdef CONFIG_ANSI_C_EXTRA
- /* TODO: ANSI C version(?) */
- printf("Action processing not supported in ANSI C build.\n");
-#else /* CONFIG_ANSI_C_EXTRA */
- int fd;
-
- fd = wpa_ctrl_get_fd(ctrl);
- eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
- ctrl, NULL);
- eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
- eloop_run();
- eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
- eloop_unregister_read_sock(fd);
-#endif /* CONFIG_ANSI_C_EXTRA */
-}
-
-
-static void wpa_cli_cleanup(void)
-{
- wpa_cli_close_connection();
- if (pid_file)
- os_daemonize_terminate(pid_file);
-
- os_program_deinit();
-}
-
-
-static void wpa_cli_terminate(int sig, void *ctx)
-{
- eloop_terminate();
- if (reconnect)
- wpa_cli_quit = 1;
-}
-
-
-static char * wpa_cli_get_default_ifname(void)
-{
- char *ifname = NULL;
-
-#ifdef ANDROID
- char ifprop[PROPERTY_VALUE_MAX];
- if (property_get("wifi.interface", ifprop, NULL) != 0) {
- ifname = os_strdup(ifprop);
- printf("Using interface '%s'\n", ifname ? ifname : "N/A");
- }
-#else /* ANDROID */
-#ifdef CONFIG_CTRL_IFACE_UNIX
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- if (!dir) {
- return NULL;
- }
- while ((dent = readdir(dir))) {
-#ifdef _DIRENT_HAVE_D_TYPE
- /*
- * Skip the file if it is not a socket. Also accept
- * DT_UNKNOWN (0) in case the C library or underlying
- * file system does not support d_type.
- */
- if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
- continue;
-#endif /* _DIRENT_HAVE_D_TYPE */
- /* Skip current/previous directory and special P2P Device
- * interfaces. */
- if (os_strcmp(dent->d_name, ".") == 0 ||
- os_strcmp(dent->d_name, "..") == 0 ||
- os_strncmp(dent->d_name, "p2p-dev-", 8) == 0)
- continue;
- printf("Selected interface '%s'\n", dent->d_name);
- ifname = os_strdup(dent->d_name);
- break;
- }
- closedir(dir);
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- char buf[4096], *pos;
- size_t len;
- struct wpa_ctrl *ctrl;
- int ret;
-
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl == NULL)
- return NULL;
-
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
- if (ret >= 0) {
- buf[len] = '\0';
- pos = os_strchr(buf, '\n');
- if (pos)
- *pos = '\0';
- ifname = os_strdup(buf);
- }
- wpa_ctrl_close(ctrl);
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-#endif /* ANDROID */
-
- return ifname;
-}
-
-
-int main(int argc, char *argv[])
-{
- int c;
- int daemonize = 0;
- int ret = 0;
-
- if (os_program_init())
- return -1;
-
- for (;;) {
- c = getopt(argc, argv, "a:Bg:G:hi:p:P:rs:v");
- if (c < 0)
- break;
- switch (c) {
- case 'a':
- action_file = optarg;
- break;
- case 'B':
- daemonize = 1;
- break;
- case 'g':
- global = optarg;
- break;
- case 'G':
- ping_interval = atoi(optarg);
- break;
- case 'h':
- usage();
- return 0;
- case 'v':
- printf("%s\n", wpa_cli_version);
- return 0;
- case 'i':
- os_free(ctrl_ifname);
- ctrl_ifname = os_strdup(optarg);
- break;
- case 'p':
- ctrl_iface_dir = optarg;
- break;
- case 'P':
- pid_file = optarg;
- break;
- case 'r':
- reconnect = 1;
- break;
- case 's':
- client_socket_dir = optarg;
- break;
- default:
- usage();
- return -1;
- }
- }
-
- interactive = (argc == optind) && (action_file == NULL);
-
- if (interactive)
- printf("%s\n\n%s\n\n", wpa_cli_version, cli_license);
-
- if (eloop_init())
- return -1;
-
- if (global && wpa_cli_open_global_ctrl() < 0)
- return -1;
-
- eloop_register_signal_terminate(wpa_cli_terminate, NULL);
-
- if (ctrl_ifname == NULL)
- ctrl_ifname = wpa_cli_get_default_ifname();
-
- if (reconnect && action_file && ctrl_ifname) {
- while (!wpa_cli_quit) {
- if (ctrl_conn)
- wpa_cli_action(ctrl_conn);
- else
- os_sleep(1, 0);
- wpa_cli_close_connection();
- wpa_cli_open_connection(ctrl_ifname, 0);
- if (ctrl_conn) {
- if (wpa_ctrl_attach(ctrl_conn) != 0)
- wpa_cli_close_connection();
- else
- wpa_cli_attached = 1;
- }
- }
- } else if (interactive) {
- wpa_cli_interactive();
- } else {
- if (!global &&
- wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
- fprintf(stderr, "Failed to connect to non-global "
- "ctrl_ifname: %s error: %s\n",
- ctrl_ifname ? ctrl_ifname : "(nil)",
- strerror(errno));
- return -1;
- }
-
- if (action_file) {
- if (wpa_ctrl_attach(ctrl_conn) == 0) {
- wpa_cli_attached = 1;
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- return -1;
- }
- }
-
- if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
- return -1;
-
- if (action_file)
- wpa_cli_action(ctrl_conn);
- else
- ret = wpa_request(ctrl_conn, argc - optind,
- &argv[optind]);
- }
-
- os_free(ctrl_ifname);
- eloop_destroy();
- wpa_cli_cleanup();
-
- return ret;
-}
-
-#else /* CONFIG_CTRL_IFACE */
-int main(int argc, char *argv[])
-{
- printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
- return -1;
-}
-#endif /* CONFIG_CTRL_IFACE */
diff --git a/wpa_supplicant/wpa_gui-qt4/.gitignore b/wpa_supplicant/wpa_gui-qt4/.gitignore
deleted file mode 100644
index da818cb66557..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.moc
-.obj
-.ui
-qrc_icons.cpp
diff --git a/wpa_supplicant/wpa_gui-qt4/addinterface.cpp b/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
deleted file mode 100644
index 7d92f63d1b1d..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * wpa_gui - AddInterface class
- * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-#include "common/wpa_ctrl.h"
-
-#include <QMessageBox>
-
-#include "wpagui.h"
-#include "addinterface.h"
-
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <windows.h>
-
-#ifndef WPA_KEY_ROOT
-#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
-#endif
-#ifndef WPA_KEY_PREFIX
-#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
-#endif
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-
-AddInterface::AddInterface(WpaGui *_wpagui, QWidget *parent)
- : QDialog(parent), wpagui(_wpagui)
-{
- setWindowTitle(tr("Select network interface to add"));
- resize(400, 200);
- vboxLayout = new QVBoxLayout(this);
-
- interfaceWidget = new QTreeWidget(this);
- interfaceWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
- interfaceWidget->setUniformRowHeights(true);
- interfaceWidget->setSortingEnabled(true);
- interfaceWidget->setColumnCount(3);
- interfaceWidget->headerItem()->setText(0, tr("driver"));
- interfaceWidget->headerItem()->setText(1, tr("interface"));
- interfaceWidget->headerItem()->setText(2, tr("description"));
- interfaceWidget->setItemsExpandable(false);
- interfaceWidget->setRootIsDecorated(false);
- vboxLayout->addWidget(interfaceWidget);
-
- connect(interfaceWidget,
- SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
- SLOT(interfaceSelected(QTreeWidgetItem *)));
-
- addInterfaces();
-}
-
-
-void AddInterface::addInterfaces()
-{
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- struct wpa_ctrl *ctrl;
- int ret;
- char buf[2048];
- size_t len;
-
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl == NULL)
- return;
-
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, "INTERFACE_LIST", 14, buf, &len, NULL);
- if (ret < 0) {
- wpa_ctrl_close(ctrl);
- return;
- }
- buf[len] = '\0';
-
- wpa_ctrl_close(ctrl);
-
- QString ifaces(buf);
- QStringList lines = ifaces.split(QRegExp("\\n"));
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- QStringList arg = (*it).split(QChar('\t'));
- if (arg.size() < 3)
- continue;
- QTreeWidgetItem *item = new QTreeWidgetItem(interfaceWidget);
- if (!item)
- break;
-
- item->setText(0, arg[0]);
- item->setText(1, arg[1]);
- item->setText(2, arg[2]);
- }
-
- interfaceWidget->resizeColumnToContents(0);
- interfaceWidget->resizeColumnToContents(1);
- interfaceWidget->resizeColumnToContents(2);
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-}
-
-
-#ifdef CONFIG_NATIVE_WINDOWS
-bool AddInterface::addRegistryInterface(const QString &ifname)
-{
- HKEY hk, ihk;
- LONG ret;
- int id, tmp;
- TCHAR name[10];
- DWORD val, i;
-
- ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX TEXT("\\interfaces"),
- 0, KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
- &hk);
- if (ret != ERROR_SUCCESS)
- return false;
-
- id = -1;
-
- for (i = 0; ; i++) {
- TCHAR name[255];
- DWORD namelen;
-
- namelen = 255;
- ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL,
- NULL);
-
- if (ret == ERROR_NO_MORE_ITEMS)
- break;
-
- if (ret != ERROR_SUCCESS)
- break;
-
- if (namelen >= 255)
- namelen = 255 - 1;
- name[namelen] = '\0';
-
-#ifdef UNICODE
- QString s((QChar *) name, namelen);
-#else /* UNICODE */
- QString s(name);
-#endif /* UNICODE */
- tmp = s.toInt();
- if (tmp > id)
- id = tmp;
- }
-
- id += 1;
-
-#ifdef UNICODE
- wsprintf(name, L"%04d", id);
-#else /* UNICODE */
- os_snprintf(name, sizeof(name), "%04d", id);
-#endif /* UNICODE */
- ret = RegCreateKeyEx(hk, name, 0, NULL, 0, KEY_WRITE, NULL, &ihk,
- NULL);
- RegCloseKey(hk);
- if (ret != ERROR_SUCCESS)
- return false;
-
-#ifdef UNICODE
- RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
- (LPBYTE) ifname.unicode(),
- (ifname.length() + 1) * sizeof(TCHAR));
-
-#else /* UNICODE */
- RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
- (LPBYTE) ifname.toLocal8Bit(), ifname.length() + 1);
-#endif /* UNICODE */
- RegSetValueEx(ihk, TEXT("config"), 0, REG_SZ,
- (LPBYTE) TEXT("default"), 8 * sizeof(TCHAR));
- RegSetValueEx(ihk, TEXT("ctrl_interface"), 0, REG_SZ,
- (LPBYTE) TEXT(""), 1 * sizeof(TCHAR));
- val = 1;
- RegSetValueEx(ihk, TEXT("skip_on_error"), 0, REG_DWORD, (LPBYTE) &val,
- sizeof(val));
-
- RegCloseKey(ihk);
- return true;
-}
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-
-void AddInterface::interfaceSelected(QTreeWidgetItem *sel)
-{
- if (!sel)
- return;
-
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- struct wpa_ctrl *ctrl;
- int ret;
- char buf[20], cmd[256];
- size_t len;
-
- /*
- * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
- * <driver_param>TAB<bridge_name>
- */
- snprintf(cmd, sizeof(cmd),
- "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
- sel->text(1).toLocal8Bit().constData(),
- "default",
- sel->text(0).toLocal8Bit().constData(),
- "yes", "", "");
- cmd[sizeof(cmd) - 1] = '\0';
-
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl == NULL)
- return;
-
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL);
- wpa_ctrl_close(ctrl);
-
- if (ret < 0) {
- QMessageBox::warning(this, "wpa_gui",
- tr("Add interface command could not be "
- "completed."));
- return;
- }
-
- buf[len] = '\0';
- if (buf[0] != 'O' || buf[1] != 'K') {
- QMessageBox::warning(this, "wpa_gui",
- tr("Failed to add the interface."));
- return;
- }
-
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-
-#ifdef CONFIG_NATIVE_WINDOWS
- if (!addRegistryInterface(sel->text(1))) {
- QMessageBox::information(this, "wpa_gui",
- tr("Failed to add the interface into "
- "registry."));
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- wpagui->selectAdapter(sel->text(1));
- close();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/addinterface.h b/wpa_supplicant/wpa_gui-qt4/addinterface.h
deleted file mode 100644
index 332fc7100f57..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/addinterface.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * wpa_gui - AddInterface class
- * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef ADDINTERFACE_H
-#define ADDINTERFACE_H
-
-#include <QObject>
-
-#include <QDialog>
-#include <QTreeWidget>
-#include <QVBoxLayout>
-
-class WpaGui;
-
-class AddInterface : public QDialog
-{
- Q_OBJECT
-
-public:
- AddInterface(WpaGui *_wpagui, QWidget *parent = 0);
-
-public slots:
- virtual void interfaceSelected(QTreeWidgetItem *sel);
-
-private:
- void addInterfaces();
- bool addRegistryInterface(const QString &ifname);
-
- QVBoxLayout *vboxLayout;
- QTreeWidget *interfaceWidget;
- WpaGui *wpagui;
-};
-
-#endif /* ADDINTERFACE_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp b/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp
deleted file mode 100644
index 09145cd9d587..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * wpa_gui - EventHistory class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <QHeaderView>
-#include <QScrollBar>
-
-#include "eventhistory.h"
-
-
-int EventListModel::rowCount(const QModelIndex &) const
-{
- return msgList.count();
-}
-
-
-int EventListModel::columnCount(const QModelIndex &) const
-{
- return 2;
-}
-
-
-QVariant EventListModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (role == Qt::DisplayRole)
- if (index.column() == 0) {
- if (index.row() >= timeList.size())
- return QVariant();
- return timeList.at(index.row());
- } else {
- if (index.row() >= msgList.size())
- return QVariant();
- return msgList.at(index.row());
- }
- else
- return QVariant();
-}
-
-
-QVariant EventListModel::headerData(int section, Qt::Orientation orientation,
- int role) const
-{
- if (role != Qt::DisplayRole)
- return QVariant();
-
- if (orientation == Qt::Horizontal) {
- switch (section) {
- case 0:
- return QString(tr("Timestamp"));
- case 1:
- return QString(tr("Message"));
- default:
- return QVariant();
- }
- } else
- return QString("%1").arg(section);
-}
-
-
-void EventListModel::addEvent(QString time, QString msg)
-{
- beginInsertRows(QModelIndex(), msgList.size(), msgList.size() + 1);
- timeList << time;
- msgList << msg;
- endInsertRows();
-}
-
-
-EventHistory::EventHistory(QWidget *parent, const char *, bool, Qt::WindowFlags)
- : QDialog(parent)
-{
- setupUi(this);
-
- connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
-
- eventListView->setItemsExpandable(false);
- eventListView->setRootIsDecorated(false);
- elm = new EventListModel(parent);
- eventListView->setModel(elm);
-}
-
-
-EventHistory::~EventHistory()
-{
- destroy();
- delete elm;
-}
-
-
-void EventHistory::languageChange()
-{
- retranslateUi(this);
-}
-
-
-void EventHistory::addEvents(WpaMsgList msgs)
-{
- WpaMsgList::iterator it;
- for (it = msgs.begin(); it != msgs.end(); it++)
- addEvent(*it);
-}
-
-
-void EventHistory::addEvent(WpaMsg msg)
-{
- bool scroll = true;
-
- if (eventListView->verticalScrollBar()->value() <
- eventListView->verticalScrollBar()->maximum())
- scroll = false;
-
- elm->addEvent(msg.getTimestamp().toString("yyyy-MM-dd hh:mm:ss.zzz"),
- msg.getMsg());
-
- if (scroll)
- eventListView->scrollToBottom();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/eventhistory.h b/wpa_supplicant/wpa_gui-qt4/eventhistory.h
deleted file mode 100644
index afd7b63469a2..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/eventhistory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * wpa_gui - EventHistory class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef EVENTHISTORY_H
-#define EVENTHISTORY_H
-
-#include <QObject>
-#include "ui_eventhistory.h"
-
-
-class EventListModel : public QAbstractTableModel
-{
- Q_OBJECT
-
-public:
- EventListModel(QObject *parent = 0)
- : QAbstractTableModel(parent) {}
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- void addEvent(QString time, QString msg);
-
-private:
- QStringList timeList;
- QStringList msgList;
-};
-
-
-class EventHistory : public QDialog, public Ui::EventHistory
-{
- Q_OBJECT
-
-public:
- EventHistory(QWidget *parent = 0, const char *name = 0,
- bool modal = false, Qt::WindowFlags fl = 0);
- ~EventHistory();
-
-public slots:
- virtual void addEvents(WpaMsgList msgs);
- virtual void addEvent(WpaMsg msg);
-
-protected slots:
- virtual void languageChange();
-
-private:
- EventListModel *elm;
-};
-
-#endif /* EVENTHISTORY_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/eventhistory.ui b/wpa_supplicant/wpa_gui-qt4/eventhistory.ui
deleted file mode 100644
index afe9149cfa0f..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/eventhistory.ui
+++ /dev/null
@@ -1,61 +0,0 @@
-<ui version="4.0" >
- <class>EventHistory</class>
- <widget class="QDialog" name="EventHistory" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>533</width>
- <height>285</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Event history</string>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="2" >
- <widget class="QTreeView" name="eventListView" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="verticalScrollBarPolicy" >
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="selectionMode" >
- <enum>QAbstractItemView::NoSelection</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1" >
- <widget class="QPushButton" name="closeButton" >
- <property name="text" >
- <string>Close</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <includes>
- <include location="local" >wpamsg.h</include>
- </includes>
- <resources/>
- <connections/>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons.qrc b/wpa_supplicant/wpa_gui-qt4/icons.qrc
deleted file mode 100644
index dd72c7ef1008..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons.qrc
+++ /dev/null
@@ -1,9 +0,0 @@
-<RCC>
- <qresource prefix="/icons" >
- <file alias="wpa_gui.svg">icons/wpa_gui.svg</file>
- <file alias="ap.svg">icons/ap.svg</file>
- <file alias="laptop.svg">icons/laptop.svg</file>
- <file alias="group.svg">icons/group.svg</file>
- <file alias="invitation.svg">icons/invitation.svg</file>
- </qresource>
-</RCC>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/.gitignore b/wpa_supplicant/wpa_gui-qt4/icons/.gitignore
deleted file mode 100644
index 8d772cc93884..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-hicolor
-pixmaps
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/Makefile b/wpa_supplicant/wpa_gui-qt4/icons/Makefile
deleted file mode 100644
index 88efc3c5b258..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/make -f
-
-NAMES := wpa_gui ap laptop group invitation
-SIZES := 16x16 22x22 32x32 48x48 64x64 128x128
-ICONS := $(addsuffix .png, $(foreach name, $(NAMES), $(foreach size, $(SIZES), $(size)/$(name))))
-ICONS += $(addsuffix .xpm, $(NAMES))
-
-ifeq (1, $(shell which inkscape; echo $$?))
-$(error "No inkscape in PATH, it is required for exporting icons.")
-else
-ifeq (0, $(shell inkscape --without-gui 2>&1 > /dev/null; echo $$?))
-# Inkscape < 1.0
-INKSCAPE_GUI_FLAG := --without-gui
-INKSCAPE_OUTPUT_FLAG := --export-png
-else
-# Inkscape >= 1.0
-INKSCAPE_GUI_FLAG :=
-INKSCAPE_OUTPUT_FLAG := --export-filename
-endif
-endif
-
-all: $(ICONS)
-
-%.png:
- mkdir -p hicolor/$(word 1, $(subst /, ,$(@)))/apps/
- inkscape $(subst .png,.svg, $(word 2, $(subst /, , $(@)))) $(INKSCAPE_GUI_FLAG) \
- --export-width=$(word 1, $(subst x, , $(@))) \
- --export-height=$(word 2, $(subst x, , $(subst /, , $(@)))) \
- $(INKSCAPE_OUTPUT_FLAG)=hicolor/$(word 1, $(subst /, ,$(@)))/apps/$(word 2, $(subst /, , $@))
-
-%.xpm:
- mkdir -p pixmaps/
- convert hicolor/16x16/apps/$(@:.xpm=.png) pixmaps/$(@:.xpm=-16.xpm)
- convert hicolor/32x32/apps/$(@:.xpm=.png) pixmaps/$@
-
-clean:
- $(RM) -r pixmaps hicolor
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/README b/wpa_supplicant/wpa_gui-qt4/icons/README
deleted file mode 100644
index 39532389766e..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/README
+++ /dev/null
@@ -1,74 +0,0 @@
-wpa_gui icon files
-
-To convert the svg icons to other formats, make sure inkscape and imagemagick
-are installed and use `make' to create various sized png and xpm icons.
-
-
-wpa_gui.svg
------------
-
-Copyright (c) 2008 Bernard Gray <bernard.gray@gmail.com>
-
-The wpa_gui icon is licensed under the GPL version 2. Alternatively, the icon
-may be distributed under the terms of BSD license.
-
-
-ap.svg
-------
-
-mystica_Wireless_Router.svg
-
-http://openclipart.org/media/files/mystica/8390
-Wireless Router
-by: mystica
-last change: April 20, 2008 10:32 pm (File added)
-date: April 20, 2008 10:31 pm
-license: PD
-
-
-laptop.svg
-----------
-
-metalmarious_Laptop.svg
-
-http://openclipart.org/media/files/metalmarious/4056
-Laptop
-by: metalmarious
-last change: May 18, 2008 07:04 pm (File added)
-date: August 27, 2007 04:44 am
-license: PD
-
-
-group.svg
----------
-
-http://www.openclipart.org/detail/25428
-http://www.openclipart.org/people/Anonymous/Anonymous_Network.svg
-Uploader:
- Anonymous
-Drawn by:
- Andrew Fitzsimon / Anonymous
-Created:
- 2009-04-29 04:07:37
-Description:
- A network icon by Andrew Fitzsimon. Etiquette Icon set.
- From 0.18 OCAL database.
-
-Public Domain
-
-
-
-invitation.svg
---------------
-
-http://www.openclipart.org/detail/974
-http://www.openclipart.org/people/jean_victor_balin/jean_victor_balin_unknown_green.svg
-Uploader:
- jean_victor_balin
-Drawn by:
- jean_victor_balin
-Created:
- 2006-10-27 02:12:13
-Description:
-
-Public Domain
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/ap.svg b/wpa_supplicant/wpa_gui-qt4/icons/ap.svg
deleted file mode 100644
index 51cc8ce646ad..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/ap.svg
+++ /dev/null
@@ -1,832 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="546"
- height="482.67157"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.45.1+0.46pre1+devel"
- sodipodi:docname="Wireless Router.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- version="1.0"
- inkscape:export-filename="C:\Documents and Settings\Dan\Skrivbord\Clipart egna (InkScape)\Original\Kanske Upload\Wireless Router.png"
- inkscape:export-xdpi="310"
- inkscape:export-ydpi="310">
- <defs
- id="defs4">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="-50 : 600 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="700 : 600 : 1"
- inkscape:persp3d-origin="300 : 400 : 1"
- id="perspective148" />
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="-50 : 600 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="700 : 600 : 1"
- inkscape:persp3d-origin="300 : 400 : 1"
- id="perspective138" />
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="-50 : 600 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="700 : 600 : 1"
- inkscape:persp3d-origin="300 : 400 : 1"
- id="perspective10" />
- <inkscape:perspective
- id="perspective2395"
- inkscape:persp3d-origin="300 : 400 : 1"
- inkscape:vp_z="700 : 600 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="-50 : 600 : 1"
- sodipodi:type="inkscape:persp3d" />
- <filter
- inkscape:collect="always"
- id="filter3304">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.27999283"
- id="feGaussianBlur3306" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3336">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.5315371"
- id="feGaussianBlur3338" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3368">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.26473573"
- id="feGaussianBlur3370" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3564"
- x="-0.37202433"
- width="1.7440487"
- y="-0.43252525"
- height="1.8650506">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1017616"
- id="feGaussianBlur3566" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3748"
- x="-0.41952851"
- width="1.839057"
- y="-0.39121628"
- height="1.7824326">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1235829"
- id="feGaussianBlur3750" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3862"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3864" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3866"
- x="-0.33298156"
- width="1.6659631"
- y="-0.20756502"
- height="1.4151301">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3868" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3870"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3872" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3874"
- x="-0.3380883"
- width="1.6761765"
- y="-0.21154897"
- height="1.4230978">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3876" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3878"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3880" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3882"
- x="-0.36018598"
- width="1.720372"
- y="-0.20953795"
- height="1.4190758">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3884" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3886"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3888" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3890"
- x="-0.35439494"
- width="1.7087899"
- y="-0.20953795"
- height="1.4190758">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3892" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3894"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3896" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3898"
- x="-0.38537359"
- width="1.7707472"
- y="-0.20562869"
- height="1.4112574">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3900" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3902"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3904" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3906"
- x="-0.38537359"
- width="1.7707472"
- y="-0.21359873"
- height="1.4271975">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3908" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3910"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3912" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3914"
- x="-0.36018598"
- width="1.720372"
- y="-0.20562869"
- height="1.4112574">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3916" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3918"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3920" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3922"
- x="-0.36616942"
- width="1.7323389"
- y="-0.20953795"
- height="1.4190758">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3924" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3926"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3928" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3930"
- x="-0.34878778"
- width="1.6975756"
- y="-0.20186263"
- height="1.4037253">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3932" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3934"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3936" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3938"
- x="-0.32802677"
- width="1.6560535"
- y="-0.21568884"
- height="1.4313776">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3940" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3942"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3944" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3946"
- x="-0.32321677"
- width="1.6464336"
- y="-0.21568884"
- height="1.4313776">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3948" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3950"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3952" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3954"
- x="-0.3185463"
- width="1.6370926"
- y="-0.21359873"
- height="1.4271975">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3956" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3958"
- x="-0.33298156"
- width="1.6659631"
- y="-1.6699424"
- height="4.3398848">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3960" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3962"
- x="-0.28553614"
- width="1.5710723"
- y="-0.21568884"
- height="1.4313776">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.82006695"
- id="feGaussianBlur3964" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3982"
- x="-0.0048889387"
- width="1.0097779"
- y="-0.26385465"
- height="1.5277092">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.0547249"
- id="feGaussianBlur3984" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3996">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.8032234"
- id="feGaussianBlur3998" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3517"
- x="-0.25713229"
- width="1.5142646"
- y="-0.087099633"
- height="1.1741993">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.33984317"
- id="feGaussianBlur3519" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3329"
- x="-0.18025071"
- width="1.3605014"
- y="-1.1780664"
- height="3.3561328">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.49086099"
- id="feGaussianBlur3331" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3333"
- x="-0.15131117"
- width="1.3026223"
- y="-0.1853139"
- height="1.3706278">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.49086099"
- id="feGaussianBlur3335" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3337"
- x="-0.14412392"
- width="1.2882478"
- y="-0.18013415"
- height="1.3602683">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.49086099"
- id="feGaussianBlur3339" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3341"
- x="-1.1780664"
- width="3.3561328"
- y="-0.23067047"
- height="1.4613409">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.49086099"
- id="feGaussianBlur3343" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
- objecttolerance="10"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.98994949"
- inkscape:cx="233.05018"
- inkscape:cy="176.49031"
- inkscape:document-units="px"
- inkscape:current-layer="layer2"
- showgrid="false"
- inkscape:window-width="1152"
- inkscape:window-height="838"
- inkscape:window-x="0"
- inkscape:window-y="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- transform="translate(-45.788597,-496.6196)">
- <path
- style="fill:#606060;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 75.574315,977.86259 L 535.56828,979.20564 L 564.86002,979.29116 C 564.86002,979.29116 573.43146,977.86259 573.43146,973.57687 C 573.43146,969.29116 574.14573,959.29117 574.14573,959.29117 L 566.03832,959.7296 L 72.464255,956.66717 L 58.640665,955.63307 C 58.640665,955.63307 59.860025,973.57688 65.574315,975.71973 C 71.288595,977.86259 75.574315,977.14831 75.574315,977.86259 z"
- id="path2402"
- sodipodi:nodetypes="cccsccccsc" />
- <path
- style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#b2b2b2;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 67.002885,957.14831 L 566.28859,960.00545 C 566.28859,960.00545 577.71717,959.29116 583.43146,955.71973 C 589.14574,952.14831 588.43146,942.86259 588.43146,942.86259 C 588.43146,942.86259 591.28859,907.14831 591.28859,902.14831 C 591.28859,897.14831 574.86002,839.29116 572.00288,827.86259 C 569.14574,816.43402 557.00288,757.1483 557.00288,757.1483 C 557.00288,757.1483 555.57431,749.29116 552.71717,748.57688 C 549.86002,747.86259 548.43146,748.57688 548.43146,748.57688 L 558.43146,797.86259 L 577.71717,880.00545 L 578.07431,881.34473 L 579.05004,882.28742 L 584.86002,897.14831 C 584.86002,897.14831 584.93925,904.12528 581.70701,906.43402 C 576.70701,910.00545 557.71717,910.71973 557.71717,910.71973 L 68.431455,907.86259 C 68.431455,907.86259 57.002885,906.43402 54.145745,903.57688 C 51.288595,900.71973 52.298745,895.51053 52.298745,895.51053 L 94.860025,745.00545 C 94.860025,745.00545 86.288605,747.86259 84.145745,752.1483 C 82.002885,756.43402 71.288595,811.43402 68.431455,820.00545 C 65.574315,828.57688 47.002885,893.57688 47.002885,893.57688 C 47.002885,893.57688 46.288597,900.00545 46.288597,903.57688 C 46.288597,907.14831 48.431455,946.43402 48.431455,946.43402 C 48.431455,946.43402 52.002885,953.57688 55.574315,955.00545 C 59.145745,956.43402 68.431455,957.14831 67.002885,957.14831 z"
- id="path2404"
- sodipodi:nodetypes="ccscsscsccccccsccsccsscscsc" />
- <path
- style="fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3336)"
- d="M 562.71717,958.57688 C 562.71717,958.57688 572.00288,957.86259 572.00288,951.43402 C 572.00288,945.00545 575.57431,922.14831 572.00288,918.57688 C 568.43146,915.00545 564.86002,912.86259 564.86002,912.86259 C 564.86002,912.86259 586.28859,903.57688 585.57431,907.86259 C 584.86002,912.14831 581.28859,914.29116 581.28859,920.00545 C 581.28859,925.71973 580.57431,948.57688 580.57431,948.57688 C 580.57431,948.57688 578.43146,952.86259 581.28859,953.57688 C 584.14574,954.29116 582.71717,955.71973 582.71717,955.71973 L 576.28859,957.86259 L 570.57431,958.57688 L 562.71717,958.57688 z"
- id="path2406" />
- <path
- style="fill:#ededed;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 75.574315,913.57688 L 560.57431,915.71973 L 557.71717,955.71973 L 77.002885,954.29116 L 75.574315,913.57688 z"
- id="path2408" />
- <path
- style="fill:#020202;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 100.57432,925.00545 L 541.28859,927.86259 C 541.28859,927.86259 548.43146,932.14831 548.43146,936.43402 C 548.43146,940.71973 540.57431,945.71973 540.57431,945.71973 L 98.431455,942.86259 C 98.431455,942.86259 89.145745,938.57688 89.860025,932.86259 C 90.574315,927.14831 101.2886,924.29116 100.57432,925.00545 z"
- id="path2410" />
- <path
- style="fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 71.497795,907.90591 L 557.85419,910.32545 L 573.61002,909.11259 C 573.61002,909.11259 581.28967,908.48718 583.43146,904.46973 C 584.17421,903.07651 585.22722,901.79095 585.2275,899.8245 C 585.22862,892.20247 577.89573,880.63045 577.89573,880.63045 C 577.89573,880.63045 578.20783,882.29016 577.30114,882.74322 C 575.50038,883.64304 573.664,884.53037 571.28859,885.00545 C 567.71717,885.71973 66.036055,879.91879 66.036055,879.91879 L 59.860025,880.00545 L 56.288605,877.68402 L 52.002885,896.43402 C 52.002885,896.43402 51.828665,903.29437 57.673845,905.51053 C 62.003235,907.15199 72.212085,908.6202 71.497795,907.90591 z"
- id="path2412"
- sodipodi:nodetypes="cccsscssccccsc" />
- <path
- style="fill:#2c2c2c;fill-opacity:1;fill-rule:evenodd;stroke:#252525;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 93.431455,743.57688 L 59.145745,868.57688 C 59.145745,868.57688 57.538605,871.96973 60.574315,873.57688 C 65.381975,876.12212 74.681455,875.18402 74.681455,875.18402 C 74.681455,875.18402 567.00288,879.29116 569.86002,878.57688 C 572.71717,877.86259 575.03859,876.96974 575.03859,876.96974 L 575.21717,868.75545 C 575.21717,868.75545 579.61685,882.27622 576.28859,883.75545 C 573.07431,885.18402 566.28859,885.00545 566.28859,885.00545 L 64.860025,880.71973 L 58.431455,879.29116 L 56.645745,876.79116 L 57.861935,870.85997 L 93.431455,743.57688 z"
- id="path2414"
- sodipodi:nodetypes="ccscsccscccccc" />
- <path
- style="fill:#d5d5d5;fill-opacity:1;fill-rule:evenodd;stroke:#d1d1d1;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3748)"
- d="M 62.002885,879.82688 L 62.181455,874.29116 L 60.217165,873.93402 L 57.360025,874.82688 L 56.824315,876.25545 C 56.824315,876.25545 56.467165,877.86259 57.360025,878.21973 C 58.252885,878.57688 59.860025,879.11259 59.860025,879.11259 L 62.002885,879.82688 z"
- id="path2416" />
- <path
- style="fill:#d5d5d5;fill-opacity:1;fill-rule:evenodd;stroke:#dadada;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3564)"
- d="M 571.82431,883.04116 C 571.82431,882.32688 570.57431,879.82688 572.18146,878.93402 C 573.78859,878.04116 575.03859,878.57688 575.03859,878.57688 C 575.03859,878.57688 578.07431,881.25545 577.36002,881.43402 C 576.64574,881.61259 576.46717,882.50545 574.68146,883.21973 C 572.89574,883.93402 572.36002,883.21973 571.82431,883.04116 z"
- id="path2418" />
- <path
- style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#2aea00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3341)"
- d="M 194.42891,930.61513 L 194.68145,934.46973"
- id="path2420"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#2aea00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3337)"
- d="M 192.18145,932.32688 C 192.18145,932.32688 189.18906,937.68402 194.50288,937.86259 C 200.57352,938.06659 197.36003,932.50545 197.36003,932.50545"
- id="path2422"
- sodipodi:nodetypes="csc" />
- <path
- sodipodi:type="arc"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#444444;stroke-width:0.92299998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path2424"
- sodipodi:cx="289.82144"
- sodipodi:cy="742.89789"
- sodipodi:rx="4.2857141"
- sodipodi:ry="4.2857141"
- d="M 294.10716,742.89789 A 4.2857141,4.2857141 0 1 1 285.53573,742.89789 A 4.2857141,4.2857141 0 1 1 294.10716,742.89789 z"
- transform="translate(-57.282828,191.92898)" />
- <path
- sodipodi:type="arc"
- style="fill:#101010;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.92626119;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path2439"
- sodipodi:cx="289.82144"
- sodipodi:cy="742.89789"
- sodipodi:rx="4.2857141"
- sodipodi:ry="4.2857141"
- d="M 294.10716,742.89789 A 4.2857141,4.2857141 0 1 1 285.53573,742.89789 A 4.2857141,4.2857141 0 1 1 294.10716,742.89789 z"
- transform="matrix(0.4791666,0,0,0.4791666,93.755115,578.94427)" />
- <path
- sodipodi:type="arc"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#7b7b7b;stroke-width:1.70648665;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3211"
- sodipodi:cx="289.82144"
- sodipodi:cy="742.89789"
- sodipodi:rx="4.2857141"
- sodipodi:ry="4.2857141"
- d="M 294.10716,742.89789 A 4.2857141,4.2857141 0 1 1 285.53573,742.89789 A 4.2857141,4.2857141 0 1 1 294.10716,742.89789 z"
- transform="matrix(0.5109914,0,0,0.5109914,116.22806,556.99816)" />
- <path
- sodipodi:type="arc"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#7b7b7b;stroke-width:1.70648665;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3213"
- sodipodi:cx="289.82144"
- sodipodi:cy="742.89789"
- sodipodi:rx="4.2857141"
- sodipodi:ry="4.2857141"
- d="M 294.10716,742.89789 A 4.2857141,4.2857141 0 1 1 285.53573,742.89789 A 4.2857141,4.2857141 0 1 1 294.10716,742.89789 z"
- transform="matrix(0.5109914,0,0,0.5109914,122.47805,556.99816)" />
- <path
- sodipodi:type="arc"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#7b7b7b;stroke-width:1.70648665;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path3215"
- sodipodi:cx="289.82144"
- sodipodi:cy="742.89789"
- sodipodi:rx="4.2857141"
- sodipodi:ry="4.2857141"
- d="M 294.10716,742.89789 A 4.2857141,4.2857141 0 1 1 285.53573,742.89789 A 4.2857141,4.2857141 0 1 1 294.10716,742.89789 z"
- transform="matrix(0.5109914,0,0,0.5109914,119.44234,552.71244)" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#606060;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 308.07431,934.29116 C 308.07431,934.29116 307.00288,935.71973 306.28859,936.61259 C 305.57431,937.50544 305.57431,939.11259 304.32431,938.57688 C 303.07431,938.04116 301.11002,936.07688 301.28859,934.64831 C 301.46717,933.21974 304.32431,931.07688 304.32431,931.07688 C 304.32431,931.07688 305.03859,932.1483 306.11002,932.86259 C 307.18145,933.57688 307.89574,934.11259 308.07431,934.29116 z"
- id="path3217"
- sodipodi:nodetypes="cssscsc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#28cc03;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3333)"
- d="M 336.28859,931.43402 L 340.57431,931.43402 L 341.82431,932.68402 L 341.82431,935.00545 L 340.93145,936.79116 L 336.46717,936.79116 L 335.03859,935.71973 L 335.03859,932.50545 L 336.28859,931.43402 z"
- id="path3221"
- sodipodi:nodetypes="ccccccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#28cc03;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3329)"
- d="M 335.75288,938.57688 L 341.28859,938.57688"
- id="path3223" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 369.86002,931.43402 L 374.14574,931.43402 L 375.39574,932.68402 L 375.39574,935.00545 L 374.50288,936.79116 L 370.0386,936.79116 L 368.61002,935.71973 L 368.61002,932.50545 L 369.86002,931.43402 z"
- id="path3225"
- sodipodi:nodetypes="ccccccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 369.32431,938.57688 L 374.86002,938.57688"
- id="path3227" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 407.00288,931.79116 L 411.2886,931.79116 L 412.5386,933.04116 L 412.5386,935.36259 L 411.64574,937.1483 L 407.18147,937.1483 L 405.75288,936.07687 L 405.75288,932.86259 L 407.00288,931.79116 z"
- id="path3229"
- sodipodi:nodetypes="ccccccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 406.46717,938.93402 L 412.00288,938.93402"
- id="path3231" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 444.14574,931.96973 L 448.43145,931.96973 L 449.68145,933.21973 L 449.68145,935.54116 L 448.78859,937.32687 L 444.32431,937.32687 L 442.89574,936.25544 L 442.89574,933.04116 L 444.14574,931.96973 z"
- id="path3233"
- sodipodi:nodetypes="ccccccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 443.61002,939.11259 L 449.14574,939.11259"
- id="path3235" />
- <path
- style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#28cc03;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dominican;-inkscape-font-specification:Dominican;filter:url(#filter3517)"
- d="M 329.05831,937.86898 L 329.10629,932.30075 L 328.72213,932.54098 C 328.65816,932.59689 328.60226,932.62485 328.55441,932.62484 C 328.52242,932.62485 328.47243,932.59085 328.40444,932.52285 C 328.33646,932.45487 328.30245,932.38486 328.30245,932.31283 C 328.30245,932.22495 328.34841,932.12497 328.44034,932.0129 C 328.53225,931.90085 328.62618,931.78879 328.72213,931.67672 L 329.68234,930.33273 L 330.47445,930.78903 L 330.46236,938.5527 C 330.46236,938.64889 330.38631,938.69699 330.23421,938.69699 C 330.1783,938.69699 330.13437,938.69296 330.10238,938.6849 C 329.86239,938.62094 329.6224,938.56088 329.38241,938.50472 C 329.16634,938.40072 329.05831,938.18881 329.05831,937.86898 L 329.05831,937.86898 z"
- id="text3237" />
- <path
- style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#939393;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dominican;-inkscape-font-specification:Dominican"
- d="M 364.94248,932.84854 C 364.94246,933.5126 364.7065,934.32059 364.23458,935.27249 C 363.84249,936.05667 363.33443,936.86868 362.71041,937.70852 L 362.50643,937.97256 L 363.8984,937.94876 C 364.14644,937.94876 364.37044,937.97476 364.5704,938.02676 C 364.77034,938.07876 364.91036,938.16067 364.99044,938.27249 C 365.16646,938.51248 365.25447,938.70449 365.25448,938.84854 C 365.25447,938.98452 365.19448,939.06851 365.07449,939.10049 C 364.95449,939.13247 364.85042,939.14846 364.76229,939.14846 L 360.97054,939.34072 L 360.5743,937.93667 C 360.83846,937.62466 361.10653,937.31265 361.3785,937.00064 C 361.96248,936.20865 362.44246,935.46463 362.81844,934.76858 C 363.3304,933.83255 363.58638,933.12857 363.58639,932.65664 C 363.58638,932.55264 363.5784,932.46866 363.5624,932.40469 C 363.54641,932.34073 363.51046,932.30875 363.45455,932.30874 C 363.30245,932.30875 362.99044,932.50064 362.51852,932.88442 C 362.21456,933.13248 361.81051,933.50052 361.30636,933.98855 C 360.90646,934.38065 360.70248,934.58462 360.69442,934.60049 L 360.02242,933.65273 C 360.02242,933.58853 360.19845,933.3605 360.5505,932.96865 C 360.95846,932.51261 361.36642,932.1326 361.77438,931.82864 C 362.32638,931.42069 362.79439,931.21671 363.17843,931.2167 C 363.40255,931.21671 363.59053,931.27664 363.74239,931.39651 C 364.29439,931.80448 364.60237,932.04849 364.66634,932.12856 C 364.85042,932.35269 364.94246,932.59268 364.94248,932.84854 L 364.94248,932.84854 z"
- id="text3241" />
- <path
- style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#939393;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dominican;-inkscape-font-specification:Dominican"
- d="M 398.55154,939.8793 L 397.90371,938.83523 L 398.62368,938.71511 C 399.16762,938.61917 399.70754,938.33914 400.24343,937.87502 C 400.73952,937.44314 400.98757,937.09915 400.98757,936.84304 C 400.98757,936.69119 400.84755,936.55526 400.56753,936.43527 C 400.2875,936.31527 399.97951,936.25528 399.64358,936.25527 C 399.42751,936.25528 399.23348,936.28128 399.06149,936.33328 C 398.88949,936.38528 398.74355,936.47525 398.62368,936.60317 L 398.17947,936.27908 L 398.17947,935.23501 L 398.50356,935.079 C 399.04751,934.83902 399.59548,934.46304 400.14748,933.95107 C 400.69948,933.43912 400.97548,933.05521 400.97549,932.79934 C 400.97548,932.7432 400.95547,932.6951 400.91544,932.65505 C 400.81948,932.55911 400.65957,932.51114 400.43569,932.51113 C 400.10756,932.51114 399.69155,932.61112 399.18765,932.81106 C 398.7797,932.97122 398.5436,933.08328 398.47939,933.14724 L 397.97549,932.00723 C 398.06363,931.91129 398.32363,931.77127 398.75552,931.58718 C 399.29165,931.36307 399.75564,931.25101 400.14748,931.251 C 400.25955,931.25101 400.3716,931.26309 400.48367,931.28726 C 400.85965,931.37516 401.16762,931.52713 401.40762,931.74319 C 401.59169,931.90311 401.78371,932.15506 401.98367,932.49905 C 402.03151,932.57913 402.06149,932.6572 402.07357,932.73324 C 402.08565,932.8093 402.09169,932.88333 402.0917,932.95535 C 402.09169,933.25125 401.98366,933.5712 401.76761,933.91519 C 401.55154,934.25919 401.28347,934.56717 400.9634,934.83914 L 400.50747,935.21121 C 400.8915,935.21121 401.28951,935.43722 401.7015,935.88925 C 402.11348,936.34128 402.31948,936.8273 402.31948,937.34731 C 402.31948,937.65127 402.24947,937.91726 402.10947,938.14529 C 401.96944,938.37332 401.76748,938.6033 401.50356,938.83523 C 401.16762,939.13113 400.79567,939.37112 400.38772,939.5552 C 399.88357,939.78713 399.3915,939.9031 398.91152,939.9031 C 398.84756,939.9031 398.78158,939.89913 398.71359,939.8912 C 398.64559,939.88326 398.59157,939.8793 398.55154,939.8793 L 398.55154,939.8793 z"
- id="text3245" />
- <path
- style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:#939393;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dominican;-inkscape-font-specification:Dominican"
- d="M 433.97515,936.58822 L 436.87884,931.5964 L 438.17486,932.11239 L 438.01885,936.03634 L 438.42718,936.13229 C 438.62712,936.1882 438.73503,936.22018 438.75091,936.22824 C 438.799,936.26022 438.83904,936.31222 438.87103,936.38424 C 438.93499,936.52829 438.98094,936.63431 439.0089,936.7023 C 439.03686,936.77029 439.05083,936.84823 439.05083,936.93612 C 439.05083,937.00033 439.03887,937.06442 439.01495,937.12838 L 437.92291,937.20016 L 437.93499,939.73214 C 437.93499,939.94015 437.86296,940.03219 437.71893,940.00826 C 437.31902,939.95236 437.08709,939.91232 437.02312,939.88815 C 436.78313,939.78414 436.66314,939.57223 436.66314,939.25241 L 436.66314,937.28439 L 434.71893,937.28439 L 433.97515,936.58822 z M 435.48687,936.08431 L 436.80706,936.10812 L 437.01104,933.13229 L 435.48687,936.08431 z"
- id="text3249" />
- <path
- style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dominican;-inkscape-font-specification:Dominican"
- d="M 109.34409,932.3674 C 109.08016,933.58322 108.9001,934.43124 108.80392,934.91146 C 108.65206,935.67123 108.49617,936.52719 108.33628,937.47933 L 107.04026,936.98715 L 106.27194,932.81124 L 105.39597,937.73129 L 104.01609,937.28744 L 103.3082,929.55929 C 103.3082,929.47141 103.38021,929.42746 103.52426,929.42745 C 103.63608,929.43527 103.71604,929.43918 103.76413,929.43917 C 103.91622,929.43918 104.04623,929.46518 104.15414,929.51718 C 104.26206,929.56919 104.32004,929.65927 104.3281,929.78744 L 104.77194,935.69113 L 105.64792,929.97933 L 107.04026,930.03939 L 107.65219,935.5234 C 107.76425,934.39523 107.95627,933.16318 108.22824,931.82723 C 108.35617,931.17124 108.46811,930.65927 108.56405,930.29135 C 108.63607,930.00327 108.78011,929.49521 108.99618,928.76718 C 109.02011,928.7352 109.04806,928.69919 109.08005,928.65914 C 109.15206,928.58713 109.23213,928.55918 109.32028,928.57528 C 109.55221,928.61533 109.73819,928.69132 109.87821,928.80325 C 110.0182,928.91519 110.08821,929.06723 110.08822,929.25936 C 109.91219,929.97129 109.78413,930.48728 109.70407,930.80734 C 109.57613,931.32736 109.45614,931.84738 109.34409,932.3674 L 109.34409,932.3674 z M 111.18136,931.43136 L 111.18136,930.65133 C 111.18136,930.49924 111.22733,930.36521 111.31924,930.24923 C 111.41116,930.13327 111.52914,930.07529 111.67319,930.07528 C 111.80917,930.07529 111.9332,930.12729 112.04525,930.23129 C 112.15732,930.3353 112.21335,930.45932 112.21335,930.60336 L 112.21335,931.68331 C 112.21335,931.79538 112.16135,931.87741 112.05734,931.92941 C 111.95334,931.98141 111.82932,932.00742 111.68527,932.00741 C 111.54122,932.00742 111.42123,931.95139 111.32529,931.83932 C 111.22933,931.72726 111.18136,931.59128 111.18136,931.43136 L 111.18136,931.43136 z M 111.13339,937.22738 L 111.13339,932.83541 C 111.13339,932.64328 111.24533,932.54721 111.46921,932.54721 C 111.74117,932.54721 111.93515,932.58121 112.05112,932.64919 C 112.16708,932.71719 112.22507,932.81125 112.22507,932.93136 L 112.1174,937.67123 C 112.1174,937.76718 112.04538,937.81515 111.90134,937.81515 C 111.82126,937.81515 111.75118,937.80715 111.69112,937.79116 C 111.63107,937.77517 111.58505,937.76327 111.55307,937.75546 C 111.27329,937.66732 111.13339,937.4913 111.13339,937.22738 L 111.13339,937.22738 z M 113.68845,932.8713 L 113.79648,932.73947 L 114.0726,932.73947 C 114.13657,932.73947 114.21053,932.77743 114.29452,932.85336 C 114.37851,932.92929 114.44455,932.97531 114.49265,932.99142 C 114.60446,933.02341 114.69638,932.93741 114.76839,932.73342 C 114.84042,932.52945 114.92641,932.41342 115.0264,932.38534 C 115.12636,932.35727 115.19638,932.34323 115.23641,932.34323 C 115.38852,932.34323 115.52255,932.39725 115.63852,932.50527 C 115.75449,932.61331 115.81247,932.74326 115.81247,932.89511 L 115.80039,933.36312 C 115.80038,933.5953 115.77237,933.80539 115.71634,933.99337 C 115.6603,934.18136 115.57236,934.27536 115.45248,934.27535 C 115.26839,934.27536 115.14437,934.0953 115.08042,933.73519 C 115.04843,933.55917 114.9924,933.47116 114.91233,933.47116 C 114.84054,933.47116 114.78261,933.53116 114.73855,933.65115 C 114.69449,933.77115 114.67246,934.0112 114.67246,934.3713 C 114.67246,934.48337 114.67246,934.58139 114.67246,934.66537 C 114.67246,934.74936 114.67246,934.81527 114.67246,934.86312 L 114.67246,937.79135 C 114.58456,937.83138 114.48459,937.8514 114.37252,937.8514 C 114.30051,937.8514 114.2125,937.83938 114.10849,937.81533 C 114.00449,937.79128 113.90451,937.73324 113.80857,937.6412 C 113.71261,937.54916 113.66464,937.43124 113.66464,937.28744 L 113.68845,932.8713 z M 119.45774,933.78317 L 119.52951,935.22311 L 117.82552,935.49923 C 117.68173,935.53122 117.58579,935.56723 117.53769,935.60726 C 117.43368,935.68734 117.38168,935.7994 117.38169,935.94345 L 117.40548,936.49533 C 117.40548,936.6152 117.44351,936.72518 117.51955,936.82528 C 117.59561,936.92538 117.68563,936.9714 117.78964,936.96334 C 118.01376,936.93136 118.29379,936.75534 118.62973,936.43527 C 118.96567,936.1152 119.11764,935.91916 119.08567,935.84713 C 119.11764,935.83126 119.16965,935.82333 119.24167,935.82333 C 119.37765,935.82333 119.47763,935.86734 119.5416,935.95535 C 119.60556,936.04336 119.63754,936.13534 119.63755,936.23129 C 119.63754,936.27133 119.62557,936.32333 119.60165,936.38729 C 119.55356,936.57138 119.48556,936.73141 119.39767,936.8674 C 119.35763,936.93136 119.24556,937.07138 119.0615,937.28744 C 118.90964,937.46322 118.75571,937.59115 118.59969,937.67123 C 118.44369,937.75131 118.25765,937.79135 118.0416,937.79135 C 117.89755,937.79135 117.77956,937.77731 117.68766,937.74923 C 117.59573,937.72116 117.50168,937.6672 117.40548,937.58737 L 116.78182,937.0234 C 116.75765,937.00729 116.73361,936.97122 116.70969,936.91519 C 116.68576,936.85916 116.66574,936.81515 116.64963,936.78317 C 116.59372,936.63937 116.56576,936.48739 116.56576,936.32723 L 116.56576,935.3912 C 116.56576,934.78329 116.69974,934.1553 116.96768,933.50723 C 117.23562,932.85916 117.52158,932.53513 117.82552,932.53512 C 117.87363,932.53513 117.90964,932.53915 117.93357,932.54721 C 118.08566,932.59531 118.27969,932.63132 118.51566,932.65524 C 118.75162,932.67917 118.93563,932.76315 119.06771,932.90719 C 119.19979,933.05124 119.29782,933.18924 119.36178,933.32119 C 119.42575,933.45315 119.45773,933.60715 119.45774,933.78317 L 119.45774,933.78317 z M 118.58176,933.77145 C 118.58176,933.63547 118.55576,933.51547 118.50376,933.41146 C 118.45175,933.30746 118.36972,933.23935 118.25765,933.20712 C 118.13754,933.1832 118.0256,933.31125 117.92185,933.59127 C 117.84982,933.79123 117.80173,933.93124 117.77756,934.01132 C 117.71358,934.17929 117.66562,934.32327 117.63363,934.44326 C 117.60165,934.56326 117.58566,934.69125 117.58567,934.82723 L 118.58176,934.59945 L 118.58176,933.77145 z M 120.69589,937.04721 L 120.80356,929.73947 C 120.80356,929.64328 120.85361,929.5712 120.95371,929.52322 C 121.0538,929.47525 121.16379,929.46323 121.28366,929.48715 C 121.45163,929.51914 121.56564,929.57517 121.6257,929.65524 C 121.68576,929.73532 121.71579,929.85129 121.71579,930.00314 L 121.53562,937.61117 C 121.53561,937.6993 121.45969,937.74337 121.30783,937.74337 C 121.25168,937.74337 121.19162,937.73532 121.12766,937.7192 C 120.91965,937.62326 120.79568,937.5433 120.75576,937.47933 C 120.71585,937.41537 120.69589,937.27133 120.69589,937.04721 L 120.69589,937.04721 z M 125.71554,933.78317 L 125.78733,935.22311 L 124.08335,935.49923 C 123.93955,935.53122 123.84359,935.56723 123.7955,935.60726 C 123.6915,935.68734 123.6395,935.7994 123.6395,935.94345 L 123.6633,936.49533 C 123.6633,936.6152 123.70132,936.72518 123.77738,936.82528 C 123.85343,936.92538 123.94344,936.9714 124.04746,936.96334 C 124.27158,936.93136 124.5516,936.75534 124.88755,936.43527 C 125.22348,936.1152 125.37546,935.91916 125.34348,935.84713 C 125.37546,935.83126 125.42746,935.82333 125.49948,935.82333 C 125.63547,935.82333 125.73543,935.86734 125.79941,935.95535 C 125.86337,936.04336 125.89534,936.13534 125.89535,936.23129 C 125.89534,936.27133 125.88339,936.32333 125.85947,936.38729 C 125.81136,936.57138 125.74338,936.73141 125.65548,936.8674 C 125.61544,936.93136 125.50339,937.07138 125.31931,937.28744 C 125.16745,937.46322 125.01352,937.59115 124.85752,937.67123 C 124.7015,937.75131 124.51547,937.79135 124.29941,937.79135 C 124.15537,937.79135 124.03737,937.77731 123.94547,937.74923 C 123.85354,937.72116 123.75949,937.6672 123.6633,937.58737 L 123.03964,937.0234 C 123.01547,937.00729 122.99142,936.97122 122.9675,936.91519 C 122.94357,936.85916 122.92355,936.81515 122.90743,936.78317 C 122.85153,936.63937 122.82358,936.48739 122.82358,936.32723 L 122.82358,935.3912 C 122.82358,934.78329 122.95755,934.1553 123.22549,933.50723 C 123.49344,932.85916 123.77938,932.53513 124.08335,932.53512 C 124.13144,932.53513 124.16745,932.53915 124.19137,932.54721 C 124.34348,932.59531 124.53751,932.63132 124.77347,932.65524 C 125.00942,932.67917 125.19344,932.76315 125.32552,932.90719 C 125.45761,933.05124 125.55562,933.18924 125.6196,933.32119 C 125.68356,933.45315 125.71554,933.60715 125.71554,933.78317 L 125.71554,933.78317 z M 124.83956,933.77145 C 124.83956,933.63547 124.81357,933.51547 124.76157,933.41146 C 124.70955,933.30746 124.62752,933.23935 124.51547,933.20712 C 124.39535,933.1832 124.28341,933.31125 124.17965,933.59127 C 124.10764,933.79123 124.05954,933.93124 124.03537,934.01132 C 123.97141,934.17929 123.92343,934.32327 123.89145,934.44326 C 123.85947,934.56326 123.84348,934.69125 123.84348,934.82723 L 124.83956,934.59945 L 124.83956,933.77145 z M 126.83358,937.26327 C 126.73764,937.19931 126.68966,937.09933 126.68966,936.96334 C 126.68966,936.88327 126.71366,936.80722 126.76163,936.73519 C 126.8096,936.66317 126.86758,936.60916 126.93558,936.57315 C 127.00357,936.53714 127.06955,936.53524 127.13352,936.56747 C 127.34152,936.70346 127.49752,936.80343 127.60153,936.8674 C 127.80148,936.99533 127.94942,937.05929 128.04538,937.05929 C 128.14937,937.05929 128.2134,937.02127 128.23746,936.94522 C 128.2615,936.86917 128.27353,936.81918 128.27353,936.79525 C 128.27353,936.75521 128.27353,936.72726 128.27353,936.71139 C 128.27353,936.54342 128.18149,936.37936 127.99741,936.2192 C 127.82138,936.08322 127.64737,935.94522 127.47537,935.8052 C 127.30338,935.66519 127.17141,935.52719 127.0795,935.3912 C 126.98757,935.25522 126.92362,935.09921 126.88761,934.92318 C 126.85159,934.74716 126.83358,934.59518 126.83358,934.46725 C 126.83358,934.05929 126.94956,933.6893 127.18149,933.35726 C 127.41342,933.02524 127.70944,932.85922 128.06955,932.85922 C 128.17355,932.85922 128.23752,932.85922 128.26145,932.85922 C 128.3176,932.85922 128.35764,932.86728 128.38155,932.88339 L 128.95761,933.23129 C 129.08553,933.31137 129.17355,933.42343 129.22164,933.56747 C 129.24556,933.63144 129.2695,933.78732 129.29343,934.03512 C 129.29343,934.21921 129.28341,934.37527 129.2634,934.50332 C 129.24338,934.63138 129.20139,934.76742 129.13742,934.91146 L 128.5134,934.91146 C 128.48946,934.84726 128.4515,934.79318 128.39951,934.74923 C 128.3475,934.70529 128.32149,934.48337 128.32151,934.08346 C 128.32149,933.9714 128.32149,933.85531 128.32151,933.73519 C 128.29757,933.67123 128.26157,933.63925 128.21347,933.63925 C 128.13363,933.63925 128.03366,933.73526 127.91354,933.92727 C 127.79343,934.11929 127.72141,934.28732 127.69747,934.43136 C 127.67355,934.6152 127.71761,934.79123 127.82968,934.95944 C 127.90951,935.07931 128.05344,935.22323 128.26145,935.3912 C 128.46945,935.55917 128.68552,935.72714 128.90964,935.89511 C 129.16549,936.12728 129.29343,936.3674 129.29343,936.61544 C 129.29343,936.92745 129.15347,937.21145 128.87357,937.46743 C 128.59366,937.72341 128.32968,937.8514 128.08164,937.8514 C 127.89755,937.8514 127.72549,937.81539 127.56546,937.74337 C 127.40543,937.67135 127.16146,937.51132 126.83358,937.26327 L 126.83358,937.26327 z M 130.2789,937.26327 C 130.18295,937.19931 130.13497,937.09933 130.13497,936.96334 C 130.13497,936.88327 130.15896,936.80722 130.20694,936.73519 C 130.25492,936.66317 130.31289,936.60916 130.38089,936.57315 C 130.44888,936.53714 130.51486,936.53524 130.57882,936.56747 C 130.78683,936.70346 130.94284,936.80343 131.04685,936.8674 C 131.24679,936.99533 131.39475,937.05929 131.49069,937.05929 C 131.5947,937.05929 131.65872,937.02127 131.68277,936.94522 C 131.70682,936.86917 131.71884,936.81918 131.71884,936.79525 C 131.71884,936.75521 131.71884,936.72726 131.71884,936.71139 C 131.71884,936.54342 131.6268,936.37936 131.44271,936.2192 C 131.26668,936.08322 131.09268,935.94522 130.92068,935.8052 C 130.74868,935.66519 130.61673,935.52719 130.52481,935.3912 C 130.43288,935.25522 130.36893,935.09921 130.33292,934.92318 C 130.29691,934.74716 130.2789,934.59518 130.2789,934.46725 C 130.2789,934.05929 130.39487,933.6893 130.6268,933.35726 C 130.85873,933.02524 131.15475,932.85922 131.51486,932.85922 C 131.61886,932.85922 131.68283,932.85922 131.70676,932.85922 C 131.76291,932.85922 131.80294,932.86728 131.82688,932.88339 L 132.40293,933.23129 C 132.53084,933.31137 132.61886,933.42343 132.66696,933.56747 C 132.69089,933.63144 132.71481,933.78732 132.73873,934.03512 C 132.73873,934.21921 132.72872,934.37527 132.70871,934.50332 C 132.68868,934.63138 132.64669,934.76742 132.58274,934.91146 L 131.95871,934.91146 C 131.93478,934.84726 131.89682,934.79318 131.84482,934.74923 C 131.79282,934.70529 131.76682,934.48337 131.76682,934.08346 C 131.76682,933.9714 131.76682,933.85531 131.76682,933.73519 C 131.74289,933.67123 131.70687,933.63925 131.65878,933.63925 C 131.57895,933.63925 131.47897,933.73526 131.35886,933.92727 C 131.23873,934.11929 131.16672,934.28732 131.14279,934.43136 C 131.11886,934.6152 131.16293,934.79123 131.275,934.95944 C 131.35483,935.07931 131.49875,935.22323 131.70676,935.3912 C 131.91476,935.55917 132.13083,935.72714 132.35495,935.89511 C 132.6108,936.12728 132.73873,936.3674 132.73873,936.61544 C 132.73873,936.92745 132.59878,937.21145 132.31887,937.46743 C 132.03897,937.72341 131.77499,937.8514 131.52695,937.8514 C 131.34287,937.8514 131.17081,937.81539 131.01077,937.74337 C 130.85074,937.67135 130.60677,937.51132 130.2789,937.26327 L 130.2789,937.26327 z M 145.64951,931.63534 C 145.6014,932.07529 145.41745,932.48727 145.09762,932.8713 C 144.84152,933.17526 144.45345,933.50326 143.93344,933.85531 L 143.41745,934.20321 L 145.36167,937.13143 C 145.37752,937.21127 145.38546,937.2712 145.38547,937.31124 C 145.38546,937.51119 145.29745,937.6672 145.12143,937.77926 C 145.03354,937.82736 144.94955,937.8514 144.86947,937.8514 C 144.74959,937.8514 144.63961,937.82137 144.53951,937.76132 C 144.43941,937.70126 144.34945,937.6152 144.26962,937.50314 L 141.84567,934.22738 L 141.78562,937.58737 C 141.78561,937.70724 141.68955,937.76718 141.49741,937.76718 C 141.38558,937.76718 141.29757,937.75118 141.23336,937.7192 C 141.0815,937.67135 140.94956,937.62539 140.8375,937.58132 C 140.72543,937.53726 140.6694,937.41525 140.66941,937.2153 L 140.69358,930.0632 C 140.69357,929.91135 140.71554,929.7814 140.75949,929.67336 C 140.80344,929.56534 140.8895,929.48337 141.01766,929.42745 C 141.08164,929.40329 141.14963,929.39121 141.22164,929.3912 C 141.39767,929.39121 141.53769,929.45529 141.64169,929.58346 C 141.84969,929.47946 142.03769,929.41342 142.20566,929.38534 C 142.37363,929.35727 142.60556,929.34323 142.90145,929.34323 L 143.52548,929.34323 C 144.03744,929.34323 144.52144,929.56723 144.97751,930.01522 C 145.43356,930.46323 145.66159,930.95126 145.66159,931.47933 C 145.65353,931.55136 145.6495,931.60336 145.64951,931.63534 L 145.64951,931.63534 z M 141.86947,933.48324 C 142.29354,933.37924 142.61758,933.24124 142.84159,933.06924 C 143.06557,932.89725 143.24959,932.75522 143.39364,932.64315 C 143.70566,932.39535 143.95163,932.11942 144.13155,931.81533 C 144.31149,931.51126 144.40145,931.19919 144.40145,930.87911 C 144.40145,930.68723 144.30544,930.54129 144.11344,930.44131 C 143.92141,930.34134 143.68538,930.29135 143.40537,930.29135 C 143.07747,930.29135 142.76552,930.34336 142.46952,930.44735 C 142.17348,930.55136 141.99752,930.67929 141.94162,930.83114 L 141.86947,933.48324 z M 147.50216,937.62325 C 147.1423,937.47921 146.87833,937.25119 146.71024,936.93917 C 146.54215,936.62716 146.4581,936.25521 146.4581,935.82333 C 146.4581,935.71933 146.4581,935.63131 146.4581,935.55929 C 146.4581,935.48727 146.47409,935.36325 146.50608,935.18722 C 146.52219,934.89132 146.53817,934.65133 146.55405,934.46725 C 146.61826,933.83517 146.87436,933.17917 147.32236,932.49923 C 147.3702,932.41916 147.4421,932.37912 147.53806,932.37911 C 147.59421,932.37912 147.7103,932.41513 147.88631,932.48715 C 148.06234,932.55917 148.19833,932.59518 148.29427,932.59518 C 148.75034,932.59518 149.09432,932.85922 149.32627,933.38729 C 149.52621,933.84335 149.62618,934.42331 149.62618,935.12716 C 149.62618,935.84713 149.53414,936.43112 149.35007,936.87911 C 149.12618,937.4233 148.7822,937.75533 148.31808,937.87521 C 148.23825,937.89132 148.18625,937.89938 148.16208,937.89938 C 148.09811,937.89938 148.03817,937.88339 147.98227,937.8514 C 147.92636,937.81942 147.87033,937.78744 147.81418,937.75546 L 147.50216,937.62325 z M 148.03025,933.43527 C 147.91012,933.69919 147.79208,933.96518 147.67612,934.23324 C 147.56015,934.50131 147.50216,934.83127 147.50216,935.22311 C 147.50216,935.34323 147.49019,935.51931 147.46627,935.75137 C 147.44235,935.98343 147.43039,936.15145 147.43039,936.25546 C 147.43039,936.45541 147.46035,936.62539 147.5203,936.76541 C 147.58023,936.90542 147.69016,937.01937 147.85007,937.10726 C 147.97824,937.17929 148.11826,937.01132 148.27011,936.60336 C 148.38217,936.29135 148.47421,935.91134 148.54623,935.46334 C 148.57015,935.3193 148.58212,935.16732 148.58212,935.00741 C 148.58212,934.62338 148.53011,934.25137 148.42612,933.89138 C 148.3221,933.5314 148.22214,933.35141 148.12618,933.3514 C 148.08615,933.35141 148.05417,933.37936 148.03025,933.43527 L 148.03025,933.43527 z M 151.76157,937.77926 C 151.64145,937.77926 151.54147,937.75521 151.46164,937.70712 L 151.05331,937.45516 C 150.98154,937.41513 150.92362,937.36715 150.87955,937.31124 C 150.83548,937.25534 150.78146,937.16732 150.7175,937.04721 C 150.6135,936.84725 150.56149,936.64328 150.5615,936.43527 L 150.72959,933.02731 C 150.72959,932.94723 150.78159,932.9072 150.88558,932.90719 C 150.93344,932.9072 150.99741,932.91721 151.07748,932.93722 C 151.15756,932.95724 151.23959,932.97726 151.32358,932.99728 C 151.40756,933.0173 151.50949,933.07529 151.62937,933.17123 L 151.46164,935.79916 C 151.46164,936.23935 151.48557,936.56344 151.53341,936.77145 C 151.58956,936.84323 151.6456,936.91122 151.7015,936.97543 C 151.97348,936.78329 152.14945,936.61526 152.2294,936.47134 C 152.30936,936.32742 152.34932,936.17538 152.34933,936.01522 L 152.4094,932.67941 L 152.72141,932.64315 C 153.01755,932.64316 153.27353,932.74716 153.48935,932.95516 L 153.47763,937.83932 C 153.40561,937.8713 153.32149,937.88729 153.2253,937.88729 C 153.20138,937.88729 153.14742,937.87728 153.06345,937.85726 C 152.97946,937.83724 152.90347,937.80721 152.83548,937.76718 C 152.76748,937.72714 152.72946,937.6672 152.72141,937.58737 L 152.64963,937.08346 L 152.13363,937.63534 C 152.03744,937.73129 151.91342,937.77926 151.76157,937.77926 L 151.76157,937.77926 z M 155.04757,933.75936 L 154.85567,933.66342 L 154.66342,933.66342 L 154.48361,933.43527 L 154.45944,932.85922 L 155.07174,932.72738 L 155.13144,930.44735 C 155.2596,930.41538 155.38363,930.39939 155.50351,930.39938 C 155.57552,930.39939 155.66153,930.40738 155.7615,930.42336 C 155.86148,930.43936 155.99545,930.4874 156.16342,930.56747 L 156.13961,932.60726 L 156.6677,932.60726 L 156.83542,932.91928 L 156.8237,933.49533 L 156.0195,933.57919 L 156.0195,937.75546 C 155.93161,937.77938 155.85959,937.79135 155.80344,937.79135 C 155.74752,937.79135 155.68154,937.78134 155.60549,937.76132 C 155.52945,937.7413 155.45553,937.72323 155.38376,937.70712 C 155.10372,937.62728 154.96372,937.4714 154.96372,937.23947 L 155.04757,933.75936 z M 160.42649,933.78317 L 160.49826,935.22311 L 158.79427,935.49923 C 158.65048,935.53122 158.55454,935.56723 158.50644,935.60726 C 158.40243,935.68734 158.35043,935.7994 158.35044,935.94345 L 158.37423,936.49533 C 158.37423,936.6152 158.41226,936.72518 158.4883,936.82528 C 158.56436,936.92538 158.65438,936.9714 158.75839,936.96334 C 158.98251,936.93136 159.26254,936.75534 159.59848,936.43527 C 159.93442,936.1152 160.08639,935.91916 160.05442,935.84713 C 160.08639,935.83126 160.1384,935.82333 160.21042,935.82333 C 160.3464,935.82333 160.44638,935.86734 160.51035,935.95535 C 160.57431,936.04336 160.60629,936.13534 160.6063,936.23129 C 160.60629,936.27133 160.59432,936.32333 160.5704,936.38729 C 160.52231,936.57138 160.45431,936.73141 160.36642,936.8674 C 160.32638,936.93136 160.21431,937.07138 160.03025,937.28744 C 159.87839,937.46322 159.72446,937.59115 159.56844,937.67123 C 159.41244,937.75131 159.2264,937.79135 159.01035,937.79135 C 158.8663,937.79135 158.74831,937.77731 158.65641,937.74923 C 158.56448,937.72116 158.47043,937.6672 158.37423,937.58737 L 157.75057,937.0234 C 157.7264,937.00729 157.70236,936.97122 157.67844,936.91519 C 157.65451,936.85916 157.63449,936.81515 157.61838,936.78317 C 157.56247,936.63937 157.53451,936.48739 157.53451,936.32723 L 157.53451,935.3912 C 157.53451,934.78329 157.66849,934.1553 157.93643,933.50723 C 158.20437,932.85916 158.49033,932.53513 158.79427,932.53512 C 158.84238,932.53513 158.87839,932.53915 158.90232,932.54721 C 159.05441,932.59531 159.24844,932.63132 159.48441,932.65524 C 159.72037,932.67917 159.90438,932.76315 160.03646,932.90719 C 160.16854,933.05124 160.26657,933.18924 160.33053,933.32119 C 160.3945,933.45315 160.42648,933.60715 160.42649,933.78317 L 160.42649,933.78317 z M 159.55051,933.77145 C 159.55051,933.63547 159.52451,933.51547 159.47251,933.41146 C 159.4205,933.30746 159.33847,933.23935 159.2264,933.20712 C 159.10629,933.1832 158.99435,933.31125 158.8906,933.59127 C 158.81857,933.79123 158.77048,933.93124 158.74631,934.01132 C 158.68233,934.17929 158.63437,934.32327 158.60238,934.44326 C 158.5704,934.56326 158.55441,934.69125 158.55442,934.82723 L 159.55051,934.59945 L 159.55051,933.77145 z M 161.68845,932.8713 L 161.79648,932.73947 L 162.0726,932.73947 C 162.13657,932.73947 162.21053,932.77743 162.29452,932.85336 C 162.37851,932.92929 162.44455,932.97531 162.49265,932.99142 C 162.60446,933.02341 162.69638,932.93741 162.76839,932.73342 C 162.84042,932.52945 162.92641,932.41342 163.0264,932.38534 C 163.12636,932.35727 163.19638,932.34323 163.23641,932.34323 C 163.38852,932.34323 163.52255,932.39725 163.63852,932.50527 C 163.75449,932.61331 163.81247,932.74326 163.81247,932.89511 L 163.80039,933.36312 C 163.80038,933.5953 163.77237,933.80539 163.71634,933.99337 C 163.6603,934.18136 163.57236,934.27536 163.45248,934.27535 C 163.26839,934.27536 163.14437,934.0953 163.08042,933.73519 C 163.04843,933.55917 162.9924,933.47116 162.91233,933.47116 C 162.84054,933.47116 162.78261,933.53116 162.73855,933.65115 C 162.69449,933.77115 162.67246,934.0112 162.67246,934.3713 C 162.67246,934.48337 162.67246,934.58139 162.67246,934.66537 C 162.67246,934.74936 162.67246,934.81527 162.67246,934.86312 L 162.67246,937.79135 C 162.58456,937.83138 162.48459,937.8514 162.37252,937.8514 C 162.30051,937.8514 162.2125,937.83938 162.10849,937.81533 C 162.00449,937.79128 161.90451,937.73324 161.80857,937.6412 C 161.71261,937.54916 161.66464,937.43124 161.66464,937.28744 L 161.68845,932.8713 z"
- id="text3253" />
- <path
- style="fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3304)"
- d="M 62.895745,955.18402 C 62.360025,954.46973 57.538595,951.43402 57.181455,948.04116 C 56.824315,944.6483 57.895745,913.75545 57.895745,913.75545 C 57.895745,913.75545 60.217165,909.11259 62.181455,908.57688 C 64.145745,908.04116 65.217165,907.50545 65.217165,907.50545 L 53.610025,904.82688 L 50.931455,901.43402 L 51.467165,913.93402 L 52.360025,944.6483 C 52.360025,944.6483 51.645745,947.68402 50.395745,948.04116 C 49.145745,948.3983 53.074315,953.57688 53.967165,953.93402 C 54.860025,954.29116 62.895745,955.54116 62.895745,955.18402 z"
- id="path3282" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#fdfdfd;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3368)"
- d="M 47.895745,901.79116 C 47.895745,901.79116 51.288595,907.68402 54.502885,908.04116 C 57.717165,908.3983 64.681455,909.6483 68.967165,909.6483 C 73.252885,909.6483 73.252885,909.6483 73.252885,909.6483"
- id="path3284" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#fdfdfd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 76.467165,910.00545 L 264.32431,909.29116"
- id="path3286" />
- <path
- style="fill:#2c2c2c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 59.598995,868.26188 L 91.671345,744.01311 C 91.671345,744.01311 93.439105,737.19458 100.76272,733.65905 C 108.08633,730.12352 119.45054,729.61844 119.45054,729.61844 C 119.45054,729.61844 522.5014,731.13367 523.51155,731.13367 C 524.5217,731.13367 538.91638,733.91159 542.19938,737.19458 C 545.48237,740.47758 548.51283,747.54865 548.51283,747.54865 L 575.02933,869.52457 C 575.02933,869.52457 576.03949,876.3431 573.76664,877.35325 C 571.4938,878.3634 564.92782,878.3634 564.92782,878.3634 L 65.407375,874.82786 C 65.407375,874.82786 60.609145,873.56518 59.851535,872.30249 C 59.093915,871.0398 59.851535,868.51442 59.598995,868.26188 z"
- id="path3752"
- sodipodi:nodetypes="ccscssccsccsc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#868686;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3982)"
- d="M 59.346455,869.77711 C 59.346455,869.77711 59.598995,872.30249 61.366765,873.0601 C 63.134535,873.81772 67.175145,873.81772 67.175145,873.81772 L 570.23111,877.85833 C 570.23111,877.85833 573.00902,878.11086 574.52425,876.3431 C 576.03949,874.57533 575.53441,870.02964 575.53441,870.02964"
- id="path3754" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3962)"
- d="M 163.96716,740.00545 L 162.18145,748.13045 L 166.02075,748.13045 L 168.07432,740.18402 L 163.96716,740.00545 z"
- id="path3810" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3958)"
- d="M 168.69932,739.20188 C 168.25288,739.20188 163.7886,739.0233 163.7886,739.0233"
- id="path3812" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3954)"
- d="M 189.36894,739.91617 L 188.29753,748.13046 L 192.13682,748.13046 L 193.4761,740.09474 L 189.36894,739.91617 z"
- id="path3814"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3950)"
- d="M 193.92253,739.1126 C 193.4761,739.1126 189.01181,738.93402 189.01181,738.93402"
- id="path3816" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3946)"
- d="M 215.44037,739.46974 L 214.45824,747.59474 L 218.29752,747.59474 L 219.54752,739.64831 L 215.44037,739.46974 z"
- id="path3818"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3942)"
- d="M 220.17252,738.66617 C 219.7261,738.66617 215.26181,738.48759 215.26181,738.48759"
- id="path3820" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3938)"
- d="M 241.06539,740.00545 L 240.17254,748.13045 L 244.01183,748.13045 L 245.17254,740.18402 L 241.06539,740.00545 z"
- id="path3822"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3934)"
- d="M 245.79754,739.20188 C 245.3511,739.20188 240.88681,739.0233 240.88681,739.0233"
- id="path3824" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3930)"
- d="M 266.33324,739.64831 L 265.79752,748.39831 L 269.63681,748.39831 L 270.44038,739.82688 L 266.33324,739.64831 z"
- id="path3826"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3926)"
- d="M 271.06538,738.84474 C 270.61895,738.84474 266.15466,738.66616 266.15466,738.66616"
- id="path3828" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3922)"
- d="M 291.95824,740.36259 L 291.69039,748.75545 L 295.52968,748.75545 L 296.06539,740.54116 L 291.95824,740.36259 z"
- id="path3830"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3918)"
- d="M 296.69039,739.55902 C 296.24397,739.55902 291.77967,739.38044 291.77967,739.38044"
- id="path3832" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3914)"
- d="M 318.11895,740.63045 L 317.76181,749.20188 L 321.6011,749.20188 L 322.2261,740.80902 L 318.11895,740.63045 z"
- id="path3834"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3910)"
- d="M 322.8511,739.82688 C 322.40467,739.82688 317.94038,739.6483 317.94038,739.6483"
- id="path3836" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3906)"
- d="M 343.56537,740.63045 L 343.65466,748.84474 L 347.49395,748.84474 L 347.67252,740.80902 L 343.56537,740.63045 z"
- id="path3838"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3902)"
- d="M 348.29752,739.82688 C 347.85109,739.82688 343.3868,739.6483 343.3868,739.6483"
- id="path3840" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3898)"
- d="M 369.81537,740.36259 L 369.81537,748.93402 L 373.65466,748.93402 L 373.92252,740.54116 L 369.81537,740.36259 z"
- id="path3842"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3894)"
- d="M 374.54752,739.55902 C 374.10109,739.55902 369.6368,739.38044 369.6368,739.38044"
- id="path3844" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3890)"
- d="M 394.27966,740.98759 L 394.99395,749.38045 L 398.83324,749.38045 L 398.38681,741.16616 L 394.27966,740.98759 z"
- id="path3846"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3886)"
- d="M 399.01181,740.18402 C 398.56538,740.18402 394.10109,740.00544 394.10109,740.00544"
- id="path3848" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3882)"
- d="M 420.61895,740.63045 L 421.24395,749.02331 L 425.08324,749.02331 L 424.7261,740.80902 L 420.61895,740.63045 z"
- id="path3850"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3878)"
- d="M 425.3511,739.82688 C 424.90467,739.82688 420.44038,739.6483 420.44038,739.6483"
- id="path3852" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3874)"
- d="M 446.15466,741.34473 L 447.13681,749.6483 L 450.9761,749.6483 L 450.26181,741.5233 L 446.15466,741.34473 z"
- id="path3854"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3870)"
- d="M 450.88681,740.54116 C 450.44038,740.54116 445.97609,740.36258 445.97609,740.36258"
- id="path3856" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3866)"
- d="M 472.1368,741.07688 L 473.20823,749.55902 L 477.04752,749.55902 L 476.24396,741.25545 L 472.1368,741.07688 z"
- id="path3858"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#494949;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3862)"
- d="M 476.86896,740.27331 C 476.42252,740.27331 471.95823,740.09473 471.95823,740.09473"
- id="path3860" />
- <path
- style="fill:#010101;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3996)"
- d="M 457.00288,731.43402 L 458.43145,635.00545 L 457.71716,507.86259 C 457.71716,507.86259 460.10513,497.86259 471.28859,497.1483 C 478.45249,496.69074 482.71717,509.29116 482.71717,509.29116 L 482.71717,651.43402 L 484.14574,731.43402 L 457.00288,731.43402 z"
- id="path3986"
- sodipodi:nodetypes="cccscccc" />
- </g>
-</svg>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/group.svg b/wpa_supplicant/wpa_gui-qt4/icons/group.svg
deleted file mode 100644
index 4ea959b5779f..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/group.svg
+++ /dev/null
@@ -1,616 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- height="160.00000"
- id="Andysvg"
- inkscape:version="0.46"
- sodipodi:docbase="/home/andy/Desktop/etiquette-icons-0.4/scalable/filesystems"
- sodipodi:docname="gnome-fs-network.svg"
- sodipodi:version="0.32"
- version="1.0"
- width="160.00000"
- x="0.00000000"
- y="0.00000000"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- inkscape:export-filename="C:\Documents and Settings\All Users\Documents\Ubuntu Brig\Andy Fitzsimon\gnome-fs-network.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <metadata
- id="metadata3">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:title>Etiquette Icons</dc:title>
- <dc:description />
- <dc:subject>
- <rdf:Bag>
- <rdf:li>hash</rdf:li>
- <rdf:li />
- <rdf:li>filesystem</rdf:li>
- <rdf:li>computer</rdf:li>
- <rdf:li>icons</rdf:li>
- </rdf:Bag>
- </dc:subject>
- <dc:publisher>
- <cc:Agent
- rdf:about="http://www.openclipart.org">
- <dc:title>Andy Fitzsimon</dc:title>
- </cc:Agent>
- </dc:publisher>
- <dc:creator>
- <cc:Agent>
- <dc:title>Andy Fitzsimon</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:rights>
- <cc:Agent>
- <dc:title>Andy Fitzsimon</dc:title>
- </cc:Agent>
- </dc:rights>
- <dc:date />
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <cc:license
- rdf:resource="http://web.resource.org/cc/PublicDomain" />
- <dc:language>en</dc:language>
- </cc:Work>
- <cc:License
- rdf:about="http://web.resource.org/cc/PublicDomain">
- <cc:permits
- rdf:resource="http://web.resource.org/cc/Reproduction" />
- <cc:permits
- rdf:resource="http://web.resource.org/cc/Distribution" />
- <cc:permits
- rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
- </cc:License>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs3">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 80 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="160 : 80 : 1"
- inkscape:persp3d-origin="80 : 53.333333 : 1"
- id="perspective97" />
- <linearGradient
- id="linearGradient4894">
- <stop
- id="stop4895"
- offset="0.0000000"
- style="stop-color:#ffffff;stop-opacity:1.0000000;" />
- <stop
- id="stop4896"
- offset="0.47000000"
- style="stop-color:#ffffff;stop-opacity:0.85567009;" />
- <stop
- id="stop4897"
- offset="1.0000000"
- style="stop-color:#ffffff;stop-opacity:0.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1853">
- <stop
- id="stop1854"
- offset="0.0000000"
- style="stop-color:#ffffff;stop-opacity:1.0000000;" />
- <stop
- id="stop1855"
- offset="0.47000000"
- style="stop-color:#ffffff;stop-opacity:0.85567009;" />
- <stop
- id="stop1856"
- offset="1.0000000"
- style="stop-color:#ffffff;stop-opacity:0.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1806">
- <stop
- id="stop1807"
- offset="0.0000000"
- style="stop-color:#000000;stop-opacity:0.35051546;" />
- <stop
- id="stop3276"
- offset="0.64999998"
- style="stop-color:#000000;stop-opacity:0.13402061;" />
- <stop
- id="stop1808"
- offset="1.0000000"
- style="stop-color:#000000;stop-opacity:0.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient893">
- <stop
- id="stop895"
- offset="0"
- style="stop-color:#000;stop-opacity:1;" />
- <stop
- id="stop896"
- offset="1"
- style="stop-color:#fff;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1317">
- <stop
- id="stop1318"
- offset="0.00000000"
- style="stop-color:#000000;stop-opacity:0.52892560;" />
- <stop
- id="stop1320"
- offset="0.50000000"
- style="stop-color:#000000;stop-opacity:0.17355372;" />
- <stop
- id="stop1319"
- offset="1.0000000"
- style="stop-color:#000000;stop-opacity:0.00000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1133">
- <stop
- id="stop1134"
- offset="0.00000000"
- style="stop-color:#8bb7df;stop-opacity:1.0000000;" />
- <stop
- id="stop1136"
- offset="0.76209301"
- style="stop-color:#2a6092;stop-opacity:1.0000000;" />
- <stop
- id="stop1135"
- offset="1.0000000"
- style="stop-color:#375e82;stop-opacity:1.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1098">
- <stop
- id="stop1099"
- offset="0.00000000"
- style="stop-color:#ffffff;stop-opacity:1.0000000;" />
- <stop
- id="stop1101"
- offset="0.50000000"
- style="stop-color:#ffffff;stop-opacity:0.22314049;" />
- <stop
- id="stop1102"
- offset="0.59930235"
- style="stop-color:#ffffff;stop-opacity:0.00000000;" />
- <stop
- id="stop1100"
- offset="1.0000000"
- style="stop-color:#ffffff;stop-opacity:0.60330576;" />
- </linearGradient>
- <linearGradient
- id="linearGradient902">
- <stop
- id="stop903"
- offset="0.00000000"
- style="stop-color:#000000;stop-opacity:0.00000000;" />
- <stop
- id="stop904"
- offset="1.0000000"
- style="stop-color:#000000;stop-opacity:0.22000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient892">
- <stop
- id="stop893"
- offset="0.0000000"
- style="stop-color:#ffffff;stop-opacity:0.0000000;" />
- <stop
- id="stop894"
- offset="1"
- style="stop-color:#fff;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient888">
- <stop
- id="stop889"
- offset="0.0000000"
- style="stop-color:#626262;stop-opacity:1.0000000;" />
- <stop
- id="stop890"
- offset="1"
- style="stop-color:#fff;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient891"
- x1="1.3485916"
- x2="0.024647888"
- xlink:href="#linearGradient888"
- y1="-0.85185188"
- y2="1.0899471" />
- <linearGradient
- id="linearGradient901"
- spreadMethod="pad"
- x1="1.5803921"
- x2="0.14117648"
- xlink:href="#linearGradient888"
- y1="2.4285715"
- y2="-0.38571429" />
- <linearGradient
- id="linearGradient905"
- x1="-1.5389611"
- x2="1.0909091"
- xlink:href="#linearGradient888"
- y1="2.7890625"
- y2="-0.19531250" />
- <radialGradient
- cx="0.10362694"
- cy="0.093750000"
- fx="0.10362694"
- fy="0.093750000"
- id="radialGradient1132"
- r="1.2958785"
- xlink:href="#linearGradient1133" />
- <linearGradient
- id="linearGradient1138"
- xlink:href="#linearGradient4894" />
- <linearGradient
- id="linearGradient1140"
- x1="0.54117650"
- x2="0.57647061"
- xlink:href="#linearGradient888"
- y1="-2.4210527"
- y2="4.6315789" />
- <linearGradient
- id="linearGradient1141"
- x1="1.8281938"
- x2="-0.0088105723"
- xlink:href="#linearGradient888"
- y1="3.0546875"
- y2="-0.44531250" />
- <linearGradient
- id="linearGradient1144"
- x1="0.21960784"
- x2="0.59607846"
- xlink:href="#linearGradient1853"
- y1="-11.111111"
- y2="5.2777777" />
- <linearGradient
- id="linearGradient1146"
- x1="0.51351351"
- x2="-0.076576576"
- xlink:href="#linearGradient892"
- y1="0.55468750"
- y2="1.1875000" />
- <linearGradient
- id="linearGradient1148"
- x1="0.23245615"
- x2="1.0789474"
- xlink:href="#linearGradient892"
- y1="0.15625000"
- y2="-0.64843750" />
- <linearGradient
- id="linearGradient1150"
- x1="0.25221238"
- x2="-0.57522124"
- xlink:href="#linearGradient892"
- y1="0.57812500"
- y2="1.4765625" />
- <linearGradient
- id="linearGradient1156"
- x1="0.48260871"
- x2="0.48260871"
- xlink:href="#linearGradient888"
- y1="-0.40000001"
- y2="1.8750000" />
- <linearGradient
- id="linearGradient1157"
- x1="1.5528169"
- x2="-1.2077465"
- xlink:href="#linearGradient888"
- y1="3.3265307"
- y2="-0.48979592" />
- <linearGradient
- id="linearGradient1166"
- x1="0.52941179"
- x2="0.57647061"
- xlink:href="#linearGradient1317"
- y1="-3.5714285"
- y2="4.6315789" />
- <linearGradient
- id="linearGradient1167"
- x1="1.6111112"
- x2="-0.083333336"
- xlink:href="#linearGradient888"
- y1="3.0703125"
- y2="0.046875000" />
- <linearGradient
- id="linearGradient1169"
- x1="1.4780220"
- x2="-0.13028169"
- xlink:href="#linearGradient893"
- y1="2.9218750"
- y2="-0.26732674" />
- <linearGradient
- gradientTransform="scale(0.998371,1.001632)"
- id="linearGradient1170"
- x1="0.47284532"
- x2="0.48655096"
- xlink:href="#linearGradient902"
- y1="-0.016295359"
- y2="1.8378206" />
- <linearGradient
- id="linearGradient1171"
- x1="0.83050847"
- x2="0.56355929"
- xlink:href="#linearGradient902"
- y1="0.57812500"
- y2="0.36718750" />
- <radialGradient
- cx="0.088082902"
- cy="0.093750000"
- fx="0.090673581"
- fy="0.10937500"
- id="radialGradient1315"
- r="1.1765809"
- xlink:href="#linearGradient1133" />
- <radialGradient
- cx="0.50000000"
- cy="0.50000006"
- fx="0.50352114"
- fy="0.18269235"
- id="radialGradient1316"
- r="0.34964636"
- xlink:href="#linearGradient1317" />
- <linearGradient
- id="linearGradient1404"
- x1="0.53169012"
- x2="0.54577464"
- xlink:href="#linearGradient892"
- y1="0.28888890"
- y2="1.1000000" />
- <linearGradient
- gradientTransform="scale(0.997825,1.002180)"
- id="linearGradient1505"
- x1="0.47157744"
- x2="0.48548824"
- xlink:href="#linearGradient902"
- y1="-0.024853170"
- y2="1.8570156" />
- <linearGradient
- gradientTransform="scale(0.995847,1.004170)"
- id="linearGradient1506"
- x1="0.47042510"
- x2="0.48481107"
- xlink:href="#linearGradient902"
- y1="-0.043652620"
- y2="1.9025002" />
- <linearGradient
- gradientTransform="scale(0.997153,1.002855)"
- id="linearGradient2740"
- x1="0.47041038"
- x2="0.48453596"
- xlink:href="#linearGradient902"
- y1="-0.033741195"
- y2="1.8771822" />
- <linearGradient
- id="linearGradient4283"
- x1="-0.77314812"
- x2="0.99074072"
- xlink:href="#linearGradient893"
- y1="2.0837989"
- y2="-0.033519555" />
- <linearGradient
- id="linearGradient4284"
- x1="-2.3960868e-17"
- x2="0.92957747"
- xlink:href="#linearGradient893"
- y1="3.3012049"
- y2="-0.45783132" />
- <radialGradient
- cx="0.50000000"
- cy="0.50000000"
- fx="0.50000000"
- fy="0.50000000"
- id="radialGradient1977"
- r="0.50000000"
- xlink:href="#linearGradient1853" />
- </defs>
- <sodipodi:namedview
- bordercolor="#666666"
- borderopacity="1.0"
- id="base"
- inkscape:cx="62.122256"
- inkscape:cy="81.091465"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:window-height="667"
- inkscape:window-width="573"
- inkscape:window-x="380"
- inkscape:window-y="151"
- inkscape:zoom="2"
- pagecolor="#ffffff"
- showborder="true"
- showgrid="false"
- inkscape:current-layer="Andysvg" />
- <path
- d="M 26.564473,83.749649 L 26.564473,121.41271 L 57.756286,121.41271"
- id="path3723"
- sodipodi:nodetypes="ccc"
- style="fill:none;fill-rule:evenodd;stroke:#9c9c9c;stroke-width:5.7184987;stroke-linecap:round;stroke-linejoin:round;" />
- <g
- id="g2843"
- transform="matrix(0.999379,0.000000,0.000000,0.999379,1.227893e-3,3.986513)">
- <rect
- height="8.3153667"
- id="rect1906"
- style="fill:url(#linearGradient1156);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:1.4473482pt;"
- transform="matrix(0.716224,0.000000,0.000000,0.716224,-12.57051,-9.652832)"
- width="57.567924"
- x="33.326111"
- y="78.658051" />
- <rect
- height="60.126495"
- id="rect1907"
- rx="5.4369707"
- ry="5.4369707"
- style="fill:url(#linearGradient905);fill-opacity:1;fill-rule:evenodd;stroke-width:1.6282668;"
- transform="matrix(0.716224,0.000000,0.000000,0.716224,-12.57051,-9.652832)"
- width="72.279724"
- x="26.015469"
- y="22.413721" />
- <rect
- height="38.044163"
- id="rect1908"
- style="fill:url(#radialGradient1315);fill-rule:evenodd;stroke:url(#linearGradient891);stroke-width:1.4649456pt;"
- transform="matrix(0.716224,0.000000,0.000000,0.716224,-12.57051,-9.652832)"
- width="58.178177"
- x="33.386066"
- y="31.695871" />
- <path
- d="M 27.690431,52.841444 L 27.370609,74.749236 C 27.319624,78.241665 29.310209,80.477938 32.807578,80.506029 L 72.625393,80.825852 L 76.463254,71.870840 L 32.008024,71.551020 L 31.688202,52.681533 L 27.690431,52.841444 z "
- id="path1909"
- sodipodi:nodetypes="czzccccc"
- style="fill:url(#linearGradient1146);fill-opacity:1;fill-rule:evenodd;stroke-width:1.0000000pt;"
- transform="matrix(0.716224,0.000000,0.000000,0.716224,-12.57051,-9.652832)" />
- <rect
- height="26.147448"
- id="rect1913"
- rx="7.4449978"
- ry="7.4449978"
- style="fill:url(#linearGradient901);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:2.3625000;"
- transform="matrix(0.571582,0.000000,0.000000,0.571582,-77.72566,72.35541)"
- width="104.09673"
- x="140.62315"
- y="-34.316952" />
- <rect
- height="15.829688"
- id="rect1914"
- rx="3.7576280"
- ry="3.7576280"
- style="fill:url(#linearGradient901);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:1.3591428;"
- transform="matrix(0.571582,0.000000,0.000000,0.571582,-77.72566,72.35541)"
- width="56.908955"
- x="184.04552"
- y="-28.539845" />
- <rect
- height="15.829688"
- id="rect1915"
- rx="2.9970589"
- ry="2.9970589"
- style="fill:url(#linearGradient1141);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:0.96249998;"
- transform="matrix(0.571582,0.000000,0.000000,0.571582,-77.72566,72.35541)"
- width="28.796961"
- x="145.28902"
- y="-28.227346" />
- <rect
- height="3.3627598"
- id="rect1916"
- rx="1.6813799"
- ry="1.6813799"
- style="fill-opacity:0.13836475;fill-rule:evenodd;stroke-width:0.46326005;"
- transform="matrix(0.571582,0.000000,0.000000,0.571582,-77.72566,72.35541)"
- width="49.231453"
- x="187.88426"
- y="-21.681381" />
- </g>
- <path
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:helvetica"
- d="M 7.0612345,-14.660837 L 7.0612345,-23.250681 L 8.2272501,-23.250681 L 12.738969,-16.50654 L 12.738969,-23.250681 L 13.828813,-23.250681 L 13.828813,-14.660837 L 12.662797,-14.660837 L 8.1510782,-21.410837 L 8.1510782,-14.660837 L 7.0612345,-14.660837 z M 19.869828,-16.664743 L 20.959672,-16.529978 C 20.787791,-15.893258 20.469432,-15.399118 20.004594,-15.047556 C 19.539745,-14.695993 18.945996,-14.520212 18.223344,-14.520212 C 17.313185,-14.520212 16.591506,-14.800485 16.058305,-15.361032 C 15.525101,-15.921578 15.2585,-16.70771 15.2585,-17.719431 C 15.2585,-18.766302 15.528031,-19.578801 16.067094,-20.156931 C 16.606155,-20.73505 17.305373,-21.024112 18.16475,-21.024118 C 18.996777,-21.024112 19.676464,-20.740909 20.203813,-20.174509 C 20.73115,-19.608098 20.994822,-18.811224 20.994828,-17.783884 C 20.994822,-17.721381 20.992869,-17.627631 20.988969,-17.502634 L 16.348344,-17.502634 C 16.387405,-16.819038 16.580764,-16.295601 16.928422,-15.932322 C 17.276076,-15.569039 17.709669,-15.387399 18.229203,-15.3874 C 18.615918,-15.387399 18.945996,-15.488961 19.219438,-15.692087 C 19.49287,-15.895211 19.709667,-16.219429 19.869828,-16.664743 L 19.869828,-16.664743 z M 16.406938,-18.369822 L 19.881547,-18.369822 C 19.834667,-18.893255 19.701855,-19.285833 19.483109,-19.547556 C 19.147168,-19.953801 18.711621,-20.156925 18.176469,-20.156931 C 17.692091,-20.156925 17.284865,-19.994816 16.954789,-19.670603 C 16.624709,-19.346379 16.442092,-18.912786 16.406938,-18.369822 L 16.406938,-18.369822 z M 24.592484,-15.604197 L 24.744828,-14.672556 C 24.44795,-14.610056 24.182326,-14.578806 23.947953,-14.578806 C 23.565139,-14.578806 23.268264,-14.639353 23.057328,-14.760447 C 22.846389,-14.88154 22.697952,-15.04072 22.612016,-15.237986 C 22.526077,-15.43525 22.483108,-15.850289 22.483109,-16.483103 L 22.483109,-20.063181 L 21.709672,-20.063181 L 21.709672,-20.883493 L 22.483109,-20.883493 L 22.483109,-22.424509 L 23.531938,-23.057322 L 23.531938,-20.883493 L 24.592484,-20.883493 L 24.592484,-20.063181 L 23.531938,-20.063181 L 23.531938,-16.424509 C 23.531936,-16.123726 23.55049,-15.930367 23.587602,-15.844431 C 23.624709,-15.758492 23.685256,-15.690133 23.769242,-15.639353 C 23.853224,-15.588571 23.973341,-15.56318 24.129594,-15.563181 C 24.246779,-15.56318 24.401075,-15.576852 24.592484,-15.604197 L 24.592484,-15.604197 z M 26.766313,-14.660837 L 24.862016,-20.883493 L 25.951859,-20.883493 L 26.942094,-17.291697 L 27.311234,-15.955759 C 27.326857,-16.022164 27.434279,-16.449898 27.6335,-17.238962 L 28.623734,-20.883493 L 29.707719,-20.883493 L 30.639359,-17.274118 L 30.949906,-16.084665 L 31.307328,-17.285837 L 32.373734,-20.883493 L 33.399125,-20.883493 L 31.453813,-14.660837 L 30.358109,-14.660837 L 29.367875,-18.3874 L 29.127641,-19.447947 L 27.867875,-14.660837 L 26.766313,-14.660837 z M 33.897172,-17.772165 C 33.897172,-18.924505 34.217484,-19.77802 34.858109,-20.332712 C 35.393264,-20.793644 36.045607,-21.024112 36.815141,-21.024118 C 37.670605,-21.024112 38.369823,-20.743839 38.912797,-20.183298 C 39.45576,-19.622746 39.727244,-18.848333 39.72725,-17.860056 C 39.727244,-17.059272 39.607127,-16.42939 39.366899,-15.970407 C 39.126659,-15.511422 38.77705,-15.154977 38.31807,-14.901072 C 37.859082,-14.647165 37.358106,-14.520212 36.815141,-14.520212 C 35.944045,-14.520212 35.239944,-14.799509 34.702836,-15.358103 C 34.165726,-15.916695 33.897172,-16.721382 33.897172,-17.772165 L 33.897172,-17.772165 z M 34.981156,-17.772165 C 34.981155,-16.975288 35.154983,-16.378609 35.502641,-15.982126 C 35.850295,-15.585641 36.287794,-15.387399 36.815141,-15.3874 C 37.338574,-15.387399 37.774121,-15.586617 38.121781,-15.985056 C 38.469433,-16.383492 38.643261,-16.990913 38.643266,-17.807322 C 38.643261,-18.576849 38.468456,-19.159856 38.118852,-19.556345 C 37.769238,-19.952824 37.334668,-20.151066 36.815141,-20.151072 C 36.287794,-20.151066 35.850295,-19.953801 35.502641,-19.559275 C 35.154983,-19.164739 34.981155,-18.569036 34.981156,-17.772165 L 34.981156,-17.772165 z M 40.957719,-14.660837 L 40.957719,-20.883493 L 41.906938,-20.883493 L 41.906938,-19.940134 C 42.149123,-20.381535 42.372756,-20.67255 42.577836,-20.813181 C 42.782912,-20.9538 43.008497,-21.024112 43.254594,-21.024118 C 43.610059,-21.024112 43.971387,-20.910831 44.338578,-20.684275 L 43.975297,-19.705759 C 43.717481,-19.858098 43.459669,-19.934269 43.201859,-19.934275 C 42.971388,-19.934269 42.764357,-19.864934 42.580766,-19.726267 C 42.39717,-19.58759 42.266311,-19.395207 42.188188,-19.149118 C 42.070998,-18.774114 42.012405,-18.363958 42.012406,-17.91865 L 42.012406,-14.660837 L 40.957719,-14.660837 z M 44.983109,-14.660837 L 44.983109,-23.250681 L 46.037797,-23.250681 L 46.037797,-18.352243 L 48.533891,-20.883493 L 49.899125,-20.883493 L 47.520219,-18.5749 L 50.139359,-14.660837 L 48.838578,-14.660837 L 46.781938,-17.842478 L 46.037797,-17.127634 L 46.037797,-14.660837 L 44.983109,-14.660837 z"
- id="text1232" />
- <path
- transform="scale(0.246729,0.246729)"
- style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:helvetica"
- d="M 91.619637,-37.962852 L 92.756355,-37.675743 C 92.518066,-36.742148 92.089356,-36.030234 91.470222,-35.540001 C 90.851076,-35.049766 90.09424,-34.804649 89.199715,-34.804649 C 88.27393,-34.804649 87.521001,-34.993126 86.940926,-35.370079 C 86.360846,-35.747031 85.91944,-36.292929 85.616707,-37.007774 C 85.313972,-37.722615 85.162605,-38.490193 85.162605,-39.310509 C 85.162605,-40.205035 85.333503,-40.985307 85.675301,-41.651329 C 86.017096,-42.317337 86.503424,-42.823196 87.134285,-43.168907 C 87.765141,-43.514602 88.459476,-43.687453 89.217293,-43.687462 C 90.076662,-43.687453 90.799318,-43.468703 91.385262,-43.031212 C 91.971192,-42.593704 92.379394,-41.97847 92.609871,-41.185509 L 91.49073,-40.921837 C 91.291505,-41.54683 91.002443,-42.001908 90.623543,-42.287071 C 90.244631,-42.57222 89.768069,-42.714798 89.193855,-42.714806 C 88.533695,-42.714798 87.981938,-42.556595 87.538582,-42.240196 C 87.09522,-41.923783 86.783697,-41.498979 86.604012,-40.965782 C 86.424322,-40.432574 86.334479,-39.882769 86.33448,-39.316368 C 86.334479,-38.585896 86.440924,-37.948201 86.653816,-37.403282 C 86.866705,-36.858358 87.197759,-36.451132 87.64698,-36.181602 C 88.096196,-35.91207 88.582523,-35.777305 89.105965,-35.777306 C 89.742678,-35.777305 90.28174,-35.960898 90.723152,-36.328087 C 91.164552,-36.695273 91.46338,-37.240194 91.619637,-37.962852 L 91.619637,-37.962852 z M 94.016121,-34.951134 L 94.016121,-41.17379 L 94.96534,-41.17379 L 94.96534,-40.230431 C 95.207525,-40.671831 95.431158,-40.962846 95.636238,-41.103477 C 95.841314,-41.244096 96.066899,-41.314409 96.312996,-41.314415 C 96.668461,-41.314409 97.029789,-41.201127 97.39698,-40.974571 L 97.033699,-39.996056 C 96.775883,-40.148394 96.518071,-40.224566 96.260262,-40.224571 C 96.02979,-40.224566 95.822759,-40.15523 95.639168,-40.016563 C 95.455572,-39.877887 95.324713,-39.685504 95.24659,-39.439415 C 95.1294,-39.064411 95.070807,-38.654255 95.070808,-38.208946 L 95.070808,-34.951134 L 94.016121,-34.951134 z M 102.29542,-36.95504 L 103.38526,-36.820274 C 103.21338,-36.183554 102.89502,-35.689414 102.43018,-35.337852 C 101.96533,-34.98629 101.37159,-34.810509 100.64893,-34.810509 C 99.738775,-34.810509 99.017096,-35.090782 98.483894,-35.651329 C 97.950691,-36.211875 97.684089,-36.998007 97.68409,-38.009727 C 97.684089,-39.056598 97.95362,-39.869098 98.492683,-40.447227 C 99.031744,-41.025346 99.730962,-41.314409 100.59034,-41.314415 C 101.42237,-41.314409 102.10205,-41.031206 102.6294,-40.464806 C 103.15674,-39.898394 103.42041,-39.10152 103.42042,-38.074181 C 103.42041,-38.011678 103.41846,-37.917928 103.41456,-37.792931 L 98.773933,-37.792931 C 98.812994,-37.109335 99.006354,-36.585898 99.354012,-36.222618 C 99.701665,-35.859336 100.13526,-35.677696 100.65479,-35.677696 C 101.04151,-35.677696 101.37159,-35.779258 101.64503,-35.982384 C 101.91846,-36.185507 102.13526,-36.509726 102.29542,-36.95504 L 102.29542,-36.95504 z M 98.832527,-38.660118 L 102.30714,-38.660118 C 102.26026,-39.183551 102.12744,-39.576129 101.9087,-39.837852 C 101.57276,-40.244097 101.13721,-40.447222 100.60206,-40.447227 C 100.11768,-40.447222 99.710454,-40.285113 99.380379,-39.960899 C 99.050299,-39.636676 98.867682,-39.203083 98.832527,-38.660118 L 98.832527,-38.660118 z M 108.77589,-35.718712 C 108.38526,-35.38668 108.00928,-35.152305 107.64796,-35.015587 C 107.28663,-34.878868 106.89893,-34.810509 106.48487,-34.810509 C 105.80128,-34.810509 105.27589,-34.977501 104.9087,-35.311485 C 104.54151,-35.645469 104.35792,-36.072226 104.35792,-36.591759 C 104.35792,-36.896444 104.42725,-37.174764 104.56593,-37.42672 C 104.7046,-37.67867 104.88624,-37.880818 105.11085,-38.033165 C 105.33546,-38.185505 105.58838,-38.30074 105.86964,-38.378868 C 106.07667,-38.433552 106.38917,-38.486286 106.80714,-38.537071 C 107.6587,-38.63863 108.28565,-38.759724 108.688,-38.900352 C 108.6919,-39.04488 108.69385,-39.136676 108.69386,-39.175743 C 108.69385,-39.605426 108.59424,-39.90816 108.39503,-40.083946 C 108.12549,-40.322222 107.7251,-40.441363 107.19386,-40.441368 C 106.69776,-40.441363 106.33155,-40.354449 106.09522,-40.180626 C 105.85889,-40.006793 105.68409,-39.699176 105.57081,-39.257774 L 104.53956,-39.398399 C 104.63331,-39.839801 104.7876,-40.196246 105.00245,-40.467735 C 105.21729,-40.739214 105.52784,-40.948198 105.93409,-41.094688 C 106.34034,-41.241167 106.81104,-41.314409 107.3462,-41.314415 C 107.87745,-41.314409 108.30909,-41.251909 108.64112,-41.126915 C 108.97315,-41.001909 109.21729,-40.844683 109.37354,-40.655235 C 109.52979,-40.465777 109.63916,-40.226519 109.70167,-39.937462 C 109.73682,-39.75777 109.7544,-39.433551 109.7544,-38.964806 L 109.7544,-37.558556 C 109.7544,-36.578085 109.77686,-35.957969 109.82178,-35.698204 C 109.8667,-35.438438 109.95557,-35.189415 110.08839,-34.951134 L 108.98682,-34.951134 C 108.87744,-35.169884 108.80713,-35.425743 108.77589,-35.718712 L 108.77589,-35.718712 z M 108.688,-38.074181 C 108.30518,-37.917928 107.73096,-37.785115 106.96534,-37.675743 C 106.53174,-37.61324 106.2251,-37.542928 106.04542,-37.464806 C 105.86573,-37.386678 105.72706,-37.27242 105.6294,-37.122032 C 105.53174,-36.97164 105.48292,-36.804647 105.48292,-36.621056 C 105.48292,-36.339804 105.58936,-36.105429 105.80225,-35.917931 C 106.01514,-35.73043 106.32667,-35.63668 106.73682,-35.636681 C 107.14307,-35.63668 107.5044,-35.725547 107.82081,-35.903282 C 108.13721,-36.081015 108.36963,-36.324179 108.51807,-36.632774 C 108.63135,-36.871054 108.68799,-37.222616 108.688,-37.687462 L 108.688,-38.074181 z M 113.69776,-35.894493 L 113.85011,-34.962852 C 113.55323,-34.900353 113.2876,-34.869103 113.05323,-34.869102 C 112.67042,-34.869103 112.37354,-34.929649 112.16261,-35.050743 C 111.95167,-35.171837 111.80323,-35.331016 111.71729,-35.528282 C 111.63135,-35.725547 111.58839,-36.140586 111.58839,-36.773399 L 111.58839,-40.353477 L 110.81495,-40.353477 L 110.81495,-41.17379 L 111.58839,-41.17379 L 111.58839,-42.714806 L 112.63721,-43.347618 L 112.63721,-41.17379 L 113.69776,-41.17379 L 113.69776,-40.353477 L 112.63721,-40.353477 L 112.63721,-36.714806 C 112.63721,-36.414023 112.65577,-36.220664 112.69288,-36.134727 C 112.72999,-36.048789 112.79053,-35.98043 112.87452,-35.929649 C 112.9585,-35.878867 113.07862,-35.853477 113.23487,-35.853477 C 113.35206,-35.853477 113.50635,-35.867148 113.69776,-35.894493 L 113.69776,-35.894493 z M 118.98292,-36.95504 L 120.07276,-36.820274 C 119.90088,-36.183554 119.58252,-35.689414 119.11768,-35.337852 C 118.65283,-34.98629 118.05909,-34.810509 117.33643,-34.810509 C 116.42627,-34.810509 115.7046,-35.090782 115.17139,-35.651329 C 114.63819,-36.211875 114.37159,-36.998007 114.37159,-38.009727 C 114.37159,-39.056598 114.64112,-39.869098 115.18018,-40.447227 C 115.71924,-41.025346 116.41846,-41.314409 117.27784,-41.314415 C 118.10987,-41.314409 118.78955,-41.031206 119.3169,-40.464806 C 119.84424,-39.898394 120.10791,-39.10152 120.10792,-38.074181 C 120.10791,-38.011678 120.10596,-37.917928 120.10206,-37.792931 L 115.46143,-37.792931 C 115.50049,-37.109335 115.69385,-36.585898 116.04151,-36.222618 C 116.38917,-35.859336 116.82276,-35.677696 117.34229,-35.677696 C 117.72901,-35.677696 118.05909,-35.779258 118.33253,-35.982384 C 118.60596,-36.185507 118.82276,-36.509726 118.98292,-36.95504 L 118.98292,-36.95504 z M 115.52003,-38.660118 L 118.99464,-38.660118 C 118.94776,-39.183551 118.81494,-39.576129 118.5962,-39.837852 C 118.26026,-40.244097 117.82471,-40.447222 117.28956,-40.447227 C 116.80518,-40.447222 116.39795,-40.285113 116.06788,-39.960899 C 115.7378,-39.636676 115.55518,-39.203083 115.52003,-38.660118 L 115.52003,-38.660118 z M 125.43995,-34.951134 L 125.43995,-35.73629 C 125.04541,-35.119102 124.46534,-34.810509 123.69971,-34.810509 C 123.20362,-34.810509 122.74756,-34.947227 122.33155,-35.220665 C 121.91553,-35.494102 121.59327,-35.875937 121.36475,-36.366173 C 121.13624,-36.856405 121.02198,-37.419881 121.02198,-38.056602 C 121.02198,-38.677693 121.1255,-39.241169 121.33253,-39.747032 C 121.53956,-40.252886 121.8501,-40.640581 122.26417,-40.910118 C 122.67823,-41.179643 123.14112,-41.314409 123.65284,-41.314415 C 124.02784,-41.314409 124.36182,-41.235307 124.65479,-41.07711 C 124.94776,-40.918901 125.18604,-40.712847 125.36964,-40.458946 L 125.36964,-43.540977 L 126.41846,-43.540977 L 126.41846,-34.951134 L 125.43995,-34.951134 z M 122.10596,-38.056602 C 122.10596,-37.259725 122.27393,-36.664023 122.60987,-36.269493 C 122.94581,-35.874961 123.34229,-35.677696 123.79932,-35.677696 C 124.26026,-35.677696 124.65186,-35.866172 124.97413,-36.243126 C 125.29639,-36.620077 125.45752,-37.195272 125.45753,-37.968712 C 125.45752,-38.82027 125.29346,-39.44527 124.96534,-39.843712 C 124.63721,-40.242144 124.23291,-40.441363 123.75245,-40.441368 C 123.2837,-40.441363 122.8921,-40.249957 122.57764,-39.867149 C 122.26319,-39.484332 122.10596,-38.880817 122.10596,-38.056602 L 122.10596,-38.056602 z M 132.38331,-34.951134 L 131.40479,-34.951134 L 131.40479,-43.540977 L 132.45948,-43.540977 L 132.45948,-40.476524 C 132.90479,-41.035112 133.47315,-41.314409 134.16456,-41.314415 C 134.54737,-41.314409 134.90967,-41.23726 135.25147,-41.08297 C 135.59326,-40.928667 135.87451,-40.71187 136.09522,-40.432579 C 136.31592,-40.153277 136.48877,-39.816363 136.61378,-39.421837 C 136.73877,-39.027302 136.80127,-38.605427 136.80128,-38.156212 C 136.80127,-37.089803 136.5376,-36.265586 136.01026,-35.683556 C 135.48291,-35.101524 134.8501,-34.810509 134.11182,-34.810509 C 133.37745,-34.810509 132.80127,-35.117149 132.38331,-35.730431 L 132.38331,-34.951134 z M 132.37159,-38.109337 C 132.37159,-37.363241 132.47315,-36.824179 132.67628,-36.492149 C 133.00831,-35.94918 133.45752,-35.677696 134.02393,-35.677696 C 134.48487,-35.677696 134.8833,-35.877891 135.21925,-36.278282 C 135.55518,-36.678671 135.72315,-37.27535 135.72315,-38.068321 C 135.72315,-38.880817 135.56201,-39.480426 135.23975,-39.867149 C 134.91748,-40.253863 134.52784,-40.447222 134.07081,-40.447227 C 133.60987,-40.447222 133.21143,-40.247027 132.8755,-39.846642 C 132.53956,-39.446246 132.37159,-38.867145 132.37159,-38.109337 L 132.37159,-38.109337 z M 138.04346,-32.554649 L 137.92628,-33.544884 C 138.15675,-33.482385 138.35792,-33.451135 138.52979,-33.451134 C 138.76417,-33.451135 138.95167,-33.490198 139.09229,-33.568321 C 139.23292,-33.646448 139.34815,-33.755822 139.438,-33.896446 C 139.5044,-34.001916 139.61182,-34.263634 139.76026,-34.681602 C 139.77979,-34.740196 139.81104,-34.826134 139.85401,-34.939415 L 137.49268,-41.17379 L 138.6294,-41.17379 L 139.92432,-37.570274 C 140.09229,-37.113241 140.24268,-36.632773 140.3755,-36.128868 C 140.49659,-36.613241 140.64112,-37.085897 140.80909,-37.546837 L 142.13917,-41.17379 L 143.19386,-41.17379 L 140.82667,-34.845665 C 140.57276,-34.162072 140.37549,-33.691369 140.23487,-33.433556 C 140.04737,-33.085901 139.83252,-32.831019 139.59034,-32.668907 C 139.34815,-32.5068 139.05909,-32.425746 138.72315,-32.425743 C 138.52003,-32.425746 138.29346,-32.468714 138.04346,-32.554649 L 138.04346,-32.554649 z M 146.60987,-34.951134 L 149.9087,-43.540977 L 151.13331,-43.540977 L 154.64893,-34.951134 L 153.35401,-34.951134 L 152.35206,-37.552696 L 148.76026,-37.552696 L 147.8169,-34.951134 L 146.60987,-34.951134 z M 149.08839,-38.478477 L 152.0005,-38.478477 L 151.10401,-40.857384 C 150.83057,-41.580033 150.62745,-42.173783 150.49464,-42.638634 C 150.38526,-42.087845 150.23096,-41.540971 150.03175,-40.998009 L 149.08839,-38.478477 z M 155.43409,-34.951134 L 155.43409,-41.17379 L 156.38331,-41.17379 L 156.38331,-40.289024 C 156.84034,-40.972612 157.50049,-41.314409 158.36378,-41.314415 C 158.73877,-41.314409 159.0835,-41.247026 159.39796,-41.112267 C 159.7124,-40.977495 159.94776,-40.800737 160.10401,-40.581993 C 160.26026,-40.363238 160.36963,-40.103472 160.43214,-39.802696 C 160.47119,-39.607379 160.49072,-39.265583 160.49073,-38.777306 L 160.49073,-34.951134 L 159.43604,-34.951134 L 159.43604,-38.73629 C 159.43604,-39.165973 159.39502,-39.487262 159.313,-39.700157 C 159.23096,-39.913043 159.08545,-40.082965 158.87647,-40.209923 C 158.66748,-40.336871 158.42237,-40.400347 158.14112,-40.400352 C 157.6919,-40.400347 157.3042,-40.257769 156.97803,-39.972618 C 156.65186,-39.687457 156.48878,-39.146442 156.48878,-38.349571 L 156.48878,-34.951134 L 155.43409,-34.951134 z M 166.15089,-34.951134 L 166.15089,-35.73629 C 165.75635,-35.119102 165.17627,-34.810509 164.41065,-34.810509 C 163.91456,-34.810509 163.4585,-34.947227 163.04249,-35.220665 C 162.62647,-35.494102 162.30421,-35.875937 162.07569,-36.366173 C 161.84718,-36.856405 161.73292,-37.419881 161.73292,-38.056602 C 161.73292,-38.677693 161.83643,-39.241169 162.04346,-39.747032 C 162.25049,-40.252886 162.56104,-40.640581 162.97511,-40.910118 C 163.38917,-41.179643 163.85206,-41.314409 164.36378,-41.314415 C 164.73877,-41.314409 165.07276,-41.235307 165.36573,-41.07711 C 165.65869,-40.918901 165.89698,-40.712847 166.08057,-40.458946 L 166.08057,-43.540977 L 167.1294,-43.540977 L 167.1294,-34.951134 L 166.15089,-34.951134 z M 162.8169,-38.056602 C 162.8169,-37.259725 162.98487,-36.664023 163.32081,-36.269493 C 163.65674,-35.874961 164.05323,-35.677696 164.51026,-35.677696 C 164.9712,-35.677696 165.3628,-35.866172 165.68507,-36.243126 C 166.00733,-36.620077 166.16846,-37.195272 166.16846,-37.968712 C 166.16846,-38.82027 166.0044,-39.44527 165.67628,-39.843712 C 165.34815,-40.242144 164.94385,-40.441363 164.46339,-40.441368 C 163.99463,-40.441363 163.60303,-40.249957 163.28858,-39.867149 C 162.97413,-39.484332 162.8169,-38.880817 162.8169,-38.056602 L 162.8169,-38.056602 z M 168.78175,-34.951134 L 168.78175,-41.17379 L 169.73096,-41.17379 L 169.73096,-40.230431 C 169.97315,-40.671831 170.19678,-40.962846 170.40186,-41.103477 C 170.60694,-41.244096 170.83252,-41.314409 171.07862,-41.314415 C 171.43409,-41.314409 171.79541,-41.201127 172.16261,-40.974571 L 171.79932,-39.996056 C 171.54151,-40.148394 171.2837,-40.224566 171.02589,-40.224571 C 170.79541,-40.224566 170.58838,-40.15523 170.40479,-40.016563 C 170.2212,-39.877887 170.09034,-39.685504 170.01221,-39.439415 C 169.89503,-39.064411 169.83643,-38.654255 169.83643,-38.208946 L 169.83643,-34.951134 L 168.78175,-34.951134 z M 177.06104,-36.95504 L 178.15089,-36.820274 C 177.97901,-36.183554 177.66065,-35.689414 177.19581,-35.337852 C 176.73096,-34.98629 176.13721,-34.810509 175.41456,-34.810509 C 174.5044,-34.810509 173.78272,-35.090782 173.24952,-35.651329 C 172.71632,-36.211875 172.44971,-36.998007 172.44971,-38.009727 C 172.44971,-39.056598 172.71925,-39.869098 173.25831,-40.447227 C 173.79737,-41.025346 174.49659,-41.314409 175.35596,-41.314415 C 176.18799,-41.314409 176.86768,-41.031206 177.39503,-40.464806 C 177.92236,-39.898394 178.18604,-39.10152 178.18604,-38.074181 C 178.18604,-38.011678 178.18408,-37.917928 178.18018,-37.792931 L 173.53956,-37.792931 C 173.57862,-37.109335 173.77198,-36.585898 174.11964,-36.222618 C 174.46729,-35.859336 174.90088,-35.677696 175.42042,-35.677696 C 175.80713,-35.677696 176.13721,-35.779258 176.41065,-35.982384 C 176.68408,-36.185507 176.90088,-36.509726 177.06104,-36.95504 L 177.06104,-36.95504 z M 173.59815,-38.660118 L 177.07276,-38.660118 C 177.02588,-39.183551 176.89307,-39.576129 176.67432,-39.837852 C 176.33838,-40.244097 175.90284,-40.447222 175.36768,-40.447227 C 174.88331,-40.447222 174.47608,-40.285113 174.146,-39.960899 C 173.81592,-39.636676 173.63331,-39.203083 173.59815,-38.660118 L 173.59815,-38.660118 z M 180.6294,-34.951134 L 178.72511,-41.17379 L 179.81495,-41.17379 L 180.80518,-37.581993 L 181.17432,-36.246056 C 181.18995,-36.31246 181.29737,-36.740194 181.49659,-37.529259 L 182.48682,-41.17379 L 183.57081,-41.17379 L 184.50245,-37.564415 L 184.813,-36.374962 L 185.17042,-37.576134 L 186.23682,-41.17379 L 187.26221,-41.17379 L 185.3169,-34.951134 L 184.2212,-34.951134 L 183.23096,-38.677696 L 182.99073,-39.738243 L 181.73096,-34.951134 L 180.6294,-34.951134 z M 191.67432,-34.951134 L 191.67432,-43.540977 L 197.46925,-43.540977 L 197.46925,-42.527306 L 192.81104,-42.527306 L 192.81104,-39.867149 L 196.84229,-39.867149 L 196.84229,-38.853477 L 192.81104,-38.853477 L 192.81104,-34.951134 L 191.67432,-34.951134 z M 198.82276,-42.328087 L 198.82276,-43.540977 L 199.87745,-43.540977 L 199.87745,-42.328087 L 198.82276,-42.328087 z M 198.82276,-34.951134 L 198.82276,-41.17379 L 199.87745,-41.17379 L 199.87745,-34.951134 L 198.82276,-34.951134 z M 203.79151,-35.894493 L 203.94386,-34.962852 C 203.64698,-34.900353 203.38135,-34.869103 203.14698,-34.869102 C 202.76417,-34.869103 202.46729,-34.929649 202.25636,-35.050743 C 202.04542,-35.171837 201.89698,-35.331016 201.81104,-35.528282 C 201.7251,-35.725547 201.68214,-36.140586 201.68214,-36.773399 L 201.68214,-40.353477 L 200.9087,-40.353477 L 200.9087,-41.17379 L 201.68214,-41.17379 L 201.68214,-42.714806 L 202.73096,-43.347618 L 202.73096,-41.17379 L 203.79151,-41.17379 L 203.79151,-40.353477 L 202.73096,-40.353477 L 202.73096,-36.714806 C 202.73096,-36.414023 202.74952,-36.220664 202.78663,-36.134727 C 202.82374,-36.048789 202.88428,-35.98043 202.96827,-35.929649 C 203.05225,-35.878867 203.17237,-35.853477 203.32862,-35.853477 C 203.44581,-35.853477 203.6001,-35.867148 203.79151,-35.894493 L 203.79151,-35.894493 z M 204.26026,-34.951134 L 204.26026,-35.806602 L 208.2212,-40.353477 C 207.77198,-40.330035 207.37549,-40.318316 207.03175,-40.318321 L 204.49464,-40.318321 L 204.49464,-41.17379 L 209.58057,-41.17379 L 209.58057,-40.476524 L 206.21143,-36.527306 L 205.56104,-35.806602 C 206.0337,-35.841758 206.47706,-35.859336 206.89112,-35.859337 L 209.76807,-35.859337 L 209.76807,-34.951134 L 204.26026,-34.951134 z M 210.39503,-36.808556 L 211.438,-36.972618 C 211.49659,-36.554648 211.65967,-36.234336 211.92725,-36.011681 C 212.19483,-35.789024 212.56885,-35.677696 213.04932,-35.677696 C 213.5337,-35.677696 213.89307,-35.776328 214.12745,-35.973595 C 214.36182,-36.170859 214.47901,-36.402304 214.47901,-36.667931 C 214.47901,-36.90621 214.37549,-37.09371 214.16846,-37.230431 C 214.02393,-37.324178 213.66455,-37.443319 213.09034,-37.587852 C 212.3169,-37.783162 211.78077,-37.952107 211.48194,-38.094688 C 211.18311,-38.237263 210.95655,-38.434529 210.80225,-38.686485 C 210.64796,-38.938434 210.57081,-39.216754 210.57081,-39.521446 C 210.57081,-39.798785 210.63428,-40.055621 210.76124,-40.291954 C 210.88819,-40.528277 211.06104,-40.724565 211.27979,-40.880821 C 211.44385,-41.001909 211.66749,-41.104448 211.95069,-41.188438 C 212.23389,-41.272416 212.5376,-41.314409 212.86182,-41.314415 C 213.3501,-41.314409 213.77881,-41.244096 214.14796,-41.103477 C 214.51709,-40.962846 214.78955,-40.772417 214.96534,-40.532188 C 215.14112,-40.291949 215.26221,-39.97066 215.32862,-39.568321 L 214.29737,-39.427696 C 214.25049,-39.748004 214.11475,-39.998004 213.89014,-40.177696 C 213.66553,-40.357378 213.34815,-40.447222 212.938,-40.447227 C 212.45362,-40.447222 212.10792,-40.367144 211.90089,-40.206993 C 211.69385,-40.046832 211.59034,-39.859332 211.59034,-39.644493 C 211.59034,-39.50777 211.63331,-39.384723 211.71925,-39.275352 C 211.80518,-39.162067 211.93995,-39.068317 212.12354,-38.994102 C 212.22901,-38.955036 212.53956,-38.865192 213.05518,-38.724571 C 213.80127,-38.525349 214.32178,-38.362263 214.61671,-38.235313 C 214.91162,-38.108357 215.14307,-37.923787 215.31104,-37.681602 C 215.47901,-37.439412 215.56299,-37.138632 215.563,-36.779259 C 215.56299,-36.427695 215.46045,-36.09664 215.25538,-35.786095 C 215.0503,-35.475547 214.7544,-35.235313 214.36768,-35.065392 C 213.98096,-34.89547 213.54346,-34.810509 213.05518,-34.810509 C 212.24659,-34.810509 211.63038,-34.978477 211.20655,-35.314415 C 210.78272,-35.650352 210.51221,-36.148398 210.39503,-36.808556 L 210.39503,-36.808556 z M 216.82276,-42.328087 L 216.82276,-43.540977 L 217.87745,-43.540977 L 217.87745,-42.328087 L 216.82276,-42.328087 z M 216.82276,-34.951134 L 216.82276,-41.17379 L 217.87745,-41.17379 L 217.87745,-34.951134 L 216.82276,-34.951134 z M 219.48878,-34.951134 L 219.48878,-41.17379 L 220.43214,-41.17379 L 220.43214,-40.300743 C 220.62745,-40.605425 220.88721,-40.850542 221.21143,-41.036095 C 221.53565,-41.221635 221.90479,-41.314409 222.31886,-41.314415 C 222.77979,-41.314409 223.15772,-41.218706 223.45264,-41.027306 C 223.74756,-40.835893 223.95557,-40.568316 224.07667,-40.224571 C 224.56885,-40.951128 225.20947,-41.314409 225.99854,-41.314415 C 226.61572,-41.314409 227.09033,-41.14351 227.42237,-40.80172 C 227.75439,-40.459917 227.92041,-39.933551 227.92042,-39.222618 L 227.92042,-34.951134 L 226.87159,-34.951134 L 226.87159,-38.871056 C 226.87158,-39.292926 226.8374,-39.596637 226.76905,-39.782188 C 226.70068,-39.96773 226.57666,-40.117144 226.39698,-40.230431 C 226.21729,-40.343706 226.00635,-40.400347 225.76417,-40.400352 C 225.32666,-40.400347 224.96338,-40.254839 224.67432,-39.963829 C 224.38526,-39.672809 224.24072,-39.206989 224.24073,-38.566368 L 224.24073,-34.951134 L 223.18604,-34.951134 L 223.18604,-38.994102 C 223.18604,-39.462848 223.1001,-39.81441 222.92823,-40.04879 C 222.75635,-40.28316 222.4751,-40.400347 222.08448,-40.400352 C 221.7876,-40.400347 221.51319,-40.322222 221.26124,-40.165977 C 221.00928,-40.009722 220.82667,-39.781207 220.71339,-39.480431 C 220.6001,-39.179645 220.54346,-38.746052 220.54346,-38.179649 L 220.54346,-34.951134 L 219.48878,-34.951134 z M 229.10401,-38.062462 C 229.10401,-39.214801 229.42432,-40.068316 230.06495,-40.623009 C 230.6001,-41.08394 231.25245,-41.314409 232.02198,-41.314415 C 232.87744,-41.314409 233.57666,-41.034135 234.11964,-40.473595 C 234.6626,-39.913043 234.93408,-39.13863 234.93409,-38.150352 C 234.93408,-37.349569 234.81397,-36.719687 234.57374,-36.260704 C 234.3335,-35.801719 233.98389,-35.445274 233.52491,-35.191368 C 233.06592,-34.937462 232.56495,-34.810509 232.02198,-34.810509 C 231.15088,-34.810509 230.44678,-35.089805 229.90968,-35.648399 C 229.37257,-36.206992 229.10401,-37.011679 229.10401,-38.062462 L 229.10401,-38.062462 z M 230.188,-38.062462 C 230.18799,-37.265585 230.36182,-36.668905 230.70948,-36.272423 C 231.05713,-35.875937 231.49463,-35.677696 232.02198,-35.677696 C 232.54541,-35.677696 232.98096,-35.876914 233.32862,-36.275352 C 233.67627,-36.673788 233.8501,-37.28121 233.85011,-38.097618 C 233.8501,-38.867145 233.6753,-39.450153 233.32569,-39.846642 C 232.97608,-40.243121 232.54151,-40.441363 232.02198,-40.441368 C 231.49463,-40.441363 231.05713,-40.244097 230.70948,-39.849571 C 230.36182,-39.455035 230.18799,-38.859333 230.188,-38.062462 L 230.188,-38.062462 z M 236.17628,-34.951134 L 236.17628,-41.17379 L 237.1255,-41.17379 L 237.1255,-40.289024 C 237.58252,-40.972612 238.24268,-41.314409 239.10596,-41.314415 C 239.48096,-41.314409 239.82569,-41.247026 240.14014,-41.112267 C 240.45459,-40.977495 240.68994,-40.800737 240.8462,-40.581993 C 241.00244,-40.363238 241.11182,-40.103472 241.17432,-39.802696 C 241.21338,-39.607379 241.23291,-39.265583 241.23292,-38.777306 L 241.23292,-34.951134 L 240.17823,-34.951134 L 240.17823,-38.73629 C 240.17823,-39.165973 240.13721,-39.487262 240.05518,-39.700157 C 239.97315,-39.913043 239.82764,-40.082965 239.61866,-40.209923 C 239.40967,-40.336871 239.16455,-40.400347 238.88331,-40.400352 C 238.43409,-40.400347 238.04639,-40.257769 237.72022,-39.972618 C 237.39405,-39.687457 237.23096,-39.146442 237.23096,-38.349571 L 237.23096,-34.951134 L 236.17628,-34.951134 z"
- id="text1235" />
- <g
- id="g2852"
- transform="matrix(1.018857,0.000000,0.000000,1.018857,-4.481650,2.131177)">
- <rect
- height="8.3153667"
- id="rect1866"
- style="fill:url(#linearGradient1156);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:1.4473482pt;"
- transform="matrix(1.150066,0.000000,0.000000,1.150066,38.98882,26.86863)"
- width="57.567924"
- x="33.326111"
- y="78.658051" />
- <rect
- height="60.126495"
- id="rect1867"
- rx="5.4369707"
- ry="5.4369707"
- style="fill:url(#linearGradient905);fill-opacity:1;fill-rule:evenodd;stroke-width:1.6282668;"
- transform="matrix(1.150066,0.000000,0.000000,1.150066,38.98882,26.86863)"
- width="72.279724"
- x="26.015469"
- y="22.413721" />
- <rect
- height="38.044163"
- id="rect1868"
- style="fill:url(#radialGradient1132);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient891);stroke-width:1.4649456pt;"
- transform="matrix(1.150066,0.000000,0.000000,1.150066,38.98882,26.86863)"
- width="58.178177"
- x="33.386066"
- y="31.695871" />
- <path
- d="M 27.690431,52.841444 L 27.370609,74.749236 C 27.319624,78.241665 29.310209,80.477938 32.807578,80.506029 L 72.625393,80.825852 L 76.463254,71.870840 L 32.008024,71.551020 L 31.688202,52.681533 L 27.690431,52.841444 z "
- id="path1869"
- sodipodi:nodetypes="czzccccc"
- style="fill:url(#linearGradient1146);fill-opacity:1;fill-rule:evenodd;stroke-width:1.0000000pt;"
- transform="matrix(1.150066,0.000000,0.000000,1.150066,38.98882,26.86863)" />
- <g
- id="g1870"
- transform="matrix(1.150066,0.000000,0.000000,1.150066,38.98882,26.86863)">
- <path
- d="M 42.062098,33.460351 L 77.341205,33.008055 C 82.787126,32.938235 89.553204,38.416797 89.553204,43.863165 L 89.553204,60.145830 L 41.609801,59.693534 L 42.062098,33.460351 z "
- id="path1871"
- sodipodi:nodetypes="czzccc"
- style="fill:url(#linearGradient1148);fill-opacity:1;fill-rule:evenodd;stroke-width:1.0000000pt;" />
- <path
- d="M 78.337784,67.629235 L 46.723745,67.724544 C 41.843589,67.739257 35.829319,62.771024 35.877168,57.891081 L 36.020221,43.301821 L 78.973514,44.128288 L 78.337784,67.629235 z "
- id="path1872"
- sodipodi:nodetypes="czzccc"
- style="fill:url(#linearGradient1150);fill-opacity:1;fill-rule:evenodd;stroke-width:1.0000000pt;" />
- </g>
- <rect
- height="26.147448"
- id="rect1888"
- rx="7.4449978"
- ry="7.4449978"
- style="fill:url(#linearGradient901);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:2.3625000;"
- transform="matrix(0.917809,0.000000,0.000000,0.917809,-65.63305,158.5521)"
- width="104.09673"
- x="140.62315"
- y="-34.316952" />
- <rect
- height="15.829688"
- id="rect1889"
- rx="3.7576280"
- ry="3.7576280"
- style="fill:url(#linearGradient901);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:1.3591428;"
- transform="matrix(0.917809,0.000000,0.000000,0.917809,-65.63305,158.5521)"
- width="56.908955"
- x="184.04552"
- y="-28.539845" />
- <rect
- height="15.829688"
- id="rect1890"
- rx="2.9970589"
- ry="2.9970589"
- style="fill:url(#linearGradient1141);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1157);stroke-width:0.96249998;"
- transform="matrix(0.917809,0.000000,0.000000,0.917809,-65.63305,158.5521)"
- width="28.796961"
- x="145.28902"
- y="-28.227346" />
- <rect
- height="3.3627598"
- id="rect1891"
- rx="1.6813799"
- ry="1.6813799"
- style="fill-opacity:0.16981132;fill-rule:evenodd;stroke-width:0.46326005;"
- transform="matrix(0.917809,0.000000,0.000000,0.917809,-65.63305,158.5521)"
- width="49.231453"
- x="187.88426"
- y="-21.681381" />
- </g>
-</svg>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/invitation.svg b/wpa_supplicant/wpa_gui-qt4/icons/invitation.svg
deleted file mode 100644
index 1a02d1327eec..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/invitation.svg
+++ /dev/null
@@ -1,374 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="64.000000px"
- height="64.000000px"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.42"
- sodipodi:docbase="G:\Projs\Cliparts Stocker\released"
- sodipodi:docname="unknown_green.svg"
- inkscape:export-filename="/datas/wiki/unknown_green.png"
- inkscape:export-xdpi="90.000000"
- inkscape:export-ydpi="90.000000">
- <defs
- id="defs4">
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2842"
- id="linearGradient1363"
- x1="25.403513"
- y1="19.175573"
- x2="35.541985"
- y2="49.068703"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-2.402975,4.759656e-3)" />
- <linearGradient
- id="linearGradient2900">
- <stop
- id="stop2902"
- offset="0.0000000"
- style="stop-color:#ffffff;stop-opacity:1.0000000;" />
- <stop
- id="stop2904"
- offset="1.0000000"
- style="stop-color:#ffffff;stop-opacity:1.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient2842">
- <stop
- style="stop-color:#ffffff;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop2844" />
- <stop
- style="stop-color:#c8c8c8;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop2846" />
- </linearGradient>
- <linearGradient
- id="linearGradient2814">
- <stop
- id="stop2816"
- offset="0.0000000"
- style="stop-color:#e6e6e6;stop-opacity:1.0000000;" />
- <stop
- id="stop2818"
- offset="1.0000000"
- style="stop-color:#11661d;stop-opacity:0.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient2171">
- <stop
- style="stop-color:#ffffff;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop2173" />
- <stop
- style="stop-color:#a3a5ee;stop-opacity:0.0000000;"
- offset="1.0000000"
- id="stop2175" />
- </linearGradient>
- <linearGradient
- id="linearGradient2160">
- <stop
- id="stop2162"
- offset="0.0000000"
- style="stop-color:#d3cece;stop-opacity:1.0000000;" />
- <stop
- id="stop2164"
- offset="1.0000000"
- style="stop-color:#474240;stop-opacity:1.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1367">
- <stop
- id="stop1369"
- offset="0.0000000"
- style="stop-color:#f67e36;stop-opacity:1.0000000;" />
- <stop
- id="stop1371"
- offset="1.0000000"
- style="stop-color:#602604;stop-opacity:1.0000000;" />
- </linearGradient>
- <linearGradient
- id="linearGradient1347">
- <stop
- style="stop-color:#f0da27;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop1349" />
- <stop
- style="stop-color:#bf4d09;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop1351" />
- </linearGradient>
- <linearGradient
- id="linearGradient1315">
- <stop
- style="stop-color:#97ff82;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop1317" />
- <stop
- style="stop-color:#ceff24;stop-opacity:0.0000000;"
- offset="1.0000000"
- id="stop1319" />
- </linearGradient>
- <linearGradient
- id="linearGradient2122">
- <stop
- style="stop-color:#2edc32;stop-opacity:1.0000000;"
- offset="0.0000000"
- id="stop2124" />
- <stop
- style="stop-color:#11661d;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop2126" />
- </linearGradient>
- <linearGradient
- id="linearGradient1364">
- <stop
- style="stop-color:#236b0d;stop-opacity:1.0000000;"
- offset="0.00000000"
- id="stop1366" />
- <stop
- style="stop-color:#0a2205;stop-opacity:1.0000000;"
- offset="1.0000000"
- id="stop1368" />
- </linearGradient>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1367"
- id="radialGradient1402"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.211118e-16,1.330643,-1.347411,2.027373e-5,44.09678,-13.39507)"
- cx="21.959658"
- cy="14.921703"
- fx="21.959658"
- fy="14.921703"
- r="27.500000" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2122"
- id="radialGradient1404"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.211118e-16,1.330643,-1.347411,2.027373e-5,44.09678,-13.39507)"
- cx="21.959658"
- cy="14.921703"
- fx="21.959658"
- fy="14.921703"
- r="27.500000" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1364"
- id="linearGradient1419"
- gradientUnits="userSpaceOnUse"
- x1="74.910713"
- y1="32.362179"
- x2="84.910713"
- y2="47.451466" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2122"
- id="linearGradient1421"
- gradientUnits="userSpaceOnUse"
- x1="73.839287"
- y1="34.428566"
- x2="76.875000"
- y2="43.714283" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1315"
- id="linearGradient1423"
- gradientUnits="userSpaceOnUse"
- x1="72.946426"
- y1="35.589287"
- x2="85.000000"
- y2="47.375000" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2171"
- id="linearGradient2177"
- x1="24.916031"
- y1="28.824427"
- x2="39.816792"
- y2="49.099239"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2122"
- id="radialGradient2184"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(9.909149e-17,1.088708,-1.102427,1.658760e-5,41.48828,-4.732338)"
- cx="21.959658"
- cy="14.921703"
- fx="21.959658"
- fy="14.921703"
- r="27.500000" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1364"
- id="linearGradient2189"
- x1="10.018247"
- y1="8.6306763"
- x2="63.487556"
- y2="63.660282"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2171"
- id="linearGradient1339"
- gradientUnits="userSpaceOnUse"
- x1="24.916031"
- y1="28.824427"
- x2="39.816792"
- y2="49.099239" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2122"
- id="radialGradient1343"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.521415e-2,1.026125,-0.978137,2.404729e-2,38.83024,-3.575704)"
- cx="24.764277"
- cy="16.361967"
- fx="24.764277"
- fy="16.361967"
- r="27.500000" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1364"
- id="linearGradient1346"
- gradientUnits="userSpaceOnUse"
- x1="10.018247"
- y1="8.6306763"
- x2="63.487556"
- y2="63.660282" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2814"
- id="radialGradient2812"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.142398e-2,1.098850,-1.843995,1.878760e-2,52.15051,-5.667446)"
- cx="18.387238"
- cy="14.046815"
- fx="18.387238"
- fy="14.046815"
- r="27.500000" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1364"
- id="linearGradient2832"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-2.841000e-3,-2.841000e-3)"
- x1="10.018247"
- y1="8.6306763"
- x2="63.487556"
- y2="63.660282" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2842"
- id="linearGradient2848"
- x1="-0.56685609"
- y1="22.651009"
- x2="-0.33713850"
- y2="23.858734"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2842"
- id="linearGradient2864"
- gradientUnits="userSpaceOnUse"
- x1="-0.82287467"
- y1="22.444542"
- x2="-0.33713850"
- y2="23.858734" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="8.2031250"
- inkscape:cx="32.000000"
- inkscape:cy="32.000000"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:grid-bbox="true"
- inkscape:grid-points="true"
- inkscape:window-width="1156"
- inkscape:window-height="693"
- inkscape:window-x="0"
- inkscape:window-y="25"
- showguides="false" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title>Green Unknown</dc:title>
- <dc:date>2005-11-01</dc:date>
- <dc:creator>
- <cc:Agent>
- <dc:title>Jean-Victor Balin</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:description>jean.victor.balin@gmail.com</dc:description>
- <cc:license
- rdf:resource="http://web.resource.org/cc/PublicDomain" />
- <dc:subject>
- <rdf:Bag>
- <rdf:li>icon</rdf:li>
- </rdf:Bag>
- </dc:subject>
- </cc:Work>
- <cc:License
- rdf:about="http://web.resource.org/cc/PublicDomain">
- <cc:permits
- rdf:resource="http://web.resource.org/cc/Reproduction" />
- <cc:permits
- rdf:resource="http://web.resource.org/cc/Distribution" />
- <cc:permits
- rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
- </cc:License>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1">
- <g
- id="g1354">
- <path
- id="path1373"
- d="M 32.000000,8.6306766 C 19.113097,8.6306766 8.6306766,19.113097 8.6306766,32.000000 C 8.6306766,44.886903 19.113097,55.369323 32.000000,55.369323 C 44.886903,55.369323 55.369323,44.886903 55.369323,32.000000 C 55.369323,19.113097 44.886903,8.6306766 32.000000,8.6306766 z "
- style="fill:url(#linearGradient1346);fill-opacity:1.0000000;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
- <path
- id="path1339"
- d="M 54.500005,32.000000 C 54.500005,44.420003 44.420003,54.500005 32.000000,54.500005 C 19.579997,54.500005 9.4999950,44.420003 9.4999950,32.000000 C 9.4999950,19.579997 19.579997,9.4999950 32.000000,9.4999950 C 44.420003,9.4999950 54.500005,19.579997 54.500005,32.000000 z "
- style="fill:url(#radialGradient1343);fill-opacity:1.0000000;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
- <path
- id="path1341"
- d="M 32.016991,9.1562500 C 22.574792,9.1562500 14.505423,14.865048 11.062500,22.968750 C 16.006322,25.801817 21.393258,27.855853 27.181339,27.593750 C 32.755311,27.279922 37.553510,23.530916 43.236968,23.812500 C 47.451058,23.716455 52.244330,25.294372 54.488550,29.000000 C 53.142630,17.846718 43.657640,9.1562500 32.016991,9.1562500 z "
- style="fill:url(#radialGradient2812);fill-opacity:1.0000000;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
- <path
- id="path2827"
- d="M 32.000000,8.6250000 C 19.113098,8.6250000 8.6250000,19.113097 8.6250000,32.000000 C 8.6250000,44.886904 19.113097,55.375000 32.000000,55.375000 C 44.886904,55.375000 55.375000,44.886903 55.375000,32.000000 C 55.375000,19.113098 44.886903,8.6250000 32.000000,8.6250000 z M 32.000000,9.5000000 C 44.420004,9.4999998 54.500000,19.579997 54.500000,32.000000 C 54.499998,44.420004 44.420003,54.500000 32.000000,54.500000 C 19.579998,54.499998 9.5000000,44.420003 9.5000000,32.000000 C 9.5000000,19.579998 19.579997,9.5000000 32.000000,9.5000000 z "
- style="fill:url(#linearGradient2832);fill-opacity:1.0000000;stroke:none;stroke-width:2.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
- <path
- id="text1353"
- d="M 32.556888,39.006317 C 32.692760,35.835967 33.100380,35.066018 35.908404,32.892064 C 39.395790,30.219911 39.803410,29.902873 40.120445,29.631129 C 41.705621,28.272407 42.611437,26.189029 42.611437,24.015074 C 42.611437,19.078386 38.625844,15.953318 32.285143,15.953318 C 26.306768,15.953318 22.094721,18.851931 22.094721,23.018677 C 22.094721,25.464376 23.906354,27.230718 26.397344,27.230718 C 28.707171,27.230718 30.292350,25.736121 30.292350,23.607457 C 30.292350,22.384608 29.794150,21.388209 28.843045,20.663558 C 28.027812,20.029488 27.982521,19.984196 27.982521,19.667161 C 27.982521,19.033091 28.978919,18.534892 30.382931,18.534892 C 33.100374,18.534892 34.640263,20.346525 34.640263,23.516876 C 34.640263,25.373795 33.960900,27.683628 32.828632,29.721710 C 30.337643,34.160201 29.975314,35.066023 29.975314,37.104105 C 29.975314,37.557012 30.020605,38.281665 30.111187,39.006317 L 32.556888,39.006317 M 31.424619,41.497309 C 29.069501,41.497309 27.167287,43.399523 27.167287,45.754641 C 27.167287,48.064467 29.069501,50.011973 31.379328,50.011973 C 33.779736,50.011973 35.681951,48.109758 35.681951,45.754641 C 35.681951,43.399523 33.779736,41.497309 31.424619,41.497309"
- style="font-size:45.290764px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient1363);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Century Schoolbook L" />
- </g>
- </g>
-</svg>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/laptop.svg b/wpa_supplicant/wpa_gui-qt4/icons/laptop.svg
deleted file mode 100644
index 06235f02d5a3..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/laptop.svg
+++ /dev/null
@@ -1,1568 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="400"
- height="400"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.45"
- version="1.0"
- sodipodi:docbase="C:\Documents and Settings\Mete Ä°slam\Desktop"
- sodipodi:docname="MyLaptop.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- inkscape:export-filename="C:\Documents and Settings\Mete Ä°slam\Desktop\MyLaptop.png"
- inkscape:export-xdpi="98"
- inkscape:export-ydpi="98"
- sodipodi:modified="true">
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
- objecttolerance="10"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="319.93339"
- inkscape:cy="202.90098"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="400px"
- height="400px"
- inkscape:window-width="1277"
- inkscape:window-height="751"
- inkscape:window-x="0"
- inkscape:window-y="22"
- showguides="true"
- inkscape:guide-bbox="true" />
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient3757">
- <stop
- style="stop-color:#70ffea;stop-opacity:1;"
- offset="0"
- id="stop3759" />
- <stop
- style="stop-color:#0055f6;stop-opacity:1;"
- offset="1"
- id="stop3761" />
- </linearGradient>
- <linearGradient
- id="linearGradient3460">
- <stop
- style="stop-color:#f1ff00;stop-opacity:1;"
- offset="0"
- id="stop3462" />
- <stop
- style="stop-color:#8bff00;stop-opacity:0;"
- offset="1"
- id="stop3464" />
- </linearGradient>
- <linearGradient
- id="linearGradient26774">
- <stop
- style="stop-color:#ffffff;stop-opacity:0.1122449;"
- offset="0"
- id="stop26776" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0.89795917;"
- offset="1"
- id="stop26778" />
- </linearGradient>
- <linearGradient
- id="linearGradient17245">
- <stop
- offset="0"
- style="stop-color:#ffefef;stop-opacity:0.58163267;"
- id="stop17247" />
- <stop
- offset="1"
- style="stop-color:#ffefef;stop-opacity:0.14285715;"
- id="stop17249" />
- </linearGradient>
- <pattern
- patternTransform="matrix(0.9848362,0,0,0.9848362,-402.92422,36.839002)"
- id="pattern13296"
- xlink:href="#pattern13289"
- inkscape:collect="always" />
- <pattern
- patternTransform="matrix(0.6565232,0,0,0.6651903,-8.1640579,-22.602821)"
- id="pattern13287"
- xlink:href="#pattern12311"
- inkscape:collect="always" />
- <pattern
- patternTransform="translate(-88.774232,-72.100299)"
- id="pattern12309"
- xlink:href="#pattern11335"
- inkscape:collect="always" />
- <pattern
- patternTransform="translate(-5.8654428,10.456268)"
- id="pattern9368"
- xlink:href="#pattern8394"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient4451">
- <stop
- offset="0"
- style="stop-color:#fffbfb;stop-opacity:0.82653064;"
- id="stop4453" />
- <stop
- offset="1"
- style="stop-color:#000000;stop-opacity:0;"
- id="stop4455" />
- </linearGradient>
- <pattern
- height="253"
- id="pattern8394"
- patternUnits="userSpaceOnUse"
- patternTransform="translate(404.25649,166.01976)"
- width="337">
- <image
- id="image4466"
- width="337"
- y="0"
- xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QCURXhpZgAASUkqAAgAAAADADEBAgAcAAAAMgAAADIBAgAU AAAATgAAAGmHBAABAAAAYgAAAAAAAABBZG9iZSBQaG90b3Nob3AgQ1MyIFdpbmRvd3MAMjAwNjow NjoxMyAxMzozNDoyNAADAAGgAwABAAAAAQAAAAKgBAABAAAAAAQAAAOgBAABAAAAAAMAAAAAAAD/ 4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3Nw TVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAA AGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAAC QAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1p AAAD+AAAABRtZWFzAAAEDAAAACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxi VFJDAAAEPAAACAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29t cGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYx OTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUA AAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklF QyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAAAC5JRUMg NjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAC5JRUMg NjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAAAAAAAA AAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2 LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0y LjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAAABOk/gAUXy4AEM8UAAPtzAAEEwsA A1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA Ao8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAKAA8AFAAZAB4AIwAoAC0AMgA3ADsA QABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDL ANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUB fAGDAYsBkgGaAaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJn AnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YD ogOuA7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUc BSsFOgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG 9QcHBxkHKwc9B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQ CSUJOglPCWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4AL mAuwC8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5k Dn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFtEYwR qhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTOFPAVEhU0 FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiKGK8Y1Rj6GSAZ RRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyjHMwc9R0eHUcdcB2Z HcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEcIUghdSGhIc4h+yInIlUi giKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3JicmVyaHJrcm6CcYJ0kneier J9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2K2krnSvRLAUsOSxuLKIs1y0MLUEt di2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIxSjGCMbox8jIqMmMymzLUMw0zRjN/ M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6 Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50Ep QWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI 10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7 UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZ aVm4WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJ Ypxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr /2xXbK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXh dj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeA qIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuW i/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaflwqX dZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqImopajBqN2 o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4trqGvFq+LsACw dbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1uy67p7whvJu9Fb2P vgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/yD3IvMk6ybnKOMq3yzbL tsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO1dHWVdbY11zX4Nhk2OjZbNnx 2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj4+vkc+T85YTmDeaW5x/nqegy6Lzp RunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio +Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQICAQECAQEBAgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEB AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wAARCAD9 AVEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIE AwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJico KSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZ mqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6 /8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAEC AxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNE RUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEA PwD+lfSrfVX862m8NeKtZEEiS215pNhfvD4eWORy8dvNMFbxJpwkbf8AZzsRSzGGU53H2vwz4x+I WonTtGs9Nlhg1SLUZZdVn02TTLzSrywmS21Pfp98piiSSS6t76FSSSXlhw2045PwD8L9X1+4XXJv ih4oeLT7vypWjS5WSSRkJKW89zq0oVlDDJaM7Tj5TXu40K38D282p6d4m1ODTVunudTtPEF5Pqtn cNctHGiW7yuHsn3sVhSNtm+cZU1/gH4PeH3HOCy6jxLWqY/hLhydnWrUcdlHt8TgYVYTdSLoV5p0 qdNYmlOWJrurhqcozwTlChRw0Px3LMHjIwVdynhqD3anTvKF09HFvRLmTcpXimnDZRXiHj+XUrC0 j0D4rxR+Jnuplk0jxbpVpPpGn2YuN6PY3l60Hk296wjRkIUp+8AmIUb15LXPBdnaeHbm/wBA8VQW 99qdzpSwNqd3HpV450CymsbjS7iZpVSC/b7bbSPl9rqilQyMGrubvx+/jW71HQ7m+kl0XU9RSTQm vfBtrqml2giaQJZandWuqlLqCUlQJWEbwvt3YXfVLQYYvHFhN8N38O20+pwTrHbaDbwav4ZuLgc2 zXpe/S9FvdWUn2cRF5PLSKTY22IBa+Yz/KOGuMc9zOnllf8A1kjnWHr4LJMVjJzebPH0o1KKwtTG 4LE4zG4+VXCYic8DiMVRr4p061KlSoVasamHOetSoYmtNU39Y9rFxpSnd1edaKLnGUpzvFvklJSl ZpJN3ivKNP8AH/xN8FwWNhqUt3b6dZvusJr+0TU9MZdwkSGSZNyXFnkDY0Ugkh3nYcZWt24+OAuL 25h8SeFxDp89uWGk214L7RrlvLMkBm0zVYJY/IkkPM1s0TgMGG8jns/FH7PPxB+Gojm0fX7+00y/ kjt1i1OOG90eSaZfltdQaxeeBGJLLma2VG2kq2K841Pwpq9jpU11410b/hF9NimFvDr/AIdNrrOn 30wcs1vb6MjTfZwEEzNLBJbRxlTvjJIQ/nOa5J9IHw7jieG8zq59w9/Y0I1J4XOaFHMcFRw9OlyU 6dTMJqVHDYapSdlUxNPK6EqdoTnXtSjT4atPOcC5UKjrUPZWbjVUZwUUtE5vSMWuslTVtLvS0vhq 5+EnjG+uxfeB9V8O3KwtKsuj6re3vhu3LNtWbUYtiS6bbbyMsHMYGeBXVaRo+h+HZYtd0TRrLxLC qTW0d/4RmbWdNtJJPNSVNbm1W6luIYnh3KypbRgq6/vSzYHmupWXim80HUbHwra6Vq3g55IL6/m8 NSpPqM6WCu8cuuROI7pZlB3OHgWNCg8tQBz5jpGt6noF3LqGjajfaRfQqojls7l4GLCSM+VPGw/0 iIgMWRxj+8CowfgZ8d4LhTF5A8/4KwdXMF7TELPMFk2X5XWnVVVtVcFCnh/qGY0KUYR5K0fqzq1K skpUuRVJ8n1uGGlR9thYSlrL2saUKbbvo4pR5JxSSs1y3b3Vrv6P0bV/D17418R+RrGkQWF/ZXOg SJrdvJqeo6lfajiKxt9MFw0wuNNi1QW52uoRUgIKBSDXG3T62dMuofE1lDBbxaouiS2yQ29ldWt0 qxWyzaYkSqtlbx3caIWwI9l6ysG3k1iab4h8K+NtQtLXxhZ/8Izr9zdRpb+NfDUKQRPdySKIX1zQ 1IjbMpXM9sY3BO5kIya9f8eajcfD2S18TWOn6T4kh1lRBca3fFNStD4ksTDa3c9rarI8Vi08ETze UcN5yEycoFr6/CPDcU8K51xFUzmjT4WyTE4mtia+BVeco0c0m3OnmGS1HOtT+p1Vh4UqdKSy+s8V iZLMKslO3RHlxGHq1nUSw9KUnJwu9Kj2nSbuuV8qSXuPmk+d6m1+zr4oFt4k8T+C7i8muRdRrqlj JdbN73umKmn6gkciSMsyvapburKeVtjwMGvr+vzA0fxrqPh3xf4V8QzXEsljYazcXKQ4gRIrK4uP suqwLHbooiZrZnYoCU/eqy4yRX6cpOkqLLEQ8cqLJE4IKvHIodHBB5BUgj2Nf2d9DXjeln/AWd8I TxE62K4GxzVL2q5an1DMlLGYZtOrVbjHEPGUoS53ejCk7Q5uSP1HDOJVfCVcNzXlhJaX0fJU96PV 315ktdktrpE1YniHw/pvibS7jSdTjkaCdWMcsEjQ3VpOY5I0urSdeYLhVkcBhnAcjBBrY3j0NHmD 0Nf1vj8Bgs0wWKy7McLDG4HGwlTq0qkVOFSnNWlGUXdNNP8AXc+jlTVSMqc0pxkrNPVNeZ8b6v4O uPhdrnhyx8PXc+oajrN+lp4fvr8Wq2/h2yQLHrGqyRGNY7rXjDczKkm1xDbRM+AdoGZ8UfiDFqNh FqdlGJZ4dSu7W21BzzYWd9Dp9xBNNZuBHdaobSGzmt2iOYAwm4cgp9BfEO5snuIdM1W106OS/s7q 28IXk98y3tzr99YX1pqNulrHHugsI9MZ/Om3HcbtEUBvmHxPrOoHT4dFtNSMzxa/qN5r99Cthcos FrcRwaTpM1nY3IwL9U0+SeMYZSJ4gMoStf5neNeCh4Y4bizhHhPMllXCmdVY8mFSny5bUofUaVO8 cQ1NV54rEqvHFXq1P7MeDlh6tOjhcK4/C5rH6gsRhsNU9nh6jVo9INciWkurlLm5tX7PkcWlGJ6H 8MbctomsQalqF082uWRtrSV79WNvazqbKG6NrcuzQsItVlcb1ZPKcPwGBrbt9Ol8O/EptPm0y/vd KawTRY7t4Z5YdPjsbDNvvklPlvePqVvHOtw+VViGVG5I8k1HV5/DWu6Zo80qTWqXFpLLJbu7Ld6L eG0torOUnBu7hNPt4HU4DQXBeMD5ePT/AIivJokmra9BLc3/APausJb2OlK8kTzTaTHbxu2q3cn7 25hF7HEY7RAHuUdWEgTIPwXDmPy3D8J06UcJOOP8JswwU8TUcoSqKk446tiI1aUoVHVpV8TJYaXI qtZSnTcIzqUqduOhUgsNpF8+XTg5N2vb327qzunL3dLvVWvZHs3hyznv7s3erQ6lKdXliFppc15b x3VlYRzGS/OrrFCIprM3TLNbK6eYHuZYI5FXbn0PUBe6n/amlXNvYTaZLohn01VLL9ovhI88MLWj zZDQCC1cMP73DLjFfNeh6t4o0211K+axm1jxVq01vqCaNPNtezs9YsBaxz3beZvgnSKDISJ1EUVv KiBWDCP2DxVr2p2GkeFhoS2F1rfkM0Viv2dtNE2nQiHVSt/Od08KiVwIgyGUIHZwocN/XXA3F2U/ 6o5vVxWEx9GGEhGtjKcqXPicZSxOIqYVUKlqUYV8ROpWqVXgaU5TwjlhsKqUKcrVPpMJiaf1aq5R mlFJyTXvSUny2eiu223yJ3jdRtbfx+S01zWNZGj6n4chj0LSxfyT6/Pp8sP9m2txGbWdhNazBbqF JzMPs7EhwvzhFUEe46/4ftPiL8M7LTdN1h7rNtp13petugnkuJ9Lfy/OuEVMSTyLFOskY2/vHKkj k1y3jQ3ev2sukW9na6laNcaZeT6ANR/se6nhawhluVEkaNm0hS4jljZCxyGVg2xlPVfDK8sLTw1a 6fpC38mk2FrqsVv9r08Wl59r0vVLpLuNbL5XKuZo/JXbkiPLNvc1zcDcMZVh+JuMeB82lLPOH+MM txdDF4vEc9HE1XGrQwtPC4dUY06csLhKEnFV/bVsbQrVKTqrC0qlBVlhKFNV8RhKt6tHE05KUpXU nrGPKrJLlinvdyi2r8qav4+99fa29pamDVtM/sxby01/TvEMcclpqJSzlktvEWrJagHS9QlW3mC3 ERMY2pA52ygnrLrR5r3TrpLTxFcCa90eHTV028gtNUhE7JG1xHPJKxjns7mVSGWX7s8bAEq7GvIf iBBq/gPxVfXllq0Njp2saha3+n6ZfR3M13q+j62q/a9Fu7W5iZZrKC5adWTexgMygxqGQjvdY1fT dY0vUdZ0IyQeXps1pqEJuYoowI7f7VFFp13Am+2m85jLbyvH8r2rrlcbW/MMkzbC08VxrknEdGrU 4kyKpKliKU8VKjUr4eEK2HhXwksJOD5I0aPtqkJUaanKu8dDD1J1FJefTqRUsVSrpuvRbTTlZtJO KlDla0Sjdqy351FtnlelWetL4vjW5tdJ0rxTZA/abe+GnnSdVsUt2xB9uRDJo92bYxi2klZSFHlC c4RR6X4YiOs+DviZ4V1q3vPDHicaRHqWrXeopdzvcW9gjJp2uLGsjfbHFraGKaRZDJKIomcMWY18 9+NPFl3Nc6N4shMx1K70mPT7jUJDCx1K1+yW4S31iyfdHPIUkk3uOJQAxBJG33T4K/EjxV4suRp1 14fs9Vvf3EOuamq2dgg8MsBbRvKikNJdK0jCEbWjdIZEAVitfCeFOfcI1OPK/BM8wx9eeaVMxp0l UwssZSx+CzbL3h1KrHCxp18NmUaVSPtcTguWhOhHFe+3UlXqceXVsNLGPCuc26ntErx5lOFSHLd8 tpRna13DRpS73fz9o+pfDLSb3R1SPxV4g1C31W2vFuraS30iCOa3uYglha2VqZWuo5QqvvyrswRQ AN1es+KtH8Z67JceHNN0DUbafUZZ7ltOgtLbTtOs7DT7+J5NRijJQ6ncXET2o891aUNZCNSxY45/ xv8ACDx94Vv9d1u30O38V2Imujpeo6e0cN9pVgWk+zXMlnp6xSvfojoG2pIqLEW6sCv2b4L1K/13 wv4d1fVLE2WpXGl2v2mFmjlZZjFGJ2SVDlQzxgshwysNrDK8/U+D/hRm+d4zjDw74wwmJ4Dq4aFG rTpYTK5YRYnBKpPCYmU8bV9vDFVKkOT2FR4rGxjGrOUX7SnBUN8sy6rWlicFiYywcopO0afLzRvy ybm+ZSbWz5pbtrVacd8FvG154t8N3tnqkCW97oWq6lo9seVa607Tp0htpvJZB5bwLJHA2erQZ4OR Xf2usWt/faxpQfbf6LNax3cbgpK0V3As0F55LKN1rIVkVHGVYwtzxivnDxx4n8Q6J441y38G2ip/ YNtaeIHgtrGWFNbuY7S8ur+xvblcG9tpZbmBPLhwfOky/wA6Zr17QvEMXxH8Mwa5ohHhjxh/Z0sI i1SzWW5065jcrLaX1s+06hpAuslTkY3h1CSZFf1Z4f8AG05Uo8B4nNKmc8U8GPEUK1SrQVJ5zQwU quFqfU6kqsaKxNGt7FONWopVIxXPJRqVMRT+gwOLdlg5VHVxGF5k21b2qg3F8rvbmTtu7vru5Lnp /iDq9xq3ifw9plk1l4r0O3fVdD0/WUMFp4g0W3vGi1CxBif92zR2jTQ3Csz7LgOF2xyLWjca/quu 6eupWenf2t4f1G5t7a3uNEmaLWvDi3No7Xt7qMMsmy6ht7lYCstvktDcLKqEA5+ZfGniTxn4X8d6 ZrNzpF/eG1Aub7R4knuYNO1S3uJo7c6Vqaqz21tMXYuN6RyW16BIpB49f1jRb+wh0DxLpmq+K/CG i3k0msXfhO0gtJ7+3uruOzE/hTSrdZ1WKMvFfXJkG6OFFd0bbhD8ZkniBnec1+LcHVnj8XPhvEun iqDp0sLUjhK1ZvCYtrFQWEcadOvVw+MpOdLEzWGwrhh6VehVqvko42rVliYyc5uhK0lZRfK2nGVp Ll0UnGSupe7FqKabMDxL4z0HwPceBYL+xvTofinTpJb/AMWaTZWkNpObjagg1i2FkoujLcvcXM6o YmDpHIRJ84PIeMfH2g6d4ps/FXgy0S+1fwrFLH9nhkSKLVNLezjebSooooUFm8unMXRZCxC2rvGk hRCMjxB8S/C3xJ0TUdN8VQ+HD4n8LahcJb2WuXuo+GbbXdMDliLC+KbbDUxGIVnS5iaIhAY2G5iv jniDwZZ31sl1beHPib4at7VhdLNoejWnjTQrOG6iWU28Gr6TrCm5jEUiNGWIKBpFIUMAPyXi3j3O q0cWuC8fgOIcjrTwWMwUqdOVHHZfWwlONOpCVWdKrg8LUo4zD1MTCOJxM8Q5K8nXw1RVY+Xi8bWa n9UnCtRfJOFladNxSTV2nCLUk5LmlzX3vF3PtuH4wab4n8BzeKPA8tsdaubGzW2sNbjmSHSr6/vH sM6oLfmSGH7NeynYQjx2e5nRWyPlzSPFupah8YoNM8Xyz6v4d+Jvhu58JXlxrkyabCwme8Rbexby V+yP5+yGKOIsWe8DRu421rW1xoGieErPwQvim+1zxSNKvdVn0zU/DWp28dzZ6+0GIpbTSvNuXv7X TJwk8CmVYkuZpcgxvtlt10eC60PWH8Y+DL3UINR0zSF125ttS+xaVJbzrZxf8I1Lb6WLa48UG+Fz vjBKIly4IU7p6+tz3ifiTi6pwbXzLOsNRx2QrL8RmFCjicG8HUrxm1j6FfDLGVaXtalKrVwlenz1 Yxi1Pnw9G6qbVsTXxf1SVStGM6Hs5TipQ5G18cZR52rtNxkrtLe8UtfmeDRbDwVf61c3sj6Xe6Vq E6XZhuhqQ8HFXmS10bSbiQBNY8eywBlSUjy9Ni33En78ARdp8PfHdiFHjH4hWdlb/D/wtcLpXw60 t9Nt9U1LT/E0hjljl0a7vV825itYit7qUkjsjzPEQokZFG58VfhL4+8c/GDWdG0bQprTwPBqt5qU OpaVaxT6VY2lyTc63qlxHZyu13r894l2BG/+kTSqkIVUAC+XeK10HUpreO5XVtM8L+G7R/Dvh7wx 5Fs9zY3TRtdLeapcPOsNrc3N8IZdRuXdpGe4eFECRqR+CVcv4g4CzjM5YLLpZblOQ43E4XBQxdJ4 fDZpiqFVOpiaykqUa2X4S1LE2go/W8SsHyUVRo08PgPCdOvgqtTkh7OlRnKMFNcsas4tXlLa8IaS stJy5bK0VGnV1u6jhM4GvWWi+IYNYub42M2lx6ZqmttNvYX82taRDKqX811ueLPk74liZwHaIt1v xJ1rxD8P/BXh34cLql1b+K/ESf8ACXfEXU/NZrlZ9QG3RfDst+gIjgjs3MkwBwzSgtw5z23w6+Hn h/XvFN98VPE8uj2PhDwqLC6tIIruO5TxFr1pYLJExuEijivLRLm1l2LboGuJoVTZgfN4Xq8958QW 8R+M76+tINT1G+vbuDSp5r1JtXl+1W0Mmj291dyRLbW0FjOjLGrSoGsyqKGLVeY5fnGScOZhjaM3 hs14vWJw+X+zxFX2ksowc4PG4+UKtS9OtjpeywdD2apyrUPrsaVKo8RF1CpTrUcPOafJVxXNGCUn d0oNOdRpvSU9IK1rrnsm5a4J+NXxQXTINFk8Z65LZ2moR321tRmked7aNYYIJrkPvls0jQhYw4jO 8kqTgjY07xJpnj7R08AP4c0jQ9ZvL281jQ9ZsJZbS2n8TeSVh057Bn8m0t7+zhhtXZMbrmG2lYcN nx/UZYfNkihgtYNjHiLzZGViMPEZXbkpkqSAVJjypIOTSgupLSSC5tnaO6t5RNFNkExyoQ8MsYPK yI4DAjowBHSvxWlxhn8MV7HOM3rZ9lsoLDV6WJm8RzYVyiqlKhPERnLDz5V7lWl7OcJJSTvv5Cxd fmtVqutBrlkpPmvHS6Tldxdlo1Zp6ln7NqH/AD4Xf/gO9Feuf8Lv1b/oAaB/4Ar/APFUVt/YnAf/ AEWNf/w21P8A5cV7HA/9Bkv/AAW/8/6ufqJoXxC0Vtd8Q+Jbm81+zt9IsLp9T8KT6jPfPYXklzFE l5a6akzQtBIqyJIN6izui4chXVl57wv8QNW+M3jXUfDFxYR2Xge2NlrstjdQqdUEejTWzWtrLcxs FMdzqRhklXa+EQoj85Pzr4ktfEPw98e6na2bvaX+navqcuk3bJmDUdPu3M/2OSGVTHdW01u4zGwK OZGQ5BXH0R8DvGfgHU9YuZotJPhjxbcabcRapbQyyf8ACPPbw3MMxuNOiuZWbTwSAZIgypEFPBXB H73wT4kcQcZ8bZH4c8T5/R4Qo4DOsW85y6tCVBZ5JudKphPrEYOk1JyVPEZbKOGw1aH+0UJTjKnh 8J9PhMdWxeLpYLEVVhYwqy9rBpr23Rxvt5Sh7sWvei2mox+qI7WCJPKitrSKLnEcdvFHGMnJ+RVA 6k/XvXyx421/Qr34mx3Pg25vtJ8a6TZXmn65ei3l0xWkj2nSrqFJVVrmW21OOyaaQAiS2nV18xYm x7LoXxa8CeIdd1bQbHxBpyXOmyCOKS6nFpDqG0bbhrGe5VY7lUl4yjsXHzKNvNfPnii30zxH+0f4 ZeXVvDkmlQ614Tsp0XVbQT3CQvBLMrqmRNIZJCoBYkqFUelfvXjfxRlme8JcGx4KzXLc7oZhxRl2 XuVCrCc6FWnWqx9thsXRq82CqYarStOrCnUlUw9SdODjCtzy9jNsRTq4bCrB1KdZVMRCGju002rx kn7ji1q0ndNpaPX9M7nw/F8SvhtaaJ44sGhfxHoGlvrdmoEc1pfvDb3MphJBMEyXK5GOV6e1fAH7 WCeIfhp4s8JjwdHfeHfCtj4cg07TpNPdjpTzI7iWyvLdlaKacrE0jecrtN5pYk4OP1EZTnjucDkd uPWvgv8Aab+IXguePxP4Z1rTNX1TT7O3stLvdY0o6ZLBa61MXnt4LX7Rdqy6haM0BkG3b85VmBOD /W/01uC+HJeB+ZYzG8TQ4X42p0svw+Gz+UfZ47FPKfrGPp4WviaFN4inhqtX2+IrSpOnTo1Z+2lz csaU/puK8LQeUzlPELD4tKEY1npOXs7zUXJK6i3du1km79En8Kjx7b61p9vpeoqnhO7hvptRTxD4 YtTbx3V7coscsms6fbur+UcFibR0VSxb7O9N16PxHYWFpqviSw0nxZoF/I1tYeJbWaKQ3LRgM0cW r2PlzwXCr1ju4y6k4KZryJ3QOwj3NGGbYzgK7Jk7C6qSFfbjIBIB6E1oWGt6jppP2K7liifcJbZi JrO4VwodLizmDRTowVQQynO0egr/AJ/IccYrH0q9DiKtXxGJdOFOniaEqfK/ZcsYLG4GrGeCzCnG mpJPlw+JdSSqVMVUS5JfjP1uU01WcnKySkmulrc8H7k0l/hlfVyex2Wm6foOp3tq+lauNMuhPDIm m+ImWGN3WRCqWms248p33Y2idYASBluTXp+m+Jv+EU8d+JfDvi2wWXwj4uvZrfUbDVo2a0iaSZv7 O1xQhwjBnRpJbdsiOYlW3RgDxNP7E1wFVaHw/q7AeVE7FtAv5DgCNZZGL6NKxzjeZLfPGYV5rqfE WsarpGtvpOpaWL6xvLLS7oaBre+UW9xfaZah5tOukZZLOU3LOVkgcJIANwda+s4Zzh8PYOnn2BjR wVbC5jhHHF4WFSvgcSquHx1GthcxwE06lKliKUqlDEUoqCqUKr9jgq0bTN6Fb2EFVgowlGcfeinK DvGacZw3SaumkleL0g9333iX4K3TnU9Q8MX1tFpejPnXNM1u9WC68PCaFLhZ4r9k8rWtHa3KPHPH iTZxIm9TX2j8KNRa+8CaFBPqOn6pfaPbLouoXWmXLXdqbjT1VIgJ2jUyObJrRmO3BL8E18PQ+N/+ EZvdP8Ia/Pq0F74aligi8R6dew3F1pGoXe06nZ3dpOrQ67okUEkdu1vKTxBIY2AkIr6g+Cup+E4t W8XaHoN/dLeTyWut6ho11pEuj2sV7tNrf6joUMszj+zZs2jNEGIiLKY2aJlx/aH0bcw4IyfxOrVO FMPTyGvxJTqZbmuArY6MJYfGU4VMVRpYfB1VRcq1KrhquGqRw6rUGpSr4R0adWrgMB9Tkc8LTxz+ rpUpV06dSEp25ZJcyUYu12nFxdrrVuNk3CH0NRTdx/unH05/EUbv9lvyr/RXlb/4dH2yi32+88n+ K3hzTNVh8Oa5qUk1rH4a1O5me+gIDWUOo2MtqtxN8p3WiXosmkGQMDJIGa+HPFtv9l8Q63b6xfX7 2Wi2Hh/TrOK5jkN/dRjTrSOGSC7c+XBMsZuCzkuCrsFV8Db+hfj6/u9O8H69qViubnT7RbtYi+xb iOGeJri1dyjbI5YPMRm2sVD7gCQBXzf4w1LwNezWFlrNxaaYm2AaBHomsu1/BJPapp73OoxXdqkE ttBO7CHypEaRRvC7WzX8MfSf8P8AJM7zPEVqeZYTJM2r/U8dVeKjUhRxc50MTllONWtGpGlJU4YS hOEKiVqtKlSl7WGLtQ+Sz7B0qlSTVSNGq+Wb5r2k3GVNJtO2iinr1STupaeUeEl1CTxjbxWmnaZF c3gt/wCxdWvY2u5mg+xiK70mzNzIIbnVZBEVWVgwhdJCpQPuX2i41PT9SivfC9xrOoHxFZzapBb6 pZWotb3TTb2tpepp8EMAP9qx/wBkywJ5kTiQ/Y8xsgZmbzHUrrxN4cc6Qrtq1v8AaDfafdQb11BN IsZYI9RSykkPmwTyXKWtvdwRujR+XKghWMFn6fXPHWk3ltbajoT2SXnhy1F1cwedb2d1f3Dxw6Qk r6jIytDNHKVSa1dw0sYhkUOvA/G+Ea2W8L5Rn+VY3MJ4fGQxHtcXhcXRnD2+HrtSxlPB0cPXhRq1 8PTprEUswjKvXWG+r06EY1o0WvMw0oYenWpSqNT5ryjJWunZyUVFpNxSupq75bJWdjat7bVLCz1X StHv9EuZIbbTV1TWZZrPTbDVNJh+3/aLKNSHlis4bGcyPISzyzRlDtVjmLx4tzq/hzwYdGNtqUmj Xc3h672odKuvsz2sXk3qW10AiF7iwu3W4yqRi2JG7kV5rrOoQaXo9tqHhvTb3UL/AMR60NsFxqMd 1bWeoxtPJc6JcaQ0YM3mNPJMEwIpo5FlaRh8q9Nc6roWsaP4v0TRNeW7uNX0m7gu4GaRNviGzjj1 XTtK8OyROEurU/YtTEoGA7OsakxjL+i86wGNynPuF/aew+sYGEadGOMk+a9armmX0Mtni6UFXqVJ 0cOsZN0sZUhTrrETftvbKroq0Jwq4e/LzQVlzb6+0gqbktW2kpaSaTu3e9+qg8Q23izwZr9q95ca td+HtXthc6lFDZxTvArC7si6tHC13p1u8d3F80kUkpjM++PzUFetfD+DXNTvdH8TtqD3Gj3ej61B NavdXEv2aW61CxudOTy7obzIqJc7slzGJBGXYDcfifwHdeJW1nStO0S7uXaS5N7rurXM1tPZWNpL ZTT6l9qGyRJ7aHSILyR0cvtlZdoD7c/Xfw48R2F3NoNr4ZgvbLwrd+HPENxDYJZhYr+5tNetrQax IyRg2moyLMztbhgsUUo2hlUEfceBnGdHi3N8lzTPXXw+Mw0MPhGozlTeKr4TMMNUw1SnOc5yxFDB wx0cNmTrVKk3OrTlCderWlGh1ZRiliatKpWvGUbR3a5nGcXFptvmUVPlndt6pptu0fCPEHjF/EHx B8X+E/FUrwabN4kll8I6jrUcUaeG9Z0+Q2tjEWuQ32fQr024huNmdpaO4GCrGvN5fEer+HptZ8Ja 8osra4t4NN8SwRQOt1HLCYRb3KOz7XljSNXVEYxSLBwWSRjXffGTSPD+va+moWsFzofiTxPpvnp9 unK6Brd7Z3EmlXWnx3bRD+y9aS9sVUiZRDcNMhMsTPluBs9d0bxLHZ+B/iGNX0TXrKWHSdI8VXVp AdR0bO61h0zxMZSkmp+H43dQhZPOt1clZDGMV/OvG39tx4t4hy3G8SU3nEswxv8AZuaVKs4YXMML j51K0MozGpU9l9VqToYhfVZYlqH1bETwtSp/Z0sLiqHiYp1ViasJ106jnL2dRtqM4zbapzbtytxl 7vNpyycW+TlkuN1uKUW9wq3FjeWAtI7uy1DT2kS2jSCVY4YHtZhm0mM1zLmMHg3IXO1MD6D/AGcf A+qX+qTfES01aTQ9IgnbR4dPhhW5l1lYobb+0RcmVwkNqZlUg4ZhISU27cn58gT/AIRW88X+HdbK yjTpJtNkKWhmc3sd0qZt47ggfYpkt3dmZdwVI5Y8OFNdX4c+Mfi34Y2Ftpeimyn0yW3tL+PTr511 CzS4vx9qvWjlhEb28hDMsiBv3b7Rzht3znhdmnBvCXiDk/FniBQxdDLskdWpPDYV1HiMFmeGr1KW HU506tKs8NTkq0uT2vNOcacKnt4xnFc2X1MLhsbSxOMUlTpXbjG/NGpGTUdU07LV2vq7J82x+nDO JAXU4bOCR2KkFTjrnGR7/lXyT8YPF8Xwx1a2j0KW80geJ72zk1qS2huZ7OxtZrtZdb1Ozt7m4+zD UpohEmFjTbuLZLOaj+FX7SFvr9z4pHjdk017e0Gq6XZ6VZSTW8Wm2Mbf2hFCQzTXN2qN57mRuURv LUbCD4j8ftV8bWPjiw1m1vpv7G1uyjvPDGoac7yaLqtjcSSNBF5FwGhnuFs5LRJ0kQ5zuxsYGv7b 8YPG3hriLwhw/GPAeLq4nFvGQpfWKNKMsdllOderhalerQjXpVsMsXGHs6TlVouarUrzp1ZUkfVZ pm1CvlccVg5OU3JK6Xv005OLbXMnHmtZap6rVNo+nPi7pPh2PwOddt7lLQ6NJYa+VNw5/tfTrua3 trmO9t0lX7QJYbpWUqBiYADG41oeHviH8OvCXhTwyJ9Z8PabHcW9tbxWuhrLPHFNLZ/aYorhIxJK tw8UYy0xLvJIMkls18Aa1451Xx9BZWXiYmTUNHtlstNudPSK0tl0y0Cy3NlLpdqUS+PmRJLhNrHy j5RyFQ5s+sa5p2g6dNZfZ0SHU9ctLJ9Pijk+zwXtjaie1Yyfv4gqPcGN5D5kUgKoVMZr8hq/SZwu D4uzji7g7hDD0MHiMswuHjOrSnOt7ajiYfWKlXDUp0FRbpVIU/Z08TOFT2NCcqjnUao+Y8/jDE1c VhcLGMJU4xu027prmbimraNKylZ2Tvd6fd/jv4aeHfjRD4b+JHg/xDd6RdFAl3faYslte67pNs8g OnRq8sQt9bjnSSGF5TsBkKy5VVI4Dxn8QtU8I6H4T0r4geFNQh8K6kr6BrEc9xdXOuaDfRkXmk6r ZaxcEjV9QTTJkF18wWV7aeIEAlRzvwF8Vaf420K8+DfjSUKlzC+p+ELmxuIrfUbefTJGmmLzWUoZ NVhuI47mAucyrG+4Mo+b2g6D4qSC50H4j3fw/wDGvg1tRubLw1ZeJ7zy9au5ILWOPQY/7SEBSPV5 r4TJKJA8sYJaN3yQP2LLJ0OPuH/9fuB8K+G8746w1Glm+LoUo4jL1nGHlReLo5xldVzq4XCVoQgo VsLUxMsXRx7qYihKuqNdelBrG0HjcHD2FbGRiqs0lKHtY8vMqtN3cYtJWcebmjNtq9mfF3xn8L+O NEuYbnWZYfGfh37LBdWPi/Tbe1e6Gk3Qb7BFq1zbxvJbqYFOxrver8hZXwQMb4Upq+m6rb+JtJ1b Xm0SyWc2dlBqsmgQ6hqce3daarIT5FxpVsJ45r2TJDR+XCgMkscZ+y7jwB4e1sJZXlr41+D8fgS1 vVsNaivdLGjXOhzTC7ls01i7eYa5o8bHz0W4VYoFumhCkbkHG6v4h+AMsum6NoXja00u6kuhcW+r aR4T0270y51nT4AJ5gJ7KKyGs3EzRMhMbRxytH5AjLhq/NMb4M08o4wfGdbiehklF1aVTBUcdmlK ni62Lg4QqUsNUzOWBxc6WHxP7mFPMsNaqo4eVSu1UqU4+bUypU8V9beJjRjdOCnUSk5JpNRdRwk1 GWiVSOvuty1aXmP/AAkFrpOoJr/iC00zXNWvQ4OqWMUmieKrizN2q/ab64sI1TRPD5jSVBFPC+pa x53liGOKUR1q6p4D8Q+IL/w1Lpnhfw9HpqeIrO78P+HNcE1nP4e0m7mSS4ay8NxTQ3FlKba0guJI LiKXy5Y5XEktu5ZLviHTP7c0uHWf2eNXg8R+NNOu7jS/EkPitoLPx7p9xJD5KXuh6LrS29tpV6Ns ytNDbicAgRTYVhWTpHwg+Lnhi2jm0+8sJvHutNa61408W6/4it724gsbW7iuE8FaDbG6kuNQv5TG TqEwVEkBWzjkCMxb36OS5tVxFXLq/DuN4tyFqninjsqhRxGGrObhJRp5l7PFf2njKmIio4nD1JQp YOeHWKq4qtVpOpPRUqrlKm8PPF0NJOdNKUXe2iqWl7SbkrSi7KDjzOTau6XxZ8f6hp+u3uh+F/E1 3JpNj4h1G+1hdLK3eoeMNXSW5lvNBlS0uEi8OaDZ2MstuGkKPO6y3TxyMgevLtE8A3HxQ102l5Lr Uuj6Rb2Wo2/jRr+xlTSvBU1quoRzeK49SLf2vdW0dy1ujxETM1vLHgxxIE1fit8MX0XxH40upfBf xIv0vr/UPEEGq6ZpkGl+GpBcXTan9na/s0u5LhkhvLqENKkTB12hR38z1n4neJbLwD4Wh8O+Z4X8 JanceJfD2q+FtLvbtbe/i0q70+9K3epTubwzPDrLRuyyIqhSqRqmUPwXFmZShxRxBU8SMJiI5blk 511l1F4iftKcMTHCU8OpYiCoUcN7SrQq4jEUKk8Vy8tamq2KqV8RPgxVW2JrvMIydKneXs05XaU1 FRXMlFRu4uUoty6rmk5Sfs3jWLw1F4b0vRPBepax4c8K+ALhr+0J0C5XxB4gvbq8hjvtU0nVLu5a 0nnluJLF0uBte3jcqwRAQ3zDqqXV/Ot1Z6lrdzBHbTX8sF7Bb7LVbBC264/s25CxsLmaYM/kq4Mh kzJuJrIh8Y3OnXVxaaN9qOk3l8JrWK6na61i3s5x5Mllb3TuRHIY22BtmS8Eco2sFIztc1K3jlur KWSLXL1rh5ZtcLSxzpI+d8SSIFN4+BH5sko5dCiqAC7fl/F/F2W8SpYunhIZesNGnRlRoVK1PDRd CKp4aGHj7SSVFYalGjThTw8YKEFKo4SaZ5mKxVOvaah7NxsmouSjppFR125VZWikkru1zEvYxFcS iJNsAlbyPmaRGiLsITFO0SGdNi8OVXd1IB6UwzE4HXOMAE565PWo/M3tl2baCATkuQueqhm5HJ4y PrT4FaeeGCGN5pZpo4YYl+V5pJZAkaAjO1mZlHtmvyGUFVqP2cLOpLSKSvdvZJL5JJeS7Hl6N6K1 xdzejfp/8TRXb/8ACEN/0HdA/wDA5v8A43RXq/6sZz/0B/8AlSn5f3/U1+r1v5PxX+Z+qkVn4h8X eC9J0Tx14YsYda0eE22pnxJq+maTe3elW6SEaxp80cjXFheW0aRGUyRhPnyySITjx7UPhnqOkapL rXhPx54Sv7bRlSa41RtWB1CziuFISHVbK1t5xcqbZ3R5kVoZkY7hjq/UdMtrPxDpT3Ny2h+L4Z7u 00LXYp5bTQvFsds721tZ63e6isyaDq5hxDLA7TDawhufKJVqy9E1u5F06+FPDOnaZrNpPP8Aa9Bu ra5vdVhltpXkuf7A1C7nVJ7MFZC2nt5bp96Hzc5r9k4lxOQZ7XyvB8TZPiMRnWVulh6OPWNlVzef 1PD0fq6TweAwUamNpynCWIw2Il7aqowxGW16kMXiMW/o686NWVOOIpSlWp2ip816r5FHl+CELzTa bT1ekqbalKZVXwH4e8Qo39n+O/A9nrXzTPpNvPqr6fLEgZp202aXTw28tylsN7L8yxsylQuH/wAI xomh38Ev/CytAttQ065hn2R6P4nM1rdW8iyqCDpgw6uq/wA67W3EXiR59N1r4c6XDqGs3djYaf4z 0rQNQtreDUtTuDHa2muaLDcRC3uHnVkkkgCSR/6zy3Qgn6N8Ufs66LqHw503w9olvZ23izR3/tCD UYzIE1PUbnyv7TsJrm4ZpDYy7Qtv5jMYTBEeBvzy5D4JY7jzL87zvgrg7LMxxfD+G+tc0q2eYWti cTGq1SwlPB/WaEaeNqUqdWtGvQr1sBUlCFHDy5nOcZoZVPGwq1sJhadSdCPM3etFyd9IqKkrTaTa abg7KMerXvHxK+OOpaZ4Q8KeGtG17T9K8eeM/A8HiCLV207VLpIrcWolurzT7RLYtHcyW0F68YkI dG27UZhkfmJ/wj3hrVL557/4saGZLy4ae5vLvSfE7zSTTuHmnk8yxw7licksMkcn09f/AGsr/UdE +KmgWdi91Zy+EPA/hDS7W5h3ILe4g04SSLHKBt3bpcMOQQSCCCRXyOZcsc4JzzgjqeegFeh9Lvxm zbi/xTzLhni/KKfElPw4xNXKqFLE4jM6WHjDDUcLSrVY0sNmNCP1rEYyli5YrESg6lSmsNT57UTT iXNKuJzGph8VTVdYGTppSlUUUoqKbtGaXNKSlzNq7XKr6Ho954R06OeaHTvH3g3UhHK8cTvc6hp3 nKGIR995p4jQkYP+sKj+8RzVF/AnizYZrPTBq8AyfP0K8s9YQgE87NOnkdRx3UdK4MyEck/pSxXU kDiSCWSGQHIlhdopByOjxsCvT261/JE8dwxias51+GamXwk24xwWOqRUU3omsZRx0pqK6e0g31kt z5tzoSbboOH+CbSX/gam396NO5tb6zkaK7sbu1lQEtHc208DrjqWWWMED8K2te8QQ6vZ+GI0F6Lr Q9CTSLme4nWRJXh1C9urdrML80MKW1zEgDEndGcAKBUdl8QvGenRyQWvibVvJljMUkNzcG+haNhh kMd+sgCkcEAdKxJtWW6wbuwspHBJMtvAthO+cZ3G0AjbGDjMZxuzzTlVynDYPF4XJ80xMVmsIwxF PFYSlGEY069OtT9nXo4ivOUlKmm5/V6LSvHWM2g5qcYyjTqSXtFaSlFJaNNWalJvVb8q7dSOW4aR 3kkO5pCWYuWZmJ6lmJyzEnJJ5JJJr6I+Avi68X4h+FklvZTKfM0O5hknYxahpVzavb2zhGbaby1l Ft0ALwRg8mL5vnO5l0owxPZvfLcl2We3ukt2gjTgo0N1E4aUnkENEgGM5PSk0rVptJ1LTtUt3aO4 02+tb6J1JV1ktZ0mQgr0OUA+hr1eBeJcXwJxpw9xDTrOvTyzG4PFVVSqaVIUa9Ov8SvaaSaakr2l OnOLhOcJaYTESwmKo107qnOMnZ7pSUvv+XdNWbR+3FMLgHA59f8A63r3rPsLyPUbCy1CE5hv7O1v YiCCDHdwRzpgj/ZkFXM46YPTqB+Pb1r/AKB6VSjVpU61Oaq0q0VKLWzjJJp/NNNH7OnCyknzKWxk eJRcy+HddSxm+zXraTf/AGS4IQiC5+zSeRMQ4K4WXY3Ix8vPFfnNFf6R4g8M3cd1f2Vx4n0k29xp ccjyva6ellcWGmapcahcxsftFtcC6WQMx2o9p5gOJMJ9+/Ea6a08AeNblTsMPhbXWDL8pU/2dcAE MOhyRivyH0u7+zWerSNE432kdslwjMJIrl5QVKOpG5Sy/OpJG0A8kCv8/wD6ZfE8Mm4m4Jy+WDjj aGPyrNPbQrTm6UVKVNUqtOnFOMcRSnTlOnVmpRjUVKpyqdGnOHxfFGJVLEYSChzRnTqXTei2s0u6 aum9nZ2ukz03VvFeq6rr8t3ql4dNt9Mv9llDbSKXL2aGaNlc7TfRGCIAyvkslygYyEqKxNP8T6nP fzx/2dHqN5qd+W1C0ijf7XqjTS73tY4IVKTXAumeVWaMlXQH5kUKOW0nW9TEtlYWKW0l6LhIrBf7 MtLqe4knlK/YZZJIWcwM0zgAZ/1hU/Ljb02oyjwtM2k6MyXHiXUUMUt/bGEpottdBopdG0q6j+W4 1LJlhurtTiPy2ggbmSQ/wxDM8wzRzz6pm2KjQhiHUxdScY1Jzq1opU8PRg5yp1q7SnRpxVGjCNJ8 1VewnPk+RVWdS9X2krKV5NpNtvaKV2pPRpaKy30vbtNalvdBmvtM0SefWtT1yP7VrepWZ82HS7W7 Ut/ZtpaWRYWt4qtKl3eJvUbWt4mMfm73eAdG1HTfEGma7frHHDZ6hZQaTBd3VtaRStPBdtBqCTtm KS2tbWGWecHaGHynG5iPKLC+lt1tooP3N1ZmRYdWC7fs6zTOhtpUkYCez8xtwbDMhduGU7R7J8MN C1fxTrEOqa1rljF4ZA1OLXb6FvtBciyYtaXVhLDsiMml6fcAEIiJbRSDcuQrfXcIuPFHGHD31HLs TUxdHFUp4PC061P6tg17WMpVa1aulObo15+3rV6vNSm4urVqWToR6cO/rGKoKNOTlzJwimuWOqbb bs3aTu5NWe7fReiaqH8IaHrOseELU3MPxBl1K10NdSiVIfC+g2iOniRZo8/ZLiN7yLybcKrK1tuk YkGuy+AWra7ea/b2N1f201np/hzWNUW10iMR6YRqr6Qtvb36gqg1CKeO5JEaYjM7oCFwK+b9T8bw eK7nx7b/AL/TvDV1baPNoVqqR48O6fpUy6Xpr21lhjJZfY7pBc+UUlkWUyfMylW734Sz33gPwxZ6 xFFGk3i/4laH4el1mzeO687w1YWcmqXi2LEbfLluAytu2t8jBlV1wP2vgnjHBLxR4bzDKalenwbk tPEVa8cNUlToQ9hjqjlKnhoxT9jmmYxo1qUsTU5KGHr0cC5OGB5D1cHi6f8AaFCVO/1WkpN8raiu WbvaKW1SpZxcnZRkoX9w07zVdE8f6P4j8Esr6nrPh64n1/wjpXnww6kvlSXH/CS+GdM1ZoGXWgkC Ry24KrK625QEPGrN51p+vS+I9DHhjWBpGqXFsby602+vtXg0rX7nSlijd9A/ted3lhurdlnaK2u1 lgkBdFZWSMt5Vr8txofiaW90zVJ5l+1x61oOtRNJBcT2txJ9qsL5TuzFcqQFlGSUlt5EJJU16Hd2 8nxStG8XeGLa2tfiLpw3+K/Dto0SXHidChz4r8Nac3+tvNqSC+tYgSsmJ4R8zAflC4qzLirHZjh3 hFU4syunVwWIwdFU5vO8ppVpVIxpNwr08RjsvppLDUZKpRq4KjQWDjCOGnh8X5rxNTETnHlviIJw lBWftaad7LSSlOmvhjrGUUuW3K4z627stK+IdtpdvpOoxR/EvR4INOh0XXIbXTrnxfoVtp+21juN QhuXtLvXbazVxFMHja4hIVkWVVz4bqmgeK9NtfKvdPvXsY1WRZ7YDU7BcgFUF7ZNLFGy+YwK7lKs zAjcTWPf+bo0ulNbw3Wm6nbwrdS3LSTwXkd8t1NtIjZVNpLEIUA2/NnLE5OB1+vyT+ItEufHnh4X ljPFLbWPxB0/T5ZIbaDVLhM2niJYrYqq6bqEsMzSIV2wXiOo+WSOvks2xeXcYUMwxGKyurg+Lcso +0xCwdeSjjcJGjB1MTVoV6M51cdhYwg8xlSrUadehGeMVGMqGKrV+WrKniY1JSpuGJpq75ZaSjZX k01dzjZc9mk1edvdk5cx4efXbTXtIudI0+4u9SjvYja2TWsrreYG6S1kRkxJBLbCVXBP+rZicDmv uDXtL0XWPhlf+BDa3Omp4at7DXNFsJbe6vNW0X7JqUp1rULZrlWOp6JE+oW8aLGxkkhEkeMqhr42 8OeNvHd1f6dBBrer39vpMbyraNeFALNZoZ5bUXUkiNEZpooIg/mBx5pVWCsyn7u+EHhHxpqvhnVb z4h+I5NQtPFNnciz0WFppdU0K2vZkaVE1+dvNQmBEj8lA6ARKwkLjNfvX0Z8lw+dQ4l4ZybA47OM PxJg8VQxFTFYTD0sFh6E8NGNZTqrFyqRVfFLDJSozq1J1MLhqv1SLoc9P2Mhpxre3w9OE6scRGUZ OUYqMU4pO75rrmly7XbcYvl0uvhHWotC0HVrjUJNasfE1zFNnS7eF7mwtzDFFHPBfakRaAzB28yL 7KPLk3KPOaP7lYPiDxDe69Hd6pJbWf2rVdZ1K5JsYFQQgWtlLNDDGBlUUupO1QOSQQCQf1Et/hJ8 OYFVZvDNjqhj2lZtbe61ifKII0DPfyvgBQABgDjPXNeQfHjwf4A8HfDbUvEGleDfC1pqWm3+nnTR 9heCJrm/uo7SdHjtJ4jODbMxKFtjeQu8Mq4r6biz6LnGGQcNcS53iOKMqy7JcBQr5hXwuHjjJy/c xdWcnWrQqVa1WNF1oUuebSclGFlKRvi+HcVQoYitLE06dGnGU3GPPf3dX7zTbdrpX8rdT4Z+G8Hi dfFuha34Zilt59M1aymGryeXb6bY7pljlN1eXLLEymFpVMRYtIGKBTnFfSvjdrnV9C1H48/Dia61 jUJ5jYeL9Os77Um0Xw9qumRQxz67p2jyRxvqtnuFvIPP/dwiQTGJ1ZtvyZfeOfEN7eaffG4gt5NA lF5p1jDHDDo1nIghjD2mikeRHJuCkhVO7JJHBr1/4AfEzVNCW58GaZrFtpep6prtjrGgRatg+HNc uvJfT9W8La25RjZJfWZh+z3GNkNzaJ5mFcmvyzwo4g4aoSqeH+Ix2Np5Xn9StXo47kpRrYTNqeHh TwGMwGGnVVKFaXNisHVpVK05YmM6EYVaNVUpUfKy2vh4v6jKclTrNtTsrxqqKVOUIt2Un70Gm3zX jZp2a7bwR8aJ7jXj4Y8X/b9d8JfE/UW0jUoNVuzKnhvWNVgj07UH0/z1JOmzNdxSrbMBEsc8bxHd Gc+OfE/4YTQvqOsfD3yvEXgvStQl06TTtOS8PiPwjOXKS6f4p0K5T7Rbzvd28xFwBJHIFB3KoFfU niPwd8PviF41huYL278G/Eu80yDUofAvinH9jzSaNLd6TYJYwWCL5eoW76V5pihd2kif5VUNvWDx LDaeDPEkln/bi6T8UviHZvrnh/U7/TGl0jw1rlsl7YWtjdavZzOt/fS/2hq9rZTSlvsiSx/afM2x Y/dc58P82zzh3G5XxnmuHz/I8rx1SGAzujVowx1KOIjzQwlq1WLhVr46VCX9iY5RqQniko4jB4fD RxC9etgqlehOni6sa1GnNqFaLippS2hZvRyna9GdmnL4oRipHzHB4k0/4a21lb+KfO1f4i3Nq1tN q2lPZnxF8M9Cu4RF9kTUJ1ePU/FjW7tiK4ydOjfy1mjmciPyjXNG08xjUtI8R6hc6JM0zDxBeW1x NKt00kzQWuupZXc0uiahtKKA0ZSbJlR5Ewa+htJ0Xxn8SR4hivNL8Hy6zbXLWniaPWPDWkImo6tD dxI14l9ZxWeoaZeCVV+028hO4Xbz27scxx+UhPDPh7WLmGS11PTNTtnube/tPAaaxKL22KMbiz1P SvHS+S9gtqszMyySBSc4bAavyjPcixOIweV+2jGjwnUcoZbUxlOphsVzwkqdZylCvNY7E1FShLFy rVKFXmhChhp0cFSo0X5FehOUafMlHCy0puScZ3Vk9m1OTt793FvSMXGCUX1eqeLPFHhvW/DPi/wt 4p1az1jxN4L8Nz2FtaaldXOi6ld22nz+ENTil05irXEx1PTY7gM8RRfNbcu4BzV1nx9canoPhy3+ J3w90Lx7cvqfiW2m1GKS58J69psltFpImU61pXlw3OpmNnaR7uGRi1sodmKNXftoHhbxL8NNB1Tw bbaBqM3h/X9WlsdV1YMq+GdM16FJPtGseHDqyJaRnxBZzouGntopplliiCSlU5zWvgZ8WfE2haPp F35c1tYaE2opeapDqdpaXF/d32p6ns0qa3gdL25/s6W1j8gK7BUyGGxQfvcXkfHUaOOWSfWeIMFn GEoY2nh8PGGYZVVxGJlg62KlUoYyFXCTlUrUsTGlVhQrUVClG0vbRkod06OOcZqjzV4VoRmlFKpS cpODleM04ttqVmoyVkvtJ2wrj4ZfCHXtItfEfw68U+Iobq4uW02bw9q154dufEOk66IRcrYWsF5N Yw6xLJEkphlhvD5gRhFG7qQvh2t+F9J0K/8A7O1g+OtLv5SfJi1fwla2Uk53kGWOGTXN1whA/gZj u4ye/Uad8OfHXh3UIrGBfDd+Naa7sbvw9qepW8UWqWdkGuFe403UPIllgZUaS1uLcGWKRCUeORWW vTbfRfF/gGxs5Y/FuiWei69b3L2PgfxjrMWr2V55iqkkPh3xTYCRNHvGjd/s955mmTebABmRlJPw uIyHD8RUFisXwI+Fq+CUY4yph6FT6pCclTSqRw88Rh6adZ1KfPGjivbRqVFToYOpFQiuCVFYhKUs C8M4fG4p8i+HVRcorW6vaXMm7Rg1ZHz7deGtNtBC51LXHgusLazv4QvrOOWfJEltuvL5AZkIGQhc HPBwM17p8Dvgxa/EXVln0a416XS7SK6tdc8R3+l2+l2GhzTxxKv9jFL2c6nrZt5LkQoxVYWdbiUB UCseGfhf4h8e+I10PwNruo28vmQ3Hi/w/wCNbr+2JfDVpdTlJtVtZ3gez8T2LQsoSVAl2ZSYmT/l qe7+M/xm0f4faLB8Hvg1eRWcOlW11o/inxHp8aQzSTtLL/aVhZOqgRXclzJcGeVN3leZ5EDLtYj0 eGODOGOH4YvjrjjL44XhHKZKGHowlOVfNsapJxweAlUxM3FU7SePqVaUKuDj+5l7LEqU6WmFwmHo RljcdTUcLSdlFX5qs+kIXm9tXUcknBaaSu17x/wpL9lr+/pn/hVt/wDHaK/KTf8A9NJP+/kv/wAV RXo/8TAcFf8ASP8Aw5/4Jo//ADGa/wBu4P8A6EWH+5f/ACB+tfijxHovia6sjqMUnhm78RwYm0bx SjHwtfaxbottq2k6gbiAt4W8W29yAIrwIFmimgkk3pIVrjvE3he4t9JvrvVtOvVvLCSwsLLVre5f SPNhlDRQ6P4vNrdiKW5MexdO1OHfbXShY5WjxhNnwX478OfFzw7beBfirc2ra5qU5j0HWFlW2uNR vrFXt4Lya7WELY6ud4jXdvjvEBVkD43ZWmat4m+Gt5rPgzVbOfx54dtI5ILjwhqoSDxLZ6dcCaL7 RojSho9a0mSI5AtjImN26C2kU42zZ5JxRh8PxLjcbHNeHeKqcqazKjh4OvgMxnh3UeHzfJqf1j2c 4yk8ZQq5e6k/ZOrVjQrRniMbW66vscQo4iclVw+IVvaKKvCo435atJc2qfvxdO7tdqLTlN+5/s4T a9rdrq17q97e6hpOlTWljYx61B5l/b6tbxDeiXksQkkW1tn8rDu7I0u4EZFfWlgnmX1mn9+6t1/7 6lUfyNeeeAdC07w54T0fTtKgvLS0e2W/W3v5DLfQtqAF0Le6lLEySQxyRwjczFVt1XJCg16NoeX1 jS1JPN9bD1/5arX+hfg3whi+FeDuDsizLHyzHMoxozxNWU6lRyq16iqOnCVVubp0VNUad7e5BPlj flX3GV4SeHwuFpVJ887Jyd29W7tK+tleyv0XQ+Kf2zfh34hk+Id94v0GW4vNP1yC1stT0uKaXzRf 6VaJt8iD7k6PaxBwg+ffC5QNnA+IvEmvR6xd2/k6Lp3h+LTbOHTVsLCBonJty5km1B3Ae5vnmeQu 7AHkKAAor9lPjB4dtfFkfirSLixs9RlaWS6023v/ADvsp1exAuNMeY28iOIxdIgbawJR2XOCRX46 zeIF1ia50vxRb2UGqQXdxFb6lcQNEbaRJ3R9K1SaE+cLNJAUimLPJbhQHEkedv8Anx9Njw0wfDPi hn2c5fjpYDB+JmMxeMdOpBVKEsbh8Q54il7eUFPCKrVxP1mMIVJ0qtSq1Up0Y0ac5fE8WYCGGzGt WhPkjmEpTs9VzqV5LmavG7lzWTabeqSSZynnDv8A174ppk56+/H+evJrsvEeheF9L8PWFzBquqWH jFLl4dZ8KaraedE9tLmWz1bQtXtYRFc6a8BQguxL5yjHHPnhmzxz/wDq/H3/AEr+Gs3yDFZHi4YP GTo1K06VOr+5rU6qgqkVJU6qhJyoV6bvCth60adejNONSEdL/JVKUqUlGTTbSejT3V7PqpLZxdmn ui+ZfQnNN8388+vc8/4VQM2ep9MA+mTz9aj87Geh7jv+HFeYqPkZmg0nPXH0z69/XpTPO7ZPOfTk c9M1Q873/QUxpRnrn6+nt6d6tUull+YH7F/BDWRrXwn8DXpcySJokOnzMWyfO0uSXTnBPri2X869 ULkjgY/Gvlz9krVftvwmW0yC2k+I9YtCOuEn+zX6Ac9N109fTZckEcc/X/Gv98vB3M1n3hV4d5tP 362JybL/AGju3erTw1OlVfr7SEr+Z+y5VVjWy3AVWm5SpQv6qKT/ABPMvjdfx6d8JvHdzOSUfQbi zADlCXvpIrNAGwcHfMOMc9K/JCAXup3Vvp9hBNcz3Mois7KFd7mSTA2xxpgKThSzYwAm5iACR+mv 7Tj3k/wuudGsI99zrmtaVaF3lSC2tbW0kk1O7vL65lIS2so4rPMjuQoyBnJAP5rXmt2OiWs2j+Gp /PluI2t9Y8SbHin1CNv9bp+kI4D6fopb7zHE911l2RYir+AfpsypZh4m5JSxlf6tlGS5PQjPlt7W vXrYrFVpYehFr3peydGc6kr0sPGcZzvUnSpVfieLJqpmFJTfJSpUle27k5SfLH5Wb6Rvd6tJ7c+o WnhSCew0i7hvPEU6Nb6rrdqd9vpkbhkn0vw/OvDylcpc3qkbwTFbHy98knM2d4jCK0u4jNbudtu5 BM1ozOSz22W2vGZGy8bAq3ONrHdXNCb3A9t2MYzx+dWIbqRSojkmMyOjWggblZ96jIUgndjgbcHd jOa/iuvmFXFV6PLSWEwOGThSw8VzU4wbi5pqTftKlSylUqzvOpUUXeKhTUPlXUba05YR2j06Xv3b tq+rtskren6b4Z1u/u4PJ1bTIIoAs0er3t5D9gt9NRJJHunRVklto4hG7NG8QZMjdtYqG9CtfGKW 3w78X23hm3uRbQxaf4ZOu6hOZtR1O41i4uLzVLmwtSBFoNo2n2V4rRpvmddSVXlONteYW8F0mkwQ yX91ZLe+Y+sfZYYLp9Ru7y/RLHSm2MDdX4htLmTypDthZSXdAWx9aTfsq/E/xV4S8Mz/AA1tdBn8 F3Wmrq9wl9rmmrqGta7dmWK6v5GhXyWVbWO2jt1xEI1Rhsy7lv6D8N+BeNc+o59/xDrhXMM4zOll tX61SwcHjcc45hSeGpfV6cFKeFo4WUvaYjEKMa8p0oYdTnG6qe3gcJjK6rLA4apVqKm+aMffnaou VWS1io3vKXxXSjdnxFY300F3FJbxCR3H2ZrbaxS7jlURSW0katl1kU4IBHJyMEA19xeG7Xwj4Z8B +H7KO6j1GXQpNS+KfimwRY4pItH1DTtY0awuLW4upW869s76C2tlETNvkkDtmNg1emaf/wAE9hf6 RHey/EXU9J1++tV+3Wd54dtWjsbqVg9zbxva6jh4wQIw8bFSmSuAcBvib9l/4o+EJb27tYNM8b+G I9D0XwbJYaHGkevN4HXyLXW4ktLyLdJqioiXMRikY74So7Bv3Lw7+i948+FlDNOIOIPC2tjsPmGH hGhWpTwuYTwcG/rk6s8LgsTWxEF7TCYaOLhPD1HKnKWHUP3lSS9fBcPZ1l0alatlzkppWacZuKvz NuMJSkvgjzJxenu21Z8HXGivq2gTzaJPNqumeGZJ7yG/NjNHMNG1B4ZLu2voow5truzu90jx5KyJ dzTQsyIxrg7DVbvRNUstV0m/MGoabdw3thdwM8c0Fxbzb4pFJUFTuQEg9VODnJFdDqtprXwt8d6t orXd5puoaDqr26TNFLbyXVvFcLJaXTRSp/q3tGSQhlZWV2jZSrMpxfEOHt7TVLS4RtM1ZZbuKzSP edKvY5Vh1DTpJzGNipI0JjJJLQzwk5bk/wAX5xgXSrV60cJVyTibhqo6OMoKbvQnhKyo0alCbqqp Sjh2qeGcJe0qwdOhNVKjnUnH5OqrNtRdLEUHaaT+Fxdk1rdKOkbatWi7u7a+pPG/hvSfibY6d4q+ Hkfh6x1bUdFk8R+MfCV7dSWN9rFwszvqup6LeXcn2a6WC5huRJ9n8mSNmJkJDba8i8Iyz+EL/wAQ jf5Ftf8Ahu8nutH1Zgt4lvZXFpdo0tg8ax6sfsiX/kPH5tvcRzHeqozV5po+u6uttbWmn301tf8A h+8m13QJoJSl5BO6wLqFpZuDk+YkEU3lDIdrVxtJkOfc7TxJ4S8U2nhjUZZxpcuqS33h3xNo2qPG vhaLVri1uYRc6Df+RJN4Qv7mzvvPiKg6eGjlgKRiIZ/YsFm2SccZzQ4owlGlwzxbCFGpWkpQo4TF TqRpYTFVcNSUYrDVlWrVKmMoRqTjXpVfrVDDKtOrBenGrRxdZYiKWHxNk3qlCTaUJOK0UXzNuUU2 nF80Y3bOfk0a2i1jQ9U+Ger29rZ+IdU01rfTdftrSWO31dLphp4hkuopIJoxJLJLBazuJUe1eMtc NEHP6WJqFj4T0a0j8S+J7czQRQxz6x4gv7CwmvriNQ085DNEgBfJCIu1FKqOma/KSy+2+ENe0+HT 7LVLbXdNvYp77wf4lt4kGsR6deQahZLpd7bAJqV2s4neBlWOT7pgMm4o3QeLtd1Hxt4cvtT8aXs/ iGGHUpdT0bxLbskV94ft9UnksLjRdT0jys+Vbaktpm1Yq4hnaSzlaNWFfqHhN4oYXw0wPGeIw3Dc nxHjownHBrEVqOUYX6tTlUxcnT/eSwrqTqNyisPD6tW5aFZ4SlUhUq9+WZlHL4YuUcPfESSahzNU o8qvN21cW76+77rtGXImnL718U/Hz4X+GNOXU5PEI1q3lle3jPhuB9XxcRkB4J7mHEEEg6hZJFZl +ZQy818E/Gj45eIPibcpYQ2kGl+D7aZ5NMtOJmvZwrxi/vL50XbeGCSRVhVV8oSFcFiWrzHSRqnh yddO1SQW/hrxUsVt/aihbrRZQsjLp+swSsjRuLa7bMisokETzwuiliBzWpPrPhm9vNPuIYbSeKRr WcW8iXWnXckLypLLGySvBcoUYr8oI2nI2MK+U8UPHzxB8Qsk/s3HpcMZDXkqeNwmDozjN1ElUpwr 16lWdSth8RDlq0o/7PTm4zVq6o88uXMc8x2Oo+zqf7PRdlOME730a5pN3cZLVL3Vo/isYk08RLtE jICz7UZvMVFz8o3MoLMBkZI5x0Fbfhov5mtujQxyx6HdQR3UrMsFkdQurLTXvGuI1YQKkF5NlyDh S235ttc5qd+l7M939nitnlYtNFABHbeYCAXghA/cIR/DkgHkYBwJ9Fee5kvrO0kZrq8064trOzG4 i+nuJIUa1jCuALgwiRowQS7wqigsVFfztlUI0s1oumvrFpT9m4x5XKThJQcYuzU+ZxcYq757Rhd2 Z4MNKqt729ul9NPn2XfRH2l4Z1/w8+l+DNV0DWNL8W/GDR5r7w7peseI0urKw1yy0m5huptJ8OXl 9cbLbxJ9j1aBbK5uVje6hjZEMcrAH2Px98PvGHji48QaE9nceEp4LfUNf8B+I9BvJrTSNTl1CO1h 1bQ/Glk1yY7bXftTRSRSrtG6CR1ychvzv8PW7654U8R+Foyses6Lejxrp9vteO+uodJspbTxBp9t MoI+2rYmK5SPAJGmSYJOAPrP4MfGHWviF4dXwr4i1G11LxJ4XttUews9at45LfxXpcWlXMtjaSXc ixrBrEFxHEN077JoLTzGw8ZkP9ueF/G+Q8TYWjwjxPgamCp8SYag8LTwdSNPD4zEYOEsHi6GKnWV bFxzOUVRxUcTDEPE1nhsDaDq2jjfrctxtDERWFxEHD28Y8qg7RlKC5JKTd5Ko1aXMpOT5YaX+M1P wl4n1TTNJNy3i7UfGWgCz0PxvpEN3fX+m63BpMbWlrruk3FlEYku3mtEEpLNLjT/AJ2ikuWjbzfU rjWPDt7Fd62NatPFlhpGmz32m6lqz3mgW+qSQLBLqOvT6Tqc9yIbi3LSSQLbrEGlUPKFcJX0lqOp SeKbSTVfDXiXWtF8b+GlMPibwZrd5Bpt7rtkz3FnDfWnkNDDHczrcWL217vS3lxA04Dsc+batdfF PwF4b8aX8/iVvGOraf8A2DdbvEOpWemXXhwyO0qbbC3uZLmEeTJaCRJLhLa6aIqkUiMoH2Wf8MZf QSzDCTzCeGpUZ13mFKnQxtBrDYerOFWvQjXp4r+0eahUp16cWo08TDFVa1Cn7enVOnEYemv3kHUc Yx5udKM1aMW05Lm5vae61JdJczkldMg+CeleN9R1fWo7rT4bvwfeaTeW2q6u8i/2fpupq9pqemaT ZXtltt5447W3kiF7aCWVbmYPMY5uDh+K0mTxKut+K9Sv9QS81OCLRfDNlrGq+I9EhXTooLPTZblL O5hm0HVd8UKvOkjiQznz7dVkG7y/TvH/AI2v73T/ABJonjCfRdXl1O1i1jStO8c6FceHrmxvLmKe dovD2p3ka2e6RLlRDGm1OA0gzmsX4n6xqFsbK+0LxBqciLdW9/NpusWmnOkV6lzcPJcWy3Clol+2 QONkvneckSMkzJHx8Ri+L8mw3BFKhh8Nj8yWTV3iFUxLounXhUknSdOjJ0alSFBOv7ahOUlGtXlJ uvTqKEOGWLpRwaSjOoqMua8uW0r2tZe62opyunf3m3qmkdV498Q3ngXUk1Dw3pEPhnPkXek3EtpB qK+H31F5fNvtNtBGlvo8s09sSwczy/uln8yOR2Q8nok3iz9oWSz8HPeSXXjO1u5Z4rwWSWnhweGC qG8+1Jp0Kw6bNDdt5od4P3rMEjdZWIfkPBl98QPHXiXT/D3hVf7Z1vxBLKbvz49lrbRs0p1CTVY1 BibREjk8x/tKypgDYobah+wNZisfgnoc3w88GXXh7w34n8SwGTxt8T9Xu7Tw5Y2kzQuDb6DZyF5t odnW0ghiaODmZyJGBHz+QYavxvLNeIMbjsZl/hjQm6eNwijyQxdeoozoYPAqlOnhXjG1TcsVKnTo 5fQUamIqypqFGWFGMsa61ec508ui7ThbSTdnGELNQ59ryslTjrJ2tE4f4hfEvw/8BfDdv8GfhfO+ rapGhHjvxWbqaG7a4mH+lafp13aybrC8AZwgiYLZK2ArTvIR8/NoGvfFg6fc6E2kXTWUN0viHW9S jttGn0m3soEmOreNNe+zpA0DQMEW4d5JZ57dyBvk8scvcHwB4cmmd7m7+JOs+a7tIftmi+ExMxLN LPLI/wDaGunzMsSPsaPnlnBrE1rx14l161GnXF8tjoibUh8OaPEukeH4UR1kRV0mxCxzuHVG8yYS yllDM5PNfn/FfG8M5xVSjxDUhDIMHThh8BkOV1ozo4HDUJRdKi8cufDqUlG9bERjjq1Sc6spRoyk mvPxONVaTjXaVCCUYUKTXLTjG1o8693prL95Jtu/Kzs/+FbeFv8Aosvw9/79+Jf/AJS0V49kf7H5 H/Civz/+3sg/6IjB/wDhVmf/AM2nD7aj/wBAcP8AwKr5f9PPL8T6Emu4p7xWgSW3tkkVLWCN/Oni iVsxjzAq+bcljuZgF3OxIVeAPrzwd4ks/iXe+EPAfxNuLuLxHpOsWM/g7xRbl/tF2bcRTS+Gtbub UgPf/ZljImUjErAOdwZn+XfGOkzeD9Zhn02Dy9JvoGutA1iG7GqWGpWVyhVZ7G+VNi3UQd45FDNJ DNET8p2mu0/ZwY3fxp8BxO7OsOoX1yodmKq8WlX0u5VPAYyIv1wM10+GOIzThzxEy3hHGUViaXFO a5fl2Y4OtB/UcTh6uMoRjKdG1NzlB1Pb4KtTVJ0JRhUoynCo0u/L51KGOp4WS5liakKdSLXuSi5x tdaXtfmg1bl0a0Z+wpZugJAzkAdB/kVr+H2P9uaSSSf9Pts5Of8Alqo71jc9v54/pUllqthp2ueH 4bu7gtp9R1aC00+GWVUlvbpFe6eC2TOZZBbQTO2PurGSeK/3EwVSlhsbga1eUaVOFeiryairyqwU Vd6XlJxjFbuTUVdtI/XoOCnTbaWq773Vt++xveK2YeI9XGSMXshABP8AskH3Nfjr+0l4dj8LfFvx FHBGIrTXPs/iK1UAhB/acZa8CgdP+JjHdn23V+x3jJAnibVV6Fplk/77jRsj8/1r4D/as+F2qeMd S8P6/oF5pR1Wz0m4099Eu763stQ1WGO8NxG+m+fIouZka4dfL7mVQDkgH+Z/pr8BY3jLgHOpZXl8 sxzjhvOFi6MKaUq0oSq1cNXhTjfmm3CtGfs4pym6UVGMpJI+f4twcsVg6vsqbqVsPV5klu024y/B 3stXZaXPhKPWxdWS6drDz3MNtA6aVdDM11pjKGeO1i81xu015MhosgIX8yLB3K+H5+AOe3vxnrnB q1qHhrxRpMbTan4d1yxhVnVprnTb1IUZGZXV5vJ2oQyOMEg/Ke3Nc/8AaM87s8nOCevfp0r/AB0z HC5lTnRo5phalDEUYqKdanKFVwVlBS50pSjBLlg3dxjaF3CMYx/LZ86aVRNSS6qzt0vfXTpfZabW NYzD2/U/57U0ze5HfHHvge/esoz+h/8AQs0eeCBnr+NecsPbpcg0TNjr3znk9/8AI/Kmmbqcg5z0 6/h6VoaN4Z8ReIg8mjaTc3cEW7zbw+XaafGQDkS6heyRwIwA+6ZM57Vat/C9xcXUViusaJJfTv5c dhp9zc61elwcECHR7KdTg9TvwAMk4Ga9nD8N5ziaWHr08tqqhinalUnF06dV3S5adSpywm7tK0JN 6q+6NI0aslGSg+WWz2T9G7J/I++f2Kb4zeEvGtiSSbbxFYXIBxgC60zyzjnPW1/SvtSviz9kPRbb w8nj3Tx4i0zWrzzNAnv7XS0uni0qTytTRbe5u5YxHNeHDB0iLiPZhm3EqPtDzE/vD/P1r/aL6NOH xWH8EeBMLjoqGKwdLF0pxjOnUUXTzDFxUXKlKcOaMUoyjzc0JJwmoyjKK/V+HpTjk+DjOPvQUk9U 9qkrK6bV7aNX0ej1TR8H/treKJ4YfBnhG2unjiuV1LXdSt45GRZ1ieGy09bhVI3oJBeMobI3LuAy AR+f/nZ789evtxXvP7U/ikeIPjH4ghikD2/h23sfDsO1soHtIDcXuP8Aa+23dwp94/avm8ze5655 wK/y7+kTxA+K/GbjvMI1XWw2DxjwNH3m4qngIQwj5OijOpRqVdNG6jet7v8AOs9xP1rNsbUveMZc i9IJQ08m03879TX8/nr19wf0rpNIeOxCalNc2kF2ZfJ02OdpWaCTpJqjQ26lysJwIhxukOeVQg8L 5/Xk8AnoP6Vt6JbW93r2laZqdw9jbXmo2Vpd3XlNO1rBNPGJJI4o8mRgr52rk/NgDPFfkuVUZrG4 d0qUalec4QpucuSnGrOSjCU5NpR5W7puUVFpTbtFp+bTvzxsrybSWtkm3pr+Turb9D60+D/wJ8bf GrxJb6Z4bcWHhbwzpEcWoeL76Hbawanqtm9xOUMMSNqGpLPeSCOEFjEtuA8gGWP6zfA/9nvSfgdp zWGieMfF2sLcMsl9aaldwf2NNcbAjy22lCFhZkgDBSTd8oJJ5z8++HP2vv2ZPg1pVt8NdAj8VfYv Co/s+8urXw6FW51CN1ivr24M92klxdPcBmclc/wj5VFfWHwx+Nvwy+MFk134C8UWerSxKGudLl3W WsWo7tNptziQxjoXQOgPG6v90Por+GX0b+DMfgY5bx7k/G/jXTVSVeeHzVSnhJuMadXA5Xho1oKr h8NTpxw863JWq1lSlUm6dOSpQ/YeHcvyHCVKfssbSxmb2bbjUu46JOFOKeqiko3tJu13ZOy9WzjG fUf/AKqU8EfRe+OwzzSUrdeueAPy4/pX+gx9xd2bTvqeNfF34CfDf40aY9t4u0WEaokTRWHiWwRL bXLB9uI2S6Uf6VAMLmKXchGQNp5r8evjL+zl44+C9xqeg6laJrngzxDdJdeFvF1okht7XWrQSmys NQ3P/wAS27ubV57Z0f5ZXlhdXYRDH72dgOxAJHHHYn/Pv0rJ1vRNJ8RaXe6Jrun2mq6TqMLQXthe RLNbzxt/eU/dcMAyMpDIwDIQwBH8seP30TvD3xtoYjOKeDpcL+IKpzjTzbD0oReKjOm4Sw+Z04r/ AGqjUhJwVdr63h3y1KNRqn7Kfzud8NYHN4yqqCw+OtZVYr4r6ONRL4k11+KO6eln/LSbl433oWhk STKlWZHikVjgIc7kZT75GPau38Oa3Y6ilz4e1d7eyg117aO51GSMeUbm2leSx1FsOv2PU4TLOomU hJ4riSGdSzLKv2d+0r+yvYeB/HE+sad8S/BHhfwv4pE8+m6d40vr231CxZ5FN5ZRyWthN9osUnYm KR8MRIUO4hs/MEnwP0XqPjz8F2JYcDXNaXjuSToY49q/xFzzwM8TvDXi/N+H8wyrDV8Tk9epQr06 mPy6lTxNCUeVVIRnjY1VSxeHneMuWE/Y1OWUUpSgfj9fJ8wwGKqUJ0oylRbUk500pR7q807Ti9Ho 7PzaOk1XS/GOi6deQ6jp9xqNvZm01fX/AA9czpJI2liP7LN4v8I3DALbadMz2tzFLa7JrO5JEoaL g7mi+IItHntJPGGp3c/hnX9FXTLrxFaeU97qokM+oaY/ibRbm3ZIdYtBeW2WYSS7beSR1vIJEdOh 8DfDtm0mPQoviv8AB7X9b0aa41DwVdr4rnmniLiFL7wvKt7bwNBoVxErybUZ0WdiDC6yurdbN8Df iFf6dqupeFZ/AOtS6zDpmsQaBZeKPD832uVyLK8sG23UUHiPQmtRdiBriKKUeV8rNIS5/Z8l4B4w lDC5zkGS4/HTVLnWGjOnmjh7KM5VqFWOElD6wqjaoOhRcJyjiI18NLD0sVi8KvUpYLFNQq0aM5tK /KmqtrXck+W3NfaytfmUo8qnKJ806gNS8MeJVMdlqmj6PdQlbaaC4h17SLqyaJDbLeQyvJpmo6fO 9w0yokkOVuWACOQDm/ZtK17QJtb0SGL+2bSGb/hKPD+pTz2OnasovlsrbU9Gsb+KXfMy3FrFIsNy s1vOEZRtckew6v8ABn4o3WlyaTa/DXxB4etryKJmsND1v+3fDUd9aNEGVY7CW5kjtXm82URTvJGv mA20sJDxy+Q+MdI8RaDrGmWfifwh4v8AB88FvHa60ms6JfzLNHNaf2XcbdStoo11C2lt0WVS0Alj acqsjjp8DnfCed5CsZPM8gxmGyfENqH1vBYnDRoVsRKN5YeriMHhaVB0VCM7VMLRlisPVq0nTUac nDhrYerRUnUoSVJ7c0JRUXK1+VyhFRta+sIuUW1aybPMdX0mwuMz+HLO9jijt0fVbTU72FrrR7kT NDcFpCkaz6WJFCpKQrL5ypKA+C/GTK1nK8M/mRTwsDvikSRMcNG0UsJOMnDK6MeBx1zXRTeKdV0+ W60t7xbW3t57mxurSILNFIjGe2nk2zw7pAVIxtZdrJ5gjDHIwVvrUTXAv4FuTDJCYtRtpC0UcSzA LHLaPlLqzKycqAsikABuor8VxuGy6vWhUw0vq2Jbaqp04U6MZRTdqcKblKHM01d8kIyUtKdNqMPF mqTfuvlez0SV12Sva/yV10W3pHhzxNdWnxA8GX15M1gbu60+01O5gumksru01s/Ybq/VgT9nL6ff TGRQcxzq77RllHS2V7f+BtQ8Q6RqWj2et6vo03izRrXVru2tL62F4unajHMLuaGLfM50yHyliMpj C3Uz/eXI8X8L20t34u0bTYIbW+87W7EKN5FmYBcCZ33eYAkYt/MY7jlQrKSCGr1STx9ba78VRO12 llFZ+MNW+wids2GuJe3VzpenC+ihi8uC5itrhAZX3RSxl92HOX/TeE8ffAUa2JzCeBxrzaNPDyko zi/bU6MMY5KcY0nVpKjha0JrlnzpqMlVqQUu/DVfcTlUcJuqlHqteVT30vHlhK+/ndo+hvhx8UV1 Txl4cthLFdzyaDb+GtN+y2q2t5De6DpOnGXQhffZGLWk5ikBt5A1tJGsNzG8M4lRtiaDwD8StNOo 6fr0/hbx7I1rp2o3cFnqHhnU9Au1vZpLCDXrW0vH/s+wluLXMk8Ylso7mJQY4zKqH5gg8XweHdQ8 UyWNkdM1rw7q0OpvBbCGyii1Oynt7Vr+0sREBK8Krf2t1AVaCSOUTpsJIr6Wi1XwJ4kup/EWmJq1 jNqHiKSF7XSY4dQ+16DrNk32XUdA/tC5WaSze4mkkeG2CmzvBLbz20q/Mf6H4S4mlnuXV8mzXG4L OJUa9adXD4lVqcpU637n2uFqurFwxOFqYSr7STcnChiFCjZ03Uj7uFxLrU3RqzhVak24y5ldSsrx d1aUXB3eukly7XPEfEXgW303Wdninxf4LmnmmsdQsrzWdLkuLDVzPPdwulx4t8OWOy0lZ0Lh5/I8 0lWkihcc89pPw81PXvGEnw1tNIn1XUJrgXcN3aLdPbLpeoRRTyX9pLcytb6XocaMo+2GSWQyoVAY SGOvWfEHwZvfGVzBd/CrWI9Vt9QtdOeZ9VnW1ttOtW1Gey8Q2uraadPSKGGPULaa5mgfaIWWWKGI bo0P0hdeMvhh8NvhxqGl+Arzw/aa75F1okb6dIFMuvR2a3V28cUssktrZMxubi3hcJG/lN5SMR83 Bl3hjl+a4/NMZxFTo8McNZW/rKxUsS8ZVzfDv2jqYXBVa05UsRUny0mq9NQWHU6F6FadeZFLLadS pVniEsNhqfvczlzyqxd7xhKTtJvT3lblvH3W5M+fPFOueG/2Z/CWoeA/hrNba98SdTs1k8Z+NFe3 M+l25dFSKC2Zi0MCPMBFbrnBIuJ8kgV8JXl7eald3F/qN1c319dSPNc3l3K9xc3EshLPJLNIxZ2L Zzk/0o1hr86pftqsk8upPdTS3k11J5txLPIxd5ZZc/vCwbO4cENkcYrPBx9f5da/mjj3jTEcWYrD YLC4FcP8NZFGVDL8qpSfsMHSUndtNKVTE1HeeKxFVzrVqrlKUrcsY/O47GSxUoQjT9hhqGlOkvhg r+msnvKTu3K7v0JwxPc9Mde3oOelFQ7uMe47DH+c4/Knbh23fkOPw/D9K/PnB/18jhJKKZvHof0/ xoqeWXYD6K8P/EfU9C8N6r4TkstN1nRNVuorw2mrQNcLZXA2pdy2BGDayz26qrPGyujxrKjBwc+w fs/XXg2X4veBbnRk8V2Oq/b7gPpk8Wn6ppYElheR3BGpRSQzQWSQuzb5IXYbQrE/er5s8R6n4XuJ rJPC+l3unWttZRxXlxf3z3dzqV+T5lxdeUQFsrcOzJFGu4+XGpcly1dX8NvEt54UbxF4ssGVLrRb TQtsu3dKkd14o0g3McL9YjLaW88THvHKy9GNfbcF59icq404U/tXF0c9yvhCvRxFOpGm6ro0Mvm8 xnDCVZwoV04uFSMVJujzWtGpSjC/o4Su6WLw3tJqrSwslJO1+WMH7RqL92WlnbXl8mkj9zxM+ex7 Yxxn169a8n0Q2Xjbx/pfjaKWG+0rweNUsfDksdzErw6nLcSaXq18sVtcSLqGm3MELCCVhHJC9lIm PmIrkfjl8WdL8I/CaTX7LVksb7xrp0Vj4Vu4oZLtw+sWQuXvoooWDYh06R2D9EkePPWue/ZI8Inw 58KbXV5Lh7q48XX0+txu8c8Rh09SbWxgRLjlVJiuJiR8rNdbgTnJ/wBZMz4tw2eeJ/Dfh9gcLTzX CYHB/wBvY+sq1Nxw0qFbDyym9K0nUc67jXipKHK3hsTTlzU01+mTxUa2Y4fAwiqsIQ9tUd17vLKL p6a3u7S8vdkndH278QMp4gadcYvLKzuAcdd0IU89+Vr8t/2xPHb2Pjfwv4fSKz1C0sfD732qaXeR 74Wl1G+k+zSRzRMs1hfLBabo54JI5E8wclcg/pf8T/EOj6D4U0bxrr99DpukWWhsNSv7htkUX2Jx Eqk9WkaR1RFGSzOABk1+Bfxa8Xa14v8AiD4k8R65A1pc6pe+daWpdZYoNIRBDpMdrOjFLi2FjHDt lQlJCWdTzX539O7jaGQ8NVOHcvrtZrxfjcNimo2fs8EksY51VZxUa9ZU6UIVFy14xxMUpKnUS4eN MYqFB0IStUxU4y06Qsp6+UnZJPSSUt7M9x0z4oax4mijitPE/iOO+ht4obZLS7WLxbpUdumFjjhj Mdr8QtIwMvHKi6kq5ZRJhi3M6z4kurpLOHxt4N0HxpYXc7W1h4u8JW3/AAj/AIgnuHKhoHutLtVj fVUwN1pf2RmDfKRjDV83LeMrK6uUdGV0dSUdHQ5V0YMCrA8gjkYzX6HfskXuma7PqGqX895rni2C BUvr5dD2Wel2Cu8dhDrWtTybdX1iZot8DxxG5iij2vOV3Afwx4c4rOvFjiDL+Dsdncsvx2OvzVq/ s8ZhasIWlL2mX4uUqeJrJK8IRjKrFXnCthsJhvZL43ATrZnXp4Odf2c5/alacWlq7056SemitddH GEbHmEP7LnjjxFY2et+EYbq10+/dwmmePI4/DevWChVYNKkZljvrY7vlkjEbt3hXnHX6T+yH4402 GW81C88G6hqqlVsdLur7UzpEOVJa71F4bANeurYEduu2NjlpXZR5bfohP1VdxLKoBz9wtyWAbP3s kZz61zPinxjoHgnRrvXvFeo2um6VZRGR5LqULPO4UsltYxZ33V05G1I0DEkjgDJr+yIfRQ8Gckp1 s2zVYmCwdLnrVquLjRwdJxh+8xCpTjKNKKd6ijUqVKdPaMVFRS+s/wBWcpop1arlaC95ufLBaayt 076tpH5QeMdKl0PWb7SfiR4rN9f6LcyWY8MeFyt0IRHnYkcjwxWOg2zIUZVWOWYKw3QBq4e+8Yzi 2l0zQLODwzpEyGO4t9Okkk1DUIzjI1bWpT598pPWJTFbjPEIrv8AxtYWfxf8Ua/4z+H2spqeqa3e y3914F1dYNI8V2o2qgj0hTcG28R26xRpgW8ouecNATyfBbyO7sLmayv7W5sby2cxXFreQSW11byL nMcsE6ho2HPBA6V/njxnRzDKc0zKpk9KUOHsbXxEMJmUKjxVTG4ZTap+0zFTqP2kqDh9YwtKdBQb 5K+HjNWPg8VzUqtV0v4E5SUKl+ZzitFepd6uNuaKattKKZ+i/wCwzua1+I0mPkM/h2MHtuCaoxHH sQfxr7o1rVrXQNH1XXL5xHZ6Pp17qdy56CGxtpLl/wASI8D3NfFf7C9qV8GeN9RK/wDH34nsrVTn gpZaWsjY45w15XfftgeNR4V+EV5pUMwjv/Gd/b6DCobDmwjIvtWcDPKfZ4I4m/6+wK/0p8Hs7h4f /RXyjibE2j/Y2WZljIRlop1Z43GVMNT161as6VOPdzR+gZVXjguG6WIl/wAuqdSWvVuc3FfNtL5n 5Ya1rlzrusatrd25e71fUb7U7hiQSZb25kuH5PQAyED6VjGbBPcfh+eazjP/AJ+nXvUDzEE89c+n AFf5MVfbYqvXxNebq18RKU5yfxSnJuUpN9W222+7Z+ZNuUnKTvJ3bfds2kuDGUlRhvR1ZQVDYK/M GIIwRuA4Oc/Trci1S7S7N2sri7d5ZVnVtkkck5YyTxYwI5iWJUjoeQOlcz5/+HA/lk+lOF03zHqW GCSAx6g5BJ4Pv71VONSm4uMpQ5WpKzfxLaX+JdH01sNNrZtHbavqVjP5jwee93eG2NxLIwMcKWsK wvEOD9qkkljWUy5BG4oVLAsYfD/irXvCmrWmu+GtX1DQ9YsJBNaahptzLa3MLoQflkicZXIGVOVI 4YEVyktyjRWwU/OkbpINpGD5sjLyWwcow6elQCYngAknpwM/hg12TxOMhj6WYYarLB4yhKFSnUoO VOdOomqiqQnBqUaim3LmTUoy+G1klTnNTVSMuWas01o097prZ3/E/Yb4H/8ABQueHSrSw+Nlkt8s bGBvFug2+y8ghiiJSXXNMO2OeaQiMIbYh33FihNfpH4G+Kvw7+JVil/4H8YaH4ghYEtBZ3sa38BA Tetzp0xWeB1LIDuQDLDBORn+W1dVUaJcaezlW+3W08EaoPmQwzi7kkkBG750s9oYNjadu3nPcfDb WrrTdZt1068u4b+6tr+SL7PM8YjItp4r+OZYcSSJJpRkZAjhlntImXtX+hngz9PbxP4WnkvDXGeG o+IuUOFKmsRiasqGa05c/s+R4uKqxxL0Tj9ZoVK9RyTlWhHb7rKON8xwzpYfGRWPpNJc0m41U72+ JJ83/b0W33sf1NbW9CPwNcD8Qvid4L+GOjT6z4w1uz09IoZJLXTzNE2q6nIiki306w3+ZcSMwAyB tUsNzAV+AKfGr4w+DfEV74auvih42m07TNT0wLfWmvaolrqFle39reQyWdncyOz21xpbh4F3qwiG GIy9eVfFXxjqviXxhc67dahfTarazXVhqMd3eXGox2lzYXVzp8SwPfD545bKKF2Ug5Z3BA28f0Bx f+0Uy/CcOZhPhvw8r4bijD1fq0qWYYylKjh5qVSFWoo4em3inRnDSkqlBVVzSVTkp1EvdxXHtOGH m6GBaxMXytTmrJ7N2ivfs1tdX1d7JnvvxX/aEu/i94z8S33jiK5tdJttVS20XwzKkUcOk6BGs8Cr JP5O+/Vp0s5LqKRG4kkuLcxyIK+W9W06wZxLobTs4gnuNQ0mfa82mGKVg/2O7Riuq2PlGNldP3gV sOvyljY1HWbO90C5kuE+0XmoT2PlyCaeW50oWNs6SfaJBCovYbq5kmWMSSM9uiADduyeJttTuba7 trmKYw3NtdR3MU+4I0U6sp8wDGF4RQcgg45GMiv8t+OOLMz4xzavmfFGOXEGY5rUqYmrjZJ/W+av WlOzndR92moKlRX+z06MvYqnSqU4qh+bY3F1MXUlUxM/b1arcnN/F70r+S0VrL4UtEote7q6Vqx0 u9tb+OSeOezvLe4h+zOsM26B/NU+aVO1fMWM9DnB5HFfVGj+NLXx5oGoatBZWui+MvDM+m3M+k21 +1jp2paXaQXCb/DlnsaNr5ZoJp5rKXctxI26ArgrXxrdXW+ZphIWeUtLLkbNsruxkUDoRk5yMD58 ADFbPhvxNeeH7pru0TzJornTLuMmWSJEOnXv20oxRgMSKHQ5PPmFRndiubgfiivw3i6uDqz9pkmO U/bQ5IykpqlNUcRSfLOUK9KTUoOL5XrCopRbtGCxUsPOUG70Z3urdUnyyXVNbr7metah458UQ3Gv eHLi7vtDlltzqeh3Fqb3SL2ym05ri/srdTDdAyWstlJexruaTY0yhXcIK9S+G37W/jzShbeF9e8T +INQ8PTWVopm1HVDqF1pVzpkbyyvZTX1rN/od1DAguIXV13tmJo8sa+ePGN7qesanL42tIZbvSLk JuSFlkk8NOJfOm02eKF99vbK73P2eRwsbRzMq4MZVfN2mgghvHhumS4+0wpapF8xms545pJ3klIz G0e22XAwWMzA/dxX1uF4+404Oz943h/iPF4SnRlUUZe1nTji8C5TqU4ThzRhVpzjKqov4kpU4xca lKmqfRHH4zCV+ehiJRSur3aUoatJ62aevnqlo0kvrrxJ+0qLi6uLLxR8LfhX48jLhpb7V/DR0vWl V8F1e80qK1LhkdXSVWcMsoYMcjHL3fi/9l/xDN/p3w38deCnEMMkmo+C/EkOoWtvLIqmYLoHiQSm WBJOMpdruHQAGvC7rXX8SaTYaFcNZG/0KK/n0/VJspfatFcst3Lpd1dMP3zxlJTbK3cmJTnYD580 5ODk5I56+uMe3FaZr4m8S4vEOrmP9n8V4PE8klLMcqwOJrQajerR+tVKMsZF05z5JVI4pTnGMakJ QjJIVXMsRKTlU9nioStZ1KUJNaXceZx59H15ruyadmj7S8GfDP4S614p07WPAPxj8O37W97b3aeF /Hmm6n4D1SMGdI0tYNRL3VhK7PMsYaScDLhgCRtPnXxG+BHxd8Ja/qXiK98C6lc+HpdZuNTttd8N yL4l0M2U9697byjVdGeZVT7OyEM+xiMNjNfPtrdOsM8EaxLLK8c4nY/vUS1iuS8SOTgK/mAkEElo k2kEc+1+GvE/xI0+z0LXfhn4l8X2Ouuw0m60/wAPXN7LPdXv2hhBFHZWHElt5EseUmjZFDxgMQ+B 34TOOC+JMr/szGcF1skxeGqvFqpkeJlKLnJwpTf1HM/rdXESS9nJUaWY4aDV1DlSsrhWweJpeynh HRnF896Mm1dtJ+5U5nJpWdlUiu2xHrEGr+JtR8WeMJENpqM0Da/c22oeWLi+s5zbxX0jL5QjurT+ 0oJIljURspYK27ccev8AwV8L+LPHltb2OkQ6RN4e8PX9jeTatqbXcGn+EbVb2bV7iLasEZvfEFtd RMFXzGWWG5InQJEjL7jda/YaR4Yj1P8Aax0PwL4lu7nR47Wx0/RbBPDvxHk+0nzr611zX/D7xwbR cF1MBhubhmQuTDnIwNU+JngT4l22i6N8GPiVpvwah0eVTZfDnx3oy6Ro2pugKpZnxXprzWtzbTK7 rMl3HA03mHz5m4x+w5bwLkGR51TzfM+K/reOxtKVWpkdWpQy7P8AGzr1ueSxFHF1/qOFUpOM3QpY 7FYzEKEPY0KdSUZw9angqFGsqtTFc05rmdFuNOvNykn70Zv2ce/KpynKytFOzOp8UftH+BvDN4fB fg+Sxuf7dW603U/HjiKWCPUJ2uUe48hGZ5LFb2U7SWMcPnfIWCMw/PnVidLudU0PVJ7m31N9Zzq0 Kw297YwvAiyW2qW90ZPMluDLNJuT51MMx+Zsitn4jfCn4i/D0eZ4n8H3Wm6Vc3Ml5put6Z5eq+Gb hbjHmJpuu6c8tvcWRKI0SiXcgyDk5I8qa5nu5Q0ha5mkWOJWYs8jMqpFFkjmRgiIo65AAr8g8UeP uL+Isxhl3F2USyfGZROccLhJUKuEjhcPiIRVWj7CcYVZ+0cIyjWm3UqRnU9rKpen7Pycyx+Lr1FT xdJ0p0X7sOVxUYySurNJ6taN6u7vfS16/v7y8ljN7cG6e2hSzjlKrua3txsgG8IGlUIRtLZbHB9B ViWSWRY4o5JpHwEiiRpJXIzkKiKSx/WtfTtNspJ7m11G6ityhEbX8dwjWtgYir3LzRqC10xUiOFV wJZTsVhy6sutVisUNloRngjV5RcaozGHUdSDYVATE3+h2OxQVgVicuTK7nAX8mngpSX1vG4jljNt Nc3PWlKLty8snfbX2knyJac0p+4/McHbnqS3+cm1pa367fPQ6Xw5oN3FJqV5qukwxwW+iai9omty RWUU2oSxrDYrFbXUqPeSmWQBFQFgzBhgqDWbrOgf2ZJZXOZE0zUESeMho7q4hhVnjvPLlhbyb0Rv FNsZZBvXYXVCxA5mG6kMd3mVROyxSieaYLMBbyq4jgkdtxlLMpwDuxHnoDXb+GNC8XyJC2jwpE+r K5C393ptrDJaxo8sjzWOrXSrc2rxI8jyNE6rHDuBwTXrYShh8xo0MvwmU18RON589Ne2qqUqij8F OnTlNTSjBQc1ytqXPpZXBRqKNONKUut17zvddEle+i1elzqNn7Pn/QV+Lv8A4KvCH/yfRUP2SD/o NfBj/wAB5v8A5W0V9hyR/wChDk//AITvy/6j/wCvy6/+4VH/AMBfl/f/AK+Rwf2jpg59QcD+ldto mr3Nr4L8c2SCA22py+FoblnhieYGDULu7hEUzDdEuYXyFOGxznAry4XIHRuB7n/D3rrdPmf/AIQv xNJkeWut+Fo2+8CGaHxA6Y454Rs59K/MMkpVqWMrzpOVOTwmPi3HflngcRCa9JQlJS7xbOCi2pu1 0+Sf3OEkzu08SeLvinP8NPh5PctdR6K0PhPw3CoYtHFq2qBmnnyx8ySOKSJA2OIbJF7HP7e2cWj+ CvDFtatNDp2heFdDige4kYR29ppmj2So88jfwoIYGZvU+pNfkX+xh4eTxF8arHUJo/MtvCejanrr FiSqXbImmWBzj7wmv2Ye8We1fWn7b/xFbw18PtL8G2Fw0N744v5BfbHw40DSDFPdRnHISa+kskPZ kikXnOK/u76PGYPgPwk8R/GniGU8yzGt7LB4d15ylOrRy2hSwuCw6qO7VOria9PDO1+WGHho+RI+ 2yGs8DlWPzivepN2hG+rapxUYRT7OTUfLlXY6fxb8fIfiz+zn4u8W6Zokd7oHw0+JlrpWueF75i6 +I/h54jtTaCe/HJsr9rzM0EiYNtKkeCSrZ/Pf4naDdaLovh6+8P358Q/CzWZrzUfBWsTQRSajozz lRqXhPWLpU32V7bz43W7N5cjL58Kje+fWv2KNUtfEutfE/4IalKosvjF8Ota0nTUkYCNfE+iwSap okig9Zi8UoXuSR3rl/h745X4V6XP8KPFN3c6UnxCuLi61bWVZWufh5dZk0vw5qtrayoyid7i3Nxf hgHWzeHYQ2TXw3Gec1vF3hjgbirjDNfqb4hy7GZVicyjCMVhM6ynHx9jhZ01KlTlgcwy/GZOpUJ1 IU8PWp/2hGdOFDF+24cZXeaYbBYrFVORV6c6Uqn8lalNWi0rLkqQnSvFtKLXtLpRnf5lM5X72V+o A+nUD3r7f/Zw+Meg+AvBVn4ZsLL+2/HHjD4irZw6dG7RxWmmPb6RbDWdTnjRmWyhV7ooijLtG+Si K7D5Z8UeLfij4O1/WPDOu+JNWTUdNu2tbpJZYbmC5QDfb3du88LLNZzQMksLjh45gRwa7H4W/ETx RDL4z8S3F9p5Twn4F1y+huJdB8Phn1PVBB4f0q1luYtOWV1kutV+4H+fyiGym4V+O+GWPXAnHVPE Zdj8XgM3oxxGFryr5ZQ58JSjrjZxjPMJRjWpYelWV5wlGDcm4SseTl1f6jjVKnOdOquaMnKnG8Er Obt7TRpKS1Tt2PYfG37Y/wASV8Ua3aeFrvw8nh2y1q+g06caMJLjU9Nt7qSKCS5mnunMfmxJu3Rh GAYMCDXmer+KJPirayS61rmr61Lame8hbVJ2v/Efg9pSGuWihhVV8TeDy4zIYIheWajeY9gbzPG7 nx7Z6k8bat4K8HTGOKKEvpNheeG5nWJWAdjo2oRxNKd2WYxHJAzX1F8Mv2cD8RPhvqPxL0dvEngv V4Z5LnwfZW13HrJ1SHS95vLq0EkNrOjSSrJFbfvyXeA/MVYZ+ly/NPEvxbznNMpo55X49wtanicZ PLatTFUo0cPTtObpwrL6rBRbp06VOWIbnUdJUpQxKo16fTSrZjmtarRjWljotSm6bclaKs3a/uK2 iSctXazUrSXy7rOk6r4bvYIr5DE0kUd9puoWkwlsr+1ZswajpWoQnbc25I4dGyrDawVwQO+j+KFv 4ltrXSfijpsvim3tIFs7HxTZyx2njrSIUyIgmpyDy9ftIweLe9ViQMLPGea6po4fF9hN4XXVbPxL BYGbUvM0iBtJMN+0Je+vW0PUIkm8K66kzSrdR4OlX7RNve1uSJW+dtd0+70LVrrSLh45bi2kCK0B P7wSANHuiYh7efDAPFIFkjYFHUEV+b5nleacHyni8kxEq/D2aSVKrSqqliMPVqQ1lQrwTqYXEqnJ TdKtG7VlVpSg3TqT8+rCrhffotvD1bJp2lFta8slrGVns9e6ezf7Q/sseHdL8N/CWwfR9W/tvTtf 1jVtbtNTNjPps09tLLHZQx3VlcEmC6jWyKSBWdNyko7qQa+JP21fHv8AwkHxNt/C1tPvsfBGmJaT KrZU61qnl3t/ntvjt/sMR9DEw9a/Qnwu+n/Cb4J6LJqZWO18FeAba91Bj8pa4tdL+3XSAY4kkvXd R6vIK/JPV/EHgf4vf2hqV5HH4K+K+q6pLctO928fgXxObh2ld7ua6MjeHtadiEBLCzkchmaHJA/t Hx8n/Yng14f+E+XYnC5Rm+YYPCV62DlOpTVWjgqVOVTC0J1HVSnUx04zoRxFZSrfVp041alZqM/r s8k6OU5flcJRo1qkIylC7V1BJuCbvq5tcqlK8uVpNvR+NCc8Z6fhzkUx58kd/wAvy61Hq1hqeg6j daTrNlcabqVlJ5VzZ3UflyxtjKsM8SRspDI6ko6sHRipBrKefkZI79wa/wA76mCrUK1ShXoyo1qM nGcJxcZRlF2lGUZJOMotNNOzT0aufBtOLaas1o09GvJrv5GqZ+Mjt+HBHU/570hnwOTj1Jx/n1rW 8FeDPFXxE1+18M+D9IuNX1a6OfLiAS3tIMhZLzULpzssrJNwLSOQOcAMxCn9Xfgt+yR4K+HKWmt+ LktfG3jJAkvmXcIk8PaPOADs0zT5lIvJlb/l4nUkkZSNK/X/AAs8C+NPFfFt5NhY5fkWHny4jMsT Fxw1N6OVOkl72IrpO/sqSajeLqzpRkpHq5Zk2MzWb9hHkox+KpK/KvJfzS8l5XaTufCPwv8A2a/i n8UVgv7PSR4d8OzFT/wkPiNZrK2ljP3pNPs9hn1HjoUQRn/noBzXj/jHRJfB/ivxH4WmuRdy+HtZ 1HR3u0iMIuTp9zJbm4WJmJiVwgbbk4DYzX9Bqv8AKAcYG0KoOAqrgKoA+6AMDAwBivwQ+PEo/wCF zfE8oflPjXXcAY6C8kz9eRX6v4/+AnCnhFwVwtiMpxWIzPPMwx06OKxVeSjGpGOHc+Wlh4fu6NNT jdJurU1tKtJaHp57kmGyrB4WVKcqtepNqcpaX929lFaJXV92+7OFN4TbGLK484SZOPMz5ZQheOU4 Geeqj0q5pWoJaX1jcNtdYZlllGWhbZgpKvnrkhBFuYYHBBwDXKfaOgOABn8c45P51YiukmuY3u5H aIFfNYBS3lxqcIMsOoUL171/KNCE4VqNSLXtKThytpWXLJNXbutHvdNPW66P5iLakn1TX4H0rp11 c+ItMhRtXjeXwxpmkvr6XVhNPM2lWYhlS9tZgC63NqQsauQoMVzGGOMIviut3hudQv7yJ5LpG1G7 33sskkstzunke3muUm+ZJTFwSxO4oSctuznaf4u1jRdcTX9NupLbU455ZU3F5IzBOphls7iOVj9o tXtdsbK2dyAAnIyMi7ukld54lWEXEjO1sJS4jY4kwGY5dMsducsMFTyMn6fO81o5tgMJTUJLG4ec 41XJzl7SnFJYepBznJQlZyjVpqMXzJ1FOXtqkafTWrxq04LXni2nre605Xrez3ut7631aVpryTMm HcB/vAHAI4OMLgFcgcY7D0qGS4BLYLfMql953Hd/ERjsT+PPOayWn+ZseuMjrz1yK3NS0xk0jT/E VhFL/Y91ImlXE0txBI1vr8Ft595ZlEIcRNCY5omZMbJtm9mU187QwFfEQr1acXUWHipzSTbUG0nP RWUYyklJ3VuZdL25lFyUmteVX+Xf5FEz9Md/pn8ff/Gt3UNDutP8M6D4ma+sJLLxDeazYQ2UFyza hbTaG9iLhr62ZAEhf7dbtEwZgec7SOeL88YPQEDkc/h9K9Z1K3lm+BXhjU47y2+zWHxH8TadcWk9 q0d817qOiaPdQPYXuwi509LWwczruXy5rqPKHIavZyTKaWNw+fudJzrYHAvEUrSS5ZQxOFjOTTlF TiqE6ycfeavzpNxNKNNTjXbV3ThzLXqpRT9dG9PmcNp2syWF0JN032adVttQgglw11bMSsi4f5TL tOY9wZVcA7SCQY/EAtYdSmNisa2zYdY4RIBCWADRTQyktaXCvuWSIlgjgqjum01zKzlWD7gpRtwY nIVl+ZSBjk5H+NdJ4V8JeMvHt+2m+EfDuteJb2WQGVdMs5blIpHbIkvLwKIrVdxJJlkUdTnijA4X G5jCllWEwdTMMVWqL2NOlTlVq8zTThThBSk+dtNxitWr73vMOeolRhB1JSfupJuXmkldu/ZGGLjZ IsikgowYFCVdWU5UqwPysCBjvkVoaVpOt+JtSXTtB0rVNd1O7lwlnptnPe3Ukkr5BaO2RvLyx5Y4 UZOSBX0lb/AHwV8PYrfUfj78SdP0S5YpInw88EvFr/i+6Jb5ba7nh3R6eWBCkqr4LcSAivoq5/aF 8H/B/wCGr23hb4ZzfD+/1q1ntPAehXXkReKb6wEM1s3jrxU89sz21sLzP2aOczyXckDn5Y13D9e4 f8HqUHiq/iJxPR4IwOXUfrFbDKP1zMVFW5Y1cNRk4YGdV2pUY46pSr1KsoQpYeo27erQypLmlmGK jgoU1zSjbnqW03jF2g3e0edqTeiizwfQ/wBmRPDWnReJvjt4z0r4baKQrDQYrmDUPFt7ESC0CQRu 0VnMwBTb/pEi5yYwRWhN+0Z4H+G9nd+HfgT4Ej0a3nt5rabxtrjvceI7yUo0cd9+9BkkQNtLRM0U TBdvkgdPj7W/EeueJNQl1bxDrGoa1qM7M0t7qd3LdzkscsEaVv3Ue7OEXaq9ABWSJAeMjrxggkD0 A/OvIfiHhOHYvD+G2QQ4XSTjLMsQ443OayatJ/WpwjRwSmt4YChQlqlKrO1zF5hCh7uXYdYa2ntJ WnWff3muWF+qpxX+JnY+IvEeoeJ9SbVdSu76+vJos3D39yblhcEGS5ktgiILa0acyOkSqFjDbeQM 1z4kHc56HGOh/OqAkA6Zzkg9sZ9x9aeJTjqB14Pb8SK/L8TVr4yvVxOJquviK8nKc5NuUpPeTbu2 3uzzZSlKTlJuUpO7b3bPXvAXxq+JPw3Mlv4X8S3cWk3Py33hzVBFrHhnUYyfmivtB1NJbadGXgny wwzwQea9Zt/GHwA+JsyN4w8NXXwT8Ys26Pxf8P1nv/BE99gmK61TwlLKZ9HAn2uz2EzKuOLcDivk oSH6j8qswDd5jsp8tIpCzFHkTcUYIjFFPlszDCk8A88DmvrMn444gy7DUMpxbpcR5BRfu4DMofWs NTW8nhpSlHEYCT3lVwFfC1XbWbWh10cdXpxjSlbEUI7U6i5orvy6qUPNwlF+Z9E/ET4LfEPwho9r 4h02Sx8eeBoriS+j+IHgm5j1rS3vrthcF9Ue3T7Vo06qExFexxMrlyOWNeDwLJfSSyzvKYoIxPeX GRJJHArpHkb2+aQvJGiA9WcA4GSOq8KfFHxl8PNefXPAPiHVvD8kixxzW6zxzWl7biJI3sdUsGQ2 +qWhClSssRV15Kgnj6FXxt8IPjJo7aL4w021+B3jbUjHd3PjbwppCSfD3xFeNNstF8VaFbo9xoMD TwK3mWTGBZWdzaYGa+gWTcHcXV60sizWfDOaxTcMtzKtGeDxE4rlpwwebTdGFFSaVqWZwoqnSVv7 QxFWSibqlg8W37Cq8NVSdqdSV4Sa0ShWbSSfary2X/LyTPDtP8SNoGnHXNLstE0+VJY9O0iwlsLD Vr+RjbvJPruqTalBKzsvyeUqiNDLMCsYiiw2HLrt5d3Gs39+93d6hJZNHLffallkjivBDFMkU6KR FHLLO5kwNpjZoFCByR0fxR+FXjv4bixk8S2kN9o+q3F1daL4w0KeHVvCniC1eK1SGfS9dscxSjZG B5LbJIQu140ORXn2hxadm/1LV/31pploZ4bAM0f9qahLIlvZWTyoQ0Vt5shlmZfmMVs6KQzhh89m tDiDLsxjw9mdCtk9bBLmlQxClRjTlKk5yxDo8rjFODUoOlHllSjBUudyUnhVVenU+r1IypOGrjLR J2vzctrbaqy2StfQqfbp/wDntP8A9/pf/jlFXP8AhKbj/oFeGv8AwQWlFfPewwn/AENJ/wDgqf8A 8n/XzOb3f+fj+70/vepTu7u3luriSzgNpayTSPbWrTm4a2gZiY4DcMoM2xSF3EAttyea6Ky8VQWv g7XfCzabDLcaxrWhavHqxkYTWkejW+qwvaKm7a6SHUQc442Nk8rjzj7WexHccnH5Un2ojqRz7k/1 4rPD1MTha1avQcadWvTrU5WpwtyV6cqVWKjy8sbwnJJxScLpwcWkKM5RblHRyTT0W0lZrstG9tuh +pH/AAT40tGX4meInXLg+H9DhkIOQp+36hOoPbJW3JHsK8Y/bg8Utq/xrk0dJN1v4V8O6RpiIGyq 3N8j6xdNg/xH7bCp7/uh1r6a/wCCf1qE+E/ie+CjfqHjm5Qtk5ZbLSNMjQHjqDM2PrX52/tF642r fHT4o3hfeF8XalZJuIIEemGPTogOvRLUAfSv6+49Usj+if4YZJQ/dyz/ABrr1bfbp+0x+Ls11tOe Hf8A26ux9bjpOhwrllGOn1ifM/NNznr83EsfBDxHfeGvi98Odd0/Uo9KuNJ8W6RfPqEwlkgtbS2u Vmv5bhYFLNALFLjeAMbc5IXJHvP7dPhS20T43XXjPRJvtvhH4t6JpPxB8L30YAtprHVLOKO4t4do wixXELKEGNqsoIr5R8JMbbRfG3iV5PKbStEi0fTyFB8zU/FNyNKZFfOUddFGtSBuxjHIOM/ZaTf8 L5/YkbYftfjz9mDXdxX5Xu7r4a+JH5x/FJDaXq+4VIe2a/M+CcBHiLwv4w8O50+bNq0JcWZT70nz 1MojUw2Ow0IJuPNXyz+0cS0o885YChG7Til5uCSxOWYzL2v3zTxVLzdJctSKV93T9pLa79mvI8in v7b4vfC20hgsjN8UfhPpp+13CyGS88W/Da3Z0Vo4+Wu9R0dpLfcpy/2Ml1JCsFoWME3hn9nnVtfT VLayuPiR40tvD0dksf2q71jQPC8LX17HvC40mOLVri2dyctOPLVcDOfD/A/jnVfAPizQ/GGjCKS/ 0O9W6jtriSVbW9iKNFcWN55TBpLSa3lljkXOGWQg5r6t/aY0u21n4dfB/wCJPgTQxpXw2vdJ1VZb CA7R4f8AE2v6xcajfWU9uANts1xFPFDN8wItVTIXygfPyaFLiHhriji6P77i3hrKHg69KnGcZ1sP WnhcvhmrlSiuaVDA1sRhsbeSc5Rw1es6qr4m+dGSr4fE4te9isNR5JJJ3cZOFNVbrrGEpRnrraMm 3zSPDfhJ4Evvin8QvDfgqzZ401S9D6pdRqD9g0a0H2jVL0kD5StojhM9ZJEXvX786Tpmm6Dpem6L pFullpmk2Ntp2n2sS4jtrSziWG3jUDHSNBk9Sck5JNfnZ/wT98BCHRPFnxNvYAbjVLseFtCkkByl hYeVd6xPESOkl7JaRkj/AJ82HHNfo3kjrj8z+gxX9r/RN8O6XC/h+uKcTQUc540l7bmatKngaUpQ wtNdlUftMS2nacatK93CJ9lwrglhcD9alH99jNfSC+FbddZabprsflD+2n8Iz4K8VwfE3w1C9roH jSaa21xLTdDHp3iWSJ2uSfLIEdrqFsskhXhTNHOCMOorxT4NW9p8U/iD4F8H+IY55dTTWdPex16C MT3FzpOkONQvNG19SQbyzFhZzLb3RJltziJ/MgKiL9wPGnwQj+LvgDxB4Z8TywaB4d1qyMcet6gF V7K+iIn0/UtPt3Ia4nhuo43UDAcAoSAxr5j/AGXfCv7OXgTxl4yg+G/hfxR468YfDwnw9rnxG8er /Zmn/wBuXct1a32neHvDEJ/cRCGymLySkvsdQCQ+T8zxl9GjEf8AEasizajjsDkHA3G+Jhi8RhcZ OXPiK1CTxOYUMFgaMKleo6lKnLE08Qo0cPh51JReIpqMIz58Zw5L+2aFaM4YfA42SnKM3rJx96pG EEnJ3SclKyjFt+8rI0/2pZtd1PwVp/gDw/4U8VeJJfHl9LZXx8LaVqGo3WkaZp0S3cWoPFZxETQD VTpgeFiBNCkyKd2K/N26/ZC/adtjJn4L+NrmJFDrPaaZ58M0LjcksQDbiGTB2sqyLna6q2Vr6l/a J/bR+KmqfE/xZ8L/AAR49m+H1joM1rpWg6j4cFrpVtfeIILdTquj6veCMtDazXkhgt7lWQW89uFl zDK7x/H9t+0/8fEefw9r3xa8f6VqFnfXZtdXm1/VLfUdJ1VnjjntdYKy7rrSmkh2ujqzWzv50Xyi SOT4LxzzjwU4v48zGtnmO4kzaWVzlluHrYGllWDwtKeElyVsM5YieLqVFUruriKNWpGhG1Wyfs3K dLgzvE5Ni8dUlWniKvsm6cZU1ShBOGjjeTm3eV5JvlWvbVUPFOl+NvDujDw38XfBfjHRLrSLWRfC mt6rot1aahpzJyuh3lxfRoNQ8Pu27YDIZLR/mgzGzxnlPhl8OfE3xb8W2HhLwvArXE/7+/v5VY2G jaajKLnU7+VR8sKAgKo+aV2WNMs3H0T4U/bf/aS0HVo/BfjabS/jBp97eWunXPg3x/pNh4hXVmvW jS2gtdRij8xzOk8Xkyo7q6zK6kqQa/X74b/Bj4c6Voeo6x8NfCOn+BfFuvx2ms+MPCNrdSX8SXot Y/PsdFvZwGbToLhpvLhUBNzswUFhny/DjwA4V8aM/oV+GOLMfisp4acIZrgc1y5YHN/ZRU3Sw+Hx eGr4vBY2bVKVFuVTDYuhRj7mGqRp04xyy7IsLnNdPDYupKlhmlVhVp8lbl1tGMoOUJvTlveM4x2i 0kjzb4TfCbwl8HfDUPh/wzaCS5lWOTW9duET+1NdvVX5p7uVRmO3DFvKgU+XEvABYsx9TEg5yAOv OT+FQskiMyOCjqxVlZSGRgcMpBPBBBphY9lJ/P8Awr/Q7Kcly7IMtwWTZNgKeW5Zl8FTo0KUVCFO EeiXdu7lJ3lOTlKbcm2/0CjThh6cKFGEadOmrKKVkkunT57tu7ZcRkLoMnJYcY9+e/pX88/xT1P+ 0fiX8Qb8MGS78Z+JJVYNkFDq92qHP+6BX76+IdZg0Dw/ruu3LiKDRtG1TVJWc4CpYWM90ST2/wBU APc1/OJd373tzdXsxzLeXNxdSNnJMtzK8zk8f3nNfxF9NrHw+p8AZOpXq1KuPxMl2jCOGpQf/bzq VEn15XbY+M40qpxwFLq3Ul8kopffdlkyg459s5Hr79etR+Z1+Y9D7f5PNZ5lPUEduBTPOIB/xz9c enGa/gFUX93yPgzSM5PLMc+pwSfxPsP8Kct2VjkTCkSbMkgErtYt8p7E/wAuKyTNnPP5nH+Hqaja Yr3B98jrz19atUuys3/wwami04yeeD0OB1Pb/PrXYaF4ssLLw/4i8K6vptrdWHiCbTbu21fc8d94 b1fTHmS21S3KBvtNm1rd3cVzblcyRyhkYSRrnP8Ah94g8IeH/FVjq3jjws/jTw7bw3YufD6Xz2H2 q4kt3S0kknjdS0UcxVim5d2O+MH1a4+PfgzTLlp/A37P/wALtDZHL2914hj1Txhdxn5gjeXqN2sC sAegjI4A7Zr7bhvKcrhhv7WxvGGEyaq5VsPLCTwmMxWJqUalJQqSUIYZ4Vwqwqzpx58VSqKUXKPJ JRmdeHhSS9rPFwou7i4uE5ScWrN2UHCzTa1mmrN6aMw4/gN8Y7y/Wy0jwD4g1uC4cjT9Z0uxlk0L VLUgPBqOn6tNsiksJYWR45GK5VxwG4r6B0H9nPxLp/w38UaN8XfFfhT4b6Va6poninSX1LXINTv9 AvfMbSNVuL3RtNlO2G7064ghVTKC1xBD/d58t1/9rX40eM/Csnhtde0/w2LBXuWm8L2UWgXl/pUY WP8AsuFoJCII7eNtyJB5bPFGwYnYM0P2ebHRtd1P4k+Kfii15qfw20bwPdN46urjULz+0ry4utQs Z/DunadcifzJtXm1ewi8pd+CI3zjNfq3DuA8K4cSYTLeGcDmfEss6w+Jpyq5piKeX5bQhPC1XWeK pYSlXxc8PhVF1a1ZYqjKjCn7eClKEJy9PDwyxYmFLDQq4n28ZK9WSp0opxbfMoRlNxha8nzRcUuZ XsmdG+p/sqfDgJ/ZuneLPjn4jgYFZ9YZvDHgt5wSBiwhAnvLfdjCsJA/r2rqYfF37S3xQ0G1bwXp +lfCj4YXd3cabayaNLpXgLwzaQ28SC4N5rV5LFcXkCI5BkTdvcuqAsCo53RfHXguw0/xP4z+B/wR 0DQ18BadYz3Pjf4o+JJPEV7Zz3s4trMaRo12VsLjxLM3mmOJfNkKxNIiAJXzb4++KPjf4n3tnqPj fXJdZuNPtDZWQ+zWlja21qZ5bnyorKwhihXEk8nzbN20BSxCitsz4iwHDuXwowzJYbCZlTbo4Phb C1MpwmJowrexlLEZ5mFGWa4yClSrU5UpUMTSnKHu4mDUkipiadCCSq8kKi0hhYOjCaUrPmr1I+1m laSa5ZK60mj1KDX/AIf/AAuubvUdDvm+JvxNtLz/AEHxNqFiy+A/D15FJIJtU0y01CQ3Pi3VUkAa 3nukjtVcCVYpcKT5H4l8XeJfGWqS634r1/VPEOrTgiS+1a8lu5wjO8ghjaRsQwh5JCsaBUXd8oFc cJR1GSOmRnA9Dx+H50eZzjJ+uSB9DX43muf47MsPDLqVOOWZPTl7SODw7nGi6j/5fVXOc6mIxDXu +3xFSpVULQjKNOMYLyKmInUiqaSpUVqoRvy3/md23KX96TbtorKyNLzOeTjrn0HHvTxJx0z9DxWY JAO459Pb1z04/GnCT1wfUDqPXjua+ddP1RgaYkOOSR9D/L0p4k4znjpznrgnv9f0rNWTnrg+/I+m aeJMnk547H+lQ6b7JgaYkx1z+HH9fYV9Q/sop4e8S/EO9+FnioW6aN8W/DupeCoLydUJ0rxJOovf CuqRyP8A6p49ctbVSwIJSZl5DYr5RWU+wA7E1r6JrN7oGr6VrmnSPBf6TqFnqdlOrMrJc2NxHcQu jcdJI16cV9Bwhm9HhvijI87xODjj8Fl+JpyxOHmrwxGFk+TFYaf93EYedWjLspu3Q6cHXWGxVCvK CqQpyTlF7ShtOL8pRbXzNjxX4d1Xwb4l1/wprkElrq3h3Vr/AEfUbd1KvHc2FxJbyAhuQpaPI9Qw PesDzSAVyyq4G4AkB8MSNwB+bnkZr7x/bs8N2mtap8Mv2idBtlTQ/jp4K0vV9UaBcQW/jPTLSC11 2BivCyuRG57llfjrXwB5mMDdjjnOPzHrzXp+I/By4G42z/hqlWeKwODqqpgq/wD0E5fiqcMTl+JX RrEYOtRq6aJzcd0aZjhPqONr4ZPmhB3hL+anJKVOX/b0HF/M9t+Gvxy8Y/DeG50SI2XinwJqrY17 4e+KoDqvhXVo2AEjizlbOm6htH7u6tminjIBV+MV63d/CvwN8YNC1bxD+z5Le22t20Eeo+IfgxrN 0bzxNpcdvJLcXl54LusD/hMNHjgaUrAgF9EsWZI5ADJXyVptmlys97ePNDpViI2vJ4UV5meVtlva WyyEK11I/AycIqtIwIXB6LSfHmreHbyxuPCN7eeDpLS6F0L7Srhv7QE8RcWtzJqMSrPJMsbyBgrp H852RqOK9Th7imEMBh8l40oPPuF4wnDD05NLMMEpXi6mV4qf+7U1Nt1MPWlPA1nzt4d1kq1LShik qcaOMj7fC2aiv+XkL6XpTfwq+8W+R6+7zWa6z/hX7f8AQv8Ajv8A8Ed7/wDIFFdv/wANpftPf9Fe 8Sflp/8A8h0V7P8Axpj/AKGWef8Ahiy7/wCiE3vkv/Pyv/4Ip+X/AFEep8o+f7jAz379+3NJ5/Oc 8dxk55649Pyrr/D3w81LxF8OvHvxGt9RtIdO8A3nh6zv9Okjna9vX8Q3DwQS27qdkcUews+45PAU HOR5v559f/Qvevz/ABeS43A0cvr4vDSo0c1o/WMPJtWqUVWq4dzVm2kq1CrCzs7wvazTflSpzhGn KUeWNVc0X3XM43/8Ci1rZ6H7gfsDMF+BZdRky+N/EJY9yVi0xAD68KPyr8kvihqDXfxK+INyxIM3 jbxTIck551u9/oK/V7/gn9crJ8CXQHJh8d+IVbHJBeHSpefbDCvyA+I0zL8QfHanIK+MvFAKncCM a3fDGM9a/qTxmp83gZ4CU4fwvq1VtL+aOHwy/BuXzufUZy/+ELIEusHf1UI/8ExxcHBBY4OMjLAH GeSO/t/9evrX9jH4s6Z8OPjNYaZ4pdX8AfEuwu/hz44tpz/osmj+JF+xQ3cyNwBb3rwSbuSoDV8Y mc+v6n+lKty6MGVyrowZHUkFWUhlZSOhBH5iv5x4Rz3H8HcT5FxRlaTxuR4mliIQnrCooSTnRqL7 VKvTcqNWOqnTnOLVmfO4PE1MHiqGKpfHQkpJPZ2esX3UldNdU2e7fHr4Zan8Ffiz41+HWpq+3QdX nGl3JDBb/Q7pjdaNfwsR+8jl0+SFsjjOR2rtPjH4y8Y6DovgbwAPEVxBol38KfAN7rfhm0MH9mx3 r2N1PamTYrB7iSwntJpGRl3NKu/LoCPe/izbP+1L+zJ8PfjfpKxTfEz4Qzab8KPiyMkXF5ok7xW/ hDxXfFVJ8gF1illYEhpH/hSvPbH9nbxv8eP2i9a+H/hGJYtC8DReGNC8W+LdR3QeH/DWleGdB0nS tQubu7cBSWe0uRBEDumYgqNuSP2jOfD3M8Jm2dYLw5wmLzDK/Earlc8iWGnNVK2XZpDH4l4Wag1z ywcsNWwGN52qVOeGxDqrltKPs1sBVhVrQy2M6lLMnReH5W7yp1VOXK7buDi6c7uycZX7n6vfs2eB L/QvhL8NfCOmWLy348Naff3kaJg/btaQ6xeyztwEAmvWBJ6CMZ6V9RvH4c8CgG78jxJ4oUZFsDv0 nS5ev78/8vEwOPl6A9h1Obe+ItJ8JaXH4T8DfJDb20Flfa+Ri7vRbRLB5duw/wBTb7VwMenHcnzd pS7FjuZmOSWOWYk8kknk5r/VjJsuy3gvJspyPLYU8bjMowtDDRq2UqGHWHpQpRjQi7xq1IqCvWkn BP8AhxbtM/VKUKWCpUaNJKdSjCMb6OMeVJWS6tW3ei6Lqb2seI9W165NzqVy05B/dQ/ct4E7Rwwr hY1A44GfWvItXbw18KvD3xJ8eW1rFZfaV1Txx4hkyFW91Wz0e3tY2AA+XzBYWyhe8k7sOXNd9vHo f0/xr40/bv8AE1/oPwEvLOxDhPFHiTRdB1CZWK+TYZuNUkRgOqyy6dFGR6Oa+F8RM7/sLhfiLjDF w+uZhkGExWKoVKi9pUjiPYTp02pO8lzymqc2mv3cpJ+6cOY4j2GFxGMmlOph4SnFvV83K0u+97el z8Z9V1q71vVdT1jUZTNfatqF5qV5IzMTJc39zJdTsSeoMkrV2klz/wAJxo0kxO7xl4bsN9wxb974 o8M2MKqblsnM+u6dbqPMPL3NjHvOZLV2k8k+0H1HQdj2r1f4E6zp+lfGP4bXurRW8+nL4s0u2uo7 pBJbBL+U2CyzLJwUSS5R+ePk5BHFf475DR/tDOMPl2OrpYXP69KjiKlRtqDrVVFYlvdVKEpuqpLV rnpybp1Jxl+P0P3laNOcvcryUZN9Lu3N6xve/qno2n9wfsP+G5fiD4gk8U+LdAsdRtfhfZ6Xa+Dv EU9vJa38F7Ot6tppT+Uqw61Y29pJPNFJMjz20iwCOXYdg/WfT9TvdOvbe9spWiubeQSROnBBXkg4 6oRkMOhBOa5OwFnpdhFFHDb2sYBKW9rDFAgUHaixQxIqqoVQOgAAr5Y+Mnhz44fFXxLc/Dzw7rk3 gf4d6jpNnqcXjHQ4pRIZYLkW2t+G/FU4vUmLTQSrLZrZgBzGFn/dmVh/qjwjkUvBngXA5bl2GxPG XEDq3csLSp0cRi8VUv7CVacpyVClSpwpYZYivVqezjCF3y2jH9SwlF5NgKdOnTljq7d7wSUpzfw3 d7RSSjHmk3ZJdND718Q6/wCG/Ftnb+LPClzbaw/9qtoHjC30Ca21GDw7rsVq908mrvbzH7DG8aKD nJMk8akbmOOXWVWJ/hA7sQKzP2Zvht4J+D2hy/DHw/bsukeJIWTWNUvXEuo6z4gaMCLWNQlzjzy6 hURQEiXaqjgk6mo2UumX15YXGElsp5YJSTtUeUxBck9E2jOemOa/a4vNMwyfLM/zjC0MDm2YprG4 fDTdWjh8XFJyjCq4U3UVSEo1JT5IRlVdVQXIont+/Uo0sRXiqdaqvfjF3jGatdJtK90072SbvZWs fKf7ZnjuHwb8ENds4p1TUvGlzbeFbFFI81oblvtWrSKc52rptvMhI6G5Ud6/EDzeOMAY/Hp0+vSv p/8AbD+NcHxS+JR0nQrwXXg/wKt1o2lTxNm21LVJJF/tvVoyDiSJp4Y4YW/iitQw4evk5ZeM54HA 5yOfp9K/yQ+kjxvQ468SsfVy+v8AWMm4epxy/DTi7wqexlOWIqwaupRniKlRQnFtTpQpy6n5PxFj o47Mqjpy5qOHSpxfR2+KXzk2l3SRfMgz1Jx6fn+dMaT3PHGScn1/PFUzL75xggY61E0vvg9Tk564 9vr+dfgipX+yeEaMbxPNEs0pgheWNJZljaVoYmcCSURBgZSqFm2ggtjAIzx1c3hmG9uLW28Ka9Ze J5brcgsfKm0XVlmjXc4+w6m6pLBjJR0mYsFO5EbivPzLkk/l259vQcVE8mVAYAjHBx6dM16OF+rU 4yp4nBLERm4++pzp1YJPWNN3lS95bupRqW0asVFxWkocyfm016Pb74s6/wAUeF/E3grUX0vxRo95 o94oQqtzse3mWRA6PbXkDvDdIVYYMcjDtwQQOWaYLyDx17YyT2wOnNdp4W+KvjLwbpmoaJpF9Y3G havPDPqGi67o2leIdKuJIFdI3+y6xaTC3bY7BjEULcZPygiPW/Gvh3xRIs2seCdF0K7FssJ1DwEj aDFJMh+W4utBuJJrOQ+WNrCEWzN98tmvbq5bw9iKXtsuzKrhK8rv6tjKXMo3k0oQxlDmjWajytzq YXBptyXKlFOWso0GuanUcZfyzXnspxvzO3Vwgt/nyljFfahf2VjpltLe6jeXdva2FpbxNcXF1eTy LHb28UKqTMzyso2gHOcHjNfpFq3h3wDonh/WvgRP4P1ix8NeHtFsPiX8ffHmkaxJLL4M8XrokdzY aLo3mweRrSpJIIYrCXJY3h8v5o3lGf8AA/wv8LvgF8O9L+N/xB1qzXxV48jZPhlFreiXcOoaCIo7 tJLiGCL7T5Ek6tGzaj5TxW8M0TqreYVb5T+JafFzxBBpt7daW1h4G8XeKJrbw5aeGtcg1vw/rviL UpjM1xeX9pfSza9r8xkDNcXwExxsjjhQCJf3HJeH34bcLvMcfg6ee8RcTUIVKuX0aVHFzwWVVYWp Qxk+Sr9ThmrrUXVnFwrPCKNCi1XxMq2D9qjR/s3C+1qQVfE4mKcqcUpuFFrRTdpcircyu1Z8lox9 6TlT9m0XwQP2htL8NfCL9nHUzGNMuLvV9R8B+J7Sbw/rGtXaQwRt4u1zxFbz3Gn65exKbhEBNqLa FwkUbHJr9LPgN/wSp8AeGray1v446tP4618rHM/hjRp5tP8ACtjIdreRcXSBbnVyCCrEGGM7eAwO T9Y/scfsw+H/ANmz4X6Zp5sreb4heIrK11Hxzr7Rq15JfTRrMuiW8xG6LTLTf5aopAeRHlbJIx9d 5PrX+ivg19E7hLD5fkvGfivw7h8642r4eg/7Pl7SWV5dTjCCo0Fgqk6lKpiKUElXUr4SFVyjRw8e X2tT9IyXhLCRpUMbm2HjXx0ox/d6+yppJcseRtpyS+K/uJ35Yq13+On/AAU5+G3w2+G/7PHgmw8D eCvDPhNV+IVnBB/Yuk2dlcvCNI1FpY5buOITXCnbGW8x2yVBPPNfguJsdDj6Hp9OeOa/cz/gsT4u hg8N/BzwQkw+0Xmr6/4luIQw3i3s7a3062kK9gZri4APqp9DX4Q+cB6fnnn3/Ov4O+mfDK4+POfZ flGEo4LCZPgssw3ssPTp0qUJLB0qrjGFOMYR5Y1YxskrW8j4HjX2Sz/EU6MVCFGFKNopJJ8idklZ aXNUS/7XXnp35GOOlP8ANH+zn6/0PespZSTycc+vU+w9KlWUcY6j1PP8ulfye6Xl+h8oaglyck44 Pf8ApjFSrL6fQn2z9PasoS99x+hyalWT16Hnjv3GQetYyortYDVEo9cnoD2+hHr1/Kvrv4l+CtPk /Zb/AGffidptmkV0+seOvAviG4iRVM9xYan/AGtpclwyj5n+z3dwgJydseOg4+NhIeOh6dOvsfav 1GsvDx1//glxc6ls3y+EPjRc6xE2MmO2nltNNuf90f8AEwXP0zX6x4VcOU+IsF4r5dOgq1XD8J47 H0m4qUqdTLcbluOcoPeMnSo1aba3hOUdmz1sqw6xMM1puN3HCVKi8nSqUp6fKLXo2dh8KdEP7Qf/ AAT18feCkX7Z4t+BXiW68T+HVBD3S6Y0D6tLaxZJIieyfWgAMZaBB2r8oomRpMTM4jQM0m1SWwqn CY/hLOFXJ6b89a/a7/gk5pulS6T8Q7u3u2uW1UjQPFehXLK8KhY/teg6jDFj/UTWb63bygkgtCmM biK/ML9p/wCGV38Ffjn8RvASLNb6dbaxc3Wjt8yLdeHdXddS0zgAb4vIljUjkboPUV+n+MPB+NzL wS8BPFqrRU6k8BPh7H1INTjJYCrXllFSUl9t4KNTC1btOEsIqe8Vf1M3wk6mS5Dm0ldum8PUa1T9 m26TfnyXi/8ADY8da7ibTmjLwpLLJJKY1aUhVge3S2gWJYyI22vdNvLHcB8x3AZxi+Mk5A+vfn2q qXHJz07A9MdAKYZD0/LnI9jX8rVOaryOSs4RS0Xb8Lttt2W7ufKt3t5Fvf8A7X/j3/16KtfYYf8A n+h/75P/AMVRWn1Kr/Kv/A4//JD5Z9vxPQPDlrrmu/CXwt8PfD9vENV+Jvxjufs++RbQagmg6Hpe nWKX1y33tPhv9ZvHy2UjZJGALV4Tfxvp99e6e8sEz2N3c2Uk1rJ51rNJbTyQPLbSgDzbdmQlWwNy kHvX1j8MxrGmr+yj4uuzY3WhQar8RdI0qxluLaS7fU7bVdavbp20+RSTYj7RYgyNwSdg5xXxzqer S6pqWoanPFawTaheXN5NDZWsNlZxSXErSvFaWlsix2tuGYhERQqgYAAr9b4syqjQyfh7EVHVWNlS oUYQnHlhHCrLcuxilFJ/bxGPryTu+eNpPlbd+7F01GjhpNvnajFJqy5fZUp3XrKpK3da+v7U/wDB ObURc/CHxTZhgzaf4/uWZQTlReaNpMqk59TG/wCVfld8aoTp/wAYPijZOApg8f8AitdvOADrN24A A9mFfoR/wTO1YS6F8WNHL/Nb6x4Z1RY+flW6stRtHYDtlrVAT7CvhX9q2zbSf2ivi1bFdgl8VT6i gxgmPVbS11FGXAxg/aT7+tfs/iNS/tD6Ong5mHxLBYjE4V+TvioJeWmF/A9vMv3nDeTVEtKcpQb/ APA1/wC2nifnjPIPufzBpfP+v4Z+prH8/IHPp3J/ECt/wn4d17xv4l0Pwh4Y0+41XxB4j1O00jSN OtUZ5rq9vZlhhjVQeF3Plj0VQWPANfzBQwFbFVqOGw1GVfE4icYU6cIylOc5yUYwhFXcpSk0oxSu 20kj5aMZTlGEU5Sk0klq23okl3Z+hf8AwTU1TxhL8cNQ8LafoY8Q/DfxV4Y1Gx+LVpfukOhaZ4Xg ie4h1/ULi4PlW89repGYSxDMZGRCMkj7G/a01HW/h9rafCvwrqXhn4IfBqTxDZeOvFvirVNcguvG /wAcdYvL+21WZtK0rTZGvNX0VZpI7aNCY4QYjvYRxBB8b/tC+OdD/Zc+GP8AwyJ8JdShn8Y6nDbX /wC0d8QNMkUXOq6+8QkHgLTbyM7k0ayDBJwG+dwVOC0oPv8A40sNL/bG+C3hLwBFbQWn7Q3ww+Dv g74ifC+4aQGf4geDZNFjTxL4Wiml+e51C2v9NmlhTLNuxgYLtX93cI1Vkfh7xD4NZbj55r4h5BFY tqFWFOlPEYlzqZhwnhMVSpSxPLGFHnxEaGKoLHZnLEZdRn7KtKWJ++wc/YZdiclpVHVzLDrndmkn KTbqYSE0uayUby5ZxVSq5Uou0nzfocHEgEinKuA6n1DDcCMdRgivmT4+fFHUdF8RfDD4QeD72S28 a/FDxTpkV3dWjD7ZoPgmxvUn17UoyAfJuJ7e2uYInPRI7hwQUBr1n4deJV8Q/Dfwf4onWaN77wpp d5qEHlyPdQXtvYJFqlo0AG9rqO+t7qMpjcXj24zxXyj8IPhl4v8AFX7Rfjb48fEm80ux1PSkuNE8 IeBLbU7LV9V8NaNeWws9JuNd+w3Dpot4NKN1i0cec019PK4QKN39CcY5nmuY5fwzlPDdOq6vGWIw 0auJp3hHCZY1HEY2v7X3VCtUw3NRw8U1VlOpKdJN0W19Fja1WrTwlHC03fHSgnNaKFLSU5X6ScPd it222tmfeRwSSOBnge1fB/8AwUN1GGz+B2l2bn99qXjvRVgAGT/olhq1xK3soXaPq4r7nr8nf20P jFYa38XNB+F1lKNS0Xwd4d8VP4us4WSSC81zWvD11PFpsu6NwJbO3tLGQttYxTTcYeM48fx3zPCZ b4aZ/hMViI4etxD7LLqF1fmq4qpGMrR3ap0VVqytqo03a7snjn9aFLLMRCVoSxFqUdnrNpPTyV5P yT6n5l+eSOvX6nP5HpT472W3kjuIZGjmgkjlhkVirxyxMJI5VJ6FZEU57ECsMT4HJ42jJ5549a/S T9jj9kf/AITcaf8AFf4o6cw8HxyLc+E/C92jIfFEsT5TV9UibBGgLIv7qPj7Wy5P7gfvP80OBuAc /wCPuIMLw/w/h+fE1ffqVZcypYaimuevWmruEIXSVk5Tm4wgpTkov8wwGBxGY4iGGw0bzlq29ox6 yk+iX3t6K7aP0s+C/ia4+JXw08FeNL22u7GbWtCspr2C6t5baZr6BDa3skKToC1nJcwySQyAbXjl VkJBBr2VFWNQiAKg6KOg/wDr186fHH9pP4b/ALP+mQRa9MdS8RXFsn9ieCdDa3XUZbdFEcM10MiP RtJUKFEkgG4JthjcjA+O9b/4KN21tqVhd6N4Vi1zQNU0OzubrSTeXOia/wCFfEETSRalptzevaTW +t6e+IZreeII2yRldQRtH+meZeJ/AXh/DDZFxPxdRxGfZfRoQxcqdOc6rm4Ri61SlS9q6bqTSnKj B1KtNVIzlH2V6i/UKma5dl6jh8Xi1LEU1FTaTb2S5mo3tzPVxV2k02ran6mXOr2nh6Fta1HULXSL PTgt7NqF/cxWdraxwurefNPM6rHGH2jcTjLAZyRXxj/wUb/aA17R9I8E2fw6P2Pw98Z/CD6xf+Mo Gliup7a3mbTdR0XTEeNWsXkKA3ExxIY5gkYUMzV8SfHX4vw+Jvg9F4rXwzN4O8S/HfXGW509/Emr a8t78PfBN0Gh1FIL9lh0f7b4ndVZbaGNJ00osc853/ijKfF//BPb9nnxNMzS3vgH4m+NfAjTyMXl FjqEX9qW8BdiSIxsXA6D2wK/KPEDxpxfFPC3iTwXwxU/s36vkGHzqGLo1KvtalP+0MJTlRSrUKFS iq+T476xUtCNSDm6SnKMfaT8jH53LFYXM8FhX7Plw8a6mm+Zr2kNNYxa5qM+Z6XV7Xsrv4LSXGAC MDn1/A/l/SrCSgYJ6fU8noM/jmsVJffOO/ORx/8AWq2spz17DA55/wDrc/rX+b9Si9bo/OjTaQ8Z yBz0zz/kH9KiaQ8479x6fT/PTioPMO3qc989D+R7cV6D4B8CR+Mf7e1LV/EVh4P8L+GdLl1DVvEO pxvLFJdssg0vQNLt0ZTf65eXCMkMIYYWOSVyEQ56MuyvF5pi6WBwNJVcTW5rJyjCKUYuc5zqVJRh TpwhGU51JyjCEYuUmkm1dOnOrONOCvKW2qW2rbbskktW20ktWefmT0JPsSR+pqN5MZ7cdCT364/z 2qu0nGcHGc5zzjJxkHoenrzXXeBPAniP4ka+PDvhuK0a6WyvdUvLzUbuPT9M0vS9Nha4v9R1LUJj 5dpbRQKxLMQGIwuScVWBy3F5ji8PgMDhp4vGYucYUqcIuU5zk0oxjFatt7f5ChCdScYQi5zm7JLV tvojlJg8Wzeu0SRJKnIO+NyQrggnqVORnIxzX1J+zj8FfD3jKHWPir8VdUt/D/wc8BXKDWrm5maG TxDqqJHPDoNqVG94j5kHm+WDJIZ0gjG9yyLN+zpb+NfiX4X8GfCPxIfFXg+58K2Wq658RbiBoNE0 pLG/1Gw8UahJJLFGqWcV/Z3CWiE7pgEO4qWYYP7QvxI8JXFroPwX+EpeP4V/Dqa5zqKufM8ceL5Q IdV8WXrA4uIy6uluTxhmdAqGMD9ZyThTD8HVMdxXxhgKGYZfk1R0MBhJVo1KObZkownFQnRbjiMu wkZqvi61KXsqq9lho1G8Rp6tHCxwbqYvGU41KdF8tODknGtV0ejjfmpQT5ptPlfuxu+Y6n9o740/ Cz4x+PIZrTS/Eln4Z0DSNP0Lwxr2jz+RLHpsFuJpobjwbq6LBCEvZZIw0FxA7R26Fi+Fx6F+wd4W g1X9pf4a2fhvx5Yar4eOtNqviDwtqkM2jX1/b6ZYXN6hk8P6l5tpqzxXEUREltNJPEQJVAVSR8F6 /rNpq9xZS2ehaZoEdppOnabJbaW140d9PY26wT6vdte3EjNqNzIvmTbCse4/Iijr9LfsMeJj4W/a q+EGsGKaW2h164h1EwoXMGm3em3kF/eyDPyww2zySSMSAqREngV7vBfFn9u+NXCWecQ0cPipY/P8 vnWxGGhVwtqc8ZQTjCMHDmoxhaHLiKVSpKinCU3fmW2Cxv1jPMHiMSozdTEUnKUU4ac8dkrXSWnv JtpWbP68TjJ3Ag89PX6GobiaC1gmurieKC2t4pbi4uJ3WKG3ghQySzTSyECOJY1ZmYkABSScCvz2 8U/8FQ/2RvDcV39m8Xa/4mvLZpo1stB8Mai7TTRMyFVub8QRBCynDbsYOeRX5SftY/8ABTTxz8dN G1HwD8ONKufhz8P9RVrfVpnuxP4q8RWh4Nre3duFTTtPcffghJLg4kkdeK/1l8QvpT+DvAuUYzF0 OKsLxZnEYS+r4DLK0cVUrVUvdjUr0efD4enzW9pUqzUlG7hTqSSg/wBdzHi3JcBRnOGMhjKyT5ad KSm2+icleMVfdt3tsnsePft6fH20+Pv7QPiDWdDuvtXg/wAKwx+EfCkysTFdWOmSy/a9TjH925v5 LiVT/c2CvjES84JB7dOPqOOlZYkI6ng9cZGP/r5/lXaeHPh58QPFyQz+FvBXirxFb3NwbSG50jQt Sv7SW6Gf9HS5t7dkaU4xt3ZzxjPFf4s8S5xn/iJxbnvEuNozzDO+I8VWxVWFGnOo1KrO6hThFSkq dNONOmteWEYo/EcViMRmOLr4mcHUr4iUptJN7u9klrZbLsrIxoPPuZY4YY5JpZXCRRRI0kssjHCp FGuSzlsAADJJwKlk82CR4JopIJo22SRTRvFLG46o8bgFGHIwQMVHb3eueFNcguY/t+ha/oOoQ3EJ liktNQ03UbKdZYpPLlUNBcRzopGQMEA4r7B8X6lpH7Tfw41n4jQabZab8fPh7CNT+JEWmWws7T4i +ClW0sYvF1pp9svlx+JLKdlOpbFQTxXAucZSU1hk/DFLO8Hm9KhjXQ4hy6Eq9LBVKdo4uhRjKWKj Sq891jKEI+1jh50lGtShW5Kqrwp0a00MPGvCso1OXE0lzKDWk4xTcknf44pX5WveSdndJP5EWTBH cnr+OT/Mf561KsgOPXk56dKyo3LlVQMxY4VQCxY8DAAGScj61YLFWKurIykhlYFWVgeVYYBByO/P HtXyEqLSulp3OU1Vl5H8+cY+uOea/af9m+2TxZ/wTJ+PuhIpmm0nU/FF6qKN7q9tDoWsI2O2Ft3P 0U1+JKynjJwOwGee9fuN/wAEvZovGHwE/aW+Gsh8ya8iklgtyQTs17wzqWnBgp7faLWH8cV/SP0U MNDH+KGY8OTt/wAZhw7xDliT1vKvltapFa7tujoj6fhKKqZpUwz/AOYzD4ikvWVNv9D54/4Jk/Ee ++H/AO0la+DNQS4ttP8AiRo11oNzaTxyRsmqWsJ1bRbloZACrFoJEDY+7dEg4NfS/wDwV0+E4Q/D 740adbEZE3gnxJNGvGV8zUNCuJyB1Km/iBPaNR6V5lB4PXwZ+3D+yNrsdoLNPHPg/wCHWqXSKuxH 1W10Wbw/qTY/56GaxUt3y/vX6+fta/C2P4w/s+fEnwYsPnai+g3GtaFhQzpregqdTsPKBH33a3kh 45IuSO+K/rDwy8Msz4p+jH42+D2Pn/aGO4MzbE1cpbjaSqU8Jg82wqhFt8ixU5TTSbssXUV2mfW5 ZltXFcMZ3k9R+0qYKrJ0dNbqEKsLLpzNtf8AbzP5E2fjg5x69eeuPyp4KYySwweCCB0PB78Z7d6q SBo5JIpU2yxO8ciN95JEba6EH7pDK2R6jFQGQjjJHoP69frX+WUabTs1Zp7H5Ze3Q6L/AISDVv8A oJP/AN+rf/4zRXM7z6D9f8aK6/rOL/6Can/gUvLz/q4+ef8AM/vZ9KaN9on8R/sVeH9AdYZx4ag1 xs3VtZxnVNa8deIZ9Xm869xH9oaOwCbfmaQxpGgLsqn431N5YdT1GKXKzRahexTDGCJIrqWOQEdv mU8deK9p+K3jXUovh3+zR4etLgW48L/D2XxLbTxWsdvdx6rqvjHXp7eYXap5kqRQ2Nt5ZD7Msz7Q zGsn9o2zt4fiO3iTS9Hg0nw9498OeF/GuhvZweTp+pLrWhWEmtX1miEqjHxCuqLOikiOdZF46V+5 8YYWjjcvrVMNNzlkssr9pG1oqGMyfB0rQgnJRjhauBVGdSU7VHWopQg1aXpYtKdJuLu6Hsb+lShT Wi1soOnyt315louv2L/wTR13yfiX8QtAaUAav4Ktb+OMnG+XRtZgUkA9SItSf8DXl/8AwUA0ptJ/ aN1q7KbY/EHhnwvq8ZwcOUsG0qZgc8nzdNbP1rlv2DvEo0P9pbwdA8uyPxFp/iLw42M4eS80qa7t 0PPObmwhx719A/8ABTvQmtvF3wu8VquF1Pw7rWgzPjGZdG1GG+hBYdW8nV3/AAXpxX6fSo/239Fr EU0uafCOeKTW7jGrOCT9G8xl93qesv3/AAlNb/UsR+bWv/lU/NHz/fnnsf8APr+dfpV+zbb2P7Mv wE8WftfeJLW3fx54oe/+HX7O+mXsas6avcW7w+IfHUcUnJhsrd2jhkAK+YrAHLA18FfBr4ca38Zf ij4H+GPh+NpNS8YeIdP0lXVWK2lrLKpv76X+7DBZJPI7HgLGSa+mf29PipoviX4p6f8ACXwFKq/C v9n7Rbf4Z+Dba3INte3ekqsXiPXiI/llurvV0mJccusS8nNfnvh9h48J5JnnifWgnj8qnHLsiUle +cYmnKcsbFO6f9k4NSxMH9jG1sBJ6Np+bl1sHQxGay/iUX7LD/8AX+Su5/8AcGF5rtOVM+P9S1m/ 1jUL7VtUu577UtTu7i+v7y5d5bi6u7qV5p55pWJLyNK7EnPO6vuvwTB41m8N/s7/ABu8C+MrLwTZ /CPSdb0Lxd4+8Q3yR2fhjUNF8V3mqWWjvY27m41v7ZpOsxR2lhDG7zpI0bbVDMPiLxz4E8ZfDbVr bRPG+gXugajfaVp2t2UN2vy3emanbx3NrdW8yEpKAsmyRQd0UqNHIFdSK9jt5Lu6/ZE1hI4okttH +PmkT3kiSy+dP/avgm7jtTcQmTb5aSW2EIAyZCTkivM4NjjMnzXiSGZYXE08wwmDqYlw56uGxMMX gcRh8fSlKoo+2puM6F6jXs6vs3N06tOo4zWOCc6NbEqrCUalODna8oTU6coVFd7rWPvbO17NPU/X b47/ABh/4XL+yjr/AMUf2Tk1OPUoPEAtvi5puiQtpfiPwZbTyXN/rfiXTNFgnkm0/SdRu4xLvjY+ RFeTksHD7Lv7EXge68J/AvSNd1Z7ifxF8SL+78c6xeXkss99dRahtt9HN3cT5kmc6Zbwy5dmO68Y 55r8h/2QfjH8QvhR8b/B7+A5Ir5PGesaZ4O8TeFr9Wn0LxV4f1y8isr/AE3V7InbNELeaV1bG6Nk 3Keor+njXfBmkNo0HiD4fwRp4btoYre40G1jRZPDawxrGltHbp93T1RQEwMKqgDjp/cfgxjf+IwZ nV8UMTKdLiLhjALK8Vl0Y8uCjUqSVR5nl0U3yutQUoYyg1KdGpOU4zdCpCFL77I6rzqr/a0m44rC U/Yzp2/dpuz9rSXTmimpx1cW278rVvmf45eO5vhn8IfiD44tJlg1DQvDd9JpMrKrhNZu1Ww0h9jg h9uo3Ns2DwduCCOK/nX8DeIbu4+Iuk6tq1zcapd6zqt5FrE11LPJc6s3iGG7sdSjuJ4z5hluRfzI XU7gZtwOQK/XT/go94wOh/A/SfDcc2yfxn4y062kjVsM+n6Hbz6vc7gPvR/bE03Pua/Jb9n/AME+ JfiN8YPAnh3wtAJNQj1/TNauruRWNrpelaJe2+o6hqd620hYI4YQAD9+SRIxy4r8S+kdmWYZ34q8 I8L5dz4mWUQwnJQhed8Zi6/PpTvZzdFYda620btqeFxPWqV83wWEptz9ioWiv55yvttdxUd/yPo7 9jb9mib40+KpPFPi6xmi+G3hC9RNRhmSSL/hJtbhKyR+HIWJB+yR/K96w6IVg+9Kdv6U/tSftOaH +zz4Yt9C8PRWF58Q9XsBF4Y8PoqfYfD+mohtotc1S1iwIrCIJstbcbfPeLAxEjmur+J3xB8Afsof B651CysLW3trFru28KeGo3SK58R+J9UmuL5xI6jLl7qae5vZ8HZErYwfLWv58PiD468U/EDxnrnj HxtNI3iXX7r7dfLLBNaJChRVtrazs5zutbCK3WNYUHyhFGOtenxLmOA+jtwTDg3hatDFeInEMI1c fjoRu8NCakoyTa91xXNTwVOVrfvMVOMZSip6YqvT4awKwODmp5niknUqW1gn1+66px6azer10tQv /GPxE8QajruoSav4q8Ra1fLLqF+6S3l5eX12zeTAuP4yEcQwR4ASIrGgRDt7zwD8HPFHjPxn4P8A Cs6w6PbeKbd9bk1SeaKW3sfCNhFNd654gke2LqIra1tb1GQkSLc2/kSIrnFGpfCHUtA8AeANdg1m 7u/iD8Q/7Q8T6N4C0YeZdaf4C0vTryYeKNVmimDWN3J9nupYVIwbRJHDbgyj3v4BeEdZ0D4QT+Ld M1efwx4m+NfjXTvhR4a8TwJLNqeieEUvYG8Sz6BbQsHbUdQ1eS1s1cGOOOOznkeVADu/nfh/gzEZ jxDQo8RYHE4iTpLMcXP28G50mqFdUqkmm418V9YoUW6tanKjUxdKrWcY3PnMNg5VMTCOJpTnde1m +Zax92Vn2lPnjF80k4uacrGL8bPC3jn4hyaP468NeFNZj8AWsA8EfDDw3Bo1+2oW3w98KqljpviW 7EVsI4IdR1OS9c+YUmkuJJCqtGA1e+eNdH1Pwb/wTZ8E6R4htnsNW1r9obVdQtrOWWGRxawaCQ0g aCV1+6ybgGJVjtcK4ZR8hfG/4i6h428aReBPCOp69eeCfB9xZeDPCGn3N9dXN1rl3pAGjv4l1IZz d61f3iyyZbPlpMscYUAg/U37clxb/DH4e/s1/su2k0Z1L4Z+Bj4s8eQxNk2/jHxuU1CazuAD/wAf ENuxznnEwr7rD1cpo4Xxu4ooOtiFSymGUSxM6kPq+JzLM8bhKU6eFpRppxpexwuNr4aKq2p4XDJe zSty+lCVGMM9xcOaSVFUedtcs6lWcItRVtFywqSir6Qjt2/PVJQeM4Axzzkn/OatLL3z7ZGD/ntW MknT8hx+HOTVpJcflyTjB6Yr+Yp079P8z5k2VkyCO3X8jnI9RW1capqg8M2Gkm7kGjnWNR1SKwzi FtRW1sbOS9kUf61/s4WNSc7AHC43tnr/AIe/BX4pfFCK0n8C+DtX1uyuNSl0x9Vji+z6PbTxxwyu 11qVyVihhVZQWYMcbcYLcH730z9hHwH4Y0ODXfjF8VYLCz8MaZJqPjCx0FrSzgtJbi4eZEfVbtnm SDyFihjxbLLPIp8kcqK/Q+DvCjj3iyhi8Zk2T1MNlapJzxuJqRwWDdNyjOT9vXlThVhGEZVKkaft OWMHJrRJ+ng8qzDGRnOhRcaNtZyahC2jfvSsmktXa9kr9r/Dngr4O+I/ib8QNB8GeE7doB4m0u01 2LUZ4Z7jTNF0y5s5Zbi81KW2VjDZxX9vc24JO4uqoAXOK/R/Xv2c/Cfwr+G+geHNZ+LWi/Cvwdf2 Tp8Y9cggNt4t+J93A6m30zTbi6meS00ICW7j+zwRsZEaN5I3YkV4nqP7b/g/4a2ln4O/Z9+F+n2X hzRok0uLxD4okmOqanpsVzcXJMcEJ84bri6upka6nkIe4LmFcla+AfGvjjxT4+1678Q+L/EGqeJN TuJZGW71S5edoYmclILaE4SzgCYASJEUAfdFfo1DOfCrw2yvH0crpR8RuMs05qVavTnisHl2DpNU pVMPQrR9lXxVGpOM6VSpRVD61hpzoSqQozlCr6Kr5TltKoqUVmWNq3UpJzhSgvdvGMlaUk2mm48v PFuLai7P7B+P37R6WOhJ8F/gXFpHhj4PQ6YlpFrPh+5FzqvjHTpgxukv7mSNZ9KikumuRcwSqtzK 5dpXMbgN8HswxgDjp8ufzIx0prP1+u4dj7fjgfpUJfPXtzxnPt+tfkHFXFWb8Y5o8zzar7tKKpYb DU7Qw2Dw8f4eGwlGKjCjQprSEIq9tZynUcpy8XF4yvjavta0r20jFaRhFbQhFaRitkl823dt7P17 /mD+JP4V9MfB6QeBPhd8Xvi9JiLU306D4WeCZSxSVNb8ZRTHXr62PXfb+F7a+QsPutqKHqRXy67j B7jHXnt7Yr6V+M8g8IfCv4H/AAwhdVuH0C++J/iWELtk/tfxtcBNKiugPvNH4c07TmTPQXZxwTXo 8Hx+o/25xHL3ZZBg5ug9v9sxco4PDOL6VKPtquMp21UsLfpcvBfu/b4rrhoNx/xzahH5xu5r/AfN bSH1z3JPf1phk7Ejrn/6x56VWLFjhQSxwAgDEsTjCqoGSxOMAc5omSaCR4Z4pbeZCA8c0bxSRkjc BJHIoKHac8gHpXycaTtzKPup7+fr8jj6Mn34zjpjsR7ZHJ+n51+13/BIH46Xlj4z8V/AfXtZd9F1 7S38TeDdMu5UNvba/psqPq0FiJPuSz6eRKVXq1iGAyK/EUufpz/+r+Y/Kuj8I+MfEngPxLovjDwj q95ofiTw/fwalpGq2MhiubO8t33xyIwHzLwQytlWVirAg4r9L8IvEDGeFviFw5xrhozrUcrrWxVC nPleIwdWLp4mjvytypycqan7qqwpyfwpr0smzKeU5lhcdC8lSl78U7c0HpKPzTbV9LpM/Zz/AILD fBzRfDnif4efGPQ7C20+fxguoeGvFTWsSQpfarpMUN3p2ozrGoBunsZpI3bGXFqpYk5NfmN+zd8S 7T4W/GPwb4n1aM3Phya+l0DxZYmSRVvfCviOCTRddgdYzmT/AIl95KwU5BaMZGK+ubj9rvxD+174 ebwB8ffD1h4x1bwjHN4q8C6R4YuT4Km8WatZ2Mlvqem3l5bwz7tRbTy89vFCkYmeB4VG5464r4s6 p8K/hBcfD7wx4L/Zt8MT+PPEPgbQ/EPiK28Xa/4i8b6jpep688t9pOn2+lW1xbrb6iNPaxlZSrsV uEBUfNn9l8TJcN8WeJGZeN3AOd4fIOH54nAY2FPFYTGfWf7Sg6NOtSdDDYbEYZ1q+IpzxEqMsSpV KU51pLkmm/czSWGxmZ1c9y6vHD4ZypzSnCfN7VcqkuWEJRvKS5mnPVNyejV/VdE/ZC1H4Z/tBz+M pr3RdW+EHw48U6x4v1WW01a0udY8OeGdJsZ/E/hKfxTpV3Fvt7PUbQWCwyiKRJfNKDEnyV8i/DSD wt8QPih4u8X/ABDsp7nwVYW3izxlr9hYT3FpPdy3P2k6JpNlPaxlknuNdvNOiTAGQ5zwDX3r8Jv2 6PCUur6rpv7UvgDwrpviLxPoFh4DuPGPhXw5HNqEPhW3ureIeHviF4WkuxDdaRHbwxICoW/jjTCs pUY3fHnwEi/ZzsY/Fnwz0ZfGnwz1u91r4zyfEvSIv7W0FNE8N2wufh/4Gb5XEBi8R3nmzE4+0R+U smDC6r6mZcA8H57gMs4g8O8RSxnCeQ5jjMyzfAV6Uq2MwFTESoUcBTxmXyjGf1CMaCddOdTDQhLE /wC1yU4U6e08Bg68KOIy2UZ4OhVnVrU5K86blyxpqdNpNU/d97eKTl77ukvx4kkXz5ykbQL50myB 92+FA5KxvuGdyjg554r9f/8Agj34rsLD4ufEjwndXMi3XibwVb3enWojDW9y+i6kkt0XctlJEtbl yowQwLelfj/q91qVzql7f6tBNBf6pcSapOs9s9q0jai7XYnWF1XET+duQgbSrArkYr6//wCCf/js eBf2sPhPfSTeRaa1q8/hS9Zmwhh8RWc2moGOeQLmS3PPdRX4j4CZ7DhLxv8ADrOZvlw9HN6GHqSm uS1HGSeCqylFS91xp15StdqLWt0mn4nD+IWDz3LazdoqtGLb092b5G7ekrn68fta+HoPCf7Qn7Cn iGCJYIrDx5deETjgLbx6zZzW0YPZR9qlx2+fiv1mZVZWVgGVgVZSAQykYIIPUEGvkX9rXw58LtRs PhDrvxOk1fS7fw58XPDUnhzxRpVxDCnhzxFqMjrp02srOhWTQZ7q1ghucEOgdXQ8GvrpSGAIIIIB BU5BBGcg9xX+1PAPDq4e4+8XPZ1qEsJneIyXGU6VOf72lbKKOBn7alZOCnLBc1Ka5oVI8yUuenUj D9uy/DLD5hm/LKPJXlQmknqv3KpvmXS7hdPVPWzuml/IJ+2D8N/+FS/tG/FLwhFA1vpqeIrjWtFR lKqdH14DVbEx8f6tY7opn/pmR2r5mLsTgdfzOPp+FftV/wAFY/hPaXXxb+EXjWTU9O8NWHjbSLzw lrHiPVhcjS7G/wBCm+02dxqD2cMkix/Yr5EyqMQIs4wDX5CeO/h54n+Hl3Y2+v29u9jq9qNQ0HXd OuotQ0HxBp5Yp9s0jVLcmO6jDfLIoIeJwUkRXBA/xW8d/DjG8EeKXiPl2EwEo5JlmZ1J05QScaOH xyhi8JGajrTh7LE06UJyUYTnGUIScoyS/E8/y2eBzXMaUabVClVbTWyjO04X7K0kk3ZNppO6OL3r 6/of8KKrbz6D/voUV+K8i7s8M6z9o+y1LRvEngDSrqzvLPS7D4NfDG28PG5jdIbrTv8AhGre6u7m ydkXz4DrF1qIdwBmRHB5BrT+IOk6x4p/Z++D3xN+02FxZeDV1f4UaxbQ6hZSXth5Ws3+ueFpp7GK XzYHuLO91FMOmdunLKTtkFdT+2Rpeu+L/wBo7x7YeELTVfFGn+CfC+hJcafo+m3Utl4J0LQdCsBq FgoG5ItMspJlMsqlUEl0wPzZz51+zNJo3ivxPr3wc8US3v8AwjnxZ0G80y1a0eLfpnjbQrefWvBu uxRTHElxHe209tgFTJFqjxHKtiv6WzHLIrjvi7hycZywuf1sRluGqymoU/rVDE0vqslJRlCVL6zQ p0JK6dKjVfM1KLT9mrTSzHG4Sz5cTKVKDvZc8Zrk6NOPPFRa+zF6u6OO+DHi0+Dfi78NfE+/Ymje NvDl1O2dqi1bU7eC8LnuPsk0wPsTmv2F/wCClHhk6t8END8TQx+ZJ4Q8b6fLJKASU07X7S60yUgj ohvBp344Pavwbkklt5HQs0c9tKyjjY8c0LkZK5yriRM47EYr+jjx5Anx3/Yxv7i3Q3d54o+EGneI rJEw0ra7o+lWusxooHPnf2npskfrliK/QPBPDPPvD/xf4JcfaVsTgo4zDw6utSp1VorX/jU8Ku+q PTyBfWctzzAWvKdNVIr+8k//AG6MD4J/Yijg+Dvwi/aL/a71OJEvvBXhdvhn8LpZBgyePvHERs5b u0LfemtdNcscchZj718vfsteCT8W/wBoTwLomqhr6ybW5vFfiNpSZPtNhoYk1q7WcsDuWa7igibP X7SQetfSf7Vsx+Df7If7KH7PVsTa6v4t0q/+PXj+3B2SS3/iVvs3hqK6QHOY9ND4VhxtBxVH/gmF p8N58Y/G+qSKrS6T8PZY7dm+YxnUtd0yGUr6ExQsCfQ+9clLIqFbjnwf8LqsL4Ph2nhMVmFN7VMw zFU81x6qK2soYZYTL5J6pYSxCoRlmOR5PJLkwqhOqukqlW1eon5qHJS/7cP0+/ab/Z/0b9oH4fXW iPFbWnjLRUuNQ8Ea66hGsdT2AtplzKq5Oj3YRYpk6IxSZRuj5/FT4UQ6tP4d+PnwA123m03Wr7QJ /FOmaZdgRTWvjj4UXM+p3enkMuWln0JNZiGDtPkIRkHNf0bFl9R+HNfk1+1l4e0v4OftT/Bv45pb pD4a8dakuheO1VE8iS4SBNB1u4mXGM3PhfVVZz/E2nu3UnP7v448BYJ4rKvEHDwjhalGpDLs4klZ Vctx6eAnWnbeph41+RSevs5RbdqEEfRcQZfTc6OZxSg01SrtfapVV7NyfnFStfs1/Kj5K/YO0BPE 37THgiSRN8Ph2z1/xSwxkCXTdKmitHPbi9vLcj3Ar+j3w54n1Xwxfi+02bAYbLm1l+e2vIf4obiL o6kZwcZGcg1+Jn7Avgg+FP2nfjjo0qof+EH0fWtBtpFJePyLjxbawWksUn8SvYWiMpPJV8+tfseW AHUe3fn8K9b6MuUYjh/gGrVV8Pj62aYycpJ2lGVB08La/wDdlQlp5tdTbhOjPDZa38NSVao36x5Y fnFnyr+2/wDA/wAOftW6r4U0j4V+L9H0/wCKvgXTLvxPqvwKv9StdI1XxZomuXMMd5qHgzUb79w+ rbNImSKF1ZQDudVBAbmf2RP2dB+zx4M8QeJ/HWmXPhvxr4me7vtWj8RCKHUfCXg3TpZp9N0jUJgq pDciCM3V8yYQyFF6RCvm2TwPqXx0/wCChninVRc39l4V+Cx8MS6tqFhcXNpI9zomnWj6ZokN5bur RPc63NdNIFYZt7Scdwa/Rv8AaO/ah+Ffhj4ea34U/aD0S88XeE9fsoPDGq3HhyWODxjGviJZlj0+ yaCVZGvG0y21C73PsjENpl3JkUHuyfCcIZ3xTxv4vZ7l9HhrOMkxeOwGDxlatP8As7HSwcPqixk6 SpVKuCqKNJ4aVTDurh5L2tSOGpVIOU9KEcDXxeYZ3iKUcLWw86lOE5SfsqjguT2jVm6bSjyNxvF+ 81CLTv8AhJ+1T+1Br/xz8a6zY6VqEsHwv0u7Nj4Z0f7PAov4LGUY12+kaIym6uriMzKm8LFE0ceM 789j4E0Tx/4z8a/B/wAO3eoSfEPwz4z8N+HPH/jW38V6boeuXGgeGotel0bxO0OsahbyXFtpUVvp YO23kD20VztZEdXNemSfsg/srfGxo7r9mL9qPR/C+pT2H21vht+0BE/hbW495MyCz14Qx29zC0Ms QTasu7buEjBhj6H+Gv7C/wC058OfgZ8X9N0vwx4e8UfEDWdIh0L4deJPBPxH0W4kk8H6/fQ3XiO1 02ZZM28Ruo2uQGEZnW6miWVCcn+dss8PvEviLirNeIM6w1bizAY6NTFzxuS4qOZYarHCc2KWCprB SxChGvBTwlDDYilB03UjD2ak0fMUctzbE4yticRGWMp1E5uph5qrB8nvqC9m5WUleEYTirc1uVM+ WvDkf/C0/wBpPxV8PNY8NfDuG81DSvF2j2PjXS38TQ6LYeB7fQojoc1iNP1OKKHSYfB0KR21wIY2 f7WPNfDMT7/qPxa0z4fWF54ni8N5+DXgN/C0Pw80BLsQ39mbKa8t/hlqltpD582bUZl8SeIL6S9k Q3Vr/ZjIVZkz9E/A/wDYb+JHh34V6vqXjPw/ZeGPjD41+Glz8PtSvvEfiHRF0zQdC00XFhpjaith qImlt7u1Glx3jxO9yY7NU3RnC1U8f3f7IHwB8MHwN4n8b+HPij438C6fFrOsfBvT/Ebaf4N8ReNN D0K0TSbfxR4gu7SSbXLOxTSoYbDTDKdpZI7j95tWv0fL/D/irhzIK2fZ5icNwXiM1liMc8ZmUaeG qwddOWCwFWhOkq+Mq0Iqpi8Xh6NKrWrScIeznVoR5fWo5djMNh3iMROOAnXcqnPVSg1za06bi4qU 5R1nOMU5SelnKKPkz9nfwNY+ArPXf28f2krG1tdFt9X1HWvhL4HuLSHTbj4o/Em8nmu7O70/RwB5 Hhm0vHEzSBfLygxuC/N8CfEb4i+I/ip478U/EPxbete6/wCK9Xu9Y1GZidkb3MhaK2hB/wBXbQwi OKNRwqQqBgCvU/2o/jl8Qfjh4j8GeJvHGo6YIJvBdlf+H/DHhzNt4Y8JaRfalqYsdF0zTEPl2ctv ZW9tDLhQ5aH52Y816B+x58B9M8fatqXxW+JBt9P+EPw236nq1zqZ8mw13U7GI3a6e7PgSadbqqS3 eM7iY7cAmUgfzXndKrxlm2TeFvA1Or/YWErzxdfF4u1Otj8bVpRljM6zKzlGhRoULxw9DnqLC4dS XPUxGIrSqfM1k8bWoZTl6f1eEnOU56OpOUU516u/LGMdIxu+SN9XKUm/T/gB+wnqPxC8LWvjv4oe JL3wJoGpwx3mh6VZW9o2tX2myAPHqd/LqDeXpNtInMSMjyujLIQqkA/Vvh/4BfspfDr7Uy+DdV8e y2DC4ufE/jW5MHhSwmhhaWG1bXtZksNKDSNj5I1uSWZd3Ar4w+NX7eXxI8Wa9qGl/CnUz4G8AWjG y0eS102yTxBqlrCoiF9eXN1HJ/ZyttzDDAEMMZUMxfOPjzxH478aeNZRP4w8WeI/FEiv5qf25rF9 qUUchBG6GC4maO34JHyKoxxgCvoq/HPgzwFCllvCHBceMM1y29OrmmYUaU4YqrG6nWw6ryxEKdOU r8lsHH93ZJ3/AHj63j8jy9KlgsCsdWp6OtUSam1vKPM5JJva0Fp95+q3j/8AaysNGCeGtL8ceF/A HhmzjEUfh34I6TF4x8VC2UErYr4wvoLXQtCkZQA72cV08RbhmYc/AfxQ+MeqePBPoekQT+HPAiXv 2630B7x9R1TWb5SwGv8AjXXpQJfE/iJ2Z3Mkp8m3Mhjtoo0GT4TG2OBgDJ9uemB+Nd94v8L2fhW2 8JqutRapquu+GLHxLq1jb27JBoS6u0lxpNh9rZz9qun0c2k8w2J5L3Ij+frX5RxZ4lcacb4bHTxO J+r5Zh1FVIQqyVqdSSp06EVOajGEtHPD4KlQo1VT9rVoNUVKHmYvNMdj4VHOfLSja6Tez0UVd7Pr GCjF2u46XT9D0Cwv/B/j3xDfC+WXw7F4ah0iS2eJbZtV1vVzbG3v1dSXhbS7bUXTYVKvbjqCRXBM eOfXPJxnGOmPoK9u8F6e0fwa+NGv6lpcl1pLy+BNC0i+PnRRW3iyTXJr2GaKRMJPJDokeqiSNs4G oRnHII8LJ/IfXA/PtXxOaYKGEwPDdVUlTqY7BTqyspKU39fxtKM5XSTvCnBRabXLGOvRcFWHLDDO 1nUg297v95NXenZK3kj6A/Zb+G3g/wCMXx5+Hvw08dahqemeHPF2qS6Xc3WlTQW+oC4azuJLGGCe 4idIjJeRxISVY4c4Ga/Yz4kf8Ebvh7eaRcy/Cr4leJtF16KFms7LxfFZ6vo95MqkrFcXVjBDNZKx AG9UlxnO0ivwP8IeKtX8D+LPDvjHQbhrbWPDGs6frmmzbmAW7025juYQxU52F4wD6gmv7Ef2Y/2g vD37S/wk0P4maDaz6dNNJLpHiLSZ9pbS/EdhFAdStYnDHzrQvOjwucFo5VyAQa/tr6H3CPg54k5T xZwNx3w3hsz4rjU+uYStOdalip4GVKnSqxw9ajUpuLwtaKqON7tYhS5ZRjPl+54MweS5pRxmAzDD Rq4xPnhJuSm6dkmoyTXwSV/+3tmkz+S/xR8CviF8PfjNY/Bbxzokuk+K5fEek6OIP9ZbX8Gp3sMN rqOnXKjbeafLFJvjkXgjrggin/tNeI4Ne+N3j17V0Ol6HqaeEtHEZAjj0nwlaweH7BYsHGzyLAHj jLGv6c/2p/2arT4t/ED4DfEbSrS3j8UeAvGL295elAHudCm0+/v7KO6YDMkVtrVrA6DqBdPjrVf4 Q/8ABPP9m74ZWgvdd8E6b8SPGl5PJqOseKfGsA1U3Gp3Er3FwdO0mcm3sLPznOxTG74ALuSa97Hf Qu4vqZrxLwhw1mVHC8LTzOlioZjj5S5nhKOEvhKKpUKcpVq8KmOxVKrJRp0nLDKo5Q9pCBvU4Hxz rYrBYWrGOEdWM1VqN35FD3I2im3JOpNPZPlvdXSP5tvA2meGvgemi/Ez4kOmpeMNR0Ua98LfAGnN ZX1/ZXl3DL/Yfjbxzb3i+Tp2lQy+VcWdlIHnvGRJDGsSkt88eIvEes+LNd1bxN4ivX1PXddvrjU9 W1CRY45Lu9unMk8zRwIiICxOFRVVRgAADFf2K/GH4D/snz+G9f8AF3xf+GvwztND0+we51nxHqWl WWkz21tbW6xR7NTsxFN56wxRxwRxuXJVI41PC1/IF8TLrwTc/EHxlP8ADiyu9P8AAcniPVT4Qsr+ Z7i8t9A+1yDTUuJpPmkk+zCMktzzzkivx/6QvgzmXg3g+G8nlxJl+PyfHVK1SjhMPKtDHTqRhCNT H42lUjySU7KlSnGfJSV6NKH8WpPw+JMjq5HDC0JYqnUoVHJxhHmVRtJKVSomrO+yd7R+FLdvjS31 BzzjJJ9j9MfrQG9cnjuTjr3qDdyck9++fX/P+eE3ZweR68/TJHP/ANav5gUH1PlD0L4Y6fqus/EX wNpGh3FzZatqPivQbPTruzZlu7W5n1K3jjngcHiRC24Hp8vPFfoZ+0f8Q/CniDxJ8R/iH8CNFuoP iX4Y1lPD/jnxZPqEo8T6TpXh+AaB/wAJT4Q0e2/cWulXwgjW8uE8ya0lAKGGKZSPmr9iqDSbb4xX njTWohcWvwv+H/jr4i29s0rQtcar4e0C5fR1SYA+W41Oa2cHqDHwc4r550Tx54i8PeLT400a+ltt Ze/u72WR8TxXi38kj3tnfwy5W+s50lkSaOQFJUkYMCCa/XMhzl8LcB0KdVp0uMsyruc4QhPFYKGW 4enSoY3Byqe7Sr+1zDER5oOFScKMoRq0XKFWHs4ev9Uy+Kl8ONqyu0k5U1SjFRnBvaV6ktmm0rXj oypp8Oo+Jtds7NXuL/VNd1SC3EsjNPdXd9qN2se93c5llaabJJOSWyTmv0I0j9qTxh+yf8XvEfw1 0S4k8e/B3RLKDwD4r+HGuXZk0TxDBb6ctp4guLIK8i6bqT6hcagVlhypD7XVlJFeNeBdP8La14hX 40fDuaHw/rHgux1HxT4g+HKW/wDaFxp2u2FnNNYX/he1lDnUfC02oNGZFIaXTwxEm6ILKPB/BXiT QD4gv4vHVsbjSPE8pi1TWoUL6z4eupLr7RHrulSHJM0VwcyxEHzoS8fysVdebJcbmvAjy/MMjzv+ zc9zbHKrhs0pVL0Hg8PSnHkmnzc9HGV8TyYuhiqSjTWG5MRSlepGM0KlXLvZVKGI9liK1S8aqfu8 kVs11jOUrTjNactpR3R9ofHH9n3RfiD8PZf2nP2eb/xTr/w+tltLHxt4A8Ui5uvGfwsnRUt7Oyiu GTGu+Eo4xHFbXEX+qjRUcAKSPiHwrr134V8UeHvEVsXhvPD+uaZq8HJSSObTr6G6UEYyrb4sEfga /XX9iP8Aazj+Gvibw98A/jdq0Unga6ku7T4e/EJGB0S+0fXpiG0bXvPKw33hq5kbzIriUGfT7pSj ELvQfGP7TX7Lvir4Z/tOX3wr8OQf8JJH411ZfEXgMWciyS6j4f128mubRXeQhGniVbiN9rEHyNwP zCvsvETgfLcz4e4a8U+Am5Zji8XRwGe5fQounLLs8ko1KNSjhlWr1KVDH1FU+rxpyqUHUp82GlTh WjhMN6GY4GlVw2FzbLnepOcaeIpxjZ0sRo04xvJqNR35Um43V4tKXJH+h79qu3i+Lv7GfinxHpKf aJbjwV4d+JWkbB8yzaS+meJsrx8rrbR3IP0Ir6l+H2tx+JfAfgvxDE4dNc8KeH9WV1OQ32/SbS6J Bz/elNeJfA2O58afAq+8C+ItHm0gaZZa/wDDSSyuo4Y2m0mzsW0W3ulgjc+VC9u7BAwU4i3YwRW5 +y5pnijQPgZ4E8L+MtLvdI8Q+ErG78LXdrfpsnktdD1G7sdKvFGTugm0mKykjYHBWQGv9d+GZ1sV xhlXEvsZuHF/DWHhiKns5whHFZVi3NQnde5Oos2xHs4yd5RoTtfkZ+xYVyljaOJ5XbGYWKk7NJSp TvZ9m/bSte11F9tPlf8A4Kn+BrTxT+zOfEFxFM//AAgfjLQNbnktlRrmLSr+Z9G1Uwb+PM8u8gIz 8pMYzxX5afBT4QW/xI8M33gKbX7bxX+z3r07P4e+Jdzpwh8Q/B34jagtounaVqNtO4NpdX0qR2s1 rDJJa3ImW5R1MbMv9CP7QXw9X4q/BX4k/D7MSyeKPC2oafbSTYEUN4FW4s53LcKqXUMTE9gpNfz3 aH8aPF2nfGbwZ8AP2eT4T8M+C/AHiCz0S58RvDZSDxedIuYo/E3i/X7jUpWtp5rlkvRGEQO8LxQo WOyv5I+k1wvw/lHjDkfGHEOEnicp4twGEy36vhoSqYvMcbHEV6NTBul7WnSng5YOdF4uVRwqQlDD fVa9Cu4VI/IcUYXD0c5w+MxMOejjKcKXLFNzqTUmnC11FwcGue9mrR5ZRlZnm/8Awxtcf8+3jn/v 1oP/AMsKK/Tbz9U/6Cenf+C8f40V+VrwF8O9P+E2t/4FDy/6eeh5X9gZb/z6l+H+f9fn+VX7Vf7X y23i/wAR/C/RPAGi33gm80pj4pOq79N1fxTN4n0vTNe06e11rQVt7vStPt5JrMvCZJPthtcTMVIA +UfDnxY+A2mah4C1mL4S+LvA3iHwJrum63H4g8H+OI9abXmsdYh1JodasPEmnL0jWRIpYZUdYwsT B/vDjvj1qV54qtvhJ8TtSvpr/V/H/wAMtMXX7qaHymm8QeCdQv8AwTqF00igLM88WjWczFcfNMxI Ga+e/O75HfPPJr8V4w424hxXFWY47EVqGPpznGphfb4PCTdLC1fZ4rCxoydOdSgowdKbVKqn7Rzl KUpVKjl8jjsxxVTGVKk5RqJtShzU4Nxg7TgotpuGln7slrfW7d/tLxt8CtQ8W/F/4palpeteGvA3 wyi1tfFNp498c3raF4WbRfGT2uv6Ra6XcCBzrGqnT9WLpZ2okfbasGKcV+yf7Aur+EvGvwi0LwT4 Q1TWPEOj+DfFuq+A21PXrWzs7vVLd7xdSS7jsLWRxaaVLbaq/wBmjdmlEKASnduA/Cj40+JdW8Tf DX9nG+n1q51LRdM+HeqeFYbB5ZDaaVrvhnxNqFvqEYjbAF4+k3WgMzkFjGIwGKgAfpR/wRS8XLJ8 WfH3gC6kJt5NIsviBYxlsotxoPn6ZqLKOzmLUdOPv5HPQV+ueCmZ5Vl/jPlWUYLL1QpcXKUa1ec2 21jqVPMKNClTjL2dOjTlyUot+0q1GlKUqak6Ufc4fr0Kef0KEKdo47SUm9f3kVVjFJaRinaPVvdt bL5c/wCCnHi6TX/2xPiTo8cJtNL+H8Hh7wBodkoxFaaX4e0SyjhSBOiws8zuuOMSVq/8EzfFdvpP x71bQLlwh8XeBNWsrQsQoe90m7sdZSIA/ec2tveEd/kNbP8AwVT8EvpXx1034m28LLZfEvSp1vpg uEOv+G7g2k5dxx5j6TcaWeeT5TEdDX58fDL4hat8LviB4S+IOiEHUvCmuWWrRwlyiXkET7L2wmYf 8sriye4hb2mJxXwnFGZYrg/6QOc5/madRYPPauLm0rOWDxNZ1Y8i/wCwOslFLRaJW6edjK8sDxNX xNbVU8S5v/r3KV9P+4ctD+nXUfiJcyfHnwx8KdLkTyLb4feIvH3i8hVZ0hk1HTtB8K2Zc8w77qTV Z2xgsLeMcrkH4w/4Kg6tpdj8LPh3ZXVta3mo3njm9nsIJ5Jo3S3tvDmoQXd1E1vIrjy572wPXaW2 hwVJB2v2PvHtt8Yvip+0v+0RLHcWPh++n8LeEfDov1xPpnhrw9plxqc8MoVmCOIvss0oU4LyE8k1 +ev7cHxbt/izrvgvxFdyapYTyR61LoHhWa4tAnh74ey3Vsvh3VdU0tR59v4o1tYp9UPmlVXT57GJ VO3ef3zxH41o4zwn4ixvtliXxficRHARl8KwOGxtDCRqpSTXLOFGNaMPilUxDny8sarj9JmuYRnk uJqKXM8bOapJ7ezjUjBS7aqKkl3lfVJtfoj+xXqnh/xh4y8X/EPSrC7gv/FHwl+FK6tfu9tFbanq ukLqPh3Xp5rGKMtHq39u+Hr5ppTMVmimgcRI5dm/RUEAgnoCCfp3/SvzY/4J1WN74b0D4q+CbprX U7Hwr4l0K78N+JI7ZreXVvD/AIz0KLxFabVfJWzaMwXCJuZUlvpgOeT+kJc+gx781+p+EsasuA8m r14KGKxUsVUrpRUUsRLF1vrCXLdNKsp2nd86tK7vc9nJFzZbh5zX7ybm5WX2+eXNto/eT1677ni3 hHTNB+D3gXxp498WJbaTe6nf+J/iJ8QdWPmT3Ege9v72zgnkUM8/2XR2tLaGJAQrApEvzAV+Y/xP 8K+LPjj8Q/CngyfwbqPi3xcvh3xD8ZvFENr4in8IeDdXOvvE+iaLFqN5pTXL3Vr4UsfCmkow+zeT NPIkiwu8kh+tP2r/AImadrfivwF+zTYWy6rqfjbXvCev+NLNIpbgR+DdP106pNpZSBgVvbtNGkYK T80ShSMTZHwza/EbUfCnivxXqknii4+KOoeL5/H1l4yuLnXjH4V+HOm+ItC1QWfgqHTNLv3uNI8T yXFvZ2VzqcDS6ZAsUVtaSTyIXH5P4l5nk1arg+E3K/DeUVaOHxUqapS5sQpwxGKhOE6dWM6yTwrl Vhh6rp+3xjrqMHK/j5tVoOdPBX/2WjKMZtKOsrqU0007te421F25qjlZHz54Q8P6VBoXxOn+KnhG 6h0/4c6honiLTNNtkdme/m8QPoVz4Ai11Lp3j0e7a6tQ8gnlMMWkSSxN5zAt+hv7Efw31TX30H9o rxN4q1S01DVI/EVv4P8ABmka/faRpV3d6RdT6Sq2+hpdJCmg6fodl5UMBLxt9qMsx/coX+Lfhj8C W8Y6L8VtS+HniCK7+H2pfDOZpIPE7XGna/oviIyab4r8OaVNbLbeV4juS+j33kXVh5nmxRSNLFDJ mOv1d034L3Vxp3w6j8ReKGs/hN4I+H+jtZeDNBVNBn13xTdL5zT6lqpkj3wy2U9raxWiuvmXLtIW VmXP5/4UcJY6WYYDOquSfW8JlVJToJVaahXxX1+r7PGVcVFRVShgsLCUabjSqclS8FRb5qT8zJMF UdSniJ0OeFGKcfejaU/au03NWvGnBNK0XZ6KO8Tovil8fPBXw18Ia58U9Y046lpWt6xoGneFvEL6 xHrc3jTVbkv5kkNpHP5lv4d0iSymaSEyBZlsZTBGcxu/4ueOfBWmfEfxJ4y8V/D2407Ttdm1LVNa 1z4U6hqclx4h+1TMNRu774fXRgI8a6DcfaTc20Y8u+iikKNDKiCU/anizwh8Y/2jfh14x8LeKvh9 pfgvwzo2qN4j/Z71C317wpDpfhpNFtodHtvhz4kaw1R40OpaNOhtLhiT9sLbj5RUj5OsPhv4M0gP Y/EfX9d1j4g/Ce2lk8SeBfhtbw2mupo9vPFHY6ZJ4r1mWCOfVtM1G5X7RLpsF7JDYzgoXS0Lji8W cbnPF+Ky2ljcqS4XlSdWhVxNL+zav1pzq/W5QnUpxq83J+/w9JQxHt8HCNSrTq4rmnTnOqmIx06S nQ/2RxbjKa9lLnu+dq6Ur296MbT5qau1Keq9P0X9kTxz8V9K+Glz4bvdKtNDg8GeC7ObVb23lsr7 VZ9f1TVdb8TzWdow3TRaFDqP2a5kfAM0EcAG58L9KftIaroPhf4Xaz+zL4L8MeJdG8B+B9C0yTWP iWAtrog8VWLx6vHoesx3EaSa1BfTPAb64tTK0N1fwjy2ijcD2/xV4q8G/srfAPwrruupqEXjK48M w+DdBvkey1vxktzrktxrt1uuNQkhh1R7Ca8kurlyI45poFB2+agH5B+KNC8R/ErULzVtD+K3/C07 a2e6n0628Y+Ijo/j1Vug1zLax+FdevSLjUZJIioi0ya6jldU2YLKo5uL8Hk3hxk1fI8gy/65xlxZ gKEMzhCvSnVo4KpQaWDhTqReIpwqvWv7CnKq6WHo89eFSrGsGNhQyuhLD4enz47G04qqlJNxpuPw JO80pfa5U3yxjeSlLmPG4C0jIqK7yOyqsaKWd2dsIiKoJZycAAcknA5rSeK4tbia0uopbe5tpZLe 4t5ozFPBNC5jlglicAxyq6sGUjIKkEAivavB3wf8VaBZaB8TfEtpFpui2q+Ltfs9HuWnj8RzTfD+ xmv5JbzSJIFex0460mmwNJIQT9rUqpDA14U11NdTTXE8jS3FxNLcTzOxZ5J5XMssjk/ednYsfdq/ kvM8jxeV4XC1cww9TCYjGvmp06keV+xdOlUhVafvctVVouGiTim+qPk6lGdKEHUi4SqapPT3bRad t7Pm09DYs42uri3tUdUa6uIbZXk3BI2nlWJXfYrEIC4JIBOBwCeK9K+KmqQ6l4816K1gt7ew0KS0 8KadDbg+Wun+FLODw/bSGRlDzySDT2ld3+djMc4GAMr4Q21hqPxQ+H+n6tZRajpmoeLdDsb+yldk SS0vb+G3nYyR/NGyRyNIGH3TEG7Vl+Lr4X/i7xVfrerqK3niTW7lb5YBbJerPqV1ItylsHYQxyBt yoCdoYDJrB0pUuGqtZTjy47HQg4/b/2ahN31+y/raty3TavPlap8ztbCt3/iVErdfci/w9/z87aX +qPAmgWM/wCx18YtX1y+1S1sk+I/hS50e3s7GO7Fzqmm2EtnENzyqLWzkuNYjjuJyMItptXfIQtf GbN6dR+XfI59/wCVfdK2N4vwV+O3wx037Rrmj/CzQvh3rF1Ppt2LO1bxTda9fX/inW5Y51Ml1p8C X/2Y2+QHGjxyjaw5+EiQ3KkEcjcpyDjGenvmvp+PcNDDYTgTDQocjwuUOjUn7z58RRzPMaeJXO26 c4U60Z04Ok7OKTfxI6swioQwEVGzjR5W+rlGrUU+rTSldK2liNmPv9c479vX/wCvXtnwZ/aS+NH7 P2oyaj8LPHGpeHormZJtQ0Vil9oGqMmADqGjXYaGdsYG/aHAGAwrxBj1zkevJI9cgdun619rfDj9 hP4x+Kf+EM8W+K9Ki8N/CbxJolp4vk8bpewahaz+HjLE02nWi6e0jQeIpLYzeXBKqbdjOx+XB5eA sq46zDPKOJ4ApY+Oc5a4T+s4B1qc8JGc1TVWriKTj9Xo80lGdWpONNJ2k7OxGApY+pXjLLlUVelZ 81PmTgm7c0pL4Y3dm20u5+nnwJ/4KAfEz42fCD4z618T9L0nwBo3w78HvexfFLwXHdDWX8RNJCiW mi6DeySRT6strKXyjiONrmPzFCsCPmm5/wCCyXxg0/VriHQfAHhTVPC9vBFaaUfFkt/L4luFt1Mf 9oate6TcQxNdzAK7xpGVQkgO5ya8a8Jap4u8f+Bf2jPDfw+8DeINI+FPhD4a3mk+APDOn6feXtu0 j+MNCn1bXNR1cwAa54nu7C1muLiYuxEKrHEoiQA/nl4b8K+JvGer2+geEfD2seJdbvDtttL0TTrn Ur6Y9CVt7WNmAHckADHJFf0txd49eMmXZZwHhMh4zzDFY/GYavCrmCoL2mZ16OPxFCMaUJUuWpQp K0aMpUViq8HTq4q0nTpUfpcbxDndOll8MPj6s6k4yTqKOtWUako2ScdYrZe6pyTTnrZR+lf2nP20 /jP+1Pc6dF45v7LRfDGkZfT/AAZ4ZF3Z6CtyxLNf30c87vqV9ghVklZgirhAozn5k13wv4j8MjST 4h0XUtGGvaVba7ox1G1ktv7T0a8Li01Sz8wDz7KQxuEkHyttOOld546+BHxl+GNvYX3xG+GfjLwX p2o3UVnZ6j4h0S9sbGW4lOVgW5kj2ecUyQmdxCkgcGvq79trwRJpugfCfxhf+KBqF3b6Np/wt0zw 6kJt7fStC8C+FfDsn9oWkcoEhjudW1a/YkhV4BXJY4/GM4yvjLi6jxzxfxvicwxPE2RrAVK/15ez quniqkqSlUhiOSpGnCMIRo06MLe/G0VCLa8OtSxuNjmGNx8qk8Vh/ZuXtNJWk2veUrNJJJRUV12s fnruA6k5AyeP58cdRTQ3GSfwxz+fSm9++PTPoOnPUemfSkyc9TxyOf51+Wcr26/1/W55B9ffs9Wp 8PeEP2ifE8rJqFmnwGvbEz6ZIsiadf8AirxFo2lWdnqUskQNtd8TFo1JLKMbiCcea/Av9nb4t/tF +J08LfC3wvd6zNCYjqusz/6HoGhQOyr9p1fVZV8u2Xk7U5kcjCIxr7G/4Jw/COw/aF/4Xp8Dta1T U9C0LxV4a8Ja1qusaPbxTXyQeHfE8Ex0+KS4/dw+eJz8zZx5OVViMH+lv4PfBr4e/AnwRpngD4ba DbaHoWmxr5jKqPqGq3m0LNqesX2wPf6hIwJaR+mdqBUAUf3F4K/Rrr+M+RcE55mmZPKeBMro4yOI 9i4vGYjGf2livaYehzKSpU/YxoTniKsZWc+SlTm+aUPvci4XlnmHwFerU9jl1KM+bla55T9rK8Y3 vZcqi3J97JPdfmD+z5/wSJ8F/D270bxZ8TviN4j1/wAX6fJHdpY+Cp28N6JZXAAJh+3yRvdajFyy uCIUdSVKlSRX2Xc/sAfsgXt5d6he/A/wtdXl9M1xdTSS6snmTycyyrDb6ikcJZssQiKuWJCjpX2L TXdI0aSR1REBZ3dgqKoGSzMxwoA7mv8ARLh3wK8IeFsqp5RlvAOW1sHTfO3jMPDHVJVOXldWdTGK vLnlFWk04q2iSikl+l4bh/JsJRVGll1KUFr78VUbdrXbnzO9v6sfHet/sHfs16n4YtfC+meBk8L2 +lXc+oeH7/RLqR9R8PX1yQ1xPpU2ri6EMcjqjPEytEWjDBFf5q534nfscaP4x8O/C7UtS17WfFfx I+CL3Fz4W8aXyWcOueINLs0uLuw8O6+kKrFekXItkilUJsaIMVAd8fVd/wDFX4YaVK0Gp/EfwJp8 ysVaG98XaBazKw4KtFNqCsDnsRXS6R4h0DxBaR3+g65o+t2MzFIbzSdSstRtZXXO5I7izmdHcbTk A5GDnpXVW8OvCvNI47LsNkWW0p4ulRpVaWEVKkuXDVadbDTlh6DjT9phqtKnKhVlTdSjy8lOcYSl F3LLcpqqpThQpRc1GLULL4WpRfLFpXhJJxdrx2TSbR+Ln/BLLxbqfhHx98Y/hH8SNd1vSviPr+r3 HiH/AIV/4o0zU7bUreTSDIL7V7bUbxilwJoLtg8QCkC0WRS6k7f06+FyeJdA+KPxr8L+IfEVnqum ajruleOPA2nS6zDd6zpOg61psVtq1lLpjN51jpUWt2kgt2I8s+cwU8Yrr/Fnwg8FeKvGPhT4jT6T bWfxB8FXTTaD4rtI1t9T+xzQyW19ompTxAHUdGntZpUaGTdsLCSIqwO7yjx94Z1jRP2nvg18TtIt idH1zwv4u+GXji4WOcxxW7iHX/Cs108MbBD/AGtFcRRvJhQZNpZdwr4zg3grO/CrhXhrIsVinxBg uE86jTwmJoyrU6lbLM3qSw1SWPozlWUquExOOnXrRhJYf2dGlXp+y5ZUo8WCwNfKcJhcPKf1iGEr pQlFyTdKs+VupFuWsJVHJpPltFSVrcq+oL21ivrO7spl3Q3ltPayqSQGiuInikUkdMq5r8O/Cn/B L3Qpfii2v6trt7pulad43S7HhzQdRXVo20+Cf7dFHqMlwlvfaak8hQgmN1iRGzIysklfubXyB+0R 8KviJqOreFvir8F/EUGh/EXwC2pajq+ltpMV5b/ELw28ERudBlgLqj60YbCK3tpHYNi4Kb0U17Hj P4ecMcY4PIs74g4RlxjU4Qr+2p4WlOMK8qVWpQWIdLmlD20qcKarfVnUpxxCpOnzc7gntneXYXGQ w9fEYN414OXMoppSs3HmtdrmaS5uW65uW172Pgj/AIRHwL/0M9n/AODBv/jtFfMn/DTXxp/6Nx1X /wAJyX/5Eor+Iv8AXvgH/oEr/wDhmzPy8v6ufEf2jl/8kv8AwRW8v6/4Y/HSyuNT8dfA3UtMMs9/ efBbXE13Trc/ObLwH43mjsddWMdRZ2viyDS5iOQh16RuhOPDDN9PXjv7da9o/Z1kub3x7J4SZZ10 f4m+H/EHwy1K5Fs0lrFc+KNPf+wHlkxsSRPEtrosiBmUnZx1rxW6hjslNvO9xFqtre3NnqNlNEFS I28hjJikHIYOjo6thgwyvAr+Wsyw7xeW5Pmck/ack8LUlJ6zlhfZqm1fdRw1ahSiu1GVvhZ+dVVK dHD1nvZwk315OXlt6QlGKX90+g9ElTxF+zV4404wrPf/AA5+JfhfxXbTFAZrPQvGmmX3hvWBG/UW zatpehFxggM6twSM/pD/AMEbPBOt2fxa+IHxS1O0fTfDVj8H/Fdpo+pXkkdsusXU2p6bY3Z02F23 3trbzKqTTKvlRyssZcyHaPgT9j2/0DWPibrvwx8SaTYar4Z+LnhTVvDS6FqmpzadbXviPSpI/FHg ixk1eErLAJNf0m2tmZCrut6wHJFftD8IfDei+El/aXvrrxL4N0PXPBv7GNl4W8RWngTUbLUF0nVt DvZ7+6u9G8MWLGPwtp8V60VjFBczLc3c8RuZIxl5H/f/AAV4ep4ziDgzjiVRVo8Ne2ozp39m3icH SxWJpSnUlHl5I4V0FTV4uThLmlBQhCr9Rw7hvaYnL8xc1L6nzRa2vOmpzjdtWsoONle7s7tJJSr/ APBQf4YP8Rv2dvEGqWVsbjXfhzeQ+OdPEab5nsbNJLXxHAmBnadHuJ5iB1NgvHFfzfed7g8enX3+ tf1rfD/xNpPxX+F3hTxS0Md5pPjzwZp17e2kyq8ckWs6Wseq2E6EYysst3C6kcFGBr+Xn4+/C+++ C3xe8cfDm7WUW+hazM+izyAj7b4b1D/TtBvFY8Pu02aBXI482N16rgdP0lOGqVfE8Pcd5fH2uCzi jDD1pxWjmo+1w1Rvq6tCUorsqEV1K4uwqlPC5lQV6deKjJ20btzQk/8AFFtf9uo/T39lXWp/BP7A nxd8V6dK8Go3fjTUbaOeGJZZUlvbjwj4ejZYWUiYiK7fCkENnGOcV+XXxj1HVL74sfEm61u6N3qk vjbxKt3OZo7kFodVuoIYY5YSUMUVvHFGip8iJCEUBVAH6ofsQanpV9+xt8QrHWoIb3SNC+LOnT6x a3DTLG+mS6l4I1Gcg2o82OVVSV42QqweEfMBk1+aPjj4b+NPE3xI+K2o6D4X1C28P6f428cXUmsa vImkaFb29vrOsTpbjXtceC3uryRLWZYYUkeaaQBERmNfI8fYHF43gTwwp4HnxVGWW0EsPTU5ONSn PGe1qyhFOPvOXKpaNckk7p3XBmcKs8ryVUrzTox9xJvVOpzSsl+O+jvofsb/AMEwdZ1LXfgv4qn1 WZbubSvGFv4csbx1/wBLOj6VodlNp1hcTdZ4bYX88cG75kiYRZ2IgX9HdR1Cy0jT77VdTuI7TTtM s7m/v7qU7Y7aztIXnuZ3bsqwxuT9K/NL/glgoPwD8VzBkJm+JmqEgMpddmg6Cq+Yg5QkZIz1HI4r 3P8Abx1+88O/srfFG6sLyWwub+20LRBcQO0cph1fxFpdpdQI6kEeZaNPG2OqyMvev6k4CzWWR+DG U53VTxEsqyqvinGT1n7JVqqi3v73Ko387n2uWYn6tw9h8RL33RoSm135VKVr/h1Pl3xl4R8Q+Pfi H8X/AIzaadN8P+Ibr4SajYaBHeTS2qabe6bqXjX4dPq91dCORoZjo8ENzCkLPI08kWFA24+M/hj8 FZvC3jK++JHhnx74UvvDfwtZNav7bUdQ0b+2dfsdOhig1y01HTLu9j0/RLW7u3vLe2tNRvPtNxH8 0dvP5cjD6ltLjTpf2XdN1P4n+L/Cngnw58RPC/h3RbrRvE1lc2lx4gsfD+s6nq0s+kaLBci7Pilt cuXju9Qjtii2rLcJHNI0deVeGPCvwt+LOuaVbfBDQ5te8DeHNama/tvHfm2Phb4X2EUhfT54vBFn cwP8Qtc1GKG9uI9U1W+Yxqrpc28EVvtP4Jn+V4LM8wyDGRw0KubYpf2hGk8W6eMqYvGVJ1fbww9G M5KnGKoV6tRwSajTTVPDU61dfNYmlSrVsLNRUq8/3qi6nLUlUqScuZQim+X4ZSdv5doKUj7E/Zn8 XeBrvwxFe+Eray1nSbn4hapb6VHrulafolj8G5NN8Pz3d3Z6xrEE8MWu25XWLxrE2cIhhjvLmECJ CzL1X7V/xOsvAfwh8K6j4oEbeLvFaWPhyw8XL4auNY8LaN4i0PU7XW7zVP8AhENQnjDaebvShPay bZLgRwQPGk6ptP5t6x8YNDs/Avis/EBJbnXviV8TviLeXa+B7LQZjf8AhEW+h6S+n6R4iWcWGjaW dW062E0tpbXMl8uj+QXFu8vmeo/tOaxJ44/Yp/Zp8ZWR1GawtPEur6XfS6nqLarqMM4ttWsLVNVv /KiW+vj/AGa4klESLu4REU4r1Fx7KPBHFWU5c6U8flWUrExUVKPuVMThaM5Sw6c5UZKjWVSLeInO hzyhQdKjSpHRHM/+E/G0KVnVoUOe2q0c6cXeP2Xyyuvfbje0bRSPhLxj8SfHHji+WTxR4tv9bjsJ Zk0+O326XotspuZJzPpeiafb29vYeZMxkytvHISwL/MOPt74IavoP7QXiXwX4k+IfheD/hJvg9f2 niX4nfFJ5PsWgax8KvDWkz/Y/wDhNreOVP7Q8W/2lZWFnbTxEPcxI/2hZQjA/EXwj+GfiX4xeP8A w98PvCkDS6prl4EmuTGz22k6ZERJqWs3xUfu7O3tt7sT95tqL8zqK/RH9tjxd4O+Dngvwx+yx8K7 SysPJ0jRLz4latZQQw6nqttYCS50TS9ZvIR5lzcXF9Nc6jcJIxCCaFAAkhFfhfBtHMaeWcQ8e8QY x1+HcsqUIzo4le3/ALVzCEva4TC05VudxlSaU6+IjerRws6sYO1WR4GXqoqWKzLFT58LScbxn73t qqd4QTlezi9ZS3jByS3Z4D+1b8cYvj94k0vxpp/iCVNAtZ9X0LRPh7dI8d74Xs9Plt/J8QS7F8m4 XWIZElLA+dA9o9s4McUcj/LUbcqw+8CGVlGGVwQQVb+HBHGPzrJjbPTjPIH49fbitSyj8+4t4AQG uJ4YFZ87QZZUiBbH8OWyfbpX5PxJnWP4nzvG53mUva5jmc1KrJOVpVOWMbxUpPkT5bxhFqnTVoU4 wpxjFeViMRUxdeeIqvmq1XeT7uyWl27LyWi2SSSS/RHX/Gtn4e/Zs8D2/jE3nia+1rwvbaTp9pPd S22u3Fxq+tS+Jbyx1HxCytcJ4Ij8N6Z4NDW9qyyzO/kvJGGLj4z8U+LdQ8Y6rHqt/ZaNp32fTtO0 ix07QNLg0nSrHTdKtUtLO2gtoSWdhEoLyyvJNK7FpJGJr6Q/a5Wyg8T/AA98A+FluLzT/C3g68a3 srKJrlIQuq3+lubVIYzI9rFpvhm2BZwzJHBukc8tXyFGwGMHOBz9D2Fe/wCJ+Y4/+13kEq3tMJkl DCYRzWvtqmGoQvKdV3lUcJ1ZxinLlStJRjKTv25pVqe3+rOV4YeNOF19pwir3lu7NtLWy3sm2e6/ Aa20+b4gR6jq1teXWm+GvDHjLxXcLYzfZ3ifw/4Y1O+tZZJfJcpD9tS2QlQG3SqVOQAcb4V+Hp/F nxA8JaNBErQy61Y3WovLg2tno9hcJfapeX00uEhsYrCCYySSFUVRlyBVX4ayPE3jq7SYRJbfDTxa sincDOt+lnpQhUL94+Zfox3cARk5yBX2T8GfgD4v1H4TWviv4c6Nc6p41+L+j3ngezvtQUwaL4W0 CXV9Vj8ca5qLXlsUhs5dDs9GsrWVBI0z6lcNbgspxycJ8N43iZZDgMFl88bHLJ4zMcRCjDnr1qSq YKgqNOMYuUp1atOnQpKV4qpWcpOMLtGCw08V7CnCm6ipOdWSirylG9OPKkk3dtKMel5anWeCdT8Z Xngz43/GfwVoPiGw8UfFvWvB/gvwhf3K6Bf6brviXU/FrLrel6Ho9vYLANNhjthAGuVkUwsfN3Mz tXzDP8WLK41C40zxx8Cvhz4u8aJqFxot9qVpbar4c1K6VVk02ewTSfB93DZPrSXCjyLyC33o0YPl ysQ1fb/w6m/Zz/Z28L+N/hX8SvjtceMdV1oiy1fRPDena5JYeCb5La6tL4+HJraCX+z9f33tyJLp HSVfKUbFYNn481n43+Cvh8b7S/2bfCFz4WeeSVLn4o+M2tfEHxFvoMgIuimeA2/hC3PLBoEN2xOW lRsiv0biuCynKOFqmacZ4PAYvD0MQsyy2NTA5zXhjZ4zEYmrOOX0qdTBxxNWeIb9viMRh3RoxjRn VnWhL2np4z91Qwjq46nCcYyVWknTryVRzlOVqSTp87cn70pRcYpRbct/S9c+En7PPgXTLXxd4+i8 Q+DfEMGh6tr8PwA8ReL4dT8TeIZJYtPPha3vdV0bR0l8MWE1xLemS3utt5JbIkgKYcV+1v8AwTg+ Mtj8ef2d73QNV0Dw/o//AAgWu3PhUeGNCt5rbSdO8OTwpe6BDbJNcPKWWN7lDM0nmO8JckMTX8tW qapqWt6hd6trOo3urapfzNcX2pajcz3t7dzt96W5url2eV8ADLE4AAHAAr7a/YV/bIuv2UPHWoR6 xph1n4c+OJdNtvGFtAManphs3kW01vSxuCyXEK3M3mQtxMhIBVgpH0XgJ435BwZ4r5ZiMVl2G4W4 HzWjXwOPnChCVSr7WEVQxWNdKnGKjCvSoudLDUqWFownWnCg5yqTn1cPZ9hsDm9Kc6UcJgKsZU6j UVd8ySjOpZJaSSbjBKCTk1G92fur+2H+zzoCfs+fG/Xfh7ba7pnii48CzPPZWOv6w+najbaRf2Gq MRpUt40NvdRWljMEeBI2ZGZH37uLv/BPr9mHw/8As/8AwQ8Navc6Tbf8LK8f6TZeJPF2tzQRtqNv FqcK3enaBb3DLut7KCzlhLopUPM7s4O1cfX3hrxT4M+Lfge38QeE9Z03xR4Q8WaVMlvqFlIlza3F re25imt7iPOYZ1WUrLDIFdGyrqDVjxb4z8E/DDwxP4i8aeItG8I+GNGtUSbUtXvIbG0iht4gkcMA c5nm8tAEiiV5GxhVJ4r/AE/peHvBFLjbDeLNOOEp08DlDw+GqR9jHB0YVa9TFVswpzVqMJ1aVTke Ii0nTlUk5Pnk3+qxyzL44+GcRUIxp0HGLVlCKcnN1E9k3F25uzbvqfkD/wAFi/iPbQaF8FPhDHOG uPEHi4eMNYtgw3rpulyJpWnlh/AHub2+wT/zxJr4l/4KCaZfazo82r299aalaeAPirf+FNShtnil OgWmu+CfC114UsTcBt1zvsdJvA4AxDLbMjHJBPmX7UXxlsf2t/2zdF1HwjLc6l4QuPEfg/wN4MSd GtJLvTLfUbaGW6SGYg24ub6a7lG7B2yLkBs16Hr1kPH3xF/bl+BEmq2c3iPWNYuPGPgSxs7abUBr PiL4Z311cXWkaS5XdDfSeGnv13YDObbYMg4P+eniJxlT8TuJvGCeBmsblPE2YYTKMrr06i5Ks8my vMq+EjSbajVWOxlGl7KN3zfWrRXPOm1+bZnjY5ris7dN89HF1IUKUk9JOhSqygo9Je0nFWS359NW mflhz/kdcelHYknHQgY5x3PTpxSyKYmaOVSjozI8bAh0dG2sjKRwwYEEex9KidxtOPTt+Hr3r+KU ntbU+CP6qP8Agk98E7H4cfs22Xj+5s418T/Fy9n1+6u2QfaE8PWE81hoVirsMrD+6u5yBwxugTna K/USvnH9kGSwm/Zf+BEmmFDZt8M/C4QxgBfNXT41uun8X2pZt3+1mvdNRSz1mPU/D/26eCV7JEvz p1yba/tbXUVuIY2iuIzvs5nWKcpIuHXy9yEHBH+//hRkmX8K+F3AmTZXTgqGHyrBuKi1FVq1bDxx Fapf+atWnUqyer95vWx/RmT0KeEynL6NFLljRp26c0pRUm/WUm2/U+M/2i/2ydG+HkereCvg9d/D /wCIHxis7j+z7jw3rXjrQ/D1l4cuZIt6y6ob68iN/cJnm2hkDKy4leMjafyQ/aT8E/8ABRb45arZ 615PibWvBuqeE9G1iPQ/AHiqxHheyuJdLhfVrdbHR9T/AH0xukuSA3mllOEZhXY/tO/8EvLDRfjN 4Ik+HV/4muPAvxc8SL4fu7u/uZ9YvvA/iu7mN9Jd6vfNC82o6HdWMN/5ckhWSO4AEspUAv8Aqp4k 8H/Bj4c/By9+HHhfW9O0rVfhh4W0PQrK++0yz+INOlvbq20rSrnUEgmSS7F1qUsaPtbAaXaCm1cf zBxBkXiR4wY/xAyfxOrYrgTh/hiUFhsPlmcUaOFxko06uJhCn7TAOeLVTBv21atWq+zU1CMaOHcK sKXymJw+aZ1VzKjm0p5dhsJbljSrRUJ2TlZXp3neHvNydr292Nml/KZ4f+FOvarq89p4zm1fwfbw eJbPwpdavq2g63f2w8Q3kskaaWZ44tovcRuwRnBdVLDKgkftFr/hpf2HvgJ8L9IPxX0zw7qdh4xl 8SeJdIvtB1nV5vGviWW3iuLyCxn0v95pUGk2I0yGCaKQRm6u7gSswHln9PfBXwt8Ua1pnhDSPizo HgTxBpuh6Nomu3d7NZ3dzrafEu0uFmlvbVb5XWe0htEtYhcTvJOxjeP5kJY5n7RX7K/gj422R1XV r7xRp/iHS9Ev9M0m60HU/KtYLm+uvtcd7PoFzFJaanKLx23IyrujkZVO8IR4nB30Xsx4E4b4nzvh nELMuMMfhqVLA1sbHFYGvh4urGviozhQxnJOf7ulCk6dSjCqoVYV5So1Z0zHA8J1MBhcVXwkvaY2 pGKpuop05RXMpTuoz1eiSs4p2kpNxbRwH7LH7dfww/aOsLXT7XXLfQ/HNpFs1Lwtq7QW11e7AV+0 2J3KJULDIkiymGxLFEcY+7Li3juo4t6KwSRJgrBX6A5UEZ5IJGQefXFfmR+zp+wdoPw+1G58S/EY /D/xXqGh6lb6j4Q8XaB4Sm8MeJZY7WFvt0msrFeIkN1DeBgDHG29VDFuStff/g7x/wCFvFV3f6V4 a1aHXDozmDUbqzmF7BbXJJMcE95Eoj+0FEkLRqWZCuHwa/qHwnzXjurwxluG8VI4TDcQ4tyhRVOc Y1sTGno5VcPGdWlGraPPJ4atVo1IWqrlUrH1eT1cweEpRzdQjiZ/DZpSkl1cU2r6XfLJxa106+hV +fP7UX7f3wf/AGafGcvgvxBoni3xJ46sNJ07VrbTtKtIYNKjt9VJZd+pXNyqm4a1ViT5ThcBQQc1 9/QrMktx5s6ypJIJLdNqq8EXlojREr/rF81XYMef3mCcAV/PR/wV/wDAnhlvjN8KfEVlqkcHifxh pUfh/X7KeVVjtbCxvYYNI1dkxuS3IvLuN2+6fsfHzA14P0leNeMPD/wrzDingqrhsPm+BxeEpzli qcKtqNeo6HNRpzlySrqtOhOHOppQU5ODcdMOJ8djcuympi8DKMK1OcE3NJ+7J8uiejldxa30u7aH mv8Aw8m0/wD6EDU//A61/wAKK+Zf+GXLH/ofPDH/AIN//tNFf5nLjr6RWn/ChT/8F4Dy/u+p+X/2 jxJ/z9j/AOA0/wDLzPyi0rW9R0S+sdQ02/urGfT9RsdUtpYJpYxFe6dcx3VrdbI3GZY5YkZTjIKj GK+jP2vfB6eEfjdr19ZW8MGgePtN0D4i+HZrS3NtY3dh4u0i01S6ltY8kADVpNQDDqGHIFeMWvh7 wPr8NnHo3jX+wNZu7i7SXR/G1mbLR7SFZJnsyvjHT2lhk3WqxK5ntLUecxAITBr7K/aI8HeMPH3w 8/Yk07Q3tPHvizXPhzrXgy1uPC9x/atndSaN4ggt7C1l1BF2L9ls50juZX2xxfZnZ2CLk8OV5LXx vC/EuHVL61VwssvxWHdGcKzcnX+pzoqMJSlGVT6/Tm48qlzUoxkk7I8KjQlUweMilzyg6U4crUrv m9m42TbTftU7WveKTseE/s4Xnh7wn4l174yeKNKvddsPgxpmmeL9I0SFmgstb8Y3Ou2GleFdM1W+ QF7Oz+13E11uRSWbSwjYVjn9Y/2dfDun2nif/goBrXhVJj4Q+MP7KWpfF7wNfZMkV1Y67J/a+o2s dwq4e4stefUbWZM7onttj4yM/kH8RfFOgeD/AAg3wM8Etb6jFa6/BrXxN8cxlifGHjHSYbmxt9H0 Tp5fgrSXuLxLVmAe8uJJbxgqGJR+k/8AwSK+INz4s134v/s6axGNRTxN8FPid/wr6aV83GlXusaf AniLQIGkYY0q8MVld+XnbHc2DOuDM9fpPhNicDR4t4c4NqSg61SddqtCKf8AwpYnCYzCTw7qpOU6 c6FenQvC9P61Qg6d6c51ZexkVSnHH4TL205ScveS/wCX06dSm4827ThKMdLrnguX3W5P60/4J8/F HQviB8BNP0rS1kg1fwVqF5p/iayMbJZWep61eXutqmkKUVYtKZbh3ihTcluHMIZgleB/8FRPgc/i HwjoXxz0GyMmp+CxH4f8Z+QmZJ/Ct9cltL1OUAZcWWqztG5/hi1TcSFj48D/AOCbfxGuvhX8b/HX wE8Z2E+hX/jC5uLS2s9Qs7mHU7Pxn4TN2f7JvRK4W1ik0kajt+Tc80cY3Mrrj9x9f0LSPFGh6x4a 1+xh1LQ9f0280jV9PnUNDeafqED211A4PTMUjYI5VgGGCAa/c+FcFhvFDwchkGYSjTzDDUpYGp7v K8NjMFJfVpSj8UWoKhKolbmjOcUkpWX0eCUc64fjhatlVjF0m7WcKlN+42t1Zcjl3Ta0Pxj/AOCX 19aeKvC/x8+FGoeXLbalD4X8Rx2s7uqTKzXWm3eQhyEEltpu4ryNw718YeOPG/jb42fFDxd8NfH/ AIw8UalJf/EjW4/A9ndSJc6N4b18a1c6d5Z0q5mhFlpT6RF5BWDY0bxRTFWCSB/rX9nPwLrf7I37 e0Xwv1uSaTw14+0fX9G8I6zOGSDXtDv1Os+G7nePle/ivdI+x3CZylxuH3XUn5c+N2meOfhz+118 XvBnw505NX8T+K/Gd5baBay+HtN13VJG8YS23iGyOiR6lbTCw1FJdQUJdxBJIliL70G41+E5xSx+ G8O+E8rzGnXo1OHc3xuT5jh6d5Tq3csVh6TpxnD2nu1aqoSu0nL2kHdq/wA1iPawynA0aylF4TEV MPWgr3lf34Rtdc2kmodm7rWx+qP/AATG8L+K/CfwU8Y2vinw/q3h+W7+JOoz2EWr2c1lJeQW+j6T Y3NxbRzqDNai8tpoxKBsdom2EgE19SftN6v430b4P63qXw68JeHPGvjGDUvD66Ro/iewTVdOt5p9 Xtrca5FpU3yX97YNKlzGrfKggaZsrEQeo+CPgjUPhv8ACP4eeCNYvZtR1rw94W0uy1u+nnNzLcay 0AuNTZrhuZ1S8mljRySWSBTk15N+1r8Qbv4W+FPhr45tIby5Gh/GbwfNqNrZxNN9q0GbTPElv4lj uFVgRAnh+XU5s8gPaoWG0Ej+osLldPhPwtw+W4jE1sHDAZcoVaq5Pb4d1VepOPuuEqmHdWXKrWk4 JJ3dz7SnTjgsljh5zlT9nSSctOaPMtXtbmjd201sj8yf22fC3xH1bx38G/gzDZTeNfGmneG7XxD4 h8dnTEga/wDF3jXU2GqqdTKLBofhK2vLMypCWit7dLjeQqIu2hb/ABG8B/D22WC51zRPEGmwX+s/ C3RP7AS4n8K20msaDqF14+8fa7cRpbt4+1mfxLc6DJMyMltp9lqgsbW4njEqj6N/bS8cXdldaf8A BDwwl14f1v40eEde1aXxHHf3F3camlj4i1fU/Dvhf+1FjM13BrKm/tjbIEW3Or21sC8Jevyn+Llx ceHj4c+EnkWsdt8MdPli1CX+zIrPU7jxj4ngsdZ8YC+ueZJ4ra++zWECM2xI9HDqoMrV/LHiDiaf C/EvEeY5dVljMTKeHpOdVSnClVjCn7HAe9KNSq4YRfWK2IqpqdaFJKCrw9qfGZpUWCxmMrUX7Sbc Itu7SklHlpatOVqfvynLeSjpzLmK/wARYhaN4ORoWtbi98G2Wv3ttC3laXb3fiHVNX1NhomnRAQ6 TpJtJbMxQwKEx8/LOa/Vz4v+BZdC/wCCcvwm8KWti97rt7f/AA81O105I2e/n1rxhqF/fC3s7Xbv lunOrNGigAnaeeMV+cXiXwTLq/xO0Hww1xBc3NjovwctjapcxzyX2haj4e8KwXgtdrFWubf7cHkt wPMETzOVxE2P6UPFOjeAtEg07xh4xn0zS9F+Hy2uq219rFxFa6Rocml2N7pOn37+cRFA0EGq3ixE glZblGX5kSu/wm4Medw8UvbVIYGFfBwyp1allGjTqymsRXf2b0lhIzcW4qTd3OMXzHRkeB+sLOOZ qmpU1Q5n9mMm1KV9rx5E7Oyb6pan55eH4PB//BPL4AW3iHXNO0/Vf2g/iNZMiWEkouJFvNomj0wy Lhrbw1pkc1s16UI+1XeUVjuQr+f/AIi+PPhf4ytf3nx38ERzeL7gxzQfFD4Y22n6B4rna3UQW2m+ ItEv5Tp2t6atqQiyKtvdRi3jHmuM4439pj4veJvjN8YPFHiXxE0UMGnX1z4f8OaVZ3kF/p+j6Bpd 1NHZwWl3au0V40pLTyzoSs0lyWUlAgHhsR4xzyAfX69T9K/J+OvEKdXFw4Z4ZpQwvAvD8XhcNg61 GE4YlwvGpjcVCcbyxVefPUVVclWkpe5KE5VJS8nMMzcprCYSKp5dhVyQpyimpW3qTTXxyd3zaSjf Szbv614i8K+CoLCXWfBPxEs9dsIkt/N0PxJpd14Z8aQzS7Vkij02M3NnqVvGzD99b3pyoYtGmMGX 4Y+HrnxF8QfAejeU8cWseJ9IjWaWCRoGtINRik1CdeP38cdvFOX25C7CDivMIznv6enTJyPpmvsn 9liwuNeutfEesaSb/wADaP4o8UaFpetNPCunT6j4T1jRm8QafeQl2lgTWJ9DhubCK3me4kvLecDM DGvz3I8HhuIOJ8qwsMFDBQrVablSpSm4SVOaqVbe2qynG9GM7JTm+ZJJJP3eDDQjicXRgoKmpSjd K7TSacvibesU+r12NX9oX4z399q1n4d8E2MPg7w9e+F9K1O7uLAt/wAJPrtr4ttJfEM2ma94gIEt 3pSHWrgRW8Qhh23DLIsnGPnTwd4R8TePPEGneFfB2iX3iDX9Ucx2WmafF5k0m0ZklkZmCW9uiZLy yMqIOWYV9uaz8LdN+Pfxa8X+CPAvgzxfqXiHS7Hwv4eXxbrWp2+ieAfhZpGjadpltJnTLS1efWJ/ JjuY44Jp42mmndkgRV3D2nxd8R/hh+wnpY8DfCLwjJ4t+KOtW4fXvHPi60u4rGWCAGKWS2vI44xf W63ySL9hsnWCIxt9omeUYP6BmnBGIz7N824q4y4khlnA2W4idGeLp06jlJwqyprA5bhVTVOdaSpp t0ebD0VNTrTdWM6S9epgJYmtWxmNxSpZfSm4uaTu2m17OlC1nLTdXjG95PmvEu/D79l74cfs+6Rf /EL4268mr6/N4B1e5m+DcF3pt1PeReVF/a1ikltL5mvoZUtlQokcMbTlZGk2ZPj37Vf7S3xEHxBH gjwH4j1X4e+FPCWj6HZt4e8KXsWkpDrU9jFqF9bXz6UQUuLI3cVk9vv2RS6fL8gZjR8GLjxt4x+M vjr9oD4xWcU/h3RPhxqHijxJqcFhNe6DZLq2i2UvhPQ7KwtHcC6WN7G5+wK+8Im+42+YzH41+IXi fTPF/i3Vda0bSn0nTpnSK3huWWTUr1ogwudY1udc+frl7dtPc3RBKrLcmNCURTV8acVYfJ+AsPl3 BeEnwVlua46pClTU6kc0xuFwbnGeMxddJSVLE15xXsIShQo1sPVpUoVP3koXjcZGjl8aeBg8BSrV HZXaq1IQunUnLR2lJr3U1FOLUU9Weu23xm0vx9AuhfHjSn8QW5UNa/EjwxpekWfxP0m4gheO3N7e FIofGOmtnE1vfYmOBJHcqy85d98GV160bVPg34oT4q2sMLXGpeHbPSbvRviDoVuoy9xqPhO4eQ39 ihKq9zYTXMasw3hFINfsn8FP+CWvwA+Jnwf+FXj6/wDEXji31XxL4Ii1fxGlpqduLK41jVNOLW0l rDNY7rGKzvWy0ZLiYRbWZc7q/HrRND8Z/Bn4lWOr/Yda0vw3eeKfEPgHT/GNzaXul6dq1hJdS+H9 WutI1gPEFuoba4S4EkMymJ40beAK5eMvC/jbhLAcJZl4nZXQzPKuL4RnQzPCYiVbMKNBwwdT2mIq R/dzjD63Tp3xtKtJvnpU61NeykzG5TjsHTwVXNaUatHGpONWEnKrGNoO8ns0udL94pPdKSXKzwW1 sb3Ur610yytLi81G+uobG0sbeIvdXN5cTLBBbRRAZadp3VQvXJwa6Pxn4a0/w5q1j4e07UG1rWra wto/Exs3t7vTrbxJO7vcaNpE1oCbsWsbwW87ksGvIZxEWiCE/S2qWmhWXha2+IGiW2qyftCWU3ih NQsrmCwgstV0nStV1HTbv4u6Tonllp9cSOOaN4o9yLPbzX6xOLZ3Pl3ws8DX2h6p4d+KnjtJfC3g LQ2fxbp95qGo2mh6p42u9ELXum6F4NivFeXUb261G3hj85YXgjQSM7hgoP5o+D54erhcsgvrlfMv ZV54uKbo4LAy9nJzrWfLSrxc/wDaoym40VCEIzn7a68l4NxcKS991bSc18NOm7O8uikr++m7Rskm +Y9d/ZE+MnxQ+AHiqXxxFr3irRPhxoN9YQ+IfDM93cWOg+JtX1m9h0qz0qXTr0hLuWGO5uL6cQIZ o4tNy5VWBri/2wfiN8XvG3xs8Z6H8R/Guv8Ai1NG8RXlt4bsbiVo9Kh0e8lFzoj6To9sFghSWxuL VlKJubzOpzX9Vdv4G+D37Q/wv8H634u+HfhDxNofi3w3pfiS3t9R0ixuHtZde021ubmS2vYYUkt7 vLBWliZHJiHPAA+MvEX7BXhSX9sz4QfEu3003vw60LwVcT6jpmoP9tT/AISfwOlpY+Ere7kuCTdQ /YriwYeZkuNHO/OST/c3Ev0XfEPDcBZBwhw5x5PiThLHZll1SNpYmjGnSx0pUsRiauD9pUpSwtGN TB1acI1Z+z9lXqqMZV5s+9xXCeZwy7DYPDZg8VgqlWk18cbKp7spOF3HkScGld2tJ6OTPkb9g3/g mn40ttV8KfG/4y3MHhi0t3s9b8N+A5dOhvtfuAksN5p+parLcHboDkxxvGqBrkL94R7q9M/bUm/Z d/Zs/aO+DPjPUvBHizR/GuoT3njB/EngHUdOt1u7648TMmqXPjCw1KNpNbFxFLdxllmjZIpCFBCh a/bYYJ5/z2A4r+ev/gr/APAn4veJ/G2k/GjRtNXXPAPhfwrBolzaaSs9xrXhy0srp7q/8Q61aiPF to8uoXyxRygnJhywAwa/V/ErwuyTwT8C8TS8POGFnub5VjsBjKmKxWHjjsR7SjVp1K+PkpprDqEK SivqqpqipKS2lUPYzbKaGQ8PSjlmE+s16M6c3OcVUleMk5VGn8KSj9i3Lf1Z4JrH7C+meIPGfxo0 zwZqE/xV+I1lZ694z0L4b+Eb2DTLLwj4b1yc3vhbVvFviTUB5V/qctpe2zwaRZ5mkY7ZpYwGU/mJ 458FeLvhx4n1XwX450HUPDXijRJlg1bRNTiEV7YyyRJNGsqKxAzFNGykEghgQSK/oj/Yd8WfE4+I /C3jnwp4A8L6l4J+Knwg8GX/AMSfiJ4l1D+w7nQdf8Bz3fgu6srDVEt3GoSzRadbXBsH2ZYmYyoM k/C3/BRzwr8FviX8d/Clr+z/AOLLr4l/G74j+JtQ0z4gabZ3s17bW+ryPZaZ4f0q03W8dvpvk+VN EYo3k2pEHkfHX+XPEzwj4XxHhrl/H/C8P7IzirmEqay+pelHHYXGVubCzy9V4SxWZYyVPEYSdVYe rLDU4/WIU6VF0lTfyGa5NhJ5VSzHCL2Fd1WvZv3faQnK8HT5lzVZtSg3ytwS5klG1j9Hv+CQv7Qm m/ED4GT/AAb1S/jHi74TXM4srSWTE174N1W5e6sbmBW5kW2vprqCTGdokh/vV6x4Z+LHiDwl+1Tq +t618Ovi5YeA/jbo1jo0mvX+jS3HhTwxr/gK81PSbW+vCB5mh6fcafEZC75jeO/jmA618bf8E+PA Nj+xTL8TfE37SPhq8+GerfadH8Ian458QLDc+G9Pl1K5gu9GsNK1exWRBY3lvL5k825ow9ogJjAO f1P+LGt/EH4k/D2w139l74yfDHQru2v4tR1HxL4gtbTxX4T1DQI4pPtVq93aPItg+/YTIOihgxXg j+y/CutxHjPCLgGhneY1cLxp4fr239l0KNGeZVMNhalXBUKWIwmNrYSUW8D9YwtR+0pRd5SVR1aT g/uMoliqmTZdHEVXDHZb73sYxi6rjBuEVKFSUGn7Pmg9Und63VjR8H+PPGF74+8UfD/xpocjWOnG HxF4Q+IFu9nb6NrkN/qF3caVotraxZJmttNS0V7hmIneRkIViFr5u+BfwVi+GHxL+L3iDxzf3XxH 8T+O/HGgafpEU1zL4ivWtTF/b8l7r1pc2yxaNollq0weGRYxHF9hWNJZXCg/Uvw8uPEOo6F4d1LV fFfhb4hIbLThe3PhHS7Y6JJqUP206rqWhX6HElk13HaiOPPH2RiCXbaPSbG80fUdUN5BALW5lj+y w3jQLbz6vBayTExCcoGntY5VnKxk9dzbcFSf2Knw3hs9nw1muYYupicZk2IxGIwbxSpzlGli6M6T hNUqk6NeVGlVUKVacqk9udzlOSn7kcLDEfVa1WTnUoSlOHPZtKaas7Nxk4ppKTbfe97PoZJ3t7dp 5Y5pmVFzDawmWR3AIbyo+pJPYngLzjmua8aaJp3iLw5e2mratqehaW0KXN3eabqD6PeQRwyJO5e9 DAwDam09NucgggEOt77w5Hqeo3kNz5+pxmG01AKZZrm15C29pNZRfNag4BTfGN+7cjNkmptT8UeG 7Z7OxvdQsXudRvv7OtNLlkQ39/dCIzSW9rpzDzLyRIss6qhChWzgjFfeYirhMRhMRSxVWl7CopU+ WU04y5m4Lmd4t8zaTgtneKlfU9GUqcoSU5RcXpq7rsr7b9vxPKLTx6s3jK5gsNUtvEPh6zGkaMdC 0nTprfxB4RuL3T57m41bV9TvL9Ydc0CSyijcG3jlkR23qzKrmux8K6HpFnqt1qPhtdPsdPuGzLpm j2ul2WjX0k80s8mui3sYkkXXGLeXcNLkssa4xk1keKr3RIZ7y+vYLSxd7vT9Os57q4stMv5rpoLu 2tmsJdRCILhoJbuKGNGMrLjajM22tDwH4UuNEaW/h1fxBf2Wr3K3i2fiJbfz9LgjtRHb2dtGkCva x5b5lLvlwcgc183goYj+06dGry5h7KtVq+0g5RlQjOTjDlVSc6nJLlinCM5QXKuSMKSVNctPm9qo ytVtJu605b7btu2ysnbTRKOh6c9vG9xDckuJYUljXa5CMk3ll1kQcPzGhGehHHU18X/ti/sWeDf2 stD0t7zU5PDHjnw4kkXh7xNBBHMotbieJ7mw1OEJvurMIJ3iVXXZLJu6FgftevCv2h/C/hbxv8J/ EWm+K9a8caFoUBjv7vUPh41/H4tVtNd5Ps2nQ2FrLNdCRlKvEIysiHDEJk1v4hZBkfEfB3EOUZ/k lDiDLcTh51J4TEVvq1OrKilODeJtJ4aUJQjKOIim6TSmth5jh6GKwWJo4ihHEUpxbcJS5U+XVe9r y2aVpLZ6n89n/Duub/oqcf8A4DQf/JlFeW/bvAv/ADx+Pn/hP2v/AMh0V/kV9W8Jf+jfUP8Aw+4r y/6df1c/HFDJ9P8AhOX/AIUT8vLy/E/EsOeMY79sYwcY6dP8a+7Ph78TfFemfsO/FvQvD2qtYXnh 74q+F7WW9tQqa1pvg34gafcR63Y6ZqEf7/TNPvNZ0K0S5MbIsolMTH58H4K3H1PQD8q+kv2er2Of Sfj34RvrYXeleJ/gn4iu5VMgRrPVvCGo6V4i0HU4cxsHkhvLZ12/KSlwwDL38fhDFVcJmtelQryw 8syweNwvNFtPmrYaoqV3HWyrKm32SurWPncBUlTryjGbh7anUhdX+1B22/vWPnfzD+PfPOc9yc1+ gn/BLjxkng/9uP4IyTy+RaeJNV1XwbdlmKo8fibRr7TY42PGAbiWH8cV+eIY4HOMgf5/z6V6R8Hf FWpeCfiz8NfF+ktjU/Dnjnwvq9nligM1nrNnKqFwCVVgCCQDgN0PSseD8z/sHizhnO1d/wBk4/CY hpbtUa9Ocl81Fr5k5fX+rY/B4jf2FWnP/wABkm/wR+ifx5S/uPjx8TvijoFnBoPxt/ZS+IlvL448 N2K3kzfEPwJ4W8SwabpfxAsW3s66xbaabW21xGLJJbyRXSkAyKP3d8OeIdN8V+H9C8U6LMlzpHiP R9N1zTJ0OVksdWs4b61bIPXyZ0B9CuO1fhv/AMFDPFF98Df+Ckfizx94PVRLrNr4M8Ta9otztbTd csfF/hjTv+Ep8N6pGYyt1pd9aSTxS70PMokC71XH6b/Cfx3oHhH4eeFdB8OeE72y0C30xbzRtMuf ExvjounatLJq1voVtdSaGrzafZrfG3tt43LBbxoSdua/sXw8zDD5Vxr4kZTiMQqU8Fj69PEe5O1W rRxVWnh8XFQi4qeIw79nil7r9ph6dW05V6jh+hZRWhh8xzihOVpQqyU9H70ozahUVla8oaT2d4KW rk7dp8dPgppvxc07wxqlrJBpPxC+G/iTTvGXw68TNHltP1jTLy3u5tIv3Qb5NAv4rcQXSDJTck6A vGA3mnjf4K6Y37R3gP4q6FpcsXi7x0INJ8ba08qPB4Z8I+B9Hl1O9h0NY4cw6vrN4dE0u5ui29bG CWODZ58hr1lfjFExx/wjUg4z/wAhtf8A5TUf8Ldty4Y+GGLqpCudZjLKrkbwrHRsqCUTODztGelf omY4PhTMa9TFVJxhiqtfCV5zVKpd1MJJqFS3s7Kq6E6mHdVfvFSlFKSdOm4+xVp4GvJzdlUlKnNu z+Knez2+Lkbhzb8rVtVG3tPnRCRIS6iWRXkjjLKHeOMqJHRM5KKZIwcDjeoPUV5h8aPBOk+P/h9q +ha3Fby6ZHJa6lfrcD5X0yxmD63bI/nRiKS40F9VtRIzBY/txc524r8zP20/2svif8KvH3w78RfD V9N0KWPwp4h0m8stZtYvElnejW9UsLiW6MMsVusM8a6DbIh2swEr/MAdtfV/wU+P2s/F34C+F9V8 Y6Yy6/4y8ManYa5q/h/UYtFInup9S0iXUNKtP7KmXTpxCqvGN0ipIueRxXl/6/cMZ7m3EfBdSNSW KwVCTnz0m6FalOFJaSV5qXPW5WpU4pKLlzbHL/aeDxWKxeXcsnOnFt3Xuyi1HZ7p3lbVLa9zwX4R zeDfiX8KPhz43+KS6hqmufsu+Ndf0LUdJtNZ06Sz8SeItIigh+HcUmqSEN4g1d1Ok2lkYJxbyXkU 8kpZAxb8ePG/jaf4lfFbXvGmpWs08PiXxnc6imk6jcl5IdNv9aee20W4u7cKSqWkywPIvPBZT0r9 R/D+peCtfms/grovhHVvDHgK11rxT8IYrKDxjPqN8NS+Hn2f4k+H/iV9tuNFT/isBrNxqETts8s2 180S7VVRXyH4y8BfDbw58a/h58L/AA54UubSxuhpmp+J9e1TXZtY13XLnT9W1yWeKxc2cNv4etLg aTCsiwW7ybWwZWAIb+WfEHDYvNsm4dpYfF4apQwVWhQxdblqqpjMwjSw2HpX56EZThSwzpR9pV5I ylKvU9nGUuR/H5pCdfD4RRqQcYOMJytK9SraEI7wTajFxV5WT952TdjvNC+Et/44/a3h8PaZPJaf EIfFGz8V6jpGjKB4W8BfDvQpY9Smg1PVcF7nXF0yLS7eO3hUwxmdYpZpJZGSP9Nv247zSvEHw41v wnrVxDpnh3T4LbWbrUdQ8ZWnhPSdX8UefGug+E70Jpt1eXax2txNqr+VGkBbT7eGRy8qhfnz/gnv baH4Q8F+Kfijc6TJrfjD4j6/fpd6hLeJatpmlWN4839l2rPZzvKst/PJNNIXUuY4l2AR5b4s/as/ aT+MXjb4k/E/wNfeM9Vs/h/a+Jr7SbLwbZPbwaVFpumyGC3t7l4LZJL53ILzNI2JZCCUAVAvtPN8 l4K8Ls1zDFQqTx/iRWqzVClGNSMKMoVZYeOInUdOEvaRl7TETpJ39p7KNGMIWXXGth8vyWtWqJut m8pPliuZKLTcFNyaTve83Fa35eVJWXzyNB8B6Sw/tLxxNr7LsBtPBeg3mxvkVpEOreJls44wHJTe lvNyu4KV6781z8GLi2sEs9I+Jul3Q1KU6lcSa34Y1qI6P5cQgSztv7Is9uoiTzixd/LwFAPORxug wWbeFPGlzPaRT3kCeG4bG5kAMlh9o1hzdSQZHEkkNusROR8jsO9UtGtoLu8ht7gTeXL5uTBIkbjZ FKy4aSFx/rApPHIBHBIYfyxWxXsY0I0cBhYQx0b8rpyqNWqygk51pTnF/u7t05JOMrPW9vkea3Ko 04JVFfZv7TVryba26NbkhMIkk8nzPI8x/JM21ZRCHPlmXZ8vmlNu7acZzjiv0v8A2Fv2cvFvii61 T4l69AuifD3UfDWtaFa6xM5j1KW5i1LQb6a4s7CdF36a9lbXKC7JeH5ZAPmUV3Xwg/Zo+D/wz8MR fFHxloV/8V9WtdDXXbHRNcv7XSfDFtPHbJdBX0uDTLg30gYgK1xJJGuM+STXqfwb/aV8Q/HDTDc6 7o0Ph3TtM8Qa2NH0LwlqMmk6Vb6NpOkPDZ6Nfw/Y3OpRbtRLO+YVY26BYUAGP2rw/wDDfK8gz/I8 w42x6eZ4yM6+CyygqklJRcE6mLxSg6UKaVSyo0XUqTvdzpOOv0eV5VSw2Kw9TMKn76onKnSjd3tb Wc0uVLX4Ytt33jYwviR+2N4X8LaP8RvCP7OEFjp9r4a0s6ne/EqdbWdNY8S6pr2lafFHo8F9Azaw 62t1qKrc3AJKWKiBRFEHbw34L/Abxl8c9N1D4lftCa3rGm/DiydfEcvjfxTqFzba7c6TC0kurPpO oXySJH4dlWLZIjrEqtIk9huYOr2fhN8Nfh74N8Y3Ol3/AIcfxjBr3xk1bwtokHiK9jm03QbLwJb3 99bXd/pkNkqeJtQlN24H2gx20TRpIbaZlArP/bH+Pvjb4g+IPGvw4sJk8JfD3wCdEim8M6ayzDxP f3D25jvtWvUhgKRQCVBBbJH5CLEMqzYYdOdZjUx2Xvi/xFxf9o0crlUwuC4bwSnTy+WIarYmCrtq FKGGpYWNKpNwdXE1Vy3q+1i6S1rVnOl9ezSftY0rwp4Wmmqbk+aS5toqChyt2vN6a82h6b4w/bx8 GeErqD4efB34Y6Dq3wg061/sjUxrZvdLvPE0EcENilxpT2p8zTlW2t4xHdXKzXM7KsjrHtUV5Brv jv8AZA+JFmg1Pw78V/h74jmngul1XRNP8N+Jrhp4rOOxTSJrgXVvJrsUjxQOLi5iW5aQMZJGd2Y/ BiuSQD7jPt1xWhY6hd6dcLdWcnlTok0aS7EdkWeF4JCm9SEfy5G2sBuQ4ZSGAI/Gsy8WOJ87q1aW fUMBmuV1HanhKuBoOhhaWiVLCez9lXo04RVoRjXT5vfcvaOU34tXOcXiHJYiNOtRe0HTjywXaFuW UUlt7/ne+p/UZ+xv+0rdfEKWT4Ix+O72+k+GHhzTzruseO9B8M+CdeTSLSEWv9gR6Pa3kxurizt4 oo7y4AX7PwHctzXzN/wUB/as/Zo8YQ2vwQ174deM9Ti8Aa/a6tb6h4buNE8OW7u8Lu9loMs/mH+w ryFj593HCj/Iixruckfn3+zLb6N4LvPhn8Vm0+51zX5fF13FrdpqGpytpPiDQpJ0srnQNTsZoJUn tZkmZ5XcOzOinGBg+i/8FOvEOh+LvivoGv6R4SsPCU8GjNoN7Dp9wk0epLYwWN/a3kwisbdY5lTV HiwqHKwqSxPT+os88YuK8x+jxmMMTiMH/aGHxGDw9Whi6VXMli8oxkVPC0oSxUJ06M8PyU/bOpUr VK0qPOpxbgl9dXzvGVeGqsZzh7WMqcZRmnV56NRJwSc01Fxsr3cm2r32P1h/Zx/Z2/Zj/aL+E3hv 432HgySPxlrF5c3emeINZ1aXWNf8HXmi3L6fp+kx29vdi0jtrWGANFBJE+4T+dL5juxPxb/wU/8A 2QrCDxv4N8W/B+K61LxX4p0yW11T4dpqtk9zLZaNGsA1zwrp2oX0cjoXaFLiysozGjt5yRoGKj3D 9gv9tFl+BNl4Qb4UaBZD4d2sWkpe+H9ZOixa8sECv/aGoWJ0OfZqkpJM8wlfzXJbavSv0N+EqeC/ jrNofx+1/wADaXB4z0Yan4d8LzXlw2tS+HNIkNrLcRWM89tFGLqS5EjmdbeOUCUoGC9f3rLuEvDH xr8J+HuGMqo5fS4k4iwuX4rGYzD4CrgKsK+FlTjj8ZD/AGZU54m9SvSUZuUa/tFGU/ZRjOH0NPA5 Vn2T4bCUI01i8VGnOc403TalBxVSovds56tK9+a9m7JNfOn/AATa+Luqar8F/D/wY+Iuia34R+JH w2tpdKttO8QaddWQ17wwk80umXmnXcimK4ubdGkgngDiaMQI5Ta2R+g/inVbjQNB1PXbXSLjXLnR 7C9v4dJtHSK81BobaSRbO0llG2O4ldURS3y5kAbAr+T3/godbar8E/2vviXp/wAO/FvjHw/Hr/8A ZfinU30/xDeadv1TxLax6tqC28WleQkFkLmT93HtYqF5djXk3hf/AIKBftieEYbG20747eMbyy05 UjgtNclstcjaCN9/kzSapaSyTKckZdmYKcA4AA+LyP6VuW+GMMX4XcZ5Hj8ZjuBJ1cohmOEnha86 kMFN4ajUqUazw8HUhShBykpNVHG0oXcpy8/D8ZUspjUyjHYepUqZc3RVWDhJtU3yxcoy5E2kk21v tbqf1oWt94m+Nvwi0bVNDvvFvwS1Xxhp9tc3i3ulWUnjHw7aTswubO3S+jaG11FogvlXPlyBVkDq u7GPw/1+f9q/4h/B7432vhHXvEXxNv8A4UfGPxX4H8eNqF2z2PxN+GS2b3uoXN/LNJEjwWd1oeTH ZyKYhfuiDDYP6FfsgfGT4ufGbxx4ys/FnjKFvBlp4B+Gvi/T/DsGhWUWraff+O9DS+vrK38U28kc jaZDdpK0Ub2zuEkEfmhV+b9ALXwl4b0rw5d+FtM0XTrDQrmzv4LjTbS1itrW5XUI5Fv3uI7cJ50s /mSGZyd8hkJZsnNf0FjeGKXjTkWT5zhOIMxyXBrC5hgMRUU/YVcdUjbDwrQw9KvVwmHgsVSqV3J0 faVKbeHnSVKpJL6WphFnuHoV44mrQgoVacmnyuo/gUlGMnCK505X5bte60otn4c/szfHbxT8KP2V PD8Ph7wf4T17xbN4n/4WLd/CK8tNSh+wfBnxJ4gl8O3mtabLqF5LJdGHWrSO7kch0S3YSt8u5x8b +A/iF8EfhD/wUHvPjF8TTqL/AA51rXNY8WeCPFXhu1lj0bTNc1CWSD+0o7a2R/7a0C11AanaM0BY FoxMoZV2nxjW/jF43+Gn7RXxg+ITXtt4l13wP4kk+HOk2eoWq23h1PBc2q3eg3XhuPQ4XaO30VvD 9rJZpArERJcM6kyANX2XoVt8N/DPxa1f4L+I/h3B408F+B9H8PfHb4Qi91n7Fq/w61HxHpVp4q1D wg1/LpV0vijwobu6K/Z7qJFJjEhUlnV/4zwvEuK4lo8GZZQzGjgqvhtmeCo4NZhhpYjDLE4R4qnh qtWlh1KShmEMHjFXo0qlSGFr4bAewlTp1q9Wj8HDFzxccBSjWjCWVVYRh7WDlFShzKMnGGtqqhPm im1CUKfK0pSlH9xLiD4F/ti/DUWbG1+I3wuvtU0zUp2RdR0/T9T1HRrlbu2s7iOeGCeaJJFiaVcK rKyruYEgesH4feBIPBsvgNfCugWngX+zm02fwxb6fa2Ogf2WI9slvJZW6pH5Hlr8+R83JYk5NeJD W/Fd7ZabrfhPV9L8F6fd+ELO7t9BtPDllf2VvM97pnzzMZ4FuGS2a6ii2RQqguclW2KK/JvT/wBs v4t/tQXvx3+FOt3aeCdK0zxDbaf4c1XwhcXFlquj6ZDJfWElrNMmw6pLLc20NxJJIyjcpjWNYzgf 3HxD4icM8JVMtee5RHMuLeKsPUw1GrRwlKlSzFYahUxPsHUqVcRWw+F99qFLFTqKMq92pfvZR/Qc TmeEwLpfWKCq43FxcIuMElV5YuXLdylKMNbJTbtzerX7naPp1noph8I+EdC03QPCukeHozp66ZbW 9jpSXF080Vpp9lbWcYEMUUEbTOVXn7RHjuTzvi74bX2vH4ftonirU/C83gfxjp3iSZdNYi18RaVH 58WqeG9UhZi0lpPDIjBixIkhViOTXnvhbx5qHgj4LQ+IdQW48TzeEPAkZnW6vRZXGtTeHmgsRcz3 a2swtp7iGePzT5cgDQAgckV5h+yv+0N4x+O3jXX5Nft7HTNDi+HfhLxhpWhWa+cNNv8AxFrXiO2k jOovGkl2senWVtFllVXZWk8tC20fWVOI+G62J4c4bxsakcw4mgp4fD04yhGhSpKNZL2tJwhThSdG MYqnJylKC93kbb7ZYrCuWFwtRP2uMV4xStyxVpLVWSSsrWbba7HqH7RXif4ffAnQtS/aa8Q+F9X1 nXvBWjr4cQeHbn7NqGpaf4i1axsobW6t5ZkgvvKupVaFp1cxea4TG/j03w1qdl8QfBWk+L7TwZf6 FqeoaN9p0zT/ABnpcGka/pZ1CFZ3SWSIyvZFmcMWjcBjhuO35gftd/G7U/i/8afEf7D2q6Dp+l+E dY8FX/iP/hNbK7vJPEFp4g0TTz4n0S8isWKwSWkNzpwjkgZv3y3DN5kZVQPjT9mf9rj9oaH446Z4 c8ffEjVfHvg/4daOuhW3hfybTw1YazBe61p3ha2udTksIZXlurZJ0njdzIxMAj3AEtX43nHjrw/k HiNismeFq4rhjM8R/Zbnh8LQh7HPcNVvmmIxUqnJiakKODqYF0p0aeIjVdKcYpzSv4lbiDD4fNJ0 ORzwlaXsrxhFcuIi/wB9KblaTSg6dnFS5mnbXf8ASXxHpKWXwu+H/gz43a2/hf4iXfxG8QDwBp/i PxNe63apr8z30eh6oviPR9Ld7x7W3vRd6atyCsMjRpI7+Wor76+HmiNoXhnSbBruW/FppWm2o1Ca e4nk1KSG0jF1qUjTkZlnuNzs21dzEsPlIqvpuh6R4ltrC51XTLC6t7GeHUtKtZrcTNp07SC4CxXM rFmiEqxNtwq7olOAoCj0EAKAqgKqgBVAAAAGAAB0GK/b+EuE4ZRjK2YutHE05YfC4ehUlFrEzp0K Sg5YqopKnVm2rwlTo0FGChH2ceV83u4PBqhOVXmU04wjFte+1FJe+9m7rS0Y2VlZWKF5qEVlPZQy qcXkxhEhZVSIkBYy5YgEtK8aAZyS/AOMVz2ok2Fve2EMWqX06xz61Yj7TJG1xJDcCZ9PhvI33jaz rtQhf3eFDHBI4v4m/D/SPiQV0DXLnUbSF20+TT7/AEa9n0/UtKvLG+ttVtr62lEjRvcLe2sDAtEf lTZnBJPo1xbTLHpMj3IluYXisbmd4QPtkM+2G5LRo48p3MYcbSQrHoQMV9FKtjcRicxpzwyp4Sgo KjWU4ylJyvGvCVJwShyJU6kJOVRT52ny8nLLqvOc6icLQjZRd0276SVmtLaNPW9+lrP8Z/8AhNfE X/QBH/gf/wDdFFe2/wDCh/g1/wBATxp/4Xb/APyhor+Mv9UuNf8AoY4T/wAKJ+X/AFLPU+J+qY3/ AJ+x/wDAn/8AKj//2Q== "
- x="0"
- height="253" />
- </pattern>
- <filter
- id="filter16257"
- inkscape:collect="always">
- <feGaussianBlur
- stdDeviation="0.41431294"
- id="feGaussianBlur16259"
- inkscape:collect="always" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17245"
- id="linearGradient27074"
- gradientUnits="userSpaceOnUse"
- x1="136.5"
- y1="161.5"
- x2="313.74622"
- y2="285.25275" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4451"
- id="linearGradient27076"
- gradientUnits="userSpaceOnUse"
- x1="155.34465"
- y1="112.46042"
- x2="136.51547"
- y2="2.1517708" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient26774"
- id="linearGradient27078"
- gradientUnits="userSpaceOnUse"
- x1="280.27875"
- y1="261.40704"
- x2="322.26389"
- y2="275.19568" />
- <filter
- inkscape:collect="always"
- x="-0.086395349"
- width="1.1727907"
- y="-0.11145"
- height="1.2229"
- id="filter3497">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="11.145"
- id="feGaussianBlur3499" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3460"
- id="radialGradient3466"
- cx="167.48819"
- cy="192.38739"
- fx="167.48819"
- fy="192.38739"
- r="105.62836"
- gradientTransform="matrix(0.8393229,-0.4383343,0.2966517,0.5680291,-30.16055,165.27307)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient26774"
- id="linearGradient2490"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- x1="280.27875"
- y1="261.40704"
- x2="322.26389"
- y2="275.19568" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4451"
- id="linearGradient2500"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- x1="159.38791"
- y1="126.94874"
- x2="138.87404"
- y2="12.596838" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17245"
- id="linearGradient2777"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- x1="136.5"
- y1="161.5"
- x2="313.74622"
- y2="285.25275" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3757"
- id="radialGradient3763"
- cx="170.31175"
- cy="209.16652"
- fx="170.31175"
- fy="209.16652"
- r="104.54334"
- gradientTransform="matrix(1.0743517,-0.8811517,0.8948667,1.0910737,-193.89727,134.77199)"
- gradientUnits="userSpaceOnUse" />
- </defs>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- id="layer1"
- inkscape:groupmode="layer">
- <g
- id="g2491">
- <path
- transform="matrix(0.9747328,0,0,0.9747328,8.1232897,4.8258519)"
- inkscape:export-ydpi="98"
- inkscape:export-xdpi="98"
- sodipodi:nodetypes="cccccc"
- id="path2486"
- d="M 183,323 L 53,296 L 0.99999999,150 L 196,96 L 255,237 L 183,323 z "
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3497)" />
- <path
- id="path5140"
- sodipodi:nodetypes="ccccc"
- d="M 103.94986,273.26347 L 112.82679,278.13224 L 130.15293,266.67465 L 121.4575,262.08933 L 103.94986,273.26347 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5128"
- sodipodi:nodetypes="ccccc"
- d="M 156.01098,239.64164 L 164.60219,243.86025 L 180.14702,233.7166 L 171.54021,229.64474 L 156.01098,239.64164 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5132"
- sodipodi:nodetypes="ccccc"
- d="M 171.60139,229.6086 L 180.08668,233.62387 L 195.07741,223.67266 L 186.68482,219.84353 L 171.60139,229.6086 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5130"
- sodipodi:nodetypes="ccccc"
- d="M 186.53932,219.8472 L 195.14618,223.77328 L 207.96039,215.29699 L 199.53214,211.5709 L 186.53932,219.8472 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5134"
- sodipodi:nodetypes="ccccc"
- d="M 199.53942,211.55443 L 208.00833,215.29699 L 219.61158,207.48873 L 211.43624,203.97858 L 199.53942,211.55443 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5136"
- sodipodi:nodetypes="ccccc"
- d="M 211.48298,203.99346 L 219.48498,207.43045 L 231.12889,200.02493 L 223.45622,196.26063 L 211.48298,203.99346 z "
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2172"
- sodipodi:nodetypes="ccccc"
- d="M 68.307573,278.59889 L 233.3461,375.01483 L 393.09703,219.55258 L 250.10479,166.11978 L 68.307573,278.59889 z "
- style="fill:#000000;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cccccc"
- id="path16273"
- d="M 277.69986,176.50516 C 177.30035,235.42715 239.60255,221.94517 101.71421,297.5792 L 189.47945,349.38523 C 273.26264,323.79193 366.41421,274.97725 355.07543,205.22753 L 295.56691,183.1214 L 277.69986,176.50516 z "
- style="fill:url(#linearGradient2777);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path2174"
- sodipodi:nodetypes="ccccc"
- d="M 68.171626,278.57262 L 68.303363,291.78988 L 232.57786,391.18452 C 235.83055,389.43142 237.23238,379.0975 233.63174,375.00319 L 68.171626,278.57262 z "
- style="fill:#000000;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path2176"
- sodipodi:nodetypes="ccccc"
- d="M 393.07972,219.62716 C 394.063,222.66073 395.10956,229.26471 392.24335,231.97585 L 232.84133,390.92104 C 237.0608,386.09241 235.76133,380.47536 233.63174,374.73973 L 393.07972,219.62716 z "
- style="fill:#000000;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- d="M 34.974214,77.099241 C 34.974214,77.099241 63.429139,279.82741 65.53691,277.66987 C 67.644683,275.51232 249.44002,164.63325 249.44002,164.63325 L 249.96698,8.789858 L 34.974214,77.099241 z "
- sodipodi:nodetypes="csccc"
- id="path2178"
- style="fill:#1a1a1a;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- inkscape:export-ydpi="98"
- inkscape:export-xdpi="98"
- d="M 243.62988,7.3609944 C 248.64901,5.9522606 248.53121,7.8674281 249.93941,8.795189 L 34.974214,76.572297 C 33.041161,74.848362 32.232239,75.552395 27.898382,75.685479 L 243.62988,7.3609944 z "
- sodipodi:nodetypes="ccccc"
- id="path2182"
- style="fill:#1a1a1a;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path3155"
- sodipodi:nodetypes="ccccc"
- d="M 41.127572,89.515883 L 247.04644,21.857141 L 245.56959,155.03645 L 66.892268,262.94003 L 41.127572,89.515883 z "
- style="fill:url(#radialGradient3763);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
- <path
- id="path4130"
- sodipodi:nodetypes="ccccc"
- d="M 270.30146,173.89938 L 92.059548,291.88393 L 83.064049,286.84829 L 262.53913,170.82327 L 270.30146,173.89938 z "
- style="fill:none;fill-rule:evenodd;stroke:#999999;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path5126"
- sodipodi:nodetypes="ccc"
- d="M 113.88343,277.34844 L 133.41939,264.57042 L 113.88343,277.34844 z "
- style="opacity:0.3;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 260.55944,282.16245 C 260.55944,282.16245 299.34305,249.72696 299.34305,249.72696 C 301.56567,247.86815 306.24993,247.63883 309.88553,249.20565 C 309.88553,249.20565 329.40032,257.90584 329.40032,257.90584 C 333.27561,259.57597 334.75677,262.55505 332.67995,264.59388 C 332.67995,264.59388 296.81833,299.27831 296.81833,299.27831 C 294.33747,301.71377 288.97351,302.06916 284.843,300.06406 C 284.843,300.06406 262.71041,289.52115 262.71041,289.52115 C 258.86144,287.6527 257.92393,284.36659 260.55944,282.16245 C 260.55944,282.16245 260.55944,282.16245 260.55944,282.16245"
- sodipodi:nodetypes="cccccccccc"
- id="rect2179"
- style="opacity:0.88999999;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97445869;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 156.31199,239.61556 C 158.84932,237.6711 165.25317,241.39833 164.88374,243.74344 L 156.31199,239.61556 z "
- sodipodi:nodetypes="ccc"
- id="path5322"
- style="opacity:0.99720004;fill:#666666;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- d="M 112.5495,278.27384 L 130.07045,266.61299 C 128.6036,263.60624 125.86497,261.45071 121.46704,261.8451 L 104.04747,273.28768 C 107.08494,271.21271 112.98604,275.81472 112.5495,278.27384 z "
- sodipodi:nodetypes="ccccc"
- id="path6299"
- style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- d="M 104.03121,273.29774 C 107.49791,271.05672 113.43311,276.6129 112.52259,278.36122 L 104.03121,273.29774 z "
- sodipodi:nodetypes="ccc"
- id="path4349"
- style="opacity:0.68999999;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path8239"
- sodipodi:nodetypes="ccccc"
- d="M 164.84019,243.7543 L 179.63884,233.97378 C 178.89388,231.15559 176.668,229.33065 171.42447,229.78669 L 156.27423,239.63114 C 158.95009,237.51097 165.57347,241.76179 164.84019,243.7543 z "
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- d="M 179.54294,233.98976 L 194.50141,224.24118 C 193.46879,221.32711 190.97123,219.43825 185.96742,220.29382 L 170.84915,230.10631 C 173.88125,228.78365 179.05461,230.45474 179.54294,233.98976 z "
- sodipodi:nodetypes="ccccc"
- id="path8241"
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path8243"
- sodipodi:nodetypes="ccccc"
- d="M 194.43749,224.22521 L 207.70194,215.40355 C 205.96614,212.71322 203.80418,211.59145 199.45559,211.72786 L 185.90349,220.3098 C 189.09541,219.56246 193.62952,220.65822 194.43749,224.22521 z "
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- d="M 207.74987,215.38757 L 219.33629,207.66862 C 217.34479,205.17006 215.05499,204.11222 211.28174,204.12078 L 199.40765,211.74385 C 202.7434,211.44397 205.80725,212.3959 207.74987,215.38757 z "
- sodipodi:nodetypes="ccccc"
- id="path8245"
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path8247"
- sodipodi:nodetypes="ccccc"
- d="M 219.30433,207.70059 L 231.03457,199.96565 C 229.55448,196.50822 226.62543,195.89785 223.29965,196.19408 L 211.04202,204.2646 C 214.01019,203.93277 216.67451,204.42126 219.30433,207.70059 z "
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="rect2202"
- sodipodi:nodetypes="cccccccccc"
- d="M 221.68659,286.68216 C 221.68659,286.68216 271.7827,246.38199 271.7827,246.38199 C 272.38533,245.90267 273.62888,245.89275 274.57389,246.35926 C 274.57389,246.35926 282.22513,250.1218 282.22513,250.1218 C 283.18438,250.59535 283.48058,251.37156 282.88624,251.86264 C 282.88624,251.86264 233.55382,293.3224 233.55382,293.3224 C 232.81433,293.93337 231.39356,293.96431 230.37209,293.3911 C 230.37209,293.3911 222.1464,288.7742 222.1464,288.7742 C 221.14187,288.21048 220.9385,287.27719 221.68659,286.68216 C 221.68659,286.68216 221.68659,286.68216 221.68659,286.68216"
- style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path2449"
- d="M 219.03426,288.29491 L 230.39646,294.74997 L 222.03124,301.79784 L 210.47874,295.2849 L 219.03426,288.29491 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2451"
- d="M 209.4152,296.07932 L 221.07617,302.55531 L 212.38161,309.86664 L 201.01939,302.85172 L 209.4152,296.07932 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2453"
- d="M 200.12349,303.5516 L 211.48907,310.55261 L 202.5404,317.99996 L 190.60096,311.18361 L 200.12349,303.5516 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2455"
- d="M 189.70952,311.95745 L 201.6931,318.78476 L 190.71106,328.04619 L 178.53214,321.0788 L 189.70952,311.95745 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2457"
- sodipodi:nodetypes="ccccc"
- d="M 273.68393,244.42789 L 284.19406,249.63047 L 292.16408,243.02723 L 281.60172,238.10854 L 273.68393,244.42789 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2459"
- sodipodi:nodetypes="ccccc"
- d="M 282.58552,237.35878 L 290.13787,231.26634 L 300.94177,235.89096 L 293.0886,242.26102 L 282.58552,237.35878 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2461"
- sodipodi:nodetypes="ccccc"
- d="M 291.16226,230.48888 L 301.87328,235.11565 L 309.36795,228.87453 L 299.02555,224.08989 L 291.16226,230.48888 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2463"
- sodipodi:nodetypes="ccccc"
- d="M 289.93538,230.01549 L 280.93975,225.55672 L 289.03737,219.25932 L 297.95995,223.58772 L 289.93538,230.01549 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2465"
- d="M 177.42321,320.41889 L 166.48786,314.26225 L 188.72682,297.2375 L 199.03429,302.90648 L 177.42321,320.41889 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2467"
- sodipodi:nodetypes="ccccc"
- d="M 290.08046,218.43641 L 298.85735,222.73969 L 319.87746,205.75759 L 310.78391,202.19572 L 290.08046,218.43641 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2469"
- sodipodi:nodetypes="ccccccc"
- d="M 298.08535,210.7646 L 309.62549,201.69751 L 288.03973,193.31937 L 273.6384,203.95987 L 283.46625,207.8962 L 286.18927,205.81393 L 298.08535,210.7646 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2471"
- sodipodi:nodetypes="ccccc"
- d="M 286.62375,192.75442 L 266.91147,207.38925 L 257.59069,203.41102 L 277.74109,189.32694 L 286.62375,192.75442 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2473"
- d="M 165.36066,313.63832 L 184.46965,298.98505 L 172.33203,292.59392 L 153.19109,306.83736 L 165.36066,313.63832 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2475"
- d="M 151.95557,306.23713 L 167.0892,294.93513 L 156.09726,289.01503 L 140.88977,299.91382 L 151.95557,306.23713 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2477"
- d="M 139.74507,299.3323 L 150.85746,291.335 L 140.35153,285.53863 L 129.36288,293.43149 L 139.74507,299.3323 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2497"
- d="M 141.44916,284.84419 L 150.48582,278.42628 L 160.93153,283.91261 L 151.79607,290.59399 L 141.44916,284.84419 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2499"
- d="M 200.06639,302.0818 L 208.31119,295.49502 L 197.64102,290.05561 L 189.67659,296.43646 L 200.06639,302.0818 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2501"
- d="M 185.44374,298.19559 L 193.86354,291.59284 L 181.96116,285.25056 L 173.47309,291.62812 L 185.44374,298.19559 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2503"
- d="M 168.25222,294.17765 L 176.70261,287.76919 L 165.64522,281.91859 L 157.20372,288.20299 L 168.25222,294.17765 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 151.55607,277.71812 L 160.35985,271.62622 L 170.55671,277.01143 L 161.94955,283.18847 L 151.55607,277.71812 z "
- sodipodi:nodetypes="ccccc"
- id="path2505"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2507"
- d="M 177.75365,287.00502 L 186.23698,280.4648 L 175.54186,274.93789 L 166.63928,281.22229 L 177.75365,287.00502 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2509"
- d="M 161.45339,270.89479 L 170.04758,264.82618 L 180.19785,270.07166 L 171.68385,276.24869 L 161.45339,270.89479 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2511"
- d="M 194.72496,290.89785 L 203.34236,284.16335 L 191.50585,278.08454 L 183.01779,284.4621 L 194.72496,290.89785 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2513"
- d="M 209.44739,294.73981 L 218.00506,287.74135 L 207.50073,282.4405 L 198.6953,289.16034 L 209.44739,294.73981 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2515"
- d="M 219.03117,287.00034 L 227.95111,279.8372 L 217.57851,274.66809 L 208.54255,281.61848 L 219.03117,287.00034 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2517"
- d="M 229.01016,279.06327 L 236.63632,273.08946 L 226.18986,268.0248 L 218.58741,273.879 L 229.01016,279.06327 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2519"
- d="M 237.61157,272.25159 L 246.12267,265.48601 L 235.81592,260.50649 L 227.24338,267.18776 L 237.61157,272.25159 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 246.92622,264.70405 L 255.31922,258.03494 L 245.2101,253.19516 L 236.79987,259.71739 L 246.92622,264.70405 z "
- sodipodi:nodetypes="ccccc"
- id="path2521"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2523"
- sodipodi:nodetypes="ccccc"
- d="M 256.24944,257.30562 L 264.00138,251.14415 L 253.91623,246.49536 L 246.24255,252.47136 L 256.24944,257.30562 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 264.94343,250.38346 L 271.79281,244.57197 L 262.14241,240.07284 L 254.8806,245.75341 L 264.94343,250.38346 z "
- sodipodi:nodetypes="ccccc"
- id="path2525"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2527"
- sodipodi:nodetypes="ccccc"
- d="M 272.6829,243.79667 L 280.45445,237.62292 L 270.90284,233.32138 L 263.17995,239.29836 L 272.6829,243.79667 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 281.41039,236.84761 L 288.91847,230.83852 L 279.86087,226.40525 L 272.03919,232.4481 L 281.41039,236.84761 z "
- sodipodi:nodetypes="ccccc"
- id="path2529"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2531"
- d="M 171.18769,264.04817 L 180.52708,257.51381 L 190.25819,262.57298 L 181.32501,269.3555 L 171.18769,264.04817 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2533"
- sodipodi:nodetypes="ccccc"
- d="M 181.56334,256.75316 L 190.15752,250.68454 L 199.60916,255.83687 L 191.23489,261.73446 L 181.56334,256.75316 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 191.13838,249.97224 L 200.12848,243.67074 L 209.58148,248.76519 L 200.57843,255.12855 L 191.13838,249.97224 z "
- sodipodi:nodetypes="ccccc"
- id="path2535"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2537"
- sodipodi:nodetypes="ccccc"
- d="M 201.14148,242.94942 L 208.96784,237.50889 L 218.76812,242.01382 L 210.62107,248.07043 L 201.14148,242.94942 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 209.93861,236.70829 L 218.48624,230.77939 L 228.17074,235.18651 L 219.79647,241.31698 L 209.93861,236.70829 z "
- sodipodi:nodetypes="ccccc"
- id="path2539"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2541"
- sodipodi:nodetypes="ccccc"
- d="M 219.48896,230.08656 L 227.94108,224.18895 L 237.62559,228.38647 L 229.19014,234.46609 L 219.48896,230.08656 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 229.04981,223.34939 L 237.64399,217.28078 L 247.18879,221.5016 L 238.67479,227.67863 L 229.04981,223.34939 z "
- sodipodi:nodetypes="ccccc"
- id="path2543"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2545"
- sodipodi:nodetypes="ccccc"
- d="M 238.75966,216.51376 L 246.46891,211.02733 L 256.03698,215.155 L 248.29149,220.74984 L 238.75966,216.51376 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 247.52515,210.2999 L 256.52687,204.13813 L 265.95523,208.14936 L 257.24328,214.48941 L 247.52515,210.2999 z "
- sodipodi:nodetypes="ccccc"
- id="path2547"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2242"
- d="M 192.42707,277.38276 L 201.04243,270.93376 L 212.81727,276.9437 L 204.25518,283.46405 L 192.42707,277.38276 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2244"
- d="M 202.01582,270.12726 L 210.21341,264.10219 L 221.92044,269.93134 L 213.74806,276.20857 L 202.01582,270.12726 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2246"
- d="M 211.22102,263.35122 L 219.52192,257.1363 L 231.06172,262.8037 L 222.85738,269.20877 L 211.22102,263.35122 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2248"
- sodipodi:nodetypes="ccccc"
- d="M 220.48694,256.41147 L 231.99345,262.05286 L 239.51447,256.25393 L 228.07804,250.72214 C 228.07804,250.72214 220.51891,256.44343 220.48694,256.41147 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 228.98488,249.90241 L 240.4914,255.5438 L 248.01241,249.74486 L 236.57599,244.21308 C 236.57599,244.21308 229.01684,249.93436 228.98488,249.90241 z "
- sodipodi:nodetypes="ccccc"
- id="path2250"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2252"
- sodipodi:nodetypes="ccccc"
- d="M 237.56868,243.44725 L 248.97931,248.99274 L 257.07404,242.57877 L 246.02277,237.37437 L 237.56868,243.44725 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 247.06561,236.56786 L 258.0749,241.84765 L 265.97947,235.69713 L 254.71266,230.82259 L 247.06561,236.56786 z "
- sodipodi:nodetypes="ccccc"
- id="path2254"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2256"
- sodipodi:nodetypes="ccccc"
- d="M 255.89713,229.9869 L 266.95163,234.90506 L 274.38224,229.19653 L 263.30742,224.43317 L 255.89713,229.9869 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 264.32207,223.68092 L 275.3101,228.44997 L 282.89504,222.58711 L 271.91318,217.99159 L 264.32207,223.68092 z "
- sodipodi:nodetypes="ccccc"
- id="path2258"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2260"
- sodipodi:nodetypes="ccccc"
- d="M 272.9276,217.22814 L 283.86907,221.82988 L 290.30525,216.88979 L 279.45645,212.28463 L 272.9276,217.22814 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 280.51495,211.48086 L 291.20783,216.17301 L 297.14678,211.54933 L 286.38838,207.05719 L 280.51495,211.48086 z "
- sodipodi:nodetypes="ccccc"
- id="path2262"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2264"
- d="M 187.21456,279.65363 L 195.69788,273.11343 L 185.00277,267.58651 L 176.10019,273.87091 L 187.21456,279.65363 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2266"
- d="M 196.93117,272.23833 L 205.68571,265.78852 L 194.71938,260.1712 L 185.8168,266.4556 L 196.93117,272.23833 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2268"
- sodipodi:nodetypes="ccccc"
- d="M 206.76011,265.04128 L 215.60505,258.63667 L 204.90993,253.42617 L 196.23337,259.52977 L 206.76011,265.04128 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 216.55615,257.79127 L 225.72667,251.12321 L 215.30323,245.97983 L 205.95318,252.6478 L 216.55615,257.79127 z "
- sodipodi:nodetypes="ccccc"
- id="path2270"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2272"
- sodipodi:nodetypes="ccccc"
- d="M 226.62217,250.28446 L 234.42747,244.46748 L 224.14692,239.49074 L 216.41185,245.13456 L 226.62217,250.28446 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 235.3202,243.66108 L 242.92208,238.20571 L 232.8824,233.22122 L 225.20027,238.78239 L 235.3202,243.66108 z "
- sodipodi:nodetypes="ccccc"
- id="path2274"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2276"
- sodipodi:nodetypes="ccccc"
- d="M 244.04269,237.40717 L 251.47219,231.70252 L 241.73406,226.77098 L 234.01317,232.34768 L 244.04269,237.40717 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 252.6522,231.11226 L 260.3045,225.27523 L 250.58643,220.64138 L 242.89843,226.09476 L 252.6522,231.11226 z "
- sodipodi:nodetypes="ccccc"
- id="path2278"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2280"
- sodipodi:nodetypes="ccccc"
- d="M 261.23976,224.42239 L 268.45876,219.21044 L 258.80517,214.83417 L 251.72352,219.79033 L 261.23976,224.42239 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 269.52519,218.43638 L 275.83883,213.61385 L 266.36416,209.30737 L 259.8121,214.10012 L 269.52519,218.43638 z "
- sodipodi:nodetypes="ccccc"
- id="path2282"
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path2284"
- sodipodi:nodetypes="ccccc"
- d="M 276.80269,212.87655 L 282.2575,208.64164 L 272.64721,204.83239 L 267.406,208.63069 L 276.80269,212.87655 z "
- style="fill:#ff00ff;fill-rule:evenodd;stroke:#000000;stroke-width:1.02280068px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="rect3291"
- d="M 302.87759,234.27933 C 302.87759,234.27933 308.38212,229.69548 308.38212,229.69548 C 308.92862,229.24038 308.77424,228.59985 308.03355,228.25718 C 308.03355,228.25718 300.43832,224.74347 300.43832,224.74347 C 299.65719,224.38211 298.56475,224.46487 297.99153,224.93134 C 297.99153,224.93134 292.2163,229.63113 292.2163,229.63113 C 291.63275,230.10601 291.81664,230.77156 292.62585,231.12111 C 292.62585,231.12111 300.49174,234.51889 300.49174,234.51889 C 301.25859,234.85015 302.32155,234.74235 302.87759,234.27933 C 302.87759,234.27933 302.87759,234.27933 302.87759,234.27933"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3293"
- d="M 235.3731,272.47703 C 235.3731,272.47703 227.42329,268.6228 227.42329,268.6228 C 226.73948,268.29128 225.78761,268.33455 225.2875,268.71966 C 225.2875,268.71966 219.50192,273.17479 219.50192,273.17479 C 218.99549,273.56477 219.13572,274.15174 219.81793,274.49107 C 219.81793,274.49107 227.7497,278.43631 227.7497,278.43631 C 228.44749,278.78339 229.41954,278.74258 229.9276,278.34461 C 229.9276,278.34461 235.73123,273.79845 235.73123,273.79845 C 236.23285,273.4055 236.07241,272.81607 235.3731,272.47703 C 235.3731,272.47703 235.3731,272.47703 235.3731,272.47703"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3299"
- d="M 247.43674,211.44485 C 247.43674,211.44485 255.04475,214.72695 255.04475,214.72695 C 255.59412,214.96395 255.68572,215.40873 255.24904,215.72416 C 255.24904,215.72416 249.09015,220.17295 249.09015,220.17295 C 248.64784,220.49244 247.85024,220.55375 247.30291,220.31051 C 247.30291,220.31051 239.72373,216.94221 239.72373,216.94221 C 239.18929,216.7047 239.11431,216.26136 239.55452,215.94809 C 239.55452,215.94809 245.68459,211.58552 245.68459,211.58552 C 246.11924,211.27618 246.90023,211.21341 247.43674,211.44485 C 247.43674,211.44485 247.43674,211.44485 247.43674,211.44485"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3301"
- d="M 211.38791,264.687 C 211.38791,264.687 220.69642,269.32187 220.69642,269.32187 C 221.37384,269.65917 221.55369,270.21304 221.09728,270.56361 C 221.09728,270.56361 214.59913,275.55485 214.59913,275.55485 C 214.12804,275.9167 213.20005,275.92451 212.52093,275.57249 C 212.52093,275.57249 203.19239,270.73714 203.19239,270.73714 C 202.53988,270.39891 202.39682,269.84723 202.86919,269.50005 C 202.86919,269.50005 209.38739,264.7093 209.38739,264.7093 C 209.84537,264.37269 210.73656,264.36268 211.38791,264.687 C 211.38791,264.687 211.38791,264.687 211.38791,264.687"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3305"
- d="M 190.80124,251.03544 C 190.80124,251.03544 198.99762,255.5035 198.99762,255.5035 C 199.33669,255.68835 199.3609,256.01171 199.05255,256.22886 C 199.05255,256.22886 191.79012,261.34344 191.79012,261.34344 C 191.48252,261.56007 190.95608,261.59085 190.60912,261.41215 C 190.60912,261.41215 182.222,257.0924 182.222,257.0924 C 181.85741,256.90462 181.81745,256.57372 182.13313,256.35082 C 182.13313,256.35082 189.58629,251.08792 189.58629,251.08792 C 189.90275,250.86444 190.44492,250.8412 190.80124,251.03544 C 190.80124,251.03544 190.80124,251.03544 190.80124,251.03544"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3309"
- d="M 200.86922,319.47957 C 200.86922,319.47957 191.5626,327.32806 191.5626,327.32806 C 191.09111,327.72566 190.29604,327.80875 189.78059,327.51386 C 189.78059,327.51386 179.45944,321.6093 179.45944,321.6093 C 178.94568,321.31539 178.91894,320.76315 179.3988,320.37157 C 179.3988,320.37157 188.87097,312.64175 188.87097,312.64175 C 189.33581,312.26242 190.11645,312.18928 190.62199,312.47729 C 190.62199,312.47729 200.77757,318.26317 200.77757,318.26317 C 201.28475,318.55212 201.32593,319.09442 200.86922,319.47957 C 200.86922,319.47957 200.86922,319.47957 200.86922,319.47957"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3311"
- d="M 227.03328,279.37981 C 227.03328,279.37981 218.4746,275.11465 218.4746,275.11465 C 217.9779,274.86712 217.23368,274.93335 216.80449,275.26346 C 216.80449,275.26346 209.3489,280.99824 209.3489,280.99824 C 208.90258,281.34154 208.94628,281.82562 209.44841,282.08328 C 209.44841,282.08328 218.10282,286.52398 218.10282,286.52398 C 218.61686,286.78775 219.38667,286.71486 219.82736,286.36095 C 219.82736,286.36095 227.18725,280.45063 227.18725,280.45063 C 227.61081,280.1105 227.5415,279.63307 227.03328,279.37981 C 227.03328,279.37981 227.03328,279.37981 227.03328,279.37981"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3313"
- d="M 200.87727,244.07429 C 200.87727,244.07429 208.8242,248.35707 208.8242,248.35707 C 209.24365,248.58313 209.26299,248.99029 208.86725,249.27001 C 208.86725,249.27001 201.29858,254.61953 201.29858,254.61953 C 200.89969,254.90148 200.24107,254.94426 199.82216,254.71545 C 199.82216,254.71545 191.88613,250.38067 191.88613,250.38067 C 191.47181,250.15435 191.45917,249.7474 191.8575,249.46819 C 191.8575,249.46819 199.41526,244.17067 199.41526,244.17067 C 199.81044,243.89367 200.46234,243.85067 200.87727,244.07429 C 200.87727,244.07429 200.87727,244.07429 200.87727,244.07429"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3317"
- d="M 168.98052,312.35404 C 168.98052,312.35404 186.52228,298.92516 186.52228,298.92516 C 187.74742,297.98727 189.20942,297.50291 189.80916,297.83277 C 189.80916,297.83277 197.94313,302.30636 197.94313,302.30636 C 198.54751,302.63875 198.08283,303.67748 196.89261,304.64197 C 196.89261,304.64197 179.8462,318.45547 179.8462,318.45547 C 178.50836,319.53957 176.90663,320.12806 176.26526,319.76696 C 176.26526,319.76696 167.6358,314.90855 167.6358,314.90855 C 166.99971,314.55042 167.60418,313.40767 168.98052,312.35404 C 168.98052,312.35404 168.98052,312.35404 168.98052,312.35404"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3319"
- d="M 192.5101,290.87165 C 192.5101,290.87165 183.27464,285.95046 183.27464,285.95046 C 182.54633,285.56237 181.54412,285.5639 181.0251,285.95388 C 181.0251,285.95388 174.43893,290.90244 174.43893,290.90244 C 173.90432,291.3041 174.06146,291.95091 174.79375,292.35267 C 174.79375,292.35267 184.08217,297.44861 184.08217,297.44861 C 184.83581,297.86207 185.87162,297.86005 186.40206,297.44408 C 186.40206,297.44408 192.93525,292.32079 192.93525,292.32079 C 193.44997,291.91714 193.25925,291.27084 192.5101,290.87165 C 192.5101,290.87165 192.5101,290.87165 192.5101,290.87165"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3321"
- d="M 185.1382,279.89699 C 185.1382,279.89699 176.63387,275.50221 176.63387,275.50221 C 176.02877,275.18952 175.15088,275.21388 174.66322,275.55813 C 174.66322,275.55813 167.58535,280.55447 167.58535,280.55447 C 167.06223,280.92372 167.14522,281.48553 167.77396,281.81266 C 167.77396,281.81266 176.61165,286.41084 176.61165,286.41084 C 177.2442,286.73996 178.15674,286.69425 178.65527,286.3099 C 178.65527,286.3099 185.39983,281.11021 185.39983,281.11021 C 185.86446,280.752 185.74682,280.2115 185.1382,279.89699 C 185.1382,279.89699 185.1382,279.89699 185.1382,279.89699"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3323"
- d="M 161.12258,272.02905 C 161.12258,272.02905 169.7964,276.60989 169.7964,276.60989 C 170.21763,276.83236 170.27487,277.2137 169.92432,277.46528 C 169.92432,277.46528 162.60291,282.7196 162.60291,282.7196 C 162.24117,282.9792 161.60395,283.00656 161.17461,282.7806 C 161.17461,282.7806 152.33353,278.12732 152.33353,278.12732 C 151.90283,277.90063 151.85435,277.51172 152.22438,277.25569 C 152.22438,277.25569 159.71303,272.0738 159.71303,272.0738 C 160.07158,271.82571 160.70003,271.80589 161.12258,272.02905 C 161.12258,272.02905 161.12258,272.02905 161.12258,272.02905"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3325"
- d="M 220.2904,303.21609 C 220.2904,303.21609 213.19436,309.1832 213.19436,309.1832 C 212.74444,309.56153 211.88835,309.56212 211.27912,309.18598 C 211.27912,309.18598 202.00839,303.46232 202.00839,303.46232 C 201.45919,303.12325 201.36941,302.5694 201.80347,302.21926 C 201.80347,302.21926 208.65568,296.69198 208.65568,296.69198 C 209.07675,296.35232 209.86703,296.33025 210.43121,296.64355 C 210.43121,296.64355 219.94579,301.92755 219.94579,301.92755 C 220.57046,302.27448 220.72603,302.84974 220.2904,303.21609 C 220.2904,303.21609 220.2904,303.21609 220.2904,303.21609"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3327"
- d="M 250.18155,231.04893 C 250.18155,231.04893 243.02922,227.42687 243.02922,227.42687 C 242.31181,227.06355 241.28875,227.09263 240.73358,227.49361 C 240.73358,227.49361 235.06335,231.58914 235.06335,231.58914 C 234.48252,232.00866 234.60822,232.64785 235.34714,233.02061 C 235.34714,233.02061 242.71349,236.73664 242.71349,236.73664 C 243.44994,237.10815 244.49431,237.0604 245.05318,236.63127 C 245.05318,236.63127 250.50942,232.44177 250.50942,232.44177 C 251.04367,232.03155 250.89663,231.41106 250.18155,231.04893 C 250.18155,231.04893 250.18155,231.04893 250.18155,231.04893"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3329"
- d="M 241.73896,237.6183 C 241.73896,237.6183 234.09875,233.82511 234.09875,233.82511 C 233.42547,233.49084 232.47146,233.51871 231.96125,233.88804 C 231.96125,233.88804 226.11501,238.1202 226.11501,238.1202 C 225.60814,238.48713 225.74764,239.04628 226.42628,239.37343 C 226.42628,239.37343 234.12755,243.08611 234.12755,243.08611 C 234.78882,243.40491 235.72382,243.37142 236.22543,243.01146 C 236.22543,243.01146 242.01062,238.85982 242.01062,238.85982 C 242.51547,238.49751 242.39495,237.94399 241.73896,237.6183 C 241.73896,237.6183 241.73896,237.6183 241.73896,237.6183"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3331"
- d="M 291.06923,231.66501 C 291.06923,231.66501 299.93537,235.46017 299.93537,235.46017 C 300.49195,235.69842 300.62867,236.14494 300.23967,236.46046 C 300.23967,236.46046 293.79405,241.68879 293.79405,241.68879 C 293.40327,242.00578 292.65126,242.0569 292.11015,241.80432 C 292.11015,241.80432 283.49087,237.78134 283.49087,237.78134 C 282.98847,237.54685 282.88811,237.11468 283.26389,236.81155 C 283.26389,236.81155 289.4626,231.81108 289.4626,231.81108 C 289.83674,231.50927 290.5524,231.44378 291.06923,231.66501 C 291.06923,231.66501 291.06923,231.66501 291.06923,231.66501"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3333"
- d="M 214.6618,258.17714 C 214.6618,258.17714 205.79323,253.8565 205.79323,253.8565 C 205.30323,253.61778 204.58399,253.65545 204.17864,253.94061 C 204.17864,253.94061 196.98327,259.00223 196.98327,259.00223 C 196.56804,259.29434 196.62028,259.73235 197.10235,259.98475 C 197.10235,259.98475 205.83129,264.55497 205.83129,264.55497 C 206.34512,264.82401 207.10144,264.79412 207.5249,264.48748 C 207.5249,264.48748 214.85991,259.17623 214.85991,259.17623 C 215.27294,258.87715 215.18363,258.43136 214.6618,258.17714 C 214.6618,258.17714 214.6618,258.17714 214.6618,258.17714"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3335"
- d="M 238.61522,217.71027 C 238.61522,217.71027 246.20482,221.06648 246.20482,221.06648 C 246.74975,221.30745 246.80537,221.77975 246.32841,222.12581 C 246.32841,222.12581 239.55856,227.03746 239.55856,227.03746 C 239.06928,227.39242 238.23201,227.47949 237.68245,227.2323 C 237.68245,227.2323 230.0291,223.78987 230.0291,223.78987 C 229.48641,223.54578 229.44798,223.06823 229.94181,222.71952 C 229.94181,222.71952 236.77542,217.89409 236.77542,217.89409 C 237.25693,217.55409 238.07699,217.47225 238.61522,217.71027 C 238.61522,217.71027 238.61522,217.71027 238.61522,217.71027"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3337"
- d="M 228.91723,224.61205 C 228.91723,224.61205 236.61775,227.94965 236.61775,227.94965 C 237.17563,228.19144 237.24665,228.65958 236.77513,228.99941 C 236.77513,228.99941 230.06777,233.83356 230.06777,233.83356 C 229.58195,234.18369 228.73926,234.26255 228.18027,234.01019 C 228.18027,234.01019 220.46652,230.52787 220.46652,230.52787 C 219.92451,230.28318 219.88144,229.8127 220.36809,229.47313 C 220.36809,229.47313 227.0887,224.78372 227.0887,224.78372 C 227.56129,224.45396 228.37602,224.37747 228.91723,224.61205 C 228.91723,224.61205 228.91723,224.61205 228.91723,224.61205"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3339"
- d="M 257.14967,204.40311 C 257.14967,204.40311 265.32623,207.88176 265.32623,207.88176 C 265.67464,208.02998 265.706,208.33073 265.3957,208.55655 C 265.3957,208.55655 257.84099,214.05443 257.84099,214.05443 C 257.51021,214.29515 256.95402,214.3647 256.59485,214.20987 C 256.59485,214.20987 248.16698,210.57659 248.16698,210.57659 C 247.81135,210.42328 247.8009,210.11114 248.14264,209.87723 C 248.14264,209.87723 255.94863,204.53395 255.94863,204.53395 C 256.2693,204.31446 256.80459,204.25629 257.14967,204.40311 C 257.14967,204.40311 257.14967,204.40311 257.14967,204.40311"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3341"
- d="M 201.8511,271.34651 C 201.8511,271.34651 212.00249,276.52784 212.00249,276.52784 C 212.45381,276.7582 212.55592,277.14272 212.23112,277.39008 C 212.23112,277.39008 204.84954,283.01143 204.84954,283.01143 C 204.52035,283.26212 203.89008,283.27634 203.43671,283.04324 C 203.43671,283.04324 193.23937,277.8004 193.23937,277.8004 C 192.78929,277.56899 192.69387,277.18305 193.0251,276.9351 C 193.0251,276.9351 200.45262,271.37525 200.45262,271.37525 C 200.77944,271.1306 201.40305,271.11781 201.8511,271.34651 C 201.8511,271.34651 201.8511,271.34651 201.8511,271.34651"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3343"
- d="M 219.21667,231.1118 C 219.21667,231.1118 227.42383,234.84661 227.42383,234.84661 C 227.83744,235.03484 227.89363,235.38938 227.54865,235.64192 C 227.54865,235.64192 220.45221,240.83693 220.45221,240.83693 C 220.08929,241.10262 219.45708,241.15831 219.03594,240.96141 C 219.03594,240.96141 210.6819,237.05577 210.6819,237.05577 C 210.26995,236.86319 210.23739,236.50104 210.60771,236.24418 C 210.60771,236.24418 217.85107,231.21996 217.85107,231.21996 C 218.20329,230.97566 218.81185,230.92758 219.21667,231.1118 C 219.21667,231.1118 219.21667,231.1118 219.21667,231.1118"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3345"
- d="M 166.11203,294.40885 C 166.11203,294.40885 157.04241,289.52408 157.04241,289.52408 C 156.51843,289.24186 155.52217,289.42717 154.80588,289.94053 C 154.80588,289.94053 142.25863,298.93279 142.25863,298.93279 C 141.50124,299.47559 141.31352,300.15596 141.84075,300.45723 C 141.84075,300.45723 150.97129,305.67469 150.97129,305.67469 C 151.51617,305.98604 152.56442,305.78244 153.31853,305.21926 C 153.31853,305.21926 165.80481,295.89435 165.80481,295.89435 C 166.51725,295.36228 166.65299,294.70021 166.11203,294.40885 C 166.11203,294.40885 166.11203,294.40885 166.11203,294.40885"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3349"
- d="M 151.01455,278.70397 C 151.01455,278.70397 160.37455,283.62006 160.37455,283.62006 C 160.68292,283.78202 160.7229,284.06518 160.46357,284.25485 C 160.46357,284.25485 152.27741,290.24195 152.27741,290.24195 C 152.01084,290.43692 151.5497,290.45709 151.24414,290.28729 C 151.24414,290.28729 141.97268,285.13512 141.97268,285.13512 C 141.68247,284.97384 141.66152,284.69337 141.92511,284.50616 C 141.92511,284.50616 150.02275,278.75515 150.02275,278.75515 C 150.27937,278.57289 150.72146,278.55003 151.01455,278.70397 C 151.01455,278.70397 151.01455,278.70397 151.01455,278.70397"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3351"
- d="M 175.52443,287.1458 C 175.52443,287.1458 166.79876,282.52893 166.79876,282.52893 C 166.15936,282.19062 165.25137,282.21179 164.76171,282.57631 C 164.76171,282.57631 158.10028,287.53553 158.10028,287.53553 C 157.60379,287.90516 157.7174,288.48077 158.35625,288.82623 C 158.35625,288.82623 167.07489,293.541 167.07489,293.541 C 167.72676,293.8935 168.65274,293.87392 169.1498,293.49696 C 169.1498,293.49696 175.81827,288.43985 175.81827,288.43985 C 176.30838,288.06815 176.17677,287.49096 175.52443,287.1458 C 175.52443,287.1458 175.52443,287.1458 175.52443,287.1458"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3353"
- d="M 201.97097,283.45905 C 201.97097,283.45905 192.78768,278.74285 192.78768,278.74285 C 192.07622,278.37747 191.08839,278.3982 190.5689,278.78852 C 190.5689,278.78852 183.98269,283.7371 183.98269,283.7371 C 183.44857,284.1384 183.58158,284.77203 184.28486,285.15865 C 184.28486,285.15865 193.36778,290.15177 193.36778,290.15177 C 194.11817,290.56428 195.16258,290.55584 195.70514,290.13183 C 195.70514,290.13183 202.39168,284.90631 202.39168,284.90631 C 202.9188,284.49436 202.72924,283.84847 201.97097,283.45905 C 201.97097,283.45905 201.97097,283.45905 201.97097,283.45905"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3355"
- d="M 183.209,298.32124 C 183.209,298.32124 173.55788,293.23939 173.55788,293.23939 C 172.87828,292.88156 171.48018,293.22782 170.41912,294.01738 C 170.41912,294.01738 155.20003,305.34244 155.20003,305.34244 C 154.08849,306.16958 153.73855,307.14332 154.41967,307.52396 C 154.41967,307.52396 164.0962,312.93167 164.0962,312.93167 C 164.79619,313.32286 166.25692,312.95103 167.36704,312.09976 C 167.36704,312.09976 182.56068,300.44889 182.56068,300.44889 C 183.61957,299.63691 183.90689,298.68872 183.209,298.32124 C 183.209,298.32124 183.209,298.32124 183.209,298.32124"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3357"
- d="M 181.25173,257.89055 C 181.25173,257.89055 189.52937,262.19408 189.52937,262.19408 C 189.93309,262.40396 189.973,262.78951 189.61763,263.05932 C 189.61763,263.05932 182.01974,268.82803 182.01974,268.82803 C 181.63543,269.11981 180.98628,269.17817 180.56566,268.95795 C 180.56566,268.95795 171.94248,264.44335 171.94248,264.44335 C 171.5243,264.2244 171.5122,263.82114 171.91393,263.54006 C 171.91393,263.54006 179.85732,257.98241 179.85732,257.98241 C 180.2289,257.72244 180.85025,257.68182 181.25173,257.89055 C 181.25173,257.89055 181.25173,257.89055 181.25173,257.89055"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3359"
- d="M 207.30074,294.9799 C 207.30074,294.9799 198.59287,290.54083 198.59287,290.54083 C 198.06485,290.27167 197.31412,290.31751 196.90812,290.6428 C 196.90812,290.6428 190.40778,295.85065 190.40778,295.85065 C 190.00268,296.17521 190.08929,296.66071 190.60345,296.94008 C 190.60345,296.94008 199.08253,301.54721 199.08253,301.54721 C 199.62684,301.84297 200.40395,301.81213 200.82331,301.47711 C 200.82331,301.47711 207.55245,296.10117 207.55245,296.10117 C 207.97277,295.76537 207.85976,295.26488 207.30074,294.9799 C 207.30074,294.9799 207.30074,294.9799 207.30074,294.9799"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3361"
- d="M 210.31834,311.52693 C 210.31834,311.52693 203.74605,316.99659 203.74605,316.99659 C 203.0788,317.55189 201.86,317.61152 201.01035,317.12644 C 201.01035,317.12644 192.24289,312.121 192.24289,312.121 C 191.3355,311.60296 191.17426,310.72413 191.88471,310.15474 C 191.88471,310.15474 198.87844,304.54948 198.87844,304.54948 C 199.56891,303.99608 200.82226,303.98204 201.68556,304.51382 C 201.68556,304.51382 210.03168,309.65489 210.03168,309.65489 C 210.84096,310.15338 210.96757,310.98662 210.31834,311.52693 C 210.31834,311.52693 210.31834,311.52693 210.31834,311.52693"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3363"
- d="M 229.40869,295.58217 C 229.40869,295.58217 223.04271,300.94565 223.04271,300.94565 C 222.48275,301.41742 221.41805,301.45214 220.65599,301.0225 C 220.65599,301.0225 211.86431,296.06605 211.86431,296.06605 C 211.09687,295.63339 210.94055,294.9076 211.51326,294.43967 C 211.51326,294.43967 218.02408,289.12024 218.02408,289.12024 C 218.58411,288.66268 219.64217,288.64028 220.39694,289.06907 C 220.39694,289.06907 229.04379,293.98149 229.04379,293.98149 C 229.79334,294.40733 229.95631,295.12081 229.40869,295.58217 C 229.40869,295.58217 229.40869,295.58217 229.40869,295.58217"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3365"
- d="M 217.05231,287.26056 C 217.05231,287.26056 208.43084,282.90987 208.43084,282.90987 C 207.9153,282.6497 207.16011,282.70044 206.73573,283.02431 C 206.73573,283.02431 199.50923,288.5392 199.50923,288.5392 C 199.05894,288.88283 199.11946,289.38044 199.64696,289.65417 C 199.64696,289.65417 208.47177,294.23353 208.47177,294.23353 C 209.01197,294.51386 209.80095,294.45066 210.23875,294.09263 C 210.23875,294.09263 217.26191,288.3491 217.26191,288.3491 C 217.67418,288.01194 217.57986,287.52677 217.05231,287.26056 C 217.05231,287.26056 217.05231,287.26056 217.05231,287.26056"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3367"
- d="M 170.90895,265.27133 C 170.90895,265.27133 179.32655,269.62137 179.32655,269.62137 C 179.80913,269.87078 179.87784,270.30382 179.47992,270.59253 C 179.47992,270.59253 172.41934,275.71508 172.41934,275.71508 C 172.01209,276.01056 171.29204,276.04365 170.8056,275.78907 C 170.8056,275.78907 162.3215,271.34911 162.3215,271.34911 C 161.84045,271.09734 161.7847,270.66085 162.19576,270.37059 C 162.19576,270.37059 169.32283,265.33795 169.32283,265.33795 C 169.72453,265.05428 170.43163,265.02465 170.90895,265.27133 C 170.90895,265.27133 170.90895,265.27133 170.90895,265.27133"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3369"
- d="M 204.55438,265.20903 C 204.55438,265.20903 195.83444,260.74237 195.83444,260.74237 C 195.21646,260.42583 194.32033,260.45289 193.82368,260.80347 C 193.82368,260.80347 186.74496,265.80041 186.74496,265.80041 C 186.23123,266.16305 186.32053,266.71769 186.94675,267.04351 C 186.94675,267.04351 195.78441,271.64167 195.78441,271.64167 C 196.41947,271.97209 197.33877,271.93803 197.84403,271.56578 C 197.84403,271.56578 204.80505,266.43735 204.80505,266.43735 C 205.29337,266.07757 205.18091,265.52994 204.55438,265.20903 C 204.55438,265.20903 204.55438,265.20903 204.55438,265.20903"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3371"
- d="M 194.5991,272.5456 C 194.5991,272.5456 186.09478,268.15083 186.09478,268.15083 C 185.48971,267.83814 184.61179,267.8625 184.12412,268.20675 C 184.12412,268.20675 177.04625,273.20308 177.04625,273.20308 C 176.52314,273.57235 176.60616,274.13416 177.23487,274.46127 C 177.23487,274.46127 186.07255,279.05946 186.07255,279.05946 C 186.70512,279.38857 187.61765,279.34288 188.11618,278.95853 C 188.11618,278.95853 194.86074,273.75884 194.86074,273.75884 C 195.32537,273.40062 195.20773,272.86013 194.5991,272.5456 C 194.5991,272.5456 194.5991,272.5456 194.5991,272.5456"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3373"
- d="M 284.73208,249.18471 C 284.73208,249.18471 291.64382,243.45826 291.64382,243.45826 C 291.9322,243.21935 291.84218,242.87732 291.44316,242.6915 C 291.44316,242.6915 282.28362,238.42609 282.28362,238.42609 C 281.90552,238.25002 281.37123,238.2925 281.08461,238.52125 C 281.08461,238.52125 274.21817,244.0015 274.21817,244.0015 C 273.92236,244.23759 273.98607,244.57745 274.36212,244.76359 C 274.36212,244.76359 283.47634,249.2752 283.47634,249.2752 C 283.87359,249.47184 284.43418,249.43153 284.73208,249.18471 C 284.73208,249.18471 284.73208,249.18471 284.73208,249.18471"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3375"
- d="M 266.25849,207.11055 C 266.25849,207.11055 258.22296,203.68087 258.22296,203.68087 C 257.8725,203.5313 258.26258,202.94141 259.09217,202.36158 C 259.09217,202.36158 276.45653,190.22478 276.45653,190.22478 C 277.16993,189.72614 278.01001,189.4307 278.34442,189.55973 C 278.34442,189.55973 286.00228,192.51461 286.00228,192.51461 C 286.34641,192.64741 286.06579,193.16868 285.36877,193.68615 C 285.36877,193.68615 268.38219,206.29734 268.38219,206.29734 C 267.56963,206.9006 266.62006,207.26486 266.25849,207.11055 C 266.25849,207.11055 266.25849,207.11055 266.25849,207.11055"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3377"
- d="M 150.04703,290.88787 C 150.04703,290.88787 141.14376,285.97573 141.14376,285.97573 C 140.70469,285.73348 139.97814,285.80683 139.51431,286.13998 C 139.51431,286.13998 130.20189,292.82886 130.20189,292.82886 C 129.7371,293.1627 129.71188,293.62984 130.14579,293.87645 C 130.14579,293.87645 138.94417,298.87711 138.94417,298.87711 C 139.38768,299.12918 140.1235,299.05996 140.59351,298.72169 C 140.59351,298.72169 150.01083,291.94429 150.01083,291.94429 C 150.47987,291.60674 150.49581,291.13546 150.04703,290.88787 C 150.04703,290.88787 150.04703,290.88787 150.04703,290.88787"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3379"
- sodipodi:nodetypes="cccccssssccccc"
- d="M 308.02082,201.07469 C 308.02082,201.07469 290.25388,194.17877 290.25388,194.17877 C 289.03643,193.70622 287.49217,193.72395 286.81047,194.22762 C 286.81047,194.22762 274.92805,203.00701 274.92805,203.00701 C 274.21432,203.53434 274.06866,203.98769 275.45256,204.3729 L 282.20799,207.13372 C 283.30081,207.58033 283.29864,207.60345 284.24763,206.91193 L 285.51228,205.99038 C 285.78882,205.78886 286.61757,205.71073 287.50613,206.09359 L 296.65875,210.03701 C 297.66812,210.31796 298.54496,210.40349 299.11475,209.9558 C 299.11475,209.9558 308.63657,202.4745 308.63657,202.4745 C 309.1849,202.04368 308.91548,201.42193 308.02082,201.07469 C 308.02082,201.07469 308.02082,201.07469 308.02082,201.07469"
- style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3381"
- d="M 263.00018,250.94679 C 263.00018,250.94679 254.5221,247.0388 254.5221,247.0388 C 254.08593,246.83775 253.46532,246.88652 253.12956,247.148 C 253.12956,247.148 246.6785,252.17186 246.6785,252.17186 C 246.33694,252.43788 246.40946,252.82015 246.84217,253.0292 C 246.84217,253.0292 255.25442,257.09309 255.25442,257.09309 C 255.70512,257.31082 256.34668,257.26542 256.6918,256.99111 C 256.6918,256.99111 263.20867,251.81133 263.20867,251.81133 C 263.54778,251.54179 263.45431,251.15613 263.00018,250.94679 C 263.00018,250.94679 263.00018,250.94679 263.00018,250.94679"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3385"
- d="M 224.63535,250.5847 C 224.63535,250.5847 216.40989,246.52591 216.40989,246.52591 C 215.79702,246.2235 214.86783,246.29035 214.3264,246.67645 C 214.3264,246.67645 206.94803,251.93833 206.94803,251.93833 C 206.39716,252.33118 206.45553,252.89148 207.07898,253.19391 C 207.07898,253.19391 215.44611,257.2528 215.44611,257.2528 C 216.0613,257.55121 216.99156,257.47468 217.53182,257.08184 C 217.53182,257.08184 224.76854,251.81989 224.76854,251.81989 C 225.29959,251.43374 225.24017,250.88315 224.63535,250.5847 C 224.63535,250.5847 224.63535,250.5847 224.63535,250.5847"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3387"
- d="M 220.79919,257.76358 C 220.79919,257.76358 229.7534,262.16116 229.7534,262.16116 C 230.47771,262.51688 230.65884,263.11821 230.15739,263.5097 C 230.15739,263.5097 223.79138,268.4796 223.79138,268.4796 C 223.27442,268.8832 222.26833,268.91225 221.53782,268.54453 C 221.53782,268.54453 212.50868,263.9994 212.50868,263.9994 C 211.79484,263.64005 211.64287,263.03537 212.16581,262.64384 C 212.16581,262.64384 218.60675,257.8215 218.60675,257.8215 C 219.11421,257.44156 220.09111,257.41585 220.79919,257.76358 C 220.79919,257.76358 220.79919,257.76358 220.79919,257.76358"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3389"
- d="M 209.90305,237.93879 C 209.90305,237.93879 217.69144,241.5189 217.69144,241.5189 C 218.2857,241.79206 218.40792,242.28161 217.95894,242.61539 C 217.95894,242.61539 211.48141,247.43084 211.48141,247.43084 C 211.00555,247.78462 210.15328,247.81772 209.57718,247.50651 C 209.57718,247.50651 202.04394,243.43694 202.04394,243.43694 C 201.54218,243.16588 201.50989,242.69331 201.96601,242.37623 C 201.96601,242.37623 208.18868,238.05054 208.18868,238.05054 C 208.62095,237.75004 209.38314,237.69979 209.90305,237.93879 C 209.90305,237.93879 209.90305,237.93879 209.90305,237.93879"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="rect3391"
- d="M 300.49388,221.41753 C 300.49388,221.41753 318.37188,206.97394 318.37188,206.97394 C 319.2072,206.29909 319.56463,205.63506 319.17704,205.48324 C 319.17704,205.48324 311.44233,202.45361 311.44233,202.45361 C 311.07717,202.31058 310.12278,202.71434 309.29892,203.3606 C 309.29892,203.3606 291.6901,217.17374 291.6901,217.17374 C 290.79969,217.87223 290.3631,218.57498 290.71507,218.74754 C 290.71507,218.74754 298.1804,222.40777 298.1804,222.40777 C 298.55498,222.59143 299.58864,222.1489 300.49388,221.41753 C 300.49388,221.41753 300.49388,221.41753 300.49388,221.41753"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 258.97104,224.63939 C 258.97104,224.63939 251.83463,221.23656 251.83463,221.23656 C 251.14159,220.90611 250.14534,220.95426 249.59505,221.34461 C 249.59505,221.34461 243.94919,225.34942 243.94919,225.34942 C 243.36824,225.76151 243.45494,226.38105 244.14978,226.73848 C 244.14978,226.73848 251.31231,230.42301 251.31231,230.42301 C 252.05284,230.80395 253.12041,230.75512 253.69927,230.31357 C 253.69927,230.31357 259.31886,226.02706 259.31886,226.02706 C 259.86601,225.60971 259.70806,224.99085 258.97104,224.63939 C 258.97104,224.63939 258.97104,224.63939 258.97104,224.63939"
- id="path13125"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 245.03115,264.95865 C 245.03115,264.95865 236.89775,261.02915 236.89775,261.02915 C 236.29828,260.73954 235.41666,260.81767 234.92021,261.2046 C 234.92021,261.2046 228.15537,266.47697 228.15537,266.47697 C 227.65036,266.87057 227.72859,267.42473 228.33161,267.71924 C 228.33161,267.71924 236.5135,271.71529 236.5135,271.71529 C 237.12168,272.01232 238.01565,271.93037 238.51705,271.53179 C 238.51705,271.53179 245.23339,266.19289 245.23339,266.19289 C 245.7263,265.80109 245.63571,265.25074 245.03115,264.95865 C 245.03115,264.95865 245.03115,264.95865 245.03115,264.95865"
- id="path13127"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 241.3425,254.88757 C 241.3425,254.88757 247.17841,250.38791 247.17841,250.38791 C 247.6407,250.03146 247.43669,249.46639 246.72219,249.12079 C 246.72219,249.12079 237.84809,244.82838 237.84809,244.82838 C 237.14306,244.48737 236.20078,244.49428 235.73414,244.84402 C 235.73414,244.84402 229.84385,249.25863 229.84385,249.25863 C 229.36826,249.61507 229.55538,250.18212 230.26467,250.52985 C 230.26467,250.52985 239.19316,254.90731 239.19316,254.90731 C 239.9121,255.25978 240.87126,255.2509 241.3425,254.88757 C 241.3425,254.88757 241.3425,254.88757 241.3425,254.88757"
- id="path13129"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path13131"
- d="M 250.09625,248.10772 C 250.09625,248.10772 256.04021,243.39795 256.04021,243.39795 C 256.61443,242.94295 256.40961,242.26587 255.58606,241.87803 C 255.58606,241.87803 247.4695,238.05567 247.4695,238.05567 C 246.66725,237.67787 245.54243,237.71942 244.94236,238.15046 C 244.94236,238.15046 238.73449,242.60981 238.73449,242.60981 C 238.09034,243.07251 238.23366,243.77042 239.06151,244.17275 C 239.06151,244.17275 247.44196,248.2456 247.44196,248.2456 C 248.29278,248.65909 249.47914,248.5967 250.09625,248.10772 C 250.09625,248.10772 250.09625,248.10772 250.09625,248.10772"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path13133"
- d="M 270.78129,244.1004 C 270.78129,244.1004 263.16585,240.54998 263.16585,240.54998 C 262.59905,240.28573 261.81284,240.33065 261.40189,240.65211 C 261.40189,240.65211 255.67209,245.13428 255.67209,245.13428 C 255.23437,245.47666 255.35686,245.97255 255.94801,246.24454 C 255.94801,246.24454 263.88891,249.89826 263.88891,249.89826 C 264.4733,250.16714 265.27704,250.1004 265.6898,249.75019 C 265.6898,249.75019 271.09419,245.16472 271.09419,245.16472 C 271.48189,244.83578 271.34185,244.36173 270.78129,244.1004 C 270.78129,244.1004 270.78129,244.1004 270.78129,244.1004"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path13135"
- d="M 279.36283,237.13131 C 279.36283,237.13131 271.95158,233.79368 271.95158,233.79368 C 271.36993,233.53174 270.52181,233.61628 270.04782,233.98311 C 270.04782,233.98311 264.05529,238.62092 264.05529,238.62092 C 263.57067,238.99597 263.64455,239.51827 264.22306,239.79213 C 264.22306,239.79213 271.59655,243.28243 271.59655,243.28243 C 272.19767,243.56699 273.0762,243.48424 273.56398,243.09674 C 273.56398,243.09674 279.59427,238.30625 279.59427,238.30625 C 280.07112,237.92743 279.96688,237.40335 279.36283,237.13131 C 279.36283,237.13131 279.36283,237.13131 279.36283,237.13131"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 259.13878,241.01984 C 259.13878,241.01984 264.94427,236.50262 264.94427,236.50262 C 265.5183,236.05597 265.27718,235.39329 264.41129,235.01866 C 264.41129,235.01866 256.13903,231.43971 256.13903,231.43971 C 255.34632,231.09675 254.26614,231.15807 253.71044,231.57558 C 253.71044,231.57558 248.09408,235.79517 248.09408,235.79517 C 247.52482,236.22286 247.6843,236.86458 248.45835,237.23578 C 248.45835,237.23578 256.54144,241.11225 256.54144,241.11225 C 257.38813,241.51828 258.54995,241.47801 259.13878,241.01984 C 259.13878,241.01984 259.13878,241.01984 259.13878,241.01984"
- id="path14377"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 232.79455,261.43519 C 232.79455,261.43519 238.72958,256.85909 238.72958,256.85909 C 239.16465,256.52365 238.9726,255.99183 238.3001,255.66653 C 238.3001,255.66653 229.27525,251.30123 229.27525,251.30123 C 228.61176,250.98029 227.72493,250.98679 227.28579,251.31591 C 227.28579,251.31591 221.29544,255.80552 221.29544,255.80552 C 220.84778,256.14104 221.02387,256.67471 221.69138,257.00198 C 221.69138,257.00198 230.77154,261.45377 230.77154,261.45377 C 231.44822,261.78553 232.35098,261.77719 232.79455,261.43519 C 232.79455,261.43519 232.79455,261.43519 232.79455,261.43519"
- id="path14379"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 254.17375,257.48652 C 254.17375,257.48652 246.32963,253.73115 246.32963,253.73115 C 245.70901,253.43402 244.79483,253.51721 244.27828,253.91779 C 244.27828,253.91779 237.75243,258.97869 237.75243,258.97869 C 237.22504,259.38768 237.29958,259.96347 237.92117,260.26957 C 237.92117,260.26957 245.77862,264.13893 245.77862,264.13893 C 246.41397,264.45181 247.35058,264.36687 247.87695,263.94859 C 247.87695,263.94859 254.38946,258.77374 254.38946,258.77374 C 254.90487,258.36419 254.80792,257.79015 254.17375,257.48652 C 254.17375,257.48652 254.17375,257.48652 254.17375,257.48652"
- id="path14381"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path14383"
- d="M 233.03678,243.79425 C 233.03678,243.79425 225.48646,240.13918 225.48646,240.13918 C 224.74342,239.77949 223.69299,239.82194 223.12841,240.23388 C 223.12841,240.23388 217.44731,244.37905 217.44731,244.37905 C 216.874,244.79736 217.00415,245.4333 217.742,245.80545 C 217.742,245.80545 225.24071,249.58767 225.24071,249.58767 C 226.00503,249.97318 227.0886,249.93684 227.66722,249.50562 C 227.66722,249.50562 233.39989,245.23329 233.39989,245.23329 C 233.96951,244.80878 233.80621,244.16674 233.03678,243.79425 C 233.03678,243.79425 233.03678,243.79425 233.03678,243.79425"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 282.03015,224.70872 C 282.03015,224.70872 287.9774,220.08364 287.9774,220.08364 C 288.56519,219.62653 289.56121,219.51344 290.21268,219.82947 C 290.21268,219.82947 296.76597,223.00851 296.76597,223.00851 C 297.42707,223.32921 297.49209,223.96249 296.90969,224.429 C 296.90969,224.429 291.01609,229.14982 291.01609,229.14982 C 290.41797,229.62893 289.39806,229.74916 288.73146,229.41875 C 288.73146,229.41875 282.12452,226.14398 282.12452,226.14398 C 281.4678,225.81845 281.42665,225.17805 282.03015,224.70872 C 282.03015,224.70872 282.03015,224.70872 282.03015,224.70872"
- id="path14385"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path20314"
- d="M 274.59176,213.04701 C 274.59176,213.04701 267.63301,209.8841 267.63301,209.8841 C 266.9305,209.56479 265.98277,209.58635 265.5079,209.93372 C 265.5079,209.93372 260.69581,213.4537 260.69581,213.4537 C 260.20677,213.81142 260.39277,214.35936 261.11308,214.68093 C 261.11308,214.68093 268.24694,217.86572 268.24694,217.86572 C 268.95551,218.18206 269.90543,218.14595 270.37662,217.78604 C 270.37662,217.78604 275.0136,214.24417 275.0136,214.24417 C 275.47126,213.89461 275.28303,213.36122 274.59176,213.04701 C 274.59176,213.04701 274.59176,213.04701 274.59176,213.04701"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 292.00448,215.55279 C 292.00448,215.55279 296.3664,212.1569 296.3664,212.1569 C 296.79902,211.82008 296.4902,211.27517 295.67813,210.9361 C 295.67813,210.9361 287.77738,207.63715 287.77738,207.63715 C 287.00644,207.31524 286.04433,207.31631 285.61635,207.63866 C 285.61635,207.63866 281.30257,210.88766 281.30257,210.88766 C 280.86653,211.21606 281.12901,211.75032 281.89503,212.08646 C 281.89503,212.08646 289.74764,215.53227 289.74764,215.53227 C 290.55499,215.88655 291.56345,215.89614 292.00448,215.55279 C 292.00448,215.55279 292.00448,215.55279 292.00448,215.55279"
- id="path20316"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path20318"
- d="M 284.72744,221.17105 C 284.72744,221.17105 289.45459,217.54272 289.45459,217.54272 C 289.926,217.18089 289.66619,216.61851 288.87179,216.28131 C 288.87179,216.28131 280.90373,212.899 280.90373,212.899 C 280.10221,212.55875 279.07175,212.57593 278.59356,212.93801 C 278.59356,212.93801 273.79834,216.56885 273.79834,216.56885 C 273.31611,216.93397 273.57888,217.50206 274.38726,217.84205 C 274.38726,217.84205 282.42339,221.22188 282.42339,221.22188 C 283.22457,221.55883 284.25207,221.53592 284.72744,221.17105 C 284.72744,221.17105 284.72744,221.17105 284.72744,221.17105"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 280.70619,208.18882 C 280.70619,208.18882 273.65334,205.39325 273.65334,205.39325 C 272.99267,205.13139 272.16292,205.14273 271.78475,205.41678 C 271.78475,205.41678 267.9355,208.20633 267.9355,208.20633 C 267.54254,208.4911 267.73876,208.95315 268.38364,209.24454 C 268.38364,209.24454 275.27945,212.36039 275.27945,212.36039 C 276.01926,212.69466 276.95281,212.71002 277.36247,212.39198 C 277.36247,212.39198 281.36853,209.28183 281.36853,209.28183 C 281.76145,208.97678 281.46158,208.48822 280.70619,208.18882 C 280.70619,208.18882 280.70619,208.18882 280.70619,208.18882"
- id="path20320"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path20322"
- d="M 267.13462,218.61017 C 267.13462,218.61017 260.04553,215.39646 260.04553,215.39646 C 259.35688,215.08427 258.39121,215.12387 257.87608,215.4844 C 257.87608,215.4844 252.67496,219.12445 252.67496,219.12445 C 252.14829,219.49305 252.26711,220.05491 252.94569,220.38521 C 252.94569,220.38521 259.93387,223.78674 259.93387,223.78674 C 260.65566,224.13807 261.67299,224.1096 262.21011,223.72182 C 262.21011,223.72182 267.5121,219.8939 267.5121,219.8939 C 268.03699,219.51494 267.86652,218.94196 267.13462,218.61017 C 267.13462,218.61017 267.13462,218.61017 267.13462,218.61017"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 287.7354,230.25946 C 287.7354,230.25946 281.08316,227.00351 281.08316,227.00351 C 280.40678,226.67245 279.40568,226.75692 278.83891,227.19481 C 278.83891,227.19481 273.09436,231.63291 273.09436,231.63291 C 272.51043,232.08403 272.60418,232.71336 273.30418,233.04198 C 273.30418,233.04198 280.18673,236.27314 280.18673,236.27314 C 280.86539,236.59174 281.86259,236.48569 282.42295,236.03722 C 282.42295,236.03722 287.93718,231.62391 287.93718,231.62391 C 288.48138,231.18834 288.39153,230.58062 287.7354,230.25946 C 287.7354,230.25946 287.7354,230.25946 287.7354,230.25946"
- id="path20324"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path20326"
- d="M 267.94729,234.14015 C 267.94729,234.14015 273.40476,229.94747 273.40476,229.94747 C 273.94662,229.5312 273.71505,228.90956 272.88832,228.55398 C 272.88832,228.55398 264.75456,225.0556 264.75456,225.0556 C 263.95198,224.71041 262.87291,224.75882 262.33246,225.16387 C 262.33246,225.16387 256.88991,229.24286 256.88991,229.24286 C 256.34026,229.6548 256.54039,230.27309 257.34135,230.62945 C 257.34135,230.62945 265.46021,234.24152 265.46021,234.24152 C 266.28553,234.60871 267.39604,234.56364 267.94729,234.14015 C 267.94729,234.14015 267.94729,234.14015 267.94729,234.14015"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path21282"
- d="M 276.32923,227.66222 C 276.32923,227.66222 281.90001,223.35623 281.90001,223.35623 C 282.4517,222.9298 282.23314,222.31013 281.41303,221.96694 C 281.41303,221.96694 273.34754,218.59182 273.34754,218.59182 C 272.55203,218.25892 271.46937,218.32422 270.91711,218.73813 C 270.91711,218.73813 265.34181,222.91665 265.34181,222.91665 C 264.77733,223.33971 264.96112,223.95828 265.75691,224.30368 C 265.75691,224.30368 273.82693,227.80624 273.82693,227.80624 C 274.64767,228.16246 275.7651,228.09826 276.32923,227.66222 C 276.32923,227.66222 276.32923,227.66222 276.32923,227.66222"
- style="opacity:0.99720004;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <g
- transform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- id="g5349">
- <path
- id="path3281"
- d="M 200.53013,313.0503 C 200.53013,313.0503 193.03458,319.37147 193.03458,319.37147 C 192.65485,319.6917 192.0145,319.75862 191.59935,319.52112 C 191.59935,319.52112 183.2867,314.76558 183.2867,314.76558 C 182.87292,314.52886 182.85139,314.08409 183.23786,313.76871 C 183.23786,313.76871 190.86675,307.54312 190.86675,307.54312 C 191.24112,307.23761 191.86986,307.1787 192.27701,307.41066 C 192.27701,307.41066 200.45632,312.07061 200.45632,312.07061 C 200.86479,312.30333 200.89796,312.7401 200.53013,313.0503 C 200.53013,313.0503 200.53013,313.0503 200.53013,313.0503"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3283"
- d="M 172.41739,306.03622 C 172.41739,306.03622 188.0277,294.08595 188.0277,294.08595 C 189.11795,293.25133 190.41897,292.82031 190.95268,293.11384 C 190.95268,293.11384 198.19106,297.09485 198.19106,297.09485 C 198.72888,297.39065 198.31537,298.31501 197.2562,299.17331 C 197.2562,299.17331 182.08669,311.46584 182.08669,311.46584 C 180.89616,312.43058 179.47079,312.95427 178.90005,312.63295 C 178.90005,312.63295 171.22074,308.30947 171.22074,308.30947 C 170.65468,307.99077 171.1926,306.97384 172.41739,306.03622 C 172.41739,306.03622 172.41739,306.03622 172.41739,306.03622"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3285"
- d="M 183.71685,293.09242 C 183.71685,293.09242 175.21974,288.61823 175.21974,288.61823 C 174.62141,288.30317 173.39049,288.60803 172.45631,289.30319 C 172.45631,289.30319 159.05702,299.27405 159.05702,299.27405 C 158.07838,300.0023 157.77029,300.8596 158.36997,301.19473 C 158.36997,301.19473 166.88944,305.95582 166.88944,305.95582 C 167.50572,306.30023 168.79179,305.97286 169.76917,305.22339 C 169.76917,305.22339 183.14605,294.96565 183.14605,294.96565 C 184.07833,294.25076 184.33129,293.41596 183.71685,293.09242 C 183.71685,293.09242 183.71685,293.09242 183.71685,293.09242"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3287"
- d="M 166.83475,289.12754 C 166.83475,289.12754 159.13844,284.98242 159.13844,284.98242 C 158.69381,284.74294 157.84841,284.90019 157.24056,285.33581 C 157.24056,285.33581 146.5932,292.96648 146.5932,292.96648 C 145.95049,293.4271 145.7912,294.00445 146.23859,294.2601 C 146.23859,294.2601 153.9866,298.68753 153.9866,298.68753 C 154.44898,298.95174 155.33851,298.77896 155.97843,298.30106 C 155.97843,298.30106 166.57405,290.38811 166.57405,290.38811 C 167.17862,289.93661 167.2938,289.37478 166.83475,289.12754 C 166.83475,289.12754 166.83475,289.12754 166.83475,289.12754"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3289"
- d="M 151.36095,285.65566 C 151.36095,285.65566 143.84889,281.51108 143.84889,281.51108 C 143.47842,281.30668 142.86541,281.36856 142.47405,281.64966 C 142.47405,281.64966 134.61675,287.29335 134.61675,287.29335 C 134.22459,287.57503 134.20331,287.96918 134.56941,288.17726 C 134.56941,288.17726 141.993,292.39653 141.993,292.39653 C 142.36721,292.60921 142.98804,292.55081 143.38462,292.2654 C 143.38462,292.2654 151.33041,286.54701 151.33041,286.54701 C 151.72616,286.2622 151.73961,285.86457 151.36095,285.65566 C 151.36095,285.65566 151.36095,285.65566 151.36095,285.65566"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3291"
- d="M 210.70247,305.77557 C 210.70247,305.77557 204.93036,310.57929 204.93036,310.57929 C 204.34435,311.06699 203.27394,311.11934 202.52773,310.69333 C 202.52773,310.69333 194.82772,306.29731 194.82772,306.29731 C 194.03081,305.84234 193.88921,305.07052 194.51315,304.57044 C 194.51315,304.57044 200.65538,299.64763 200.65538,299.64763 C 201.26179,299.16161 202.36255,299.14928 203.12074,299.61631 C 203.12074,299.61631 210.45071,304.13144 210.45071,304.13144 C 211.16146,304.56926 211.27265,305.30104 210.70247,305.77557 C 210.70247,305.77557 210.70247,305.77557 210.70247,305.77557"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3293"
- d="M 220.36679,297.64972 C 220.36679,297.64972 214.19821,302.83693 214.19821,302.83693 C 213.8071,303.16581 213.0629,303.16632 212.53329,302.83934 C 212.53329,302.83934 204.47426,297.86377 204.47426,297.86377 C 203.99682,297.56901 203.91878,297.08754 204.2961,296.78318 C 204.2961,296.78318 210.25274,291.97831 210.25274,291.97831 C 210.61877,291.68306 211.30575,291.66386 211.7962,291.93623 C 211.7962,291.93623 220.06723,296.5296 220.06723,296.5296 C 220.61026,296.83118 220.74549,297.33126 220.36679,297.64972 C 220.36679,297.64972 220.36679,297.64972 220.36679,297.64972"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3295"
- d="M 229.27683,290.15464 C 229.27683,290.15464 223.76946,294.79471 223.76946,294.79471 C 223.28503,295.20286 222.36392,295.23289 221.70465,294.86121 C 221.70465,294.86121 214.09874,290.57325 214.09874,290.57325 C 213.43481,290.19895 213.29956,289.57104 213.79504,289.16623 C 213.79504,289.16623 219.4277,284.56425 219.4277,284.56425 C 219.91221,284.1684 220.82757,284.14902 221.48054,284.51999 C 221.48054,284.51999 228.96116,288.76985 228.96116,288.76985 C 229.60961,289.13825 229.75059,289.75549 229.27683,290.15464 C 229.27683,290.15464 229.27683,290.15464 229.27683,290.15464"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3297"
- d="M 207.6366,289.76045 C 207.6366,289.76045 200.20453,285.97175 200.20453,285.97175 C 199.75388,285.74202 199.11315,285.78115 198.76662,286.05878 C 198.76662,286.05878 193.21867,290.50362 193.21867,290.50362 C 192.87292,290.78062 192.94685,291.19499 193.38567,291.43343 C 193.38567,291.43343 200.62246,295.36556 200.62246,295.36556 C 201.08703,295.61798 201.75028,295.59166 202.10819,295.30573 C 202.10819,295.30573 207.85144,290.71744 207.85144,290.71744 C 208.21018,290.43084 208.11372,290.00367 207.6366,289.76045 C 207.6366,289.76045 207.6366,289.76045 207.6366,289.76045"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3299"
- d="M 193.30538,285.7839 C 193.30538,285.7839 185.22052,281.47582 185.22052,281.47582 C 184.58295,281.13609 183.70561,281.13742 183.25124,281.47882 C 183.25124,281.47882 177.48561,285.81085 177.48561,285.81085 C 177.01761,286.16248 177.15516,286.7287 177.79623,287.08041 C 177.79623,287.08041 185.92745,291.54147 185.92745,291.54147 C 186.5872,291.90343 187.49396,291.90165 187.95831,291.53752 C 187.95831,291.53752 193.67756,287.05251 193.67756,287.05251 C 194.12816,286.69915 193.9612,286.13336 193.30538,285.7839 C 193.30538,285.7839 193.30538,285.7839 193.30538,285.7839"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3301"
- d="M 153.65825,274.40909 C 153.65825,274.40909 161.75797,278.66326 161.75797,278.66326 C 162.02482,278.80341 162.05943,279.04844 161.83501,279.21257 C 161.83501,279.21257 154.75107,284.39353 154.75107,284.39353 C 154.52039,284.56224 154.12135,284.5797 153.85694,284.43276 C 153.85694,284.43276 145.83383,279.97431 145.83383,279.97431 C 145.58269,279.83475 145.56457,279.59204 145.79266,279.43005 C 145.79266,279.43005 152.79999,274.45338 152.79999,274.45338 C 153.02206,274.29566 153.40462,274.27588 153.65825,274.40909 C 153.65825,274.40909 153.65825,274.40909 153.65825,274.40909"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3303"
- d="M 176.68036,282.15173 C 176.68036,282.15173 169.08774,278.13438 169.08774,278.13438 C 168.53136,277.83999 167.74128,277.85841 167.31522,278.1756 C 167.31522,278.1756 161.51878,282.49085 161.51878,282.49085 C 161.08675,282.81248 161.18562,283.31335 161.7415,283.61396 C 161.7415,283.61396 169.32801,287.71649 169.32801,287.71649 C 169.89523,288.02323 170.70097,288.00619 171.1335,287.67818 C 171.1335,287.67818 176.93604,283.27774 176.93604,283.27774 C 177.36252,282.95432 177.24799,282.45207 176.68036,282.15173 C 176.68036,282.15173 176.68036,282.15173 176.68036,282.15173"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3305"
- d="M 186.05575,275.08382 C 186.05575,275.08382 178.66837,271.26624 178.66837,271.26624 C 178.14275,270.99462 177.38016,271.01579 176.95654,271.31482 C 176.95654,271.31482 170.80827,275.65494 170.80827,275.65494 C 170.35386,275.97571 170.42595,276.46372 170.9721,276.74789 C 170.9721,276.74789 178.64907,280.74215 178.64907,280.74215 C 179.19855,281.02804 179.99123,280.98835 180.42429,280.65448 C 180.42429,280.65448 186.28302,276.1377 186.28302,276.1377 C 186.68663,275.82653 186.58444,275.35703 186.05575,275.08382 C 186.05575,275.08382 186.05575,275.08382 186.05575,275.08382"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3307"
- d="M 163.51597,267.87954 C 163.51597,267.87954 171.1646,271.91896 171.1646,271.91896 C 171.53604,272.11513 171.58651,272.4514 171.2774,272.67324 C 171.2774,272.67324 164.82134,277.30652 164.82134,277.30652 C 164.50235,277.53544 163.94045,277.55958 163.56185,277.36032 C 163.56185,277.36032 155.76574,273.25703 155.76574,273.25703 C 155.38595,273.05714 155.34321,272.7142 155.66949,272.48842 C 155.66949,272.48842 162.27303,267.91901 162.27303,267.91901 C 162.5892,267.70024 163.14337,267.68276 163.51597,267.87954 C 163.51597,267.87954 163.51597,267.87954 163.51597,267.87954"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3309"
- d="M 173.08132,261.26965 C 173.08132,261.26965 180.42033,265.06231 180.42033,265.06231 C 180.84108,265.27975 180.901,265.65731 180.55405,265.90902 C 180.55405,265.90902 174.39819,270.3752 174.39819,270.3752 C 174.04312,270.63281 173.41533,270.66166 172.99122,270.43971 C 172.99122,270.43971 165.59423,266.56865 165.59423,266.56865 C 165.17482,266.34916 165.12621,265.96859 165.4846,265.71552 C 165.4846,265.71552 171.69844,261.32774 171.69844,261.32774 C 172.04868,261.08043 172.66517,261.05459 173.08132,261.26965 C 173.08132,261.26965 173.08132,261.26965 173.08132,261.26965"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3311"
- d="M 183.15808,254.05968 C 183.15808,254.05968 190.5411,257.89809 190.5411,257.89809 C 190.90119,258.0853 190.9368,258.42917 190.61983,258.66983 C 190.61983,258.66983 183.84308,263.81508 183.84308,263.81508 C 183.50031,264.07534 182.92132,264.12739 182.54615,263.93097 C 182.54615,263.93097 174.85492,259.90428 174.85492,259.90428 C 174.48192,259.709 174.47113,259.34932 174.82945,259.09862 C 174.82945,259.09862 181.91436,254.14161 181.91436,254.14161 C 182.24579,253.90973 182.79998,253.8735 183.15808,254.05968 C 183.15808,254.05968 183.15808,254.05968 183.15808,254.05968"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3313"
- d="M 195.50846,268.00414 C 195.50846,268.00414 187.92237,264.08387 187.92237,264.08387 C 187.38263,263.80495 186.5995,263.82667 186.16449,264.13375 C 186.16449,264.13375 179.85083,268.59062 179.85083,268.59062 C 179.38419,268.92002 179.45825,269.42118 180.01907,269.71297 C 180.01907,269.71297 187.90254,273.81468 187.90254,273.81468 C 188.4668,274.10826 189.28081,274.0675 189.72552,273.72465 C 189.72552,273.72465 195.74185,269.08637 195.74185,269.08637 C 196.15632,268.76683 196.05137,268.2847 195.50846,268.00414 C 195.50846,268.00414 195.50846,268.00414 195.50846,268.00414"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3315"
- d="M 202.55006,278.55525 C 202.55006,278.55525 194.52053,274.43157 194.52053,274.43157 C 193.89847,274.1121 193.03474,274.13023 192.58051,274.47152 C 192.58051,274.47152 186.82178,278.79836 186.82178,278.79836 C 186.35477,279.14926 186.47106,279.70327 187.086,280.04131 C 187.086,280.04131 195.02775,284.40711 195.02775,284.40711 C 195.68386,284.76779 196.59706,284.76041 197.07144,284.38968 C 197.07144,284.38968 202.9179,279.82067 202.9179,279.82067 C 203.3788,279.46048 203.21306,278.89574 202.55006,278.55525 C 202.55006,278.55525 202.55006,278.55525 202.55006,278.55525"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path3317"
- d="M 217.28268,282.30723 C 217.28268,282.30723 209.76798,278.51506 209.76798,278.51506 C 209.31861,278.28829 208.66038,278.33252 208.29049,278.6148 C 208.29049,278.6148 201.99168,283.42172 201.99168,283.42172 C 201.5992,283.72125 201.65194,284.15497 202.11173,284.39356 C 202.11173,284.39356 209.80365,288.38505 209.80365,288.38505 C 210.27451,288.62939 210.96221,288.57431 211.3438,288.26224 C 211.3438,288.26224 217.46536,283.25603 217.46536,283.25603 C 217.82471,282.96216 217.7425,282.53927 217.28268,282.30723 C 217.28268,282.30723 217.28268,282.30723 217.28268,282.30723"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5259"
- sodipodi:nodetypes="cccccccccc"
- d="M 223.6315,280.9685 C 223.6315,280.9685 271.20382,242.80623 271.20382,242.80623 C 271.77183,242.35446 272.94396,242.34509 273.8347,242.78481 C 273.8347,242.78481 280.16259,245.8893 280.16259,245.8893 C 281.06675,246.33566 281.34594,247.06729 280.78574,247.53016 C 280.78574,247.53016 233.93323,286.78539 233.93323,286.78539 C 233.23622,287.36129 231.89705,287.39044 230.93425,286.85016 C 230.93425,286.85016 224.06489,282.94036 224.06489,282.94036 C 223.11807,282.40904 222.92637,281.52934 223.6315,280.9685 C 223.6315,280.9685 223.6315,280.9685 223.6315,280.9685"
- style="opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5261"
- d="M 227.03565,274.61509 C 227.03565,274.61509 219.57159,270.89543 219.57159,270.89543 C 219.13842,270.67957 218.48938,270.73732 218.1151,271.02521 C 218.1151,271.02521 211.61304,276.02653 211.61304,276.02653 C 211.22381,276.32593 211.26193,276.7481 211.69984,276.97279 C 211.69984,276.97279 219.24737,280.84554 219.24737,280.84554 C 219.69565,281.07556 220.36702,281.012 220.75135,280.70336 C 220.75135,280.70336 227.16991,275.54895 227.16991,275.54895 C 227.53929,275.25232 227.47886,274.83596 227.03565,274.61509 C 227.03565,274.61509 227.03565,274.61509 227.03565,274.61509"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5263"
- d="M 192.51964,247.35677 C 192.51964,247.35677 199.78325,251.31635 199.78325,251.31635 C 200.08373,251.48015 200.10518,251.76671 199.83193,251.95915 C 199.83193,251.95915 193.39598,256.49168 193.39598,256.49168 C 193.12338,256.68366 192.65687,256.71094 192.34938,256.55257 C 192.34938,256.55257 184.91676,252.72442 184.91676,252.72442 C 184.59365,252.55801 184.55824,252.26477 184.83799,252.06723 C 184.83799,252.06723 191.44296,247.40326 191.44296,247.40326 C 191.7234,247.20524 192.20387,247.18464 192.51964,247.35677 C 192.51964,247.35677 192.51964,247.35677 192.51964,247.35677"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5265"
- d="M 204.95758,260.67876 C 204.95758,260.67876 197.45088,256.83357 197.45088,256.83357 C 196.91888,256.56107 196.14744,256.58436 195.71989,256.88617 C 195.71989,256.88617 189.62606,261.18786 189.62606,261.18786 C 189.18381,261.50005 189.26067,261.97752 189.79977,262.25801 C 189.79977,262.25801 197.4078,266.21641 197.4078,266.21641 C 197.95451,266.50085 198.7459,266.47153 199.18087,266.15108 C 199.18087,266.15108 205.17336,261.73618 205.17336,261.73618 C 205.59375,261.42646 205.49693,260.95503 204.95758,260.67876 C 204.95758,260.67876 204.95758,260.67876 204.95758,260.67876"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5267"
- d="M 203.42735,267.20908 C 203.42735,267.20908 212.2333,271.70369 212.2333,271.70369 C 212.6248,271.90351 212.71338,272.23708 212.43163,272.45164 C 212.43163,272.45164 206.02839,277.32796 206.02839,277.32796 C 205.74282,277.54543 205.19609,277.55776 204.8028,277.35556 C 204.8028,277.35556 195.957,272.80759 195.957,272.80759 C 195.56658,272.60686 195.48379,272.27205 195.77113,272.05697 C 195.77113,272.05697 202.21422,267.23402 202.21422,267.23402 C 202.49773,267.02179 203.03868,267.0107 203.42735,267.20908 C 203.42735,267.20908 203.42735,267.20908 203.42735,267.20908"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5269"
- d="M 212.72962,260.6903 C 212.72962,260.6903 220.81856,264.71792 220.81856,264.71792 C 221.40722,265.01103 221.56351,265.49233 221.1669,265.79697 C 221.1669,265.79697 215.52012,270.13427 215.52012,270.13427 C 215.11075,270.44871 214.30434,270.45549 213.7142,270.1496 C 213.7142,270.1496 205.60787,265.94776 205.60787,265.94776 C 205.04085,265.65385 204.91653,265.17445 205.32701,264.87276 C 205.32701,264.87276 210.99121,260.70967 210.99121,260.70967 C 211.38919,260.41716 212.16362,260.40847 212.72962,260.6903 C 212.72962,260.6903 212.72962,260.6903 212.72962,260.6903"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5271"
- d="M 235.38208,267.94652 C 235.38208,267.94652 228.36195,264.54302 228.36195,264.54302 C 227.7581,264.25027 226.91755,264.28848 226.47592,264.62855 C 226.47592,264.62855 221.36693,268.56268 221.36693,268.56268 C 220.91972,268.90705 221.04356,269.42537 221.64599,269.72502 C 221.64599,269.72502 228.65018,273.2089 228.65018,273.2089 C 229.26637,273.51538 230.12476,273.47935 230.5734,273.12791 C 230.5734,273.12791 235.69833,269.1134 235.69833,269.1134 C 236.14129,268.76642 235.99961,268.24591 235.38208,267.94652 C 235.38208,267.94652 235.38208,267.94652 235.38208,267.94652"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5273"
- d="M 202.3439,240.55011 C 202.3439,240.55011 209.40685,244.3565 209.40685,244.3565 C 209.77966,244.55741 209.79685,244.91929 209.44513,245.16789 C 209.44513,245.16789 202.71836,249.92236 202.71836,249.92236 C 202.36384,250.17294 201.77847,250.21096 201.40617,250.00761 C 201.40617,250.00761 194.3529,246.15501 194.3529,246.15501 C 193.98466,245.95386 193.97344,245.59217 194.32745,245.34403 C 194.32745,245.34403 201.04453,240.63577 201.04453,240.63577 C 201.39575,240.38958 201.97514,240.35138 202.3439,240.55011 C 202.3439,240.55011 202.3439,240.55011 202.3439,240.55011"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5275"
- d="M 214.95641,253.88523 C 214.95641,253.88523 207.20865,250.11064 207.20865,250.11064 C 206.78058,249.90209 206.15223,249.93501 205.79811,250.18412 C 205.79811,250.18412 199.5121,254.60606 199.5121,254.60606 C 199.14935,254.86124 199.19499,255.24389 199.61614,255.46439 C 199.61614,255.46439 207.24189,259.45703 207.24189,259.45703 C 207.69079,259.69206 208.35153,259.66596 208.72148,259.39808 C 208.72148,259.39808 215.12948,254.75806 215.12948,254.75806 C 215.49031,254.49678 215.41229,254.10733 214.95641,253.88523 C 214.95641,253.88523 214.95641,253.88523 214.95641,253.88523"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5277"
- d="M 221.9033,253.92205 C 221.9033,253.92205 229.74607,257.77376 229.74607,257.77376 C 230.38047,258.08533 230.53912,258.61203 230.09991,258.95492 C 230.09991,258.95492 224.52409,263.30793 224.52409,263.30793 C 224.07129,263.66142 223.1901,263.68688 222.55025,263.36479 C 222.55025,263.36479 214.64187,259.38384 214.64187,259.38384 C 214.01663,259.0691 213.88352,258.53947 214.34155,258.19654 C 214.34155,258.19654 219.983,253.97277 219.983,253.97277 C 220.42747,253.64 221.28312,253.61747 221.9033,253.92205 C 221.9033,253.92205 221.9033,253.92205 221.9033,253.92205"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 244.75785,260.58731 C 244.75785,260.58731 237.5872,257.12295 237.5872,257.12295 C 237.05869,256.86761 236.28144,256.9365 235.84374,257.27763 C 235.84374,257.27763 229.87966,261.92591 229.87966,261.92591 C 229.43444,262.2729 229.5034,262.76148 230.03504,263.02113 C 230.03504,263.02113 237.24843,266.54415 237.24843,266.54415 C 237.78463,266.80603 238.57278,266.73378 239.01483,266.38238 C 239.01483,266.38238 244.93616,261.67544 244.93616,261.67544 C 245.3707,261.33002 245.29084,260.84482 244.75785,260.58731 C 244.75785,260.58731 244.75785,260.58731 244.75785,260.58731"
- id="path5279"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 233.2943,256.416 C 233.2943,256.416 238.45564,252.43646 238.45564,252.43646 C 238.83398,252.14474 238.66697,251.68224 238.08213,251.39936 C 238.08213,251.39936 230.23378,247.60312 230.23378,247.60312 C 229.65678,247.32402 228.88557,247.32967 228.50367,247.6159 C 228.50367,247.6159 223.29424,251.52023 223.29424,251.52023 C 222.90493,251.812 223.05807,252.27611 223.63856,252.56071 C 223.63856,252.56071 231.535,256.43217 231.535,256.43217 C 232.12348,256.72068 232.90856,256.71342 233.2943,256.416 C 233.2943,256.416 233.2943,256.416 233.2943,256.416"
- id="path5281"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5283"
- d="M 224.84883,246.55597 C 224.84883,246.55597 217.52734,242.94323 217.52734,242.94323 C 216.98183,242.67405 216.15475,242.73355 215.67283,243.07723 C 215.67283,243.07723 209.10533,247.76083 209.10533,247.76083 C 208.61499,248.11051 208.66694,248.60923 209.22188,248.87843 C 209.22188,248.87843 216.66948,252.49124 216.66948,252.49124 C 217.21707,252.75687 218.04508,252.68874 218.52598,252.33907 C 218.52598,252.33907 224.96738,247.65541 224.96738,247.65541 C 225.44008,247.3117 225.38717,246.82161 224.84883,246.55597 C 224.84883,246.55597 224.84883,246.55597 224.84883,246.55597"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5285"
- d="M 211.2176,234.55068 C 211.2176,234.55068 218.13924,237.73238 218.13924,237.73238 C 218.66737,237.97515 218.77598,238.41021 218.37697,238.70684 C 218.37697,238.70684 212.62031,242.9864 212.62031,242.9864 C 212.1974,243.3008 211.43997,243.33022 210.928,243.05365 C 210.928,243.05365 204.23311,239.43697 204.23311,239.43697 C 203.78717,239.19607 203.75848,238.77609 204.16385,238.4943 C 204.16385,238.4943 209.694,234.65 209.694,234.65 C 210.07817,234.38294 210.75554,234.33829 211.2176,234.55068 C 211.2176,234.55068 211.2176,234.55068 211.2176,234.55068"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5287"
- d="M 233.15615,239.94299 C 233.15615,239.94299 226.44421,236.69379 226.44421,236.69379 C 225.78369,236.37403 224.84989,236.41177 224.348,236.77797 C 224.348,236.77797 219.29773,240.46286 219.29773,240.46286 C 218.78807,240.83472 218.90378,241.40005 219.55968,241.73088 C 219.55968,241.73088 226.22576,245.09312 226.22576,245.09312 C 226.90521,245.43582 227.86846,245.40352 228.38283,245.02018 C 228.38283,245.02018 233.47896,241.22224 233.47896,241.22224 C 233.98531,240.84488 233.84015,240.27412 233.15615,239.94299 C 233.15615,239.94299 233.15615,239.94299 233.15615,239.94299"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5289"
- d="M 220.30432,227.87754 C 220.30432,227.87754 227.46486,231.13608 227.46486,231.13608 C 227.82573,231.3003 227.87475,231.60963 227.57378,231.82996 C 227.57378,231.82996 221.38229,236.3625 221.38229,236.3625 C 221.06565,236.59429 220.51407,236.64288 220.14663,236.4711 C 220.14663,236.4711 212.85793,233.06353 212.85793,233.06353 C 212.49851,232.8955 212.47011,232.57953 212.7932,232.35543 C 212.7932,232.35543 219.11286,227.97192 219.11286,227.97192 C 219.42016,227.75877 219.95112,227.71681 220.30432,227.87754 C 220.30432,227.87754 220.30432,227.87754 220.30432,227.87754"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 253.8328,253.35343 C 253.8328,253.35343 246.80705,249.98982 246.80705,249.98982 C 246.25118,249.7237 245.43236,249.7982 244.96971,250.15699 C 244.96971,250.15699 239.12467,254.6899 239.12467,254.6899 C 238.65231,255.05622 238.71907,255.57195 239.27581,255.84611 C 239.27581,255.84611 246.31353,259.3118 246.31353,259.3118 C 246.88258,259.59203 247.72148,259.51595 248.19294,259.14132 C 248.19294,259.14132 254.02601,254.50633 254.02601,254.50633 C 254.48765,254.13951 254.40082,253.62536 253.8328,253.35343 C 253.8328,253.35343 253.8328,253.35343 253.8328,253.35343"
- id="path5291"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 241.69245,250.18836 C 241.69245,250.18836 246.86241,246.20217 246.86241,246.20217 C 247.27195,245.8864 247.09122,245.38581 246.45826,245.07965 C 246.45826,245.07965 238.59679,241.27706 238.59679,241.27706 C 237.97222,240.97496 237.13747,240.98108 236.72408,241.29091 C 236.72408,241.29091 231.50595,245.20176 231.50595,245.20176 C 231.08462,245.51753 231.25039,246.01986 231.87874,246.32792 C 231.87874,246.32792 239.78839,250.20585 239.78839,250.20585 C 240.42527,250.5181 241.27499,250.51024 241.69245,250.18836 C 241.69245,250.18836 241.69245,250.18836 241.69245,250.18836"
- id="path5293"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5295"
- d="M 262.29906,246.8676 C 262.29906,246.8676 254.88168,243.44853 254.88168,243.44853 C 254.50008,243.27263 253.95712,243.3153 253.66336,243.54406 C 253.66336,243.54406 248.0194,247.9394 248.0194,247.9394 C 247.72057,248.17212 247.78403,248.50657 248.1626,248.68946 C 248.1626,248.68946 255.52239,252.24492 255.52239,252.24492 C 255.9167,252.43541 256.47799,252.39569 256.77993,252.1557 C 256.77993,252.1557 262.48146,247.62397 262.48146,247.62397 C 262.77816,247.38815 262.69638,247.05074 262.29906,246.8676 C 262.29906,246.8676 262.29906,246.8676 262.29906,246.8676"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5297"
- d="M 269.92313,240.18072 C 269.92313,240.18072 263.31143,237.09826 263.31143,237.09826 C 262.81933,236.86884 262.13676,236.90784 261.77997,237.18694 C 261.77997,237.18694 256.80537,241.07833 256.80537,241.07833 C 256.42536,241.3756 256.53169,241.80611 257.04493,242.04226 C 257.04493,242.04226 263.93919,245.21441 263.93919,245.21441 C 264.44655,245.44785 265.14436,245.3899 265.50271,245.08585 C 265.50271,245.08585 270.19479,241.10477 270.19479,241.10477 C 270.53139,240.81918 270.4098,240.40761 269.92313,240.18072 C 269.92313,240.18072 269.92313,240.18072 269.92313,240.18072"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5299"
- d="M 284.15897,244.25926 C 284.15897,244.25926 290.08975,239.34554 290.08975,239.34554 C 290.3372,239.14053 290.25996,238.84705 289.91756,238.6876 C 289.91756,238.6876 282.05801,235.02758 282.05801,235.02758 C 281.73357,234.87649 281.27511,234.91294 281.02917,235.10924 C 281.02917,235.10924 275.13725,239.81168 275.13725,239.81168 C 274.88342,240.01427 274.9381,240.30589 275.26078,240.46561 C 275.26078,240.46561 283.08145,244.3369 283.08145,244.3369 C 283.42232,244.50564 283.90334,244.47105 284.15897,244.25926 C 284.15897,244.25926 284.15897,244.25926 284.15897,244.25926"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5301"
- d="M 290.6347,228.41799 C 290.6347,228.41799 298.47677,231.7748 298.47677,231.7748 C 298.96904,231.98552 299.08998,232.38046 298.7459,232.65955 C 298.7459,232.65955 293.04479,237.28397 293.04479,237.28397 C 292.69915,237.56434 292.03399,237.60956 291.55538,237.38617 C 291.55538,237.38617 283.93166,233.82786 283.93166,233.82786 C 283.4873,233.62045 283.39853,233.2382 283.73091,232.97007 C 283.73091,232.97007 289.21363,228.54719 289.21363,228.54719 C 289.54456,228.28023 290.17756,228.22231 290.6347,228.41799 C 290.6347,228.41799 290.6347,228.41799 290.6347,228.41799"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5303"
- d="M 301.86982,230.05516 C 301.86982,230.05516 306.72655,226.01075 306.72655,226.01075 C 307.20873,225.60921 307.07252,225.04406 306.41901,224.74173 C 306.41901,224.74173 299.71761,221.64153 299.71761,221.64153 C 299.02841,221.32268 298.06453,221.39571 297.55878,221.80728 C 297.55878,221.80728 292.46319,225.95398 292.46319,225.95398 C 291.94831,226.37298 292.11057,226.9602 292.82454,227.2686 C 292.82454,227.2686 299.76474,230.26652 299.76474,230.26652 C 300.44135,230.5588 301.37922,230.4637 301.86982,230.05516 C 301.86982,230.05516 301.86982,230.05516 301.86982,230.05516"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5305"
- d="M 229.75901,221.51708 C 229.75901,221.51708 236.30365,224.3537 236.30365,224.3537 C 236.77779,224.55921 236.83816,224.95708 236.4374,225.2459 C 236.4374,225.2459 230.73685,229.35443 230.73685,229.35443 C 230.32395,229.65201 229.60775,229.71902 229.13267,229.50455 C 229.13267,229.50455 222.57677,226.54493 222.57677,226.54493 C 222.11612,226.33697 222.07952,225.93711 222.49312,225.64852 C 222.49312,225.64852 228.20494,221.66299 228.20494,221.66299 C 228.60659,221.38273 229.29903,221.31772 229.75901,221.51708 C 229.75901,221.51708 229.75901,221.51708 229.75901,221.51708"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5307"
- d="M 241.4331,233.77444 C 241.4331,233.77444 234.86702,230.51453 234.86702,230.51453 C 234.2884,230.22725 233.46852,230.2512 233.03004,230.56861 C 233.03004,230.56861 228.00571,234.20578 228.00571,234.20578 C 227.5701,234.52112 227.69,235.00165 228.27321,235.28282 C 228.27321,235.28282 234.89177,238.47354 234.89177,238.47354 C 235.46008,238.74751 236.26364,238.71874 236.69472,238.40938 C 236.69472,238.40938 241.66657,234.84141 241.66657,234.84141 C 242.10045,234.53004 241.99687,234.05434 241.4331,233.77444 C 241.4331,233.77444 241.4331,233.77444 241.4331,233.77444"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5309"
- d="M 250.21733,243.40142 C 250.21733,243.40142 255.39176,239.30139 255.39176,239.30139 C 255.89164,238.9053 255.71333,238.31587 254.9964,237.97824 C 254.9964,237.97824 247.93065,234.65074 247.93065,234.65074 C 247.23226,234.32185 246.25306,234.35802 245.73067,234.73327 C 245.73067,234.73327 240.32649,238.61528 240.32649,238.61528 C 239.76575,239.01809 239.8905,239.62564 240.61117,239.97588 C 240.61117,239.97588 247.90666,243.52145 247.90666,243.52145 C 248.64734,243.88142 249.68011,243.82709 250.21733,243.40142 C 250.21733,243.40142 250.21733,243.40142 250.21733,243.40142"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 259.03235,236.38432 C 259.03235,236.38432 264.00233,232.5172 264.00233,232.5172 C 264.49375,232.13483 264.28734,231.56751 263.54605,231.2468 C 263.54605,231.2468 256.4643,228.18292 256.4643,228.18292 C 255.78568,227.88932 254.86097,227.94181 254.38524,228.29923 C 254.38524,228.29923 249.57716,231.91156 249.57716,231.91156 C 249.08982,232.2777 249.22635,232.82706 249.889,233.14485 C 249.889,233.14485 256.80881,236.46342 256.80881,236.46342 C 257.53364,236.81102 258.52826,236.77654 259.03235,236.38432 C 259.03235,236.38432 259.03235,236.38432 259.03235,236.38432"
- id="path5311"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5313"
- d="M 249.92718,227.47874 C 249.92718,227.47874 243.57843,224.26363 243.57843,224.26363 C 242.94161,223.94113 242.03351,223.96693 241.54071,224.32288 C 241.54071,224.32288 236.50753,227.95826 236.50753,227.95826 C 235.99196,228.33065 236.10354,228.89802 236.75945,229.2289 C 236.75945,229.2289 243.29817,232.52743 243.29817,232.52743 C 243.95188,232.8572 244.8789,232.81481 245.37499,232.4339 C 245.37499,232.4339 250.21821,228.7151 250.21821,228.7151 C 250.69243,228.35098 250.56193,227.80019 249.92718,227.47874 C 249.92718,227.47874 249.92718,227.47874 249.92718,227.47874"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5315"
- d="M 278.37779,233.42877 C 278.37779,233.42877 271.86628,230.49633 271.86628,230.49633 C 271.35525,230.26619 270.61009,230.34047 270.19363,230.66278 C 270.19363,230.66278 264.92861,234.73754 264.92861,234.73754 C 264.50283,235.06706 264.56772,235.52596 265.07602,235.76657 C 265.07602,235.76657 271.55435,238.83315 271.55435,238.83315 C 272.08251,239.08315 272.85436,239.01044 273.28293,238.66998 C 273.28293,238.66998 278.58112,234.46107 278.58112,234.46107 C 279.00009,234.12824 278.90852,233.66778 278.37779,233.42877 C 278.37779,233.42877 278.37779,233.42877 278.37779,233.42877"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 286.64967,226.73945 C 286.64967,226.73945 280.75469,223.85413 280.75469,223.85413 C 280.1553,223.56076 279.26816,223.63562 278.7659,224.02366 C 278.7659,224.02366 273.67528,227.95655 273.67528,227.95655 C 273.15783,228.35631 273.24091,228.914 273.86123,229.20522 C 273.86123,229.20522 279.9603,232.06855 279.9603,232.06855 C 280.56171,232.3509 281.4454,232.25691 281.94196,231.85949 C 281.94196,231.85949 286.82847,227.94856 286.82847,227.94856 C 287.31074,227.56258 287.23111,227.02404 286.64967,226.73945 C 286.64967,226.73945 286.64967,226.73945 286.64967,226.73945"
- id="path5317"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5319"
- d="M 267.6823,229.91307 C 267.6823,229.91307 272.46908,226.23566 272.46908,226.23566 C 272.94434,225.87054 272.74124,225.3253 272.01611,225.01342 C 272.01611,225.01342 264.88193,221.94496 264.88193,221.94496 C 264.17799,221.64219 263.23154,221.68466 262.7575,222.03994 C 262.7575,222.03994 257.98381,225.61763 257.98381,225.61763 C 257.50171,225.97894 257.67724,226.52125 258.37978,226.83381 C 258.37978,226.83381 265.50086,230.00199 265.50086,230.00199 C 266.22477,230.32406 267.1988,230.28451 267.6823,229.91307 C 267.6823,229.91307 267.6823,229.91307 267.6823,229.91307"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 258.51488,221.22986 C 258.51488,221.22986 252.19037,218.21416 252.19037,218.21416 C 251.57618,217.9213 250.69327,217.96397 250.20557,218.30991 C 250.20557,218.30991 245.20204,221.8591 245.20204,221.8591 C 244.68719,222.22431 244.76403,222.77336 245.37981,223.09013 C 245.37981,223.09013 251.72747,226.35547 251.72747,226.35547 C 252.38375,226.69307 253.32987,226.6498 253.84288,226.25849 C 253.84288,226.25849 258.82312,222.45965 258.82312,222.45965 C 259.30803,222.08977 259.16806,221.54132 258.51488,221.22986 C 258.51488,221.22986 258.51488,221.22986 258.51488,221.22986"
- id="path5321"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5323"
- d="M 239.22906,214.77058 C 239.22906,214.77058 245.75948,217.65839 245.75948,217.65839 C 246.22836,217.86574 246.27624,218.27214 245.86583,218.5699 C 245.86583,218.5699 240.04074,222.79608 240.04074,222.79608 C 239.61975,223.10153 238.89933,223.17644 238.42646,222.96374 C 238.42646,222.96374 231.84118,220.00174 231.84118,220.00174 C 231.37421,219.79169 231.34116,219.38081 231.76608,219.08076 C 231.76608,219.08076 237.64602,214.92874 237.64602,214.92874 C 238.06034,214.63619 238.76594,214.56577 239.22906,214.77058 C 239.22906,214.77058 239.22906,214.77058 239.22906,214.77058"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5325"
- d="M 247.90724,208.64597 C 247.90724,208.64597 254.53759,211.50631 254.53759,211.50631 C 255.01636,211.71285 255.09618,212.10048 254.71562,212.37537 C 254.71562,212.37537 249.34818,216.25246 249.34818,216.25246 C 248.96271,216.5309 248.26761,216.58434 247.79061,216.37235 C 247.79061,216.37235 241.18538,213.43689 241.18538,213.43689 C 240.71963,213.22991 240.65428,212.84354 241.03791,212.57052 C 241.03791,212.57052 246.38024,208.76857 246.38024,208.76857 C 246.75905,208.49898 247.43968,208.44427 247.90724,208.64597 C 247.90724,208.64597 247.90724,208.64597 247.90724,208.64597"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5327"
- d="M 266.53609,215.35847 C 266.53609,215.35847 260.2425,212.50539 260.2425,212.50539 C 259.63111,212.22823 258.77381,212.26339 258.31648,212.58345 C 258.31648,212.58345 253.69899,215.81504 253.69899,215.81504 C 253.23142,216.14228 253.3369,216.6411 253.93933,216.93434 C 253.93933,216.93434 260.14335,219.95417 260.14335,219.95417 C 260.78415,220.26608 261.68732,220.24081 262.16416,219.89654 C 262.16416,219.89654 266.87121,216.49816 266.87121,216.49816 C 267.3372,216.16172 267.18586,215.65303 266.53609,215.35847 C 266.53609,215.35847 266.53609,215.35847 266.53609,215.35847"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5329"
- d="M 275.86123,223.49708 C 275.86123,223.49708 280.69597,219.76003 280.69597,219.76003 C 281.17477,219.38993 280.98509,218.85214 280.27334,218.55429 C 280.27334,218.55429 273.2735,215.62511 273.2735,215.62511 C 272.58309,215.3362 271.64347,215.39287 271.16418,215.75208 C 271.16418,215.75208 266.32552,219.37853 266.32552,219.37853 C 265.83563,219.74569 265.99513,220.28253 266.68578,220.58229 C 266.68578,220.58229 273.68954,223.62208 273.68954,223.62208 C 274.40184,223.93123 275.37164,223.87552 275.86123,223.49708 C 275.86123,223.49708 275.86123,223.49708 275.86123,223.49708"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 282.59083,221.04513 C 282.59083,221.04513 287.71903,217.05699 287.71903,217.05699 C 288.22587,216.66285 289.08472,216.56532 289.64647,216.83783 C 289.64647,216.83783 295.29725,219.57907 295.29725,219.57907 C 295.86731,219.85561 295.92338,220.40166 295.42118,220.80393 C 295.42118,220.80393 290.33924,224.87461 290.33924,224.87461 C 289.82349,225.28773 288.94404,225.3914 288.36924,225.1065 C 288.36924,225.1065 282.67221,222.28271 282.67221,222.28271 C 282.10592,222.00203 282.07045,221.44982 282.59083,221.04513 C 282.59083,221.04513 282.59083,221.04513 282.59083,221.04513"
- id="path5331"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5333"
- d="M 273.82385,209.9072 C 273.82385,209.9072 267.67742,207.1135 267.67742,207.1135 C 267.05691,206.83146 266.21983,206.85051 265.80038,207.15733 C 265.80038,207.15733 261.55003,210.26641 261.55003,210.26641 C 261.11807,210.58238 261.28238,211.06634 261.91859,211.35037 C 261.91859,211.35037 268.21969,214.1634 268.21969,214.1634 C 268.84554,214.4428 269.68458,214.41091 270.10075,214.09302 C 270.10075,214.09302 274.19645,210.96462 274.19645,210.96462 C 274.60069,210.65585 274.43443,210.18473 273.82385,209.9072 C 273.82385,209.9072 273.82385,209.9072 273.82385,209.9072"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5335"
- d="M 257.3726,201.76885 C 257.3726,201.76885 264.64202,204.86157 264.64202,204.86157 C 264.95177,204.99335 264.97965,205.26073 264.70378,205.46149 C 264.70378,205.46149 257.98723,210.34941 257.98723,210.34941 C 257.69315,210.56343 257.19866,210.62527 256.87934,210.48761 C 256.87934,210.48761 249.38649,207.25742 249.38649,207.25742 C 249.07032,207.12112 249.06104,206.84361 249.36486,206.63564 C 249.36486,206.63564 256.30482,201.88518 256.30482,201.88518 C 256.58991,201.69003 257.06581,201.63832 257.3726,201.76885 C 257.3726,201.76885 257.3726,201.76885 257.3726,201.76885"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5337"
- d="M 284.0905,217.40082 C 284.0905,217.40082 288.28521,214.18116 288.28521,214.18116 C 288.70353,213.86008 288.47298,213.36105 287.76806,213.06182 C 287.76806,213.06182 280.69745,210.06045 280.69745,210.06045 C 279.9862,209.75854 279.07181,209.77379 278.64748,210.09508 C 278.64748,210.09508 274.39236,213.31696 274.39236,213.31696 C 273.96443,213.64097 274.19761,214.14507 274.91495,214.44677 C 274.91495,214.44677 282.04596,217.44592 282.04596,217.44592 C 282.75689,217.74492 283.66866,217.7246 284.0905,217.40082 C 284.0905,217.40082 284.0905,217.40082 284.0905,217.40082"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5339"
- d="M 300.10154,217.06983 C 300.10154,217.06983 316.31837,203.96829 316.31837,203.96829 C 317.07607,203.35614 317.4003,202.7538 317.04873,202.61609 C 317.04873,202.61609 310.03269,199.86796 310.03269,199.86796 C 309.70146,199.73822 308.83575,200.10447 308.08844,200.69068 C 308.08844,200.69068 292.11577,213.22035 292.11577,213.22035 C 291.30809,213.85393 290.91207,214.49139 291.23134,214.64793 C 291.23134,214.64793 298.003,217.96805 298.003,217.96805 C 298.34279,218.13465 299.2804,217.73322 300.10154,217.06983 C 300.10154,217.06983 300.10154,217.06983 300.10154,217.06983"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 291.15172,211.81971 C 291.15172,211.81971 294.95784,208.85652 294.95784,208.85652 C 295.33535,208.56261 295.06588,208.08714 294.35728,207.79127 C 294.35728,207.79127 287.46322,204.91266 287.46322,204.91266 C 286.7905,204.63177 285.951,204.6327 285.57753,204.91398 C 285.57753,204.91398 281.81341,207.749 281.81341,207.749 C 281.43293,208.03556 281.66197,208.50175 282.33038,208.79505 C 282.33038,208.79505 289.18243,211.80181 289.18243,211.80181 C 289.88692,212.11095 290.76688,212.11932 291.15172,211.81971 C 291.15172,211.81971 291.15172,211.81971 291.15172,211.81971"
- id="path5341"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- d="M 279.78845,205.15721 C 279.78845,205.15721 273.64923,202.7238 273.64923,202.7238 C 273.07415,202.49585 272.35188,202.50572 272.02271,202.74427 C 272.02271,202.74427 268.6721,205.17246 268.6721,205.17246 C 268.33004,205.42034 268.50084,205.82253 269.06217,206.07617 C 269.06217,206.07617 275.0647,208.78839 275.0647,208.78839 C 275.70867,209.07937 276.52129,209.09274 276.87788,208.8159 C 276.87788,208.8159 280.365,206.10863 280.365,206.10863 C 280.70701,205.84311 280.44598,205.41784 279.78845,205.15721 C 279.78845,205.15721 279.78845,205.15721 279.78845,205.15721"
- id="path5343"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5345"
- d="M 266.63729,203.4528 C 266.63729,203.4528 259.22437,200.28887 259.22437,200.28887 C 258.90107,200.15088 259.26093,199.6067 260.02623,199.07179 C 260.02623,199.07179 276.04515,187.8754 276.04515,187.8754 C 276.70328,187.4154 277.47826,187.14286 277.78675,187.26189 C 277.78675,187.26189 284.85126,189.98782 284.85126,189.98782 C 285.16872,190.11032 284.90984,190.59119 284.26684,191.06857 C 284.26684,191.06857 268.59644,202.70261 268.59644,202.70261 C 267.84684,203.25912 266.97083,203.59516 266.63729,203.4528 C 266.63729,203.4528 266.63729,203.4528 266.63729,203.4528"
- style="opacity:0.99720004;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- id="path5347"
- sodipodi:nodetypes="cccccssssccccc"
- d="M 306.08894,198.05464 C 306.08894,198.05464 289.86483,191.75754 289.86483,191.75754 C 288.75309,191.32603 287.34294,191.34222 286.72043,191.80216 C 286.72043,191.80216 275.86985,199.81916 275.86985,199.81916 C 275.21811,200.30071 275.08509,200.71469 276.34881,201.06644 L 282.51762,203.58752 C 283.51554,203.99535 283.51356,204.01646 284.38014,203.38499 L 285.53498,202.54346 C 285.7875,202.35945 286.54428,202.2881 287.35569,202.6377 L 295.71352,206.2387 C 296.63524,206.49525 297.43593,206.57335 297.95625,206.16455 C 297.95625,206.16455 306.65122,199.3329 306.65122,199.3329 C 307.15193,198.93949 306.90591,198.37173 306.08894,198.05464 C 306.08894,198.05464 306.08894,198.05464 306.08894,198.05464"
- style="opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- </g>
- <path
- d="M 195.84384,316.18138 C 198.01729,317.52381 197.72963,318.48268 195.26851,320.68809 C 192.78733,322.9115 196.00365,319.69726 196.67486,318.67446 C 197.37566,317.60657 193.70779,314.86206 195.84384,316.18138 z "
- sodipodi:nodetypes="czzz"
- id="path2379"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3350"
- sodipodi:nodetypes="czzz"
- d="M 216.172,300.16816 C 218.34546,301.51059 218.79294,302.1818 216.33181,304.38722 C 213.85064,306.61061 216.81125,303.42834 217.61032,302.34161 C 218.38754,301.28458 214.03595,298.84884 216.172,300.16816 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 206.4554,308.31861 C 208.62885,309.66103 209.20418,310.14046 206.74306,312.34587 C 204.26188,314.56927 207.35035,311.1313 207.82978,310.49205 C 208.39381,309.74001 204.31935,306.99928 206.4554,308.31861 z "
- sodipodi:nodetypes="czzz"
- id="path3352"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3354"
- sodipodi:nodetypes="czzz"
- d="M 225.50506,292.46519 C 227.67851,293.80762 228.25383,294.28706 225.79272,296.49247 C 223.31154,298.71586 227.0073,295.62948 226.78356,294.4149 C 226.56079,293.20564 223.36901,291.14588 225.50506,292.46519 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3356"
- sodipodi:nodetypes="czzz"
- d="M 203.49886,293.36015 C 205.63491,294.67947 206.0239,295.13407 203.48288,297.25957 C 200.9308,299.39433 204.5367,295.76662 204.79335,295.2779 C 205.04344,294.80165 201.36281,292.04083 203.49886,293.36015 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 189.00386,289.3009 C 191.59281,290.73922 191.94897,291.213 189.29153,293.32818 C 186.61856,295.45568 190.37824,292.20949 190.37824,291.21865 C 190.37824,290.19585 186.42834,287.87006 189.00386,289.3009 z "
- sodipodi:nodetypes="czzz"
- id="path3358"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3360"
- sodipodi:nodetypes="czzz"
- d="M 171.16877,285.43344 C 173.47007,286.64801 174.17325,287.38316 171.45643,289.46072 C 168.74413,291.53484 172.83082,288.34203 172.60709,287.38316 C 172.36917,286.36356 168.8898,284.23064 171.16877,285.43344 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 155.9546,281.50205 C 158.12806,282.78055 158.83124,283.54764 156.24227,285.52933 C 153.64201,287.51964 157.42488,284.66634 157.20114,283.38784 C 156.97829,282.11439 153.75272,280.20681 155.9546,281.50205 z "
- sodipodi:nodetypes="czzz"
- id="path3362"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 161.10057,292.56108 C 163.27403,293.9035 163.96914,294.4897 161.38823,296.58835 C 158.81117,298.6839 157.15517,299.80076 160.6531,296.71621 C 164.16898,293.61583 158.96453,291.24176 161.10057,292.56108 z "
- sodipodi:nodetypes="czzz"
- id="path3364"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 178.74389,296.62031 C 182.35566,298.53807 181.81229,298.31433 176.12296,302.85301 C 170.44917,307.37928 178.76168,300.08938 179.60688,299.14536 C 180.42197,298.23497 175.15702,294.71579 178.74389,296.62031 z "
- sodipodi:nodetypes="czzz"
- id="path3366"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 193.22292,300.42386 C 195.39636,301.76628 195.49224,303.36442 189.3874,308.28664 C 183.26317,313.22451 195.05807,303.89438 193.51058,301.89414 C 192.00596,299.94933 191.08687,299.10454 193.22292,300.42386 z "
- sodipodi:nodetypes="czzz"
- id="path3368"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3370"
- sodipodi:nodetypes="czzz"
- d="M 145.18324,288.69362 C 147.80416,290.22781 147.8681,290.89903 145.18324,292.91266 C 142.52875,294.90353 146.62155,291.63417 146.39782,290.67529 C 146.18115,289.74671 142.58609,287.17332 145.18324,288.69362 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3372"
- sodipodi:nodetypes="czzz"
- d="M 165.73514,274.56618 C 167.9086,275.9086 168.61177,276.57982 166.0228,278.59347 C 163.40256,280.63143 166.7899,277.25103 167.20542,276.73963 C 167.59048,276.2657 163.5991,273.24685 165.73514,274.56618 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 181.26892,278.14598 C 183.44237,279.48841 184.0177,279.96784 181.55659,282.17326 C 179.07541,284.39665 182.5794,281.34223 182.35566,280.06373 C 182.13279,278.79029 179.13287,276.82666 181.26892,278.14598 z "
- sodipodi:nodetypes="czzz"
- id="path3374"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3376"
- sodipodi:nodetypes="czzz"
- d="M 198.2659,281.884 C 200.43936,283.22641 201.01468,283.70585 198.55356,285.91126 C 196.07238,288.13466 199.57637,285.08024 199.35263,283.80174 C 199.12976,282.52829 196.12986,280.56467 198.2659,281.884 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 213.08942,285.57681 C 215.8957,286.96443 216.29022,287.35347 213.37708,289.60408 C 210.50713,291.82133 214.72017,288.27028 214.62817,287.40415 C 214.54091,286.58272 210.2463,284.17095 213.08942,285.57681 z "
- sodipodi:nodetypes="czzz"
- id="path3378"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3380"
- sodipodi:nodetypes="czzz"
- d="M 175.13212,267.66227 C 177.30557,269.00471 177.99635,269.63282 175.41979,271.68956 C 172.87468,273.72117 176.44259,270.7946 176.41062,269.64395 C 176.37866,268.4933 172.99607,266.34296 175.13212,267.66227 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3382"
- sodipodi:nodetypes="czzz"
- d="M 190.72984,270.85853 C 192.96721,272.0731 193.60646,272.74431 191.01751,274.88581 C 188.47105,276.99212 192.23208,274.11871 192.00834,272.84021 C 191.78548,271.56676 188.48472,269.63975 190.72984,270.85853 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 207.55763,274.67852 C 209.73109,276.02094 210.30641,276.50038 207.8453,278.70579 C 205.36412,280.92919 208.8681,277.87477 208.64437,276.59627 C 208.4215,275.32282 205.42158,273.35919 207.55763,274.67852 z "
- sodipodi:nodetypes="czzz"
- id="path3384"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3386"
- sodipodi:nodetypes="czzz"
- d="M 223.20376,277.63457 C 226.23604,279.29342 225.95254,279.45644 223.49142,281.66186 C 221.01023,283.88525 224.74999,280.23696 224.6521,279.41673 C 224.56485,278.6857 220.20621,275.99474 223.20376,277.63457 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 277.38117,248.70302 C 281.95031,251.26589 281.48626,250.13465 270.88855,258.92295 C 260.38024,267.63712 274.33964,254.68517 277.12282,252.1444 C 279.88337,249.62427 272.7431,246.10148 277.38117,248.70302 z "
- sodipodi:nodetypes="czzz"
- id="path3388"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3390"
- sodipodi:nodetypes="czzz"
- d="M 231.57794,270.34712 C 233.75139,271.68956 234.32672,272.16899 231.86561,274.37441 C 229.38442,276.5978 232.88839,273.54338 232.66467,272.26488 C 232.4418,270.99143 229.44189,269.02781 231.57794,270.34712 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 241.29454,263.69892 C 243.46799,265.04135 244.04332,265.52079 241.58221,267.72621 C 239.10103,269.9496 242.60501,266.89517 242.38128,265.61667 C 242.15841,264.34322 239.15849,262.3796 241.29454,263.69892 z "
- sodipodi:nodetypes="czzz"
- id="path3392"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3394"
- sodipodi:nodetypes="czzz"
- d="M 250.24405,256.53932 C 252.4175,257.88175 252.99283,258.36119 250.53172,260.5666 C 248.05053,262.78999 251.55451,259.73557 251.33077,258.45707 C 251.10792,257.18362 248.10801,255.21999 250.24405,256.53932 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 258.68216,249.37971 C 260.85561,250.72214 261.43093,251.20158 258.96982,253.40699 C 256.48864,255.63038 259.99262,252.57596 259.76888,251.29747 C 259.54603,250.02402 256.54611,248.06039 258.68216,249.37971 z "
- sodipodi:nodetypes="czzz"
- id="path3396"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3398"
- sodipodi:nodetypes="czzz"
- d="M 215.08528,267.40658 C 217.25872,268.749 217.83405,269.22845 215.37294,271.43386 C 212.89175,273.65725 216.39574,270.60283 216.172,269.32432 C 215.94914,268.05088 212.94923,266.08725 215.08528,267.40658 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 200.54781,263.45098 C 204.31939,265.43265 203.68014,265.40068 200.83547,267.47825 C 198.05046,269.51225 201.27066,266.64722 202.04136,265.54954 C 202.78342,264.49262 196.80222,261.48295 200.54781,263.45098 z "
- sodipodi:nodetypes="czzz"
- id="path3400"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3402"
- sodipodi:nodetypes="czzz"
- d="M 185.48798,260.50267 C 188.30069,262.16472 188.68423,262.2606 185.77564,264.52995 C 182.90663,266.76843 187.05414,263.76284 186.83041,262.48434 C 186.60755,261.21089 182.72253,258.86853 185.48798,260.50267 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 194.50141,253.47091 C 196.67486,254.81334 197.25018,255.29277 194.78907,257.49819 C 192.30789,259.72159 195.81187,256.66717 195.58814,255.38867 C 195.36528,254.11522 192.36537,252.15159 194.50141,253.47091 z "
- sodipodi:nodetypes="czzz"
- id="path3404"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3406"
- sodipodi:nodetypes="czzz"
- d="M 204.79335,246.88664 C 206.96679,248.22906 207.54211,248.7085 205.081,250.91391 C 202.59982,253.13731 206.10381,250.08289 205.88007,248.80439 C 205.65721,247.53094 202.6573,245.56731 204.79335,246.88664 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 209.97127,256.34754 C 212.14473,257.68997 212.72004,258.16941 210.25893,260.37482 C 207.77775,262.59821 211.28174,259.54379 211.058,258.26529 C 210.83513,256.99184 207.83522,255.02823 209.97127,256.34754 z "
- sodipodi:nodetypes="czzz"
- id="path3408"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3410"
- sodipodi:nodetypes="czzz"
- d="M 219.94358,248.99617 C 222.11703,250.33858 222.69236,250.81803 220.23124,253.02345 C 217.75006,255.24684 221.25405,252.19241 221.03031,250.91391 C 220.80745,249.64046 217.80754,247.67683 219.94358,248.99617 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 226.08039,260.5666 C 228.25383,261.90901 228.82916,262.38845 226.36805,264.59388 C 223.88687,266.81727 227.39085,263.76284 227.16711,262.48434 C 226.94426,261.21089 223.94434,259.24727 226.08039,260.5666 z "
- sodipodi:nodetypes="czzz"
- id="path3412"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3414"
- sodipodi:nodetypes="czzz"
- d="M 234.39063,254.11016 C 236.56408,255.4526 237.13941,255.93204 234.6783,258.13745 C 232.19712,260.36084 235.70111,257.30642 235.47737,256.02792 C 235.25451,254.75447 232.25458,252.79084 234.39063,254.11016 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 229.27663,242.2201 C 231.45009,243.56254 232.02541,244.04197 229.5643,246.24738 C 227.08312,248.47078 230.58711,245.41636 230.36337,244.13786 C 230.1405,242.86442 227.14058,240.90079 229.27663,242.2201 z "
- sodipodi:nodetypes="czzz"
- id="path3416"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3418"
- sodipodi:nodetypes="czzz"
- d="M 243.0141,247.59302 C 245.39457,248.78588 245.85328,249.41488 243.39217,251.6203 C 240.91099,253.84369 244.68618,250.11125 244.59804,249.42037 C 244.51044,248.73372 240.56163,246.3641 243.0141,247.59302 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 213.8707,239.98274 C 216.04415,241.32515 216.61948,241.8046 214.15837,244.01001 C 211.67717,246.23341 215.18116,243.17898 214.95742,241.90048 C 214.73456,240.62703 211.73465,238.66341 213.8707,239.98274 z "
- sodipodi:nodetypes="czzz"
- id="path3420"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3422"
- sodipodi:nodetypes="czzz"
- d="M 222.91837,233.04137 C 225.31782,234.20299 225.93836,234.99885 223.20602,237.06866 C 220.48021,239.13354 224.63565,235.424 224.54751,234.77832 C 224.44726,234.04379 220.53635,231.8882 222.91837,233.04137 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 246.64686,229.49127 C 249.00111,230.74329 249.89286,231.08713 246.93452,233.51855 C 243.99824,235.93184 248.36413,232.59712 248.14039,231.31861 C 247.91754,230.04517 244.31107,228.24907 246.64686,229.49127 z "
- sodipodi:nodetypes="czzz"
- id="path3424"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3426"
- sodipodi:nodetypes="czzz"
- d="M 237.71153,235.84633 C 240.02059,237.03055 240.64112,237.84899 237.9992,239.87362 C 235.36048,241.89576 239.38361,238.50015 239.25027,237.67368 C 239.10149,236.75149 235.41158,234.66678 237.71153,235.84633 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 284.38244,228.84004 C 286.66889,230.04686 287.0481,230.84805 284.67009,232.86732 C 282.27897,234.89772 285.51201,231.73741 285.85337,231.07421 C 286.18578,230.42841 282.11363,227.64254 284.38244,228.84004 z "
- sodipodi:nodetypes="czzz"
- id="path3428"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3430"
- sodipodi:nodetypes="czzz"
- d="M 232.52396,226.41189 C 234.78783,227.52831 235.40834,228.14335 232.81163,230.16796 C 230.19284,232.20977 234.24125,228.7945 234.06271,228.10364 C 233.88666,227.4224 230.2964,225.31338 232.52396,226.41189 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 242.49949,219.69334 C 245.873,221.52582 244.75103,221.244 242.19951,223.3138 C 239.67516,225.36158 243.76147,221.8425 243.54101,221.11387 C 243.32053,220.38523 239.12596,217.86086 242.49949,219.69334 z "
- sodipodi:nodetypes="czzz"
- id="path3432"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3434"
- sodipodi:nodetypes="czzz"
- d="M 255.29092,223.29442 C 257.75818,224.59164 258.28831,225.25187 255.57858,227.32169 C 252.87211,229.38902 256.89519,225.88045 256.80705,225.21217 C 256.71558,224.51847 252.84135,222.00649 255.29092,223.29442 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 269.10194,227.3895 C 271.27539,228.73192 271.85071,229.21136 269.3896,231.41677 C 266.90842,233.64017 270.41241,230.58576 270.18867,229.30725 C 269.96581,228.0338 266.96589,226.07017 269.10194,227.3895 z "
- sodipodi:nodetypes="czzz"
- id="path3436"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3438"
- sodipodi:nodetypes="czzz"
- d="M 260.47206,233.782 C 262.64551,235.12443 263.22084,235.60386 260.75972,237.80927 C 258.27854,240.03267 261.78252,236.97826 261.55878,235.69975 C 261.33593,234.42631 258.33601,232.46268 260.47206,233.782 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 252.00426,240.41924 C 254.76534,241.85208 254.88865,242.2863 252.29193,244.44653 C 249.69924,246.60338 253.58595,242.98267 253.49781,242.15619 C 253.40345,241.27142 249.33359,239.0316 252.00426,240.41924 z "
- sodipodi:nodetypes="czzz"
- id="path3440"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3442"
- sodipodi:nodetypes="czzz"
- d="M 266.73671,242.2201 C 268.91017,243.56254 269.4855,244.04197 267.02438,246.24738 C 264.54319,248.47078 268.04717,245.41636 267.82343,244.13786 C 267.60058,242.86442 264.60067,240.90079 266.73671,242.2201 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 275.77863,235.80888 C 278.29108,237.0157 278.6856,237.56294 276.08889,239.70055 C 273.50776,241.82532 277.52012,238.29917 277.43037,237.50061 C 277.34312,236.7244 273.32091,234.62837 275.77863,235.80888 z "
- sodipodi:nodetypes="czzz"
- id="path3444"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3446"
- sodipodi:nodetypes="czzz"
- d="M 286.95302,240.94161 C 289.63786,242.37993 289.92552,242.74749 287.24067,244.96888 C 284.57146,247.17734 287.44366,244.39791 288.24749,243.37076 C 289.03146,242.369 284.28786,239.51385 286.95302,240.94161 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 295.77487,234.08611 C 298.28732,235.22513 298.70444,235.86277 296.06253,238.11339 C 293.44279,240.34511 296.0466,237.62948 297.1102,236.38809 C 298.1513,235.17297 293.28962,232.95944 295.77487,234.08611 z "
- sodipodi:nodetypes="czzz"
- id="path3448"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3450"
- sodipodi:nodetypes="czzz"
- d="M 304.36663,227.14477 C 306.83388,228.44201 307.1154,228.96663 304.65428,231.17204 C 302.17311,233.39544 304.72941,230.49547 305.36295,229.31112 C 306.04412,228.03769 301.92637,225.86174 304.36663,227.14477 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 293.12178,221.54036 C 295.47102,222.691 295.98242,223.42615 293.40945,225.56763 C 290.83798,227.70786 294.60852,224.14154 294.54411,223.33025 C 294.48107,222.53624 290.77257,220.38972 293.12178,221.54036 z "
- sodipodi:nodetypes="czzz"
- id="path3452"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3454"
- sodipodi:nodetypes="czzz"
- d="M 277.5149,220.70385 C 280.36638,222.31747 280.39928,222.70652 277.80256,224.73113 C 275.18377,226.77294 276.77322,224.86768 278.55642,223.48044 C 280.36765,222.07138 274.77049,219.15079 277.5149,220.70385 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 263.22084,217.41719 C 265.39428,218.75961 265.96961,219.23905 263.5085,221.44447 C 261.02732,223.66786 264.5313,220.61343 264.30756,219.33494 C 264.08471,218.06149 261.08479,216.09787 263.22084,217.41719 z "
- sodipodi:nodetypes="czzz"
- id="path3456"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3458"
- sodipodi:nodetypes="czzz"
- d="M 251.15585,213.31501 C 254.39256,214.77625 254.35665,214.86567 251.3531,216.98068 C 248.32814,219.11078 252.86671,215.85366 252.60418,214.91636 C 252.33613,213.95933 247.95664,211.87072 251.15585,213.31501 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 260.85561,206.10245 C 263.02906,207.44489 263.60438,207.92432 261.14327,210.12974 C 258.66209,212.35313 262.16607,209.29871 261.94234,208.02022 C 261.71947,206.74677 258.71956,204.78313 260.85561,206.10245 z "
- sodipodi:nodetypes="czzz"
- id="path3460"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3462"
- sodipodi:nodetypes="czzz"
- d="M 271.01969,211.72786 C 273.19314,213.07028 273.76847,213.54972 271.30736,215.75513 C 268.82618,217.97853 272.33015,214.92411 272.10641,213.64561 C 271.88356,212.37216 268.88364,210.40854 271.01969,211.72786 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 284.99091,214.99901 C 287.70679,216.25102 288.10131,216.82086 285.27858,219.02628 C 282.51164,221.18811 285.03572,219.0993 286.34886,217.27838 C 287.55847,215.60098 282.34938,213.78125 284.99091,214.99901 z "
- sodipodi:nodetypes="czzz"
- id="path3464"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3466"
- sodipodi:nodetypes="czzz"
- d="M 276.90079,206.80563 C 279.07425,208.14806 279.64957,208.6275 277.18845,210.83291 C 274.70727,213.05631 278.21126,210.00188 277.98752,208.72339 C 277.76466,207.44994 274.76474,205.48631 276.90079,206.80563 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 292.17888,209.68226 C 294.35233,211.02468 294.92766,211.50412 292.46654,213.70954 C 289.98536,215.93294 293.48934,212.87852 293.2656,211.60001 C 293.04275,210.32657 290.04283,208.36293 292.17888,209.68226 z "
- sodipodi:nodetypes="czzz"
- id="path3468"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3470"
- sodipodi:nodetypes="czzz"
- d="M 314.68049,204.24863 C 317.7489,205.39928 317.87645,205.56214 311.38835,210.80095 C 304.93164,216.01443 312.98405,209.0753 315.15994,207.02937 C 317.35285,204.96744 311.62248,203.10188 314.68049,204.24863 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="M 303.62147,199.96565 C 305.79492,201.30808 306.37025,201.78752 303.90913,203.99293 C 301.42794,206.21632 304.93192,203.16191 304.70818,201.8834 C 304.48533,200.60995 301.48542,198.64633 303.62147,199.96565 z "
- sodipodi:nodetypes="czzz"
- id="path3472"
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3474"
- sodipodi:nodetypes="czzz"
- d="M 281.07787,191.30607 C 284.96899,192.8745 284.82107,192.72112 278.69861,197.41265 C 272.5826,202.09922 281.39387,194.86394 282.66181,193.63065 C 283.93119,192.39593 277.15462,189.7247 281.07787,191.30607 z "
- style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- id="path3477"
- d="M 247.0478,21.870476 L 41.113266,89.503174 L 48.496608,139.14097 C 116.54867,104.13919 192.87556,126.61352 246.15284,103.7265 L 247.0478,21.870476 z "
- style="fill:url(#linearGradient2500);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:transform-center-x="21.926591"
- inkscape:transform-center-y="-98.60823"
- d="M 27.882376,75.746856 C 32.065415,74.206702 33.389047,74.781014 34.949531,76.633878 L 65.088465,277.78657 L 56.641394,273.5449 L 27.882376,75.746856 z "
- sodipodi:nodetypes="ccccc"
- id="path2180"
- style="fill:#1a1a1a;fill-rule:evenodd;stroke:#333333;stroke-width:0.81824058;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- id="path13298"
- sodipodi:nodetypes="ccccc"
- d="M 92.828627,259.35202 L 230.90672,174.71526 C 232.64824,175.78414 234.17161,176.98389 234.23083,179.06216 L 96.66413,263.82678 C 96.420949,261.86067 95.117349,260.38059 92.828627,259.35202 z "
- style="fill:#808080;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- transform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- id="path14269"
- sodipodi:nodetypes="ccccc"
- d="M 166.43526,236.83511 L 228.92582,195.64614 L 229.45615,196.53002 L 168.02625,238.24933 L 166.43526,236.83511 z "
- style="opacity:0.67000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16257)" />
- <path
- transform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- d="M 114.5513,270.06913 L 130.10765,259.99286 L 130.63798,260.87674 L 116.14229,271.48335 L 114.5513,270.06913 z "
- sodipodi:nodetypes="ccccc"
- id="path16261"
- style="opacity:0.67000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16257)" />
- <path
- transform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- d="M 114.5513,270.06913 L 130.10765,259.99286 L 130.63798,260.87674 L 116.14229,271.48335 L 114.5513,270.06913 z "
- sodipodi:nodetypes="ccccc"
- id="path16263"
- style="opacity:0.67000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16257)" />
- <path
- transform="matrix(1.0228007,0,0,1.0228007,-6.1273429,-1.9735657)"
- d="M 166.43526,236.83511 L 228.92582,195.64614 L 229.45615,196.53002 L 168.02625,238.24933 L 166.43526,236.83511 z "
- sodipodi:nodetypes="ccccc"
- id="path16267"
- style="opacity:0.67000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16257)" />
- <path
- d="M 104.05869,273.38134 C 106.59601,271.03005 113.13546,275.43531 112.49482,278.36804 L 104.05869,273.38134 z "
- sodipodi:nodetypes="ccc"
- id="path16269"
- style="opacity:0.99720004;fill:#666666;fill-rule:evenodd;stroke:#000000;stroke-width:0.20456015;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccsccccc"
- id="path25800"
- d="M 304.06894,248.1971 C 302.1656,248.29093 300.4498,248.80189 299.33849,249.7313 C 299.33849,249.7313 260.56796,282.17326 260.56795,282.17326 C 257.93245,284.37739 258.86046,287.65621 262.70943,289.52464 C 262.70943,289.52464 267.73895,291.93253 272.68174,294.28706 C 306.66914,288.15442 283.9982,253.02759 313.94536,251.0098 C 312.61326,250.41591 309.88612,249.2199 309.88612,249.2199 C 308.06831,248.43649 305.97228,248.10326 304.06894,248.1971 z "
- style="fill:url(#linearGradient2490);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.9527356;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
- </g>
- </g>
-</svg>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons/wpa_gui.svg b/wpa_supplicant/wpa_gui-qt4/icons/wpa_gui.svg
deleted file mode 100644
index b3abf0a288d8..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons/wpa_gui.svg
+++ /dev/null
@@ -1,256 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.0"
- width="128"
- height="128"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.46"
- sodipodi:docname="wpa_gui.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape">
- <metadata
- id="metadata47">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <sodipodi:namedview
- inkscape:window-height="771"
- inkscape:window-width="640"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- guidetolerance="10.0"
- gridtolerance="10.0"
- objecttolerance="10.0"
- borderopacity="1.0"
- bordercolor="#666666"
- pagecolor="#ffffff"
- id="base"
- showgrid="false"
- inkscape:zoom="4.2421875"
- inkscape:cx="64"
- inkscape:cy="64"
- inkscape:window-x="634"
- inkscape:window-y="0"
- inkscape:current-layer="svg2" />
- <defs
- id="defs4">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 64 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="128 : 64 : 1"
- inkscape:persp3d-origin="64 : 42.666667 : 1"
- id="perspective49" />
- <linearGradient
- id="linearGradient39133">
- <stop
- id="stop39135"
- style="stop-color:#252525;stop-opacity:1"
- offset="0" />
- <stop
- id="stop39137"
- style="stop-color:#515151;stop-opacity:1"
- offset="0" />
- <stop
- id="stop39139"
- style="stop-color:#878787;stop-opacity:1"
- offset="0.28677997" />
- <stop
- id="stop39141"
- style="stop-color:#000000;stop-opacity:1"
- offset="0.92151743" />
- <stop
- id="stop39143"
- style="stop-color:#ffffff;stop-opacity:0.73786408"
- offset="1" />
- </linearGradient>
- <linearGradient
- id="linearGradient39119">
- <stop
- id="stop39121"
- style="stop-color:#ffffff;stop-opacity:0.82905984"
- offset="0" />
- <stop
- id="stop39123"
- style="stop-color:#ffffff;stop-opacity:0"
- offset="1" />
- </linearGradient>
- <linearGradient
- id="linearGradient39106">
- <stop
- id="stop39108"
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0" />
- <stop
- id="stop39110"
- style="stop-color:#a8a8a8;stop-opacity:0"
- offset="1" />
- </linearGradient>
- <linearGradient
- id="linearGradient39094">
- <stop
- id="stop39096"
- style="stop-color:#000000;stop-opacity:1"
- offset="0" />
- <stop
- id="stop39098"
- style="stop-color:#333333;stop-opacity:1"
- offset="1" />
- </linearGradient>
- <linearGradient
- id="linearGradient39062">
- <stop
- id="stop39064"
- style="stop-color:#252525;stop-opacity:1"
- offset="0" />
- <stop
- id="stop39086"
- style="stop-color:#515151;stop-opacity:1"
- offset="0.21101321" />
- <stop
- id="stop39088"
- style="stop-color:#878787;stop-opacity:1"
- offset="0.75" />
- <stop
- id="stop39090"
- style="stop-color:#6c6c6c;stop-opacity:1"
- offset="0.875" />
- <stop
- id="stop39066"
- style="stop-color:#1e1e1e;stop-opacity:1"
- offset="1" />
- </linearGradient>
- <linearGradient
- x1="4"
- y1="40"
- x2="124"
- y2="60"
- id="linearGradient39068"
- xlink:href="#linearGradient39062"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- cx="100.70589"
- cy="96"
- r="60"
- fx="158.07428"
- fy="95.718063"
- id="radialGradient39100"
- xlink:href="#linearGradient39094"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.7837903e-8,-1,0.99999999,-2.1864248e-6,-32.000004,164.7061)" />
- <radialGradient
- cx="100.44444"
- cy="34.363636"
- r="32"
- fx="83.18"
- fy="34.228985"
- id="radialGradient39104"
- xlink:href="#linearGradient39106"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(3.1472435e-6,1.0227273,-0.87499999,-9.5061964e-8,94.067865,-4.7272712)" />
- <radialGradient
- cx="75.999977"
- cy="-2.7730541"
- r="48"
- fx="55.266491"
- fy="-2.5338216"
- id="radialGradient39125"
- xlink:href="#linearGradient39119"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.83333324,-1.6666667,2.518705e-6,59.378243,-35.333302)" />
- <radialGradient
- cx="64.066589"
- cy="63.713329"
- r="60"
- fx="64.066589"
- fy="63.713329"
- id="radialGradient39131"
- xlink:href="#linearGradient39133"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.1333333,5.1768857e-8,5.2556881e-6,1.1666667,-8.6091298,-10.332226)" />
- <filter
- id="filter39153">
- <feGaussianBlur
- id="feGaussianBlur39155"
- stdDeviation="2.28"
- inkscape:collect="always" />
- </filter>
- <filter
- id="filter39159">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.68"
- id="feGaussianBlur39161" />
- </filter>
- </defs>
- <g
- id="layer1"
- style="display:inline">
- <path
- d="M 29,4 C 15.147058,4 4,15.14706 4,29 l 0,70 c 0,13.85294 11.147058,25 25,25 l 70,0 c 13.85294,0 25,-11.14706 25,-25 l 0,-70 C 124,15.14706 112.85294,4 99,4 L 29,4 z"
- id="path39151"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter39153)" />
- <path
- d="M 29,4 C 15.147058,4 4,15.14706 4,29 l 0,70 c 0,13.85294 11.147058,25 25,25 l 70,0 c 13.85294,0 25,-11.14706 25,-25 l 0,-70 C 124,15.14706 112.85294,4 99,4 L 29,4 z"
- id="path39157"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter39159)" />
- <rect
- width="120"
- height="120"
- ry="25.00531"
- x="4"
- y="0"
- id="rect2573"
- style="opacity:1;fill:url(#radialGradient39100);fill-opacity:1;stroke:none" />
- <path
- d="M 29,0 C 15.147058,0 4,11.14706 4,25 l 0,70 c 0,13.85294 11.147058,25 25,25 l 70,0 c 13.85294,0 25,-11.14706 25,-25 l 0,-70 C 124,11.14706 112.85294,0 99,0 L 29,0 z"
- id="path39127"
- style="opacity:0.20512821;fill:url(#radialGradient39131);fill-opacity:1;stroke:none" />
- <path
- d="m 44,68 40,0 12,40 c -20,7.27273 -44,7.27273 -64,0 L 44,68 z"
- id="path39102"
- style="opacity:0.53418801;fill:url(#radialGradient39104);fill-opacity:1;stroke:none" />
- <path
- d="M 25.339207,12 C 52,8 76,8 102.66079,12 107.83471,12 112,16.165286 112,21.339207 L 116,52 C 100,73.339207 28,73.339207 12,52 L 16,21.339207 C 16,16.165286 20.165286,12 25.339207,12 z"
- id="rect39116"
- style="opacity:0.92307691;fill:url(#radialGradient39125);fill-opacity:1;stroke:none" />
- <path
- d="M 29,8 C 15.147058,8 4,19.14706 4,33 l 0,70 c 0,13.85294 11.147058,25 25,25 l 70,0 c 13.85294,0 25,-11.14706 25,-25 l 0,-70 C 124,19.14706 112.85294,8 99,8 L 29,8 z"
- id="path39147"
- style="opacity:0.20512821;fill:#000000;fill-opacity:1;stroke:none" />
- <path
- d="M 29,0 C 15.147058,0 4,11.147058 4,25 l 0,70 c 0,13.85294 11.147058,25 25,25 l 70,0 c 13.85294,0 25,-11.14706 25,-25 l 0,-70 C 124,11.147058 112.85294,0 99,0 L 29,0 z m 0,4 70,0 c 11.70613,0 21,9.293869 21,21 l 0,70 c 0,11.70613 -9.29387,21 -21,21 l -70,0 C 17.293869,116 8,106.70613 8,95 L 8,25 C 8,13.293869 17.293869,4 29,4 z"
- id="rect39029"
- style="opacity:1;fill:url(#linearGradient39068);fill-opacity:1;stroke:none" />
- <path
- d="M 66.35081,74.771345 A 36,36 0 1 1 54.34964,35.777782"
- transform="matrix(-0.16680323,0.53082142,-0.53082142,-0.16680323,103.31027,53.117897)"
- id="path3351"
- style="opacity:1;fill:none;stroke:#ffffff;stroke-width:21.56673813;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- d="m 36,56 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
- transform="matrix(1.4851301,0,0,1.4851301,16.475837,-23.948973)"
- id="path3353"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none" />
- <path
- d="M 66.35081,74.771345 A 36,36 0 1 1 54.34964,35.777782"
- transform="matrix(-0.35033273,1.1148712,-1.1148712,-0.35033273,146.5624,46.88078)"
- id="path2622"
- style="opacity:1;fill:none;stroke:#ffffff;stroke-width:10.26852894;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </g>
-</svg>
diff --git a/wpa_supplicant/wpa_gui-qt4/icons_png.qrc b/wpa_supplicant/wpa_gui-qt4/icons_png.qrc
deleted file mode 100644
index 9a30b7f560ba..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/icons_png.qrc
+++ /dev/null
@@ -1,9 +0,0 @@
-<RCC>
- <qresource prefix="/icons" >
- <file alias="wpa_gui.png">icons/hicolor/16x16/apps/wpa_gui.png</file>
- <file alias="ap.png">icons/hicolor/32x32/apps/ap.png</file>
- <file alias="laptop.png">icons/hicolor/32x32/apps/laptop.png</file>
- <file alias="group.png">icons/hicolor/32x32/apps/group.png</file>
- <file alias="invitation.png">icons/hicolor/32x32/apps/invitation.png</file>
- </qresource>
-</RCC>
diff --git a/wpa_supplicant/wpa_gui-qt4/lang/.gitignore b/wpa_supplicant/wpa_gui-qt4/lang/.gitignore
deleted file mode 100644
index 8df47d550c7d..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/lang/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.qm
diff --git a/wpa_supplicant/wpa_gui-qt4/lang/wpa_gui_de.ts b/wpa_supplicant/wpa_gui-qt4/lang/wpa_gui_de.ts
deleted file mode 100644
index d7a9c89fa18a..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/lang/wpa_gui_de.ts
+++ /dev/null
@@ -1,1262 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.0" language="de_DE" sourcelanguage="en_US">
-<context>
- <name>AddInterface</name>
- <message>
- <location filename="../addinterface.cpp" line="38"/>
- <source>Select network interface to add</source>
- <translation>Wähle die Netzwerkschnittstelle zum hinzufügen aus</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="47"/>
- <source>driver</source>
- <translation>Treiber</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="48"/>
- <source>interface</source>
- <translation>Schnittstelle</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="49"/>
- <source>description</source>
- <translation>Beschreibung</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="221"/>
- <source>Add interface command could not be completed.</source>
- <translation>Das Schnittstellen hinzufügen Kommando konnte nicht abgeschlossen werden.</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="229"/>
- <source>Failed to add the interface.</source>
- <translation>Fehler beim hinzufügen der Schnittstelle.</translation>
- </message>
- <message>
- <location filename="../addinterface.cpp" line="238"/>
- <source>Failed to add the interface into registry.</source>
- <translation>Fehler beim hinzufügen der Schnittstelle in die Registry.</translation>
- </message>
-</context>
-<context>
- <name>ErrorMsg</name>
- <message>
- <location filename="../wpagui.cpp" line="1621"/>
- <source>wpa_gui error</source>
- <translation>wpa_gui Fehler</translation>
- </message>
-</context>
-<context>
- <name>EventHistory</name>
- <message>
- <location filename="../eventhistory.ui" line="13"/>
- <source>Event history</source>
- <translation>Ereignis Historie</translation>
- </message>
- <message>
- <location filename="../eventhistory.ui" line="48"/>
- <source>Close</source>
- <translation>Schließen</translation>
- </message>
-</context>
-<context>
- <name>EventListModel</name>
- <message>
- <location filename="../eventhistory.cpp" line="62"/>
- <source>Timestamp</source>
- <translation>Zeit</translation>
- </message>
- <message>
- <location filename="../eventhistory.cpp" line="64"/>
- <source>Message</source>
- <translation>Meldung</translation>
- </message>
-</context>
-<context>
- <name>NetworkConfig</name>
- <message>
- <location filename="../networkconfig.ui" line="13"/>
- <source>NetworkConfig</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="19"/>
- <source>Cancel</source>
- <translation>Abbrechen</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="35"/>
- <source>SSID</source>
- <translation>SSID</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="42"/>
- <source>Network name (Service Set IDentifier)</source>
- <translation>Netzwerkname (Service Set IDentifier)</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="52"/>
- <source>Authentication</source>
- <translation>Authentifizierung</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="60"/>
- <source>Plaintext (open / no authentication)</source>
- <translation>Plaintext (offen / keine Authentifizierung)</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="65"/>
- <source>Static WEP (no authentication)</source>
- <translation>Static WEP (keine Authentifizierung)</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="70"/>
- <source>Static WEP (Shared Key authentication)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="75"/>
- <source>IEEE 802.1X</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="80"/>
- <source>WPA-Personal (PSK)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="85"/>
- <source>WPA-Enterprise (EAP)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="90"/>
- <source>WPA2-Personal (PSK)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="95"/>
- <source>WPA2-Enterprise (EAP)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="103"/>
- <source>Encryption</source>
- <translation>Verschlüsselung</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="111"/>
- <source>None</source>
- <translation>Keine</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="116"/>
- <source>WEP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="121"/>
- <source>TKIP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="126"/>
- <source>CCMP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="134"/>
- <source>PSK</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="144"/>
- <source>WPA/WPA2 pre-shared key or passphrase</source>
- <translation>WPA/WPA2 Pre-Shared Key oder Passphrase</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="157"/>
- <source>EAP method</source>
- <translation>EAP Verfahren</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="171"/>
- <source>Identity</source>
- <translation>Identität</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="181"/>
- <source>Username/Identity for EAP methods</source>
- <translation>Nutzername/Identitär für die EAP Verfahren</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="188"/>
- <source>Password</source>
- <translation>Passwort</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="198"/>
- <source>Password for EAP methods</source>
- <translation>Passwort für die EAP Verfahren</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="208"/>
- <source>CA certificate</source>
- <translation>CA Zertifikat</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="225"/>
- <source>WEP keys</source>
- <translation>WEP Schlüssel</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="234"/>
- <source>key 0</source>
- <translation>Schlüssel 0</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="244"/>
- <source>key 1</source>
- <translation>Schlüssel 1</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="254"/>
- <source>key 3</source>
- <translation>Schlüssel 3</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="264"/>
- <source>key 2</source>
- <translation>Schlüssel 2</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="305"/>
- <source>Optional Settings</source>
- <translation>Optionale Einstellungen</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="311"/>
- <source>Network Identification String</source>
- <translation>Netzwerk Indentifikations Zeichenfolge</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="318"/>
- <source>Network Priority</source>
- <translation>Netzwerk Priorität</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="331"/>
- <source>IDString</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="338"/>
- <source>Priority</source>
- <translation>Priorität</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="345"/>
- <source>Inner auth</source>
- <translation>Geheime Auth</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="365"/>
- <source>Add</source>
- <translation>Hinzufügen</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="375"/>
- <source>Remove</source>
- <translation>Entfernen</translation>
- </message>
- <message>
- <location filename="../networkconfig.ui" line="398"/>
- <source>WPS</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="202"/>
- <source>WPA Pre-Shared Key Error</source>
- <translation>WPA Pre Shared Key Fehler</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="203"/>
- <source>WPA-PSK requires a passphrase of 8 to 63 characters
-or 64 hex digit PSK</source>
- <translation>WPA PSK benötigt ein Passphrase mit 8 bis 63 Zeichen
-oder 64 hexadezimal stelligen PSK</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="215"/>
- <source>Network ID Error</source>
- <translation>Netzwerk ID Fehler</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="216"/>
- <source>Network ID String contains non-word characters.
-It must be a simple string, without spaces, containing
-only characters in this range: [A-Za-z0-9_-]
-</source>
- <translation>Netzwerk ID Zeichnfolge beinhaltet ungültige Zeichen.
-Es muss eine einfache Zeichnfolge aus [A-Za-z0-9_] ohne
-Leerzeichen sein
-</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="237"/>
- <source>Failed to add network to wpa_supplicant
-configuration.</source>
- <translation>Hinzufügen des Netzwerks in die wpa_supplicant
-Konfiguration fehlgeschlagen.</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="414"/>
- <source>Failed to enable network in wpa_supplicant
-configuration.</source>
- <translation>Aktivieren des Netzwerks in der wpa_supplicant
-Konfiguration fehlgeschlagen.</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="802"/>
- <source>This will permanently remove the network
-from the configuration. Do you really want
-to remove this network?</source>
- <translation>Dies wird das Netzwerk permanent aus
-der Konfiguration entfernen. Möchtest du
-das Netzwerk wirklich entfernen?</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="805"/>
- <source>Yes</source>
- <translation>Ja</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="805"/>
- <source>No</source>
- <translation>Nein</translation>
- </message>
- <message>
- <location filename="../networkconfig.cpp" line="813"/>
- <source>Failed to remove network from wpa_supplicant
-configuration.</source>
- <translation>Entfernen des Netzwerks aus der wpa_supplicant
-Konfiguration fehlgeschlagen.</translation>
- </message>
-</context>
-<context>
- <name>Peers</name>
- <message>
- <location filename="../peers.ui" line="14"/>
- <source>Peers</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="107"/>
- <source>Associated station</source>
- <translation>Verbundene Stationen</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="110"/>
- <source>AP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="113"/>
- <source>WPS AP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="116"/>
- <source>WPS PIN needed</source>
- <translation>WPS PIN wird benötigt</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="119"/>
- <source>ER: WPS AP</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="122"/>
- <source>ER: WPS AP (Unconfigured)</source>
- <translation>ER: WPS AP (nicht konfiguriert)</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="125"/>
- <source>ER: WPS Enrollee</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="128"/>
- <source>WPS Enrollee</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="159"/>
- <source>Enter WPS PIN</source>
- <translation>WPS PIN Eingabe</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="164"/>
- <source>Connect (PBC)</source>
- <translation>Verbinden (PBC)</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="172"/>
- <source>Enroll (PBC)</source>
- <translation>Anmelden (PBC)</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="177"/>
- <source>Learn Configuration</source>
- <translation>Konfiguration lernen</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="181"/>
- <source>Properties</source>
- <translation>Eigenschaften</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="184"/>
- <source>Refresh</source>
- <translation>Aktualisieren</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="205"/>
- <source>PIN:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="206"/>
- <source>PIN for </source>
- <translation>Pin für </translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="227"/>
- <source>Failed to set the WPS PIN.</source>
- <translation>Setzten des WPS PIN fehlgeschlagen.</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="815"/>
- <source>Peer Properties</source>
- <translation>Peer Eigenschaften</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="820"/>
- <source>Name: </source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="827"/>
- <source>Address: </source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="831"/>
- <source>UUID: </source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="835"/>
- <source>Primary Device Type: </source>
- <translation>Primärer Geräte Typ: </translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="840"/>
- <source>SSID: </source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="845"/>
- <source>Configuration Methods: </source>
- <translation>Konfigurationsverfahren: </translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="847"/>
- <source>[USBA]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="849"/>
- <source>[Ethernet]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="851"/>
- <source>[Label]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="853"/>
- <source>[Display]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="855"/>
- <source>[Ext. NFC Token]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="857"/>
- <source>[Int. NFC Token]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="859"/>
- <source>[NFC Interface]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="861"/>
- <source>[Push Button]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="863"/>
- <source>[Keypad]</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="869"/>
- <source>Device Password ID: </source>
- <translation>Geräte Passwort ID: </translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="872"/>
- <source> (Default PIN)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="875"/>
- <source> (User-specified PIN)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="878"/>
- <source> (Machine-specified PIN)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="881"/>
- <source> (Rekey)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="884"/>
- <source> (Push Button)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="887"/>
- <source> (Registrar-specified)</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="924"/>
- <source>Failed to start WPS PBC.</source>
- <translation>Starten von WPS PBC fehlgeschlagen.</translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="937"/>
- <source>AP PIN:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="938"/>
- <source>AP PIN for </source>
- <translation>AP PIN für </translation>
- </message>
- <message>
- <location filename="../peers.cpp" line="953"/>
- <source>Failed to start learning AP configuration.</source>
- <translation>Fehler beim erkennen der AP Konfiguration.</translation>
- </message>
-</context>
-<context>
- <name>ScanResults</name>
- <message>
- <location filename="../scanresults.ui" line="13"/>
- <source>Scan results</source>
- <translation>Scan Ergebnisse</translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="32"/>
- <source>SSID</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="37"/>
- <source>BSSID</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="42"/>
- <source>frequency</source>
- <translation>Frequenz</translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="47"/>
- <source>signal</source>
- <translation>Signal</translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="52"/>
- <source>flags</source>
- <translation>Flags</translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="75"/>
- <source>Scan</source>
- <translation>Scannen</translation>
- </message>
- <message>
- <location filename="../scanresults.ui" line="82"/>
- <source>Close</source>
- <translation>Schließen</translation>
- </message>
-</context>
-<context>
- <name>UserDataRequest</name>
- <message>
- <location filename="../userdatarequest.ui" line="16"/>
- <source>Authentication credentials required</source>
- <translation>Authentifzierungs Beglaubigung nötig</translation>
- </message>
- <message>
- <location filename="../userdatarequest.ui" line="77"/>
- <source>&amp;OK</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../userdatarequest.ui" line="93"/>
- <source>&amp;Cancel</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../userdatarequest.cpp" line="67"/>
- <source>Password: </source>
- <translation>Passwort: </translation>
- </message>
- <message>
- <location filename="../userdatarequest.cpp" line="70"/>
- <source>New password: </source>
- <translation>Neues Passwort: </translation>
- </message>
- <message>
- <location filename="../userdatarequest.cpp" line="73"/>
- <source>Identity: </source>
- <translation>Identität: </translation>
- </message>
- <message>
- <location filename="../userdatarequest.cpp" line="75"/>
- <source>Private key passphrase: </source>
- <translation>Privater Key Passphrase: </translation>
- </message>
-</context>
-<context>
- <name>WpaGui</name>
- <message>
- <location filename="../wpagui.ui" line="13"/>
- <source>wpa_gui</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="24"/>
- <source>Adapter:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="34"/>
- <source>Network:</source>
- <translation>Netzwerk:</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="48"/>
- <source>Current Status</source>
- <translation>Aktueller Status</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="63"/>
- <location filename="../wpagui.ui" line="300"/>
- <source>Status:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="70"/>
- <source>Last message:</source>
- <translation>Letzte Meldung:</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="77"/>
- <source>Authentication:</source>
- <translation>Authentifizierung:</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="84"/>
- <source>Encryption:</source>
- <translation>Verschlüsselung:</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="91"/>
- <source>SSID:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="98"/>
- <source>BSSID:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="105"/>
- <source>IP address:</source>
- <translation>IP Adresse:</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="177"/>
- <source>Connect</source>
- <translation>Verbinden</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="184"/>
- <source>Disconnect</source>
- <translation>Trennen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="191"/>
- <location filename="../wpagui.ui" line="286"/>
- <source>Scan</source>
- <translation>Scannen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="212"/>
- <source>Manage Networks</source>
- <translation>Netzwerke verwalten</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="238"/>
- <source>Enabled</source>
- <translation>Aktiviert</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="245"/>
- <source>Edit</source>
- <translation>Bearbeiten</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="252"/>
- <source>Remove</source>
- <translation>Entfernen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="272"/>
- <source>Disabled</source>
- <translation>Deaktiviert</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="279"/>
- <source>Add</source>
- <translation>Hinzufügen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="294"/>
- <source>WPS</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="314"/>
- <source>PBC - push button</source>
- <translation>PBC - Taste</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="321"/>
- <source>Generate PIN</source>
- <translation>PIN erzeugen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="328"/>
- <source>PIN:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="348"/>
- <source>Use AP PIN</source>
- <translation>AP PIN verwenden</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="355"/>
- <source>AP PIN:</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="390"/>
- <source>&amp;File</source>
- <translation>&amp;Datei</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="401"/>
- <source>&amp;Network</source>
- <translation>&amp;Netzwerk</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="413"/>
- <source>&amp;Help</source>
- <translation>&amp;Hilfe</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="426"/>
- <source>Event &amp;History</source>
- <translation>Ereignis &amp;Historie</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="431"/>
- <source>&amp;Save Configuration</source>
- <translation>Konfiguration &amp;Speichern</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="434"/>
- <source>Ctrl+S</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="439"/>
- <source>E&amp;xit</source>
- <translation>&amp;Beenden</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="442"/>
- <source>Ctrl+Q</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="447"/>
- <source>&amp;Add</source>
- <translation>&amp;Hinzufügen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="452"/>
- <source>&amp;Edit</source>
- <translation>&amp;Bearbeiten</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="457"/>
- <source>&amp;Remove</source>
- <translation>&amp;Entfernen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="462"/>
- <source>E&amp;nable All</source>
- <translation>Alle &amp;aktivieren</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="467"/>
- <source>&amp;Disable All</source>
- <translation>Alle &amp;deaktivieren</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="472"/>
- <source>Re&amp;move All</source>
- <translation>Alle &amp;entfernen</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="480"/>
- <source>&amp;Contents...</source>
- <translation>&amp;Inhalt...</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="488"/>
- <source>&amp;Index...</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="493"/>
- <source>&amp;About</source>
- <translation>&amp;Ãœber</translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="501"/>
- <source>&amp;Wi-Fi Protected Setup</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.ui" line="506"/>
- <source>&amp;Peers</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="53"/>
- <source>Stop Service</source>
- <translation>Dienst stoppen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="58"/>
- <source>Start Service</source>
- <translation>Dienst starten</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="67"/>
- <source>Add Interface</source>
- <translation>Schnittstelle hinzufügen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="167"/>
- <source>connecting to wpa_supplicant</source>
- <translation>Verbindungsaufbau zu wpa_supplicant</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="343"/>
- <source>wpa_supplicant service is not running.
-Do you want to start it?</source>
- <translation>wpa_supplicant ist nicht gestartet.
-Möchtest du ihn starten?</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="466"/>
- <source>Disconnected</source>
- <translation>Getrennt</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="468"/>
- <source>Inactive</source>
- <translation>Inaktiv</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="470"/>
- <source>Scanning</source>
- <translation>Scannen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="472"/>
- <source>Authenticating</source>
- <translation>Authentifizieren</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="474"/>
- <source>Associating</source>
- <translation>Assoziieren</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="476"/>
- <source>Associated</source>
- <translation>Assoziiert</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="478"/>
- <source>4-Way Handshake</source>
- <translation>4-Wege Handshake</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="480"/>
- <source>Group Handshake</source>
- <translation>Gruppen Handshake</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="482"/>
- <source>Completed</source>
- <translation>Abgeschlossen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="484"/>
- <source>Unknown</source>
- <translation>Unbekannt</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="497"/>
- <source>Could not get status from wpa_supplicant</source>
- <translation>Status konnte nicht von wpa_supplicant abgerufen werden</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="512"/>
- <source>No network interfaces in use.
-Would you like to add one?</source>
- <translation>Es ist keine Netzwerkschnittstelle in verwendung.
-Möchtest du eine hinzufügen?</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="682"/>
- <location filename="../wpagui.cpp" line="974"/>
- <location filename="../wpagui.cpp" line="1039"/>
- <location filename="../wpagui.cpp" line="1117"/>
- <source>Select any network</source>
- <translation>Wähle beliebiges Netzwerk</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="883"/>
- <source>Disconnected from network.</source>
- <translation>Getrennt vom Netzwerk.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="886"/>
- <source>Connection to network established.</source>
- <translation>Verbindung zum Netzwerk wurde aufgebaut.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="890"/>
- <location filename="../wpagui.cpp" line="1523"/>
- <source>WPS AP in active PBC mode found</source>
- <translation>WPS AP im aktiven PBC Modus gefunden</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="894"/>
- <source>Press the PBC button on the screen to start registration</source>
- <translation>Drücke den PBC Knopf auf dem Bildschirm um die Registrierung zu starten</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="897"/>
- <source>WPS AP with recently selected registrar</source>
- <translation>WPS AP mit kürzlich ausgewähltem Registrator</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="903"/>
- <source>WPS AP detected</source>
- <translation>WPS AP erkannt</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="905"/>
- <source>PBC mode overlap detected</source>
- <translation>PBC Modus Overlap erkannt</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="906"/>
- <source>More than one AP is currently in active WPS PBC mode. Wait couple of minutes and try again</source>
- <translation>Mehr als ein AP ist momentan im aktiven WPS PBC Modus. Versuch es in ein paar Minuten nochmal</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="911"/>
- <source>Network configuration received</source>
- <translation>Netzwerk Konfiguration empfangen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="915"/>
- <source>Registration started</source>
- <translation>Registrierung gestartet</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="917"/>
- <source>Registrar does not yet know PIN</source>
- <translation>Registrator kennt den PIN noch nicht</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="919"/>
- <source>Registration failed</source>
- <translation>Registrierung fehlgeschlagen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="921"/>
- <source>Registration succeeded</source>
- <translation>Registrierung erfolgreich</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1069"/>
- <location filename="../wpagui.cpp" line="1138"/>
- <source>No Networks</source>
- <translation>Keine Netzwerke</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1070"/>
- <source>There are no networks to edit.
-</source>
- <translation>Keine Netzwerke zum bearbeiten.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1081"/>
- <location filename="../wpagui.cpp" line="1151"/>
- <source>Select A Network</source>
- <translation>Wähle ein Netzwerk</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1082"/>
- <source>Select a network from the list to edit it.
-</source>
- <translation>Wähle ein Netzwerk aus der Liste zum bearbeiten.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1139"/>
- <source>There are no networks to remove.
-</source>
- <translation>Es sind keine Netzwerke zum entfernen vorhanden.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1152"/>
- <source>Select a network from the list to remove it.
-</source>
- <translation>Wähle ein Netzwerk aus der Liste zum entfernen.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1264"/>
- <source>Failed to save configuration</source>
- <translation>Speichern der Konfiguration fehlgeschlagen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1265"/>
- <source>The configuration could not be saved.
-
-The update_config=1 configuration option
-must be used for configuration saving to
-be permitted.
-</source>
- <translation>Die Konfiguration konnte nicht gespeichert werden.
-
-Die Einstellung update_config=1 muss gesetzt sein,
-damit Konfigurationen gespeichert werden können.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1272"/>
- <source>Saved configuration</source>
- <translation>Konfiguration gespeichert</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1273"/>
- <source>The current configuration was saved.
-</source>
- <translation>Die aktuelle Konfiguration wurde gespeichert.
-</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1293"/>
- <source> - wpa_supplicant user interface</source>
- <translation> - wpa_supplicant Benutzerschnittstelle</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1307"/>
- <source>&amp;Disconnect</source>
- <translation>&amp;Trennen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1308"/>
- <source>Re&amp;connect</source>
- <translation>&amp;Wiederverbinden</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1317"/>
- <source>&amp;Event History</source>
- <translation>&amp;Ereignis Historie</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1318"/>
- <source>Scan &amp;Results</source>
- <translation>Scan E&amp;rgebnisse</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1319"/>
- <source>S&amp;tatus</source>
- <translation></translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1328"/>
- <source>&amp;Show Window</source>
- <translation>&amp;Fenster anzeigen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1329"/>
- <source>&amp;Hide Window</source>
- <translation>&amp;Fenster ausblenden</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1330"/>
- <source>&amp;Quit</source>
- <translation>&amp;Beenden</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1462"/>
- <source> will keep running in the system tray.</source>
- <translation> wird weiterhin in der System Ablage laufen.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1466"/>
- <source> systray</source>
- <translation>System Ablage</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1467"/>
- <source>The program will keep running in the system tray.</source>
- <translation>Das Programm wird weiterhin in der System Ablage laufen.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1524"/>
- <source>Press the push button on the AP to start the PBC mode.</source>
- <translation>Drücke die Taste am AP um den PBC Modus zu starten.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1527"/>
- <source>If you have not yet done so, press the push button on the AP to start the PBC mode.</source>
- <translation>Wenn Sie es noch nicht getan haben, so drücken Sie die Taste am AP um den PBC Modus zu starten.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1531"/>
- <location filename="../wpagui.cpp" line="1551"/>
- <source>Waiting for Registrar</source>
- <translation>Warte auf Registrator</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1548"/>
- <source>Enter the generated PIN into the Registrar (either the internal one in the AP or an external one).</source>
- <translation>Geben Sie den generierten PIN in der Registrierungsstelle ein (entweder der interne oder der externe im AP).</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1561"/>
- <source>WPS AP selected from scan results</source>
- <translation>WPS AP ausgewählt aus Scan Ergebnissen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1562"/>
- <source>If you want to use an AP device PIN, e.g., from a label in the device, enter the eight digit AP PIN and click Use AP PIN button.</source>
- <translation>Wenn Sie einen AP Geräte PIN verwenden möchten, z.B.: von einem Aufkleber am Gerät, geben Sie denn acht stelligen AP PIN ein und klicken Sie auf den AP PIN Knopf.</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1583"/>
- <source>Waiting for AP/Enrollee</source>
- <translation>Warte auf AP/Bewerber</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1591"/>
- <source>Connected to the network</source>
- <translation>Verbunden zum Netzwerk</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1592"/>
- <source>Stopped</source>
- <translation>Gestoppt</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1651"/>
- <location filename="../wpagui.cpp" line="1679"/>
- <source>OpenSCManager failed</source>
- <translation>OpenSCManager fehlgeschlagen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1657"/>
- <location filename="../wpagui.cpp" line="1685"/>
- <source>OpenService failed</source>
- <translation>OpenService fehlgeschlagen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1663"/>
- <source>Failed to start wpa_supplicant service</source>
- <translation>Starten des wpa_supplicant Dienstes fehlgeschlagen</translation>
- </message>
- <message>
- <location filename="../wpagui.cpp" line="1691"/>
- <source>Failed to stop wpa_supplicant service</source>
- <translation>Stoppen des wpa_supplicant Dienstes fehlgeschlagen</translation>
- </message>
- <message>
- <source>OpenSCManager failed: %d
-</source>
- <translation type="obsolete">OpenSCManager fehlgeschlagen: %d
-</translation>
- </message>
- <message>
- <source>OpenService failed: %d
-
-</source>
- <translation type="obsolete">OpenService fehlgeschlagen: %d
-
-</translation>
- </message>
-</context>
-</TS>
diff --git a/wpa_supplicant/wpa_gui-qt4/main.cpp b/wpa_supplicant/wpa_gui-qt4/main.cpp
deleted file mode 100644
index bbd45c6e1d28..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/main.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * wpa_gui - Application startup
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <winsock.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-#include <QApplication>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QTranslator>
-#include "wpagui.h"
-
-WpaGuiApp::WpaGuiApp(int &argc, char **argv) :
- QApplication(argc, argv),
- argc(argc),
- argv(argv)
-{
- w = NULL;
-}
-
-#if !defined(QT_NO_SESSIONMANAGER) && QT_VERSION < 0x050000
-void WpaGuiApp::saveState(QSessionManager &manager)
-{
- QApplication::saveState(manager);
- w->saveState();
-}
-#endif
-
-
-int main(int argc, char *argv[])
-{
- WpaGuiApp app(argc, argv);
- QTranslator translator;
- QString locale;
- QString resourceDir;
- int ret;
-
- locale = QLocale::system().name();
- resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
- if (!translator.load("wpa_gui_" + locale, resourceDir))
- translator.load("wpa_gui_" + locale, "lang");
- app.installTranslator(&translator);
-
- WpaGui w(&app);
-
-#ifdef CONFIG_NATIVE_WINDOWS
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
- /* printf("Could not find a usable WinSock.dll\n"); */
- return -1;
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- app.w = &w;
-
- ret = app.exec();
-
-#ifdef CONFIG_NATIVE_WINDOWS
- WSACleanup();
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- return ret;
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp b/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
deleted file mode 100644
index 2727318bcd5c..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * wpa_gui - NetworkConfig class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-#include <QMessageBox>
-
-#include "networkconfig.h"
-#include "wpagui.h"
-
-enum {
- AUTH_NONE_OPEN,
- AUTH_NONE_WEP,
- AUTH_NONE_WEP_SHARED,
- AUTH_IEEE8021X,
- AUTH_WPA_PSK,
- AUTH_WPA_EAP,
- AUTH_WPA2_PSK,
- AUTH_WPA2_EAP
-};
-
-#define WPA_GUI_KEY_DATA "[key is configured]"
-
-
-NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool,
- Qt::WindowFlags)
- : QDialog(parent)
-{
- setupUi(this);
-
- encrSelect->setEnabled(false);
- connect(authSelect, SIGNAL(activated(int)), this,
- SLOT(authChanged(int)));
- connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
- connect(addButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
- connect(encrSelect, SIGNAL(activated(const QString &)), this,
- SLOT(encrChanged(const QString &)));
- connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
- connect(eapSelect, SIGNAL(activated(int)), this,
- SLOT(eapChanged(int)));
- connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps()));
-
- wpagui = NULL;
- new_network = false;
-}
-
-
-NetworkConfig::~NetworkConfig()
-{
-}
-
-
-void NetworkConfig::languageChange()
-{
- retranslateUi(this);
-}
-
-
-void NetworkConfig::paramsFromScanResults(QTreeWidgetItem *sel)
-{
- new_network = true;
-
- /* SSID BSSID frequency signal flags */
- setWindowTitle(sel->text(0));
- ssidEdit->setText(sel->text(0));
-
- QString flags = sel->text(4);
- int auth, encr = 0;
- if (flags.indexOf("[WPA2-EAP") >= 0)
- auth = AUTH_WPA2_EAP;
- else if (flags.indexOf("[WPA-EAP") >= 0)
- auth = AUTH_WPA_EAP;
- else if (flags.indexOf("[WPA2-PSK") >= 0)
- auth = AUTH_WPA2_PSK;
- else if (flags.indexOf("[WPA-PSK") >= 0)
- auth = AUTH_WPA_PSK;
- else
- auth = AUTH_NONE_OPEN;
-
- if (flags.indexOf("-CCMP") >= 0)
- encr = 1;
- else if (flags.indexOf("-TKIP") >= 0)
- encr = 0;
- else if (flags.indexOf("WEP") >= 0) {
- encr = 1;
- if (auth == AUTH_NONE_OPEN)
- auth = AUTH_NONE_WEP;
- } else
- encr = 0;
-
- authSelect->setCurrentIndex(auth);
- authChanged(auth);
- encrSelect->setCurrentIndex(encr);
-
- wepEnabled(auth == AUTH_NONE_WEP);
-
- getEapCapa();
-
- if (flags.indexOf("[WPS") >= 0)
- useWpsButton->setEnabled(true);
- bssid = sel->text(1);
-}
-
-
-void NetworkConfig::authChanged(int sel)
-{
- encrSelect->setEnabled(sel != AUTH_NONE_OPEN && sel != AUTH_NONE_WEP &&
- sel != AUTH_NONE_WEP_SHARED);
- pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
- bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
- sel == AUTH_WPA2_EAP;
- eapSelect->setEnabled(eap);
- identityEdit->setEnabled(eap);
- passwordEdit->setEnabled(eap);
- cacertEdit->setEnabled(eap);
- phase2Select->setEnabled(eap);
- if (eap)
- eapChanged(eapSelect->currentIndex());
-
- while (encrSelect->count())
- encrSelect->removeItem(0);
-
- if (sel == AUTH_NONE_OPEN || sel == AUTH_NONE_WEP ||
- sel == AUTH_NONE_WEP_SHARED || sel == AUTH_IEEE8021X) {
- encrSelect->addItem("None");
- encrSelect->addItem("WEP");
- encrSelect->setCurrentIndex(sel == AUTH_NONE_OPEN ? 0 : 1);
- } else {
- encrSelect->addItem("TKIP");
- encrSelect->addItem("CCMP");
- encrSelect->setCurrentIndex((sel == AUTH_WPA2_PSK ||
- sel == AUTH_WPA2_EAP) ? 1 : 0);
- }
-
- wepEnabled(sel == AUTH_NONE_WEP || sel == AUTH_NONE_WEP_SHARED);
-}
-
-
-void NetworkConfig::eapChanged(int sel)
-{
- QString prev_val = phase2Select->currentText();
- while (phase2Select->count())
- phase2Select->removeItem(0);
-
- QStringList inner;
- inner << "PEAP" << "TTLS" << "FAST";
- if (!inner.contains(eapSelect->itemText(sel)))
- return;
-
- phase2Select->addItem("[ any ]");
-
- /* Add special cases based on outer method */
- if (eapSelect->currentText().compare("TTLS") == 0) {
- phase2Select->addItem("PAP");
- phase2Select->addItem("CHAP");
- phase2Select->addItem("MSCHAP");
- phase2Select->addItem("MSCHAPv2");
- } else if (eapSelect->currentText().compare("FAST") == 0)
- phase2Select->addItem("GTC(auth) + MSCHAPv2(prov)");
-
- /* Add all enabled EAP methods that can be used in the tunnel */
- int i;
- QStringList allowed;
- allowed << "MSCHAPV2" << "MD5" << "GTC" << "TLS" << "OTP" << "SIM"
- << "AKA";
- for (i = 0; i < eapSelect->count(); i++) {
- if (allowed.contains(eapSelect->itemText(i))) {
- phase2Select->addItem("EAP-" + eapSelect->itemText(i));
- }
- }
-
- for (i = 0; i < phase2Select->count(); i++) {
- if (phase2Select->itemText(i).compare(prev_val) == 0) {
- phase2Select->setCurrentIndex(i);
- break;
- }
- }
-}
-
-
-void NetworkConfig::addNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
- int id;
- int psklen = pskEdit->text().length();
- int auth = authSelect->currentIndex();
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
- if (psklen < 8 || psklen > 64) {
- QMessageBox::warning(
- this,
- tr("WPA Pre-Shared Key Error"),
- tr("WPA-PSK requires a passphrase of 8 to 63 "
- "characters\n"
- "or 64 hex digit PSK"));
- pskEdit->setFocus();
- return;
- }
- }
-
- if (idstrEdit->isEnabled() && !idstrEdit->text().isEmpty()) {
- QRegExp rx("^(\\w|-)+$");
- if (rx.indexIn(idstrEdit->text()) < 0) {
- QMessageBox::warning(
- this, tr("Network ID Error"),
- tr("Network ID String contains non-word "
- "characters.\n"
- "It must be a simple string, "
- "without spaces, containing\n"
- "only characters in this range: "
- "[A-Za-z0-9_-]\n"));
- idstrEdit->setFocus();
- return;
- }
- }
-
- if (wpagui == NULL)
- return;
-
- memset(reply, 0, sizeof(reply));
- reply_len = sizeof(reply) - 1;
-
- if (new_network) {
- wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
- if (reply[0] == 'F') {
- QMessageBox::warning(this, "wpa_gui",
- tr("Failed to add "
- "network to wpa_supplicant\n"
- "configuration."));
- return;
- }
- id = atoi(reply);
- } else
- id = edit_network_id;
-
- setNetworkParam(id, "ssid", ssidEdit->text().toLocal8Bit().constData(),
- true);
-
- const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
- switch (auth) {
- case AUTH_NONE_OPEN:
- case AUTH_NONE_WEP:
- case AUTH_NONE_WEP_SHARED:
- key_mgmt = "NONE";
- break;
- case AUTH_IEEE8021X:
- key_mgmt = "IEEE8021X";
- break;
- case AUTH_WPA_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA";
- break;
- case AUTH_WPA_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA";
- break;
- case AUTH_WPA2_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA2";
- break;
- case AUTH_WPA2_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA2";
- break;
- }
-
- if (auth == AUTH_NONE_WEP_SHARED)
- setNetworkParam(id, "auth_alg", "SHARED", false);
- else
- setNetworkParam(id, "auth_alg", "OPEN", false);
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
- auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
- int encr = encrSelect->currentIndex();
- if (encr == 0)
- pairwise = "TKIP";
- else
- pairwise = "CCMP";
- }
-
- if (proto)
- setNetworkParam(id, "proto", proto, false);
- if (key_mgmt)
- setNetworkParam(id, "key_mgmt", key_mgmt, false);
- if (pairwise) {
- setNetworkParam(id, "pairwise", pairwise, false);
- setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
- }
- if (pskEdit->isEnabled() &&
- strcmp(pskEdit->text().toLocal8Bit().constData(),
- WPA_GUI_KEY_DATA) != 0)
- setNetworkParam(id, "psk",
- pskEdit->text().toLocal8Bit().constData(),
- psklen != 64);
- if (eapSelect->isEnabled()) {
- const char *eap =
- eapSelect->currentText().toLocal8Bit().constData();
- setNetworkParam(id, "eap", eap, false);
- if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
- setNetworkParam(id, "pcsc", "", true);
- else
- setNetworkParam(id, "pcsc", "NULL", false);
- }
- if (phase2Select->isEnabled()) {
- QString eap = eapSelect->currentText();
- QString inner = phase2Select->currentText();
- char phase2[32];
- phase2[0] = '\0';
- if (eap.compare("PEAP") == 0) {
- if (inner.startsWith("EAP-"))
- snprintf(phase2, sizeof(phase2), "auth=%s",
- inner.right(inner.size() - 4).
- toLocal8Bit().constData());
- } else if (eap.compare("TTLS") == 0) {
- if (inner.startsWith("EAP-"))
- snprintf(phase2, sizeof(phase2), "autheap=%s",
- inner.right(inner.size() - 4).
- toLocal8Bit().constData());
- else
- snprintf(phase2, sizeof(phase2), "auth=%s",
- inner.toLocal8Bit().constData());
- } else if (eap.compare("FAST") == 0) {
- const char *provisioning = NULL;
- if (inner.startsWith("EAP-")) {
- snprintf(phase2, sizeof(phase2), "auth=%s",
- inner.right(inner.size() - 4).
- toLocal8Bit().constData());
- provisioning = "fast_provisioning=2";
- } else if (inner.compare("GTC(auth) + MSCHAPv2(prov)")
- == 0) {
- snprintf(phase2, sizeof(phase2),
- "auth=GTC auth=MSCHAPV2");
- provisioning = "fast_provisioning=1";
- } else
- provisioning = "fast_provisioning=3";
- if (provisioning) {
- char blob[32];
- setNetworkParam(id, "phase1", provisioning,
- true);
- snprintf(blob, sizeof(blob),
- "blob://fast-pac-%d", id);
- setNetworkParam(id, "pac_file", blob, true);
- }
- }
- if (phase2[0])
- setNetworkParam(id, "phase2", phase2, true);
- else
- setNetworkParam(id, "phase2", "NULL", false);
- } else
- setNetworkParam(id, "phase2", "NULL", false);
- if (identityEdit->isEnabled() && identityEdit->text().length() > 0)
- setNetworkParam(id, "identity",
- identityEdit->text().toLocal8Bit().constData(),
- true);
- else
- setNetworkParam(id, "identity", "NULL", false);
- if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
- strcmp(passwordEdit->text().toLocal8Bit().constData(),
- WPA_GUI_KEY_DATA) != 0)
- setNetworkParam(id, "password",
- passwordEdit->text().toLocal8Bit().constData(),
- true);
- else if (passwordEdit->text().length() == 0)
- setNetworkParam(id, "password", "NULL", false);
- if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0)
- setNetworkParam(id, "ca_cert",
- cacertEdit->text().toLocal8Bit().constData(),
- true);
- else
- setNetworkParam(id, "ca_cert", "NULL", false);
- writeWepKey(id, wep0Edit, 0);
- writeWepKey(id, wep1Edit, 1);
- writeWepKey(id, wep2Edit, 2);
- writeWepKey(id, wep3Edit, 3);
-
- if (wep0Radio->isEnabled() && wep0Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "0", false);
- else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "1", false);
- else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "2", false);
- else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "3", false);
-
- if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0)
- setNetworkParam(id, "id_str",
- idstrEdit->text().toLocal8Bit().constData(),
- true);
- else
- setNetworkParam(id, "id_str", "NULL", false);
-
- if (prioritySpinBox->isEnabled()) {
- QString prio;
- prio = prio.setNum(prioritySpinBox->value());
- setNetworkParam(id, "priority", prio.toLocal8Bit().constData(),
- false);
- }
-
- snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui",
- tr("Failed to enable "
- "network in wpa_supplicant\n"
- "configuration."));
- /* Network was added, so continue anyway */
- }
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
-
- close();
-}
-
-
-void NetworkConfig::setWpaGui(WpaGui *_wpagui)
-{
- wpagui = _wpagui;
-}
-
-
-int NetworkConfig::setNetworkParam(int id, const char *field,
- const char *value, bool quote)
-{
- char reply[10], cmd[256];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
- id, field, quote ? "\"" : "", value, quote ? "\"" : "");
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
-}
-
-
-void NetworkConfig::encrChanged(const QString &)
-{
-}
-
-
-void NetworkConfig::wepEnabled(bool enabled)
-{
- wep0Edit->setEnabled(enabled);
- wep1Edit->setEnabled(enabled);
- wep2Edit->setEnabled(enabled);
- wep3Edit->setEnabled(enabled);
- wep0Radio->setEnabled(enabled);
- wep1Radio->setEnabled(enabled);
- wep2Radio->setEnabled(enabled);
- wep3Radio->setEnabled(enabled);
-}
-
-
-void NetworkConfig::writeWepKey(int network_id, QLineEdit *edit, int id)
-{
- char buf[10];
- bool hex;
- const char *txt, *pos;
- size_t len;
-
- if (!edit->isEnabled() || edit->text().isEmpty())
- return;
-
- /*
- * Assume hex key if only hex characters are present and length matches
- * with 40, 104, or 128-bit key
- */
- txt = edit->text().toLocal8Bit().constData();
- if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
- return;
- len = strlen(txt);
- if (len == 0)
- return;
- pos = txt;
- hex = true;
- while (*pos) {
- if (!((*pos >= '0' && *pos <= '9') ||
- (*pos >= 'a' && *pos <= 'f') ||
- (*pos >= 'A' && *pos <= 'F'))) {
- hex = false;
- break;
- }
- pos++;
- }
- if (hex && len != 10 && len != 26 && len != 32)
- hex = false;
- snprintf(buf, sizeof(buf), "wep_key%d", id);
- setNetworkParam(network_id, buf, txt, !hex);
-}
-
-
-static int key_value_isset(const char *reply, size_t reply_len)
-{
- return reply_len > 0 && (reply_len < 4 || memcmp(reply, "FAIL", 4) != 0);
-}
-
-
-void NetworkConfig::paramsFromConfig(int network_id)
-{
- int i, res;
-
- edit_network_id = network_id;
- getEapCapa();
-
- char reply[1024], cmd[256], *pos;
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- ssidEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
- reply_len = sizeof(reply) - 1;
- int wpa = 0;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
- wpa = 2;
- else if (strstr(reply, "WPA"))
- wpa = 1;
- }
-
- int auth = AUTH_NONE_OPEN, encr = 0;
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "WPA-EAP"))
- auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
- else if (strstr(reply, "WPA-PSK"))
- auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
- else if (strstr(reply, "IEEE8021X")) {
- auth = AUTH_IEEE8021X;
- encr = 1;
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "CCMP") && auth != AUTH_NONE_OPEN &&
- auth != AUTH_NONE_WEP && auth != AUTH_NONE_WEP_SHARED)
- encr = 1;
- else if (strstr(reply, "TKIP"))
- encr = 0;
- else if (strstr(reply, "WEP"))
- encr = 1;
- else
- encr = 0;
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- pskEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- pskEdit->setText(WPA_GUI_KEY_DATA);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- identityEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- passwordEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- passwordEdit->setText(WPA_GUI_KEY_DATA);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- cacertEdit->setText(reply + 1);
- }
-
- enum { NO_INNER, PEAP_INNER, TTLS_INNER, FAST_INNER } eap = NO_INNER;
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 1) {
- reply[reply_len] = '\0';
- for (i = 0; i < eapSelect->count(); i++) {
- if (eapSelect->itemText(i).compare(reply) == 0) {
- eapSelect->setCurrentIndex(i);
- if (strcmp(reply, "PEAP") == 0)
- eap = PEAP_INNER;
- else if (strcmp(reply, "TTLS") == 0)
- eap = TTLS_INNER;
- else if (strcmp(reply, "FAST") == 0)
- eap = FAST_INNER;
- break;
- }
- }
- }
-
- if (eap != NO_INNER) {
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d phase2",
- network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 1) {
- reply[reply_len] = '\0';
- eapChanged(eapSelect->currentIndex());
- } else
- eap = NO_INNER;
- }
-
- char *val;
- val = reply + 1;
- while (*(val + 1))
- val++;
- if (*val == '"')
- *val = '\0';
-
- switch (eap) {
- case PEAP_INNER:
- if (strncmp(reply, "\"auth=", 6))
- break;
- val = reply + 2;
- memcpy(val, "EAP-", 4);
- break;
- case TTLS_INNER:
- if (strncmp(reply, "\"autheap=", 9) == 0) {
- val = reply + 5;
- memcpy(val, "EAP-", 4);
- } else if (strncmp(reply, "\"auth=", 6) == 0)
- val = reply + 6;
- break;
- case FAST_INNER:
- if (strncmp(reply, "\"auth=", 6))
- break;
- if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) {
- val = (char *) "GTC(auth) + MSCHAPv2(prov)";
- break;
- }
- val = reply + 2;
- memcpy(val, "EAP-", 4);
- break;
- case NO_INNER:
- break;
- }
-
- for (i = 0; i < phase2Select->count(); i++) {
- if (phase2Select->itemText(i).compare(val) == 0) {
- phase2Select->setCurrentIndex(i);
- break;
- }
- }
-
- for (i = 0; i < 4; i++) {
- QLineEdit *wepEdit;
- switch (i) {
- default:
- case 0:
- wepEdit = wep0Edit;
- break;
- case 1:
- wepEdit = wep1Edit;
- break;
- case 2:
- wepEdit = wep2Edit;
- break;
- case 3:
- wepEdit = wep3Edit;
- break;
- }
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d",
- network_id, i);
- reply_len = sizeof(reply) - 1;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (res >= 0 && reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
- if (auth == AUTH_NONE_OPEN)
- auth = AUTH_NONE_WEP;
- encr = 1;
- }
-
- wepEdit->setText(reply + 1);
- } else if (res >= 0 && key_value_isset(reply, reply_len)) {
- if (auth == AUTH_NONE_OPEN || auth == AUTH_IEEE8021X) {
- if (auth == AUTH_NONE_OPEN)
- auth = AUTH_NONE_WEP;
- encr = 1;
- }
- wepEdit->setText(WPA_GUI_KEY_DATA);
- }
- }
-
- if (auth == AUTH_NONE_WEP) {
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d auth_alg",
- network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strcmp(reply, "SHARED") == 0)
- auth = AUTH_NONE_WEP_SHARED;
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
- {
- reply[reply_len] = '\0';
- switch (atoi(reply)) {
- case 0:
- wep0Radio->setChecked(true);
- break;
- case 1:
- wep1Radio->setChecked(true);
- break;
- case 2:
- wep2Radio->setChecked(true);
- break;
- case 3:
- wep3Radio->setChecked(true);
- break;
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d id_str", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 &&
- reply_len >= 2 && reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- idstrEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d priority", network_id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1)
- {
- reply[reply_len] = '\0';
- prioritySpinBox->setValue(atoi(reply));
- }
-
- authSelect->setCurrentIndex(auth);
- authChanged(auth);
- encrSelect->setCurrentIndex(encr);
- wepEnabled(auth == AUTH_NONE_WEP || auth == AUTH_NONE_WEP_SHARED);
-
- removeButton->setEnabled(true);
- addButton->setText("Save");
-}
-
-
-void NetworkConfig::removeNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
-
- if (QMessageBox::information(
- this, "wpa_gui",
- tr("This will permanently remove the network\n"
- "from the configuration. Do you really want\n"
- "to remove this network?"),
- tr("Yes"), tr("No")) != 0)
- return;
-
- snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui",
- tr("Failed to remove network from "
- "wpa_supplicant\n"
- "configuration."));
- } else {
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
- }
-
- close();
-}
-
-
-void NetworkConfig::newNetwork()
-{
- new_network = true;
- getEapCapa();
-}
-
-
-void NetworkConfig::getEapCapa()
-{
- char reply[256];
- size_t reply_len;
-
- if (wpagui == NULL)
- return;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
-
- QString res(reply);
- QStringList types = res.split(QChar(' '));
- eapSelect->insertItems(-1, types);
-}
-
-
-void NetworkConfig::useWps()
-{
- if (wpagui == NULL)
- return;
- wpagui->setBssFromScan(bssid);
- wpagui->wpsDialog();
- close();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/networkconfig.h b/wpa_supplicant/wpa_gui-qt4/networkconfig.h
deleted file mode 100644
index fd09dec54318..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/networkconfig.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * wpa_gui - NetworkConfig class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef NETWORKCONFIG_H
-#define NETWORKCONFIG_H
-
-#include <QObject>
-#include "ui_networkconfig.h"
-
-class WpaGui;
-
-class NetworkConfig : public QDialog, public Ui::NetworkConfig
-{
- Q_OBJECT
-
-public:
- NetworkConfig(QWidget *parent = 0, const char *name = 0,
- bool modal = false, Qt::WindowFlags fl = 0);
- ~NetworkConfig();
-
- virtual void paramsFromScanResults(QTreeWidgetItem *sel);
- virtual void setWpaGui(WpaGui *_wpagui);
- virtual int setNetworkParam(int id, const char *field,
- const char *value, bool quote);
- virtual void paramsFromConfig(int network_id);
- virtual void newNetwork();
-
-public slots:
- virtual void authChanged(int sel);
- virtual void addNetwork();
- virtual void encrChanged(const QString &sel);
- virtual void writeWepKey(int network_id, QLineEdit *edit, int id);
- virtual void removeNetwork();
- virtual void eapChanged(int sel);
- virtual void useWps();
-
-protected slots:
- virtual void languageChange();
-
-private:
- WpaGui *wpagui;
- int edit_network_id;
- bool new_network;
- QString bssid;
-
- virtual void wepEnabled(bool enabled);
- virtual void getEapCapa();
-};
-
-#endif /* NETWORKCONFIG_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/networkconfig.ui b/wpa_supplicant/wpa_gui-qt4/networkconfig.ui
deleted file mode 100644
index 217a8ff58704..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/networkconfig.ui
+++ /dev/null
@@ -1,435 +0,0 @@
-<ui version="4.0" >
- <class>NetworkConfig</class>
- <widget class="QDialog" name="NetworkConfig" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>410</width>
- <height>534</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>NetworkConfig</string>
- </property>
- <layout class="QGridLayout" >
- <item row="1" column="3" >
- <widget class="QPushButton" name="cancelButton" >
- <property name="text" >
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="4" >
- <widget class="QFrame" name="frame9" >
- <property name="frameShape" >
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow" >
- <enum>QFrame::Plain</enum>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="ssidLabel" >
- <property name="text" >
- <string>SSID</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="ssidEdit" >
- <property name="toolTip" >
- <string>Network name (Service Set IDentifier)</string>
- </property>
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="authLabel" >
- <property name="text" >
- <string>Authentication</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QComboBox" name="authSelect" >
- <item>
- <property name="text" >
- <string>Plaintext (open / no authentication)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Static WEP (no authentication)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Static WEP (Shared Key authentication)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>IEEE 802.1X</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>WPA-Personal (PSK)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>WPA-Enterprise (EAP)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>WPA2-Personal (PSK)</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>WPA2-Enterprise (EAP)</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="encrLabel" >
- <property name="text" >
- <string>Encryption</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="QComboBox" name="encrSelect" >
- <item>
- <property name="text" >
- <string>None</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>WEP</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>TKIP</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>CCMP</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QLabel" name="pskLabel" >
- <property name="text" >
- <string>PSK</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1" >
- <widget class="QLineEdit" name="pskEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="toolTip" >
- <string>WPA/WPA2 pre-shared key or passphrase</string>
- </property>
- <property name="whatsThis" >
- <string/>
- </property>
- <property name="echoMode" >
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- <item row="4" column="0" >
- <widget class="QLabel" name="eapLabel" >
- <property name="text" >
- <string>EAP method</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1" >
- <widget class="QComboBox" name="eapSelect" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="5" column="0" >
- <widget class="QLabel" name="identityLabel" >
- <property name="text" >
- <string>Identity</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1" >
- <widget class="QLineEdit" name="identityEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="toolTip" >
- <string>Username/Identity for EAP methods</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0" >
- <widget class="QLabel" name="passwordLabel" >
- <property name="text" >
- <string>Password</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1" >
- <widget class="QLineEdit" name="passwordEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="toolTip" >
- <string>Password for EAP methods</string>
- </property>
- <property name="echoMode" >
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- <item row="7" column="0" >
- <widget class="QLabel" name="cacertLabel" >
- <property name="text" >
- <string>CA certificate</string>
- </property>
- </widget>
- </item>
- <item row="7" column="1" >
- <widget class="QLineEdit" name="cacertEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="8" column="0" colspan="2" >
- <widget class="QGroupBox" name="wepBox" >
- <property name="enabled" >
- <bool>true</bool>
- </property>
- <property name="title" >
- <string>WEP keys</string>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QRadioButton" name="wep0Radio" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>key 0</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QRadioButton" name="wep1Radio" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>key 1</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QRadioButton" name="wep3Radio" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>key 3</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QRadioButton" name="wep2Radio" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>key 2</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="wep0Edit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QLineEdit" name="wep1Edit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="QLineEdit" name="wep2Edit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="1" >
- <widget class="QLineEdit" name="wep3Edit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="9" column="0" colspan="2" >
- <widget class="QGroupBox" name="optionalSettingsBox" >
- <property name="enabled" >
- <bool>true</bool>
- </property>
- <property name="title" >
- <string>Optional Settings</string>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="1" >
- <widget class="QLineEdit" name="idstrEdit" >
- <property name="toolTip" >
- <string>Network Identification String</string>
- </property>
- </widget>
- </item>
- <item row="0" column="3" >
- <widget class="QSpinBox" name="prioritySpinBox" >
- <property name="toolTip" >
- <string>Network Priority</string>
- </property>
- <property name="maximum" >
- <number>10000</number>
- </property>
- <property name="singleStep" >
- <number>10</number>
- </property>
- </widget>
- </item>
- <item row="0" column="0" >
- <widget class="QLabel" name="idstrLabel" >
- <property name="text" >
- <string>IDString</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2" >
- <widget class="QLabel" name="priorityLabel" >
- <property name="text" >
- <string>Priority</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="phase2Label" >
- <property name="text" >
- <string>Inner auth</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QComboBox" name="phase2Select" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="addButton" >
- <property name="text" >
- <string>Add</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3" >
- <widget class="QPushButton" name="removeButton" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1" >
- <widget class="QPushButton" name="useWpsButton" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>WPS</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <tabstops>
- <tabstop>ssidEdit</tabstop>
- <tabstop>authSelect</tabstop>
- <tabstop>encrSelect</tabstop>
- <tabstop>pskEdit</tabstop>
- <tabstop>eapSelect</tabstop>
- <tabstop>identityEdit</tabstop>
- <tabstop>passwordEdit</tabstop>
- <tabstop>cacertEdit</tabstop>
- <tabstop>wep0Radio</tabstop>
- <tabstop>wep0Edit</tabstop>
- <tabstop>wep1Radio</tabstop>
- <tabstop>wep1Edit</tabstop>
- <tabstop>wep2Radio</tabstop>
- <tabstop>wep2Edit</tabstop>
- <tabstop>wep3Radio</tabstop>
- <tabstop>wep3Edit</tabstop>
- <tabstop>idstrEdit</tabstop>
- <tabstop>prioritySpinBox</tabstop>
- <tabstop>phase2Select</tabstop>
- <tabstop>addButton</tabstop>
- <tabstop>removeButton</tabstop>
- <tabstop>cancelButton</tabstop>
- </tabstops>
- <includes>
- <include location="global" >qtreewidget.h</include>
- </includes>
- <resources/>
- <connections/>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.cpp b/wpa_supplicant/wpa_gui-qt4/peers.cpp
deleted file mode 100644
index 0a0b3ffcb51b..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/peers.cpp
+++ /dev/null
@@ -1,1885 +0,0 @@
-/*
- * wpa_gui - Peers class
- * Copyright (c) 2009-2010, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-#include <QImageReader>
-#include <QMessageBox>
-
-#include "common/wpa_ctrl.h"
-#include "wpagui.h"
-#include "stringquery.h"
-#include "peers.h"
-
-
-enum {
- peer_role_address = Qt::UserRole + 1,
- peer_role_type,
- peer_role_uuid,
- peer_role_details,
- peer_role_ifname,
- peer_role_pri_dev_type,
- peer_role_ssid,
- peer_role_config_methods,
- peer_role_dev_passwd_id,
- peer_role_bss_id,
- peer_role_selected_method,
- peer_role_selected_pin,
- peer_role_requested_method,
- peer_role_network_id
-};
-
-enum selected_method {
- SEL_METHOD_NONE,
- SEL_METHOD_PIN_PEER_DISPLAY,
- SEL_METHOD_PIN_LOCAL_DISPLAY
-};
-
-/*
- * TODO:
- * - add current AP info (e.g., from WPS) in station mode
- */
-
-enum peer_type {
- PEER_TYPE_ASSOCIATED_STATION,
- PEER_TYPE_AP,
- PEER_TYPE_AP_WPS,
- PEER_TYPE_WPS_PIN_NEEDED,
- PEER_TYPE_P2P,
- PEER_TYPE_P2P_CLIENT,
- PEER_TYPE_P2P_GROUP,
- PEER_TYPE_P2P_PERSISTENT_GROUP_GO,
- PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT,
- PEER_TYPE_P2P_INVITATION,
- PEER_TYPE_WPS_ER_AP,
- PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
- PEER_TYPE_WPS_ER_ENROLLEE,
- PEER_TYPE_WPS_ENROLLEE
-};
-
-
-Peers::Peers(QWidget *parent, const char *, bool, Qt::WindowFlags)
- : QDialog(parent)
-{
- setupUi(this);
-
- if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
- {
- default_icon = new QIcon(":/icons/wpa_gui.svg");
- ap_icon = new QIcon(":/icons/ap.svg");
- laptop_icon = new QIcon(":/icons/laptop.svg");
- group_icon = new QIcon(":/icons/group.svg");
- invitation_icon = new QIcon(":/icons/invitation.svg");
- } else {
- default_icon = new QIcon(":/icons/wpa_gui.png");
- ap_icon = new QIcon(":/icons/ap.png");
- laptop_icon = new QIcon(":/icons/laptop.png");
- group_icon = new QIcon(":/icons/group.png");
- invitation_icon = new QIcon(":/icons/invitation.png");
- }
-
- peers->setModel(&model);
- peers->setResizeMode(QListView::Adjust);
- peers->setDragEnabled(false);
- peers->setSelectionMode(QAbstractItemView::NoSelection);
-
- peers->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
- this, SLOT(context_menu(const QPoint &)));
-
- wpagui = NULL;
- hide_ap = false;
-}
-
-
-void Peers::setWpaGui(WpaGui *_wpagui)
-{
- wpagui = _wpagui;
- update_peers();
-}
-
-
-Peers::~Peers()
-{
- delete default_icon;
- delete ap_icon;
- delete laptop_icon;
- delete group_icon;
- delete invitation_icon;
-}
-
-
-void Peers::languageChange()
-{
- retranslateUi(this);
-}
-
-
-QString Peers::ItemType(int type)
-{
- QString title;
- switch (type) {
- case PEER_TYPE_ASSOCIATED_STATION:
- title = tr("Associated station");
- break;
- case PEER_TYPE_AP:
- title = tr("AP");
- break;
- case PEER_TYPE_AP_WPS:
- title = tr("WPS AP");
- break;
- case PEER_TYPE_WPS_PIN_NEEDED:
- title = tr("WPS PIN needed");
- break;
- case PEER_TYPE_P2P:
- title = tr("P2P Device");
- break;
- case PEER_TYPE_P2P_CLIENT:
- title = tr("P2P Device (group client)");
- break;
- case PEER_TYPE_P2P_GROUP:
- title = tr("P2P Group");
- break;
- case PEER_TYPE_P2P_PERSISTENT_GROUP_GO:
- title = tr("P2P Persistent Group (GO)");
- break;
- case PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT:
- title = tr("P2P Persistent Group (client)");
- break;
- case PEER_TYPE_P2P_INVITATION:
- title = tr("P2P Invitation");
- break;
- case PEER_TYPE_WPS_ER_AP:
- title = tr("ER: WPS AP");
- break;
- case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
- title = tr("ER: WPS AP (Unconfigured)");
- break;
- case PEER_TYPE_WPS_ER_ENROLLEE:
- title = tr("ER: WPS Enrollee");
- break;
- case PEER_TYPE_WPS_ENROLLEE:
- title = tr("WPS Enrollee");
- break;
- }
- return title;
-}
-
-
-void Peers::context_menu(const QPoint &pos)
-{
- QMenu *menu = new QMenu;
- if (menu == NULL)
- return;
-
- QModelIndex idx = peers->indexAt(pos);
- if (idx.isValid()) {
- ctx_item = model.itemFromIndex(idx);
- int type = ctx_item->data(peer_role_type).toInt();
- menu->addAction(Peers::ItemType(type))->setEnabled(false);
- menu->addSeparator();
-
- int config_methods = -1;
- QVariant var = ctx_item->data(peer_role_config_methods);
- if (var.isValid())
- config_methods = var.toInt();
-
- enum selected_method method = SEL_METHOD_NONE;
- var = ctx_item->data(peer_role_selected_method);
- if (var.isValid())
- method = (enum selected_method) var.toInt();
-
- if ((type == PEER_TYPE_ASSOCIATED_STATION ||
- type == PEER_TYPE_AP_WPS ||
- type == PEER_TYPE_WPS_PIN_NEEDED ||
- type == PEER_TYPE_WPS_ER_ENROLLEE ||
- type == PEER_TYPE_WPS_ENROLLEE) &&
- (config_methods == -1 || (config_methods & 0x010c))) {
- menu->addAction(tr("Enter WPS PIN"), this,
- SLOT(enter_pin()));
- }
-
- if (type == PEER_TYPE_P2P || type == PEER_TYPE_P2P_CLIENT) {
- menu->addAction(tr("P2P Connect"), this,
- SLOT(ctx_p2p_connect()));
- if (method == SEL_METHOD_NONE &&
- config_methods > -1 &&
- config_methods & 0x0080 /* PBC */ &&
- config_methods != 0x0080)
- menu->addAction(tr("P2P Connect (PBC)"), this,
- SLOT(connect_pbc()));
- if (method == SEL_METHOD_NONE) {
- menu->addAction(tr("P2P Request PIN"), this,
- SLOT(ctx_p2p_req_pin()));
- menu->addAction(tr("P2P Show PIN"), this,
- SLOT(ctx_p2p_show_pin()));
- }
-
- if (config_methods > -1 && (config_methods & 0x0100)) {
- /* Peer has Keypad */
- menu->addAction(tr("P2P Display PIN"), this,
- SLOT(ctx_p2p_display_pin()));
- }
-
- if (config_methods > -1 && (config_methods & 0x000c)) {
- /* Peer has Label or Display */
- menu->addAction(tr("P2P Enter PIN"), this,
- SLOT(ctx_p2p_enter_pin()));
- }
- }
-
- if (type == PEER_TYPE_P2P_GROUP) {
- menu->addAction(tr("Show passphrase"), this,
- SLOT(ctx_p2p_show_passphrase()));
- menu->addAction(tr("Remove P2P Group"), this,
- SLOT(ctx_p2p_remove_group()));
- }
-
- if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
- type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT ||
- type == PEER_TYPE_P2P_INVITATION) {
- menu->addAction(tr("Start group"), this,
- SLOT(ctx_p2p_start_persistent()));
- }
-
- if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
- type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT) {
- menu->addAction(tr("Invite"), this,
- SLOT(ctx_p2p_invite()));
- }
-
- if (type == PEER_TYPE_P2P_INVITATION) {
- menu->addAction(tr("Ignore"), this,
- SLOT(ctx_p2p_delete()));
- }
-
- if (type == PEER_TYPE_AP_WPS) {
- menu->addAction(tr("Connect (PBC)"), this,
- SLOT(connect_pbc()));
- }
-
- if ((type == PEER_TYPE_ASSOCIATED_STATION ||
- type == PEER_TYPE_WPS_ER_ENROLLEE ||
- type == PEER_TYPE_WPS_ENROLLEE) &&
- config_methods >= 0 && (config_methods & 0x0080)) {
- menu->addAction(tr("Enroll (PBC)"), this,
- SLOT(connect_pbc()));
- }
-
- if (type == PEER_TYPE_WPS_ER_AP) {
- menu->addAction(tr("Learn Configuration"), this,
- SLOT(learn_ap_config()));
- }
-
- menu->addAction(tr("Properties"), this, SLOT(properties()));
- } else {
- ctx_item = NULL;
- menu->addAction(QString(tr("Refresh")), this,
- SLOT(ctx_refresh()));
- menu->addAction(tr("Start P2P discovery"), this,
- SLOT(ctx_p2p_start()));
- menu->addAction(tr("Stop P2P discovery"), this,
- SLOT(ctx_p2p_stop()));
- menu->addAction(tr("P2P listen only"), this,
- SLOT(ctx_p2p_listen()));
- menu->addAction(tr("Start P2P group"), this,
- SLOT(ctx_p2p_start_group()));
- if (hide_ap)
- menu->addAction(tr("Show AP entries"), this,
- SLOT(ctx_show_ap()));
- else
- menu->addAction(tr("Hide AP entries"), this,
- SLOT(ctx_hide_ap()));
- }
-
- menu->exec(peers->mapToGlobal(pos));
-}
-
-
-void Peers::enter_pin()
-{
- if (ctx_item == NULL)
- return;
-
- int peer_type = ctx_item->data(peer_role_type).toInt();
- QString uuid;
- QString addr;
- addr = ctx_item->data(peer_role_address).toString();
- if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
- uuid = ctx_item->data(peer_role_uuid).toString();
-
- StringQuery input(tr("PIN:"));
- input.setWindowTitle(tr("PIN for ") + ctx_item->text());
- if (input.exec() != QDialog::Accepted)
- return;
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
- snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
- uuid.toLocal8Bit().constData(),
- input.get_string().toLocal8Bit().constData(),
- addr.toLocal8Bit().constData());
- } else {
- snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
- addr.toLocal8Bit().constData(),
- input.get_string().toLocal8Bit().constData());
- }
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to set the WPS PIN."));
- msg.exec();
- }
-}
-
-
-void Peers::ctx_refresh()
-{
- update_peers();
-}
-
-
-void Peers::ctx_p2p_start()
-{
- char reply[20];
- size_t reply_len;
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("P2P_FIND", reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to start P2P discovery.");
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_stop()
-{
- char reply[20];
- size_t reply_len;
- reply_len = sizeof(reply) - 1;
- wpagui->ctrlRequest("P2P_STOP_FIND", reply, &reply_len);
-}
-
-
-void Peers::ctx_p2p_listen()
-{
- char reply[20];
- size_t reply_len;
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("P2P_LISTEN 3600", reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to start P2P listen.");
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_start_group()
-{
- char reply[20];
- size_t reply_len;
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("P2P_GROUP_ADD", reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to start P2P group.");
- msg.exec();
- }
-}
-
-
-void Peers::add_station(QString info)
-{
- QStringList lines = info.split(QRegExp("\\n"));
- QString name;
-
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- int pos = (*it).indexOf('=') + 1;
- if (pos < 1)
- continue;
-
- if ((*it).startsWith("wpsDeviceName="))
- name = (*it).mid(pos);
- else if ((*it).startsWith("p2p_device_name="))
- name = (*it).mid(pos);
- }
-
- if (name.isEmpty())
- name = lines[0];
-
- QStandardItem *item = new QStandardItem(*laptop_icon, name);
- if (item) {
- /* Remove WPS enrollee entry if one is still pending */
- if (model.rowCount() > 0) {
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_address,
- lines[0]);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item;
- item = model.itemFromIndex(lst[i]);
- if (item == NULL)
- continue;
- int type = item->data(peer_role_type).toInt();
- if (type == PEER_TYPE_WPS_ENROLLEE) {
- model.removeRow(lst[i].row());
- break;
- }
- }
- }
-
- item->setData(lines[0], peer_role_address);
- item->setData(PEER_TYPE_ASSOCIATED_STATION,
- peer_role_type);
- item->setData(info, peer_role_details);
- item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
- model.appendRow(item);
- }
-}
-
-
-void Peers::add_stations()
-{
- char reply[2048];
- size_t reply_len;
- char cmd[30];
- int res;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
- return;
-
- do {
- reply[reply_len] = '\0';
- QString info(reply);
- char *txt = reply;
- while (*txt != '\0' && *txt != '\n')
- txt++;
- *txt++ = '\0';
- if (strncmp(reply, "FAIL", 4) == 0 ||
- strncmp(reply, "UNKNOWN", 7) == 0)
- break;
-
- add_station(info);
-
- reply_len = sizeof(reply) - 1;
- res = snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- break;
- res = wpagui->ctrlRequest(cmd, reply, &reply_len);
- } while (res >= 0);
-}
-
-
-void Peers::add_single_station(const char *addr)
-{
- char reply[2048];
- size_t reply_len;
- char cmd[30];
-
- reply_len = sizeof(reply) - 1;
- snprintf(cmd, sizeof(cmd), "STA %s", addr);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
- return;
-
- reply[reply_len] = '\0';
- QString info(reply);
- char *txt = reply;
- while (*txt != '\0' && *txt != '\n')
- txt++;
- *txt++ = '\0';
- if (strncmp(reply, "FAIL", 4) == 0 ||
- strncmp(reply, "UNKNOWN", 7) == 0)
- return;
-
- add_station(info);
-}
-
-
-void Peers::add_p2p_group_client(QStandardItem * /*parent*/, QString params)
-{
- /*
- * dev=02:b5:64:63:30:63 iface=02:b5:64:63:30:63 dev_capab=0x0
- * dev_type=1-0050f204-1 dev_name='Wireless Client'
- * config_methods=0x8c
- */
-
- QStringList items =
- params.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
- QString addr = "";
- QString name = "";
- int config_methods = 0;
- QString dev_type;
-
- for (int i = 0; i < items.size(); i++) {
- QString str = items.at(i);
- int pos = str.indexOf('=') + 1;
- if (str.startsWith("dev_name='"))
- name = str.section('\'', 1, -2);
- else if (str.startsWith("config_methods="))
- config_methods =
- str.section('=', 1).toInt(0, 0);
- else if (str.startsWith("dev="))
- addr = str.mid(pos);
- else if (str.startsWith("dev_type=") && dev_type.isEmpty())
- dev_type = str.mid(pos);
- }
-
- QStandardItem *item = find_addr(addr);
- if (item)
- return;
-
- item = new QStandardItem(*default_icon, name);
- if (item) {
- /* TODO: indicate somehow the relationship to the group owner
- * (parent) */
- item->setData(addr, peer_role_address);
- item->setData(config_methods, peer_role_config_methods);
- item->setData(PEER_TYPE_P2P_CLIENT, peer_role_type);
- if (!dev_type.isEmpty())
- item->setData(dev_type, peer_role_pri_dev_type);
- item->setData(items.join(QString("\n")), peer_role_details);
- item->setToolTip(ItemType(PEER_TYPE_P2P_CLIENT));
- model.appendRow(item);
- }
-}
-
-
-void Peers::remove_bss(int id)
-{
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0), peer_role_bss_id,
- id);
- if (lst.size() == 0)
- return;
- model.removeRow(lst[0].row());
-}
-
-
-bool Peers::add_bss(const char *cmd)
-{
- char reply[2048];
- size_t reply_len;
-
- if (hide_ap)
- return false;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
- return false;
- reply[reply_len] = '\0';
-
- QString bss(reply);
- if (bss.isEmpty() || bss.startsWith("FAIL"))
- return false;
-
- QString ssid, bssid, flags, wps_name, pri_dev_type;
- int id = -1;
-
- QStringList lines = bss.split(QRegExp("\\n"));
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- int pos = (*it).indexOf('=') + 1;
- if (pos < 1)
- continue;
-
- if ((*it).startsWith("bssid="))
- bssid = (*it).mid(pos);
- else if ((*it).startsWith("id="))
- id = (*it).mid(pos).toInt();
- else if ((*it).startsWith("flags="))
- flags = (*it).mid(pos);
- else if ((*it).startsWith("ssid="))
- ssid = (*it).mid(pos);
- else if ((*it).startsWith("wps_device_name="))
- wps_name = (*it).mid(pos);
- else if ((*it).startsWith("wps_primary_device_type="))
- pri_dev_type = (*it).mid(pos);
- }
-
- QString name = wps_name;
- if (name.isEmpty())
- name = ssid + "\n" + bssid;
-
- QStandardItem *item = new QStandardItem(*ap_icon, name);
- if (item) {
- item->setData(bssid, peer_role_address);
- if (id >= 0)
- item->setData(id, peer_role_bss_id);
- int type;
- if (flags.contains("[WPS"))
- type = PEER_TYPE_AP_WPS;
- else
- type = PEER_TYPE_AP;
- item->setData(type, peer_role_type);
-
- for (int i = 0; i < lines.size(); i++) {
- if (lines[i].length() > 60) {
- lines[i].remove(60, lines[i].length());
- lines[i] += "..";
- }
- }
- item->setToolTip(ItemType(type));
- item->setData(lines.join("\n"), peer_role_details);
- if (!pri_dev_type.isEmpty())
- item->setData(pri_dev_type,
- peer_role_pri_dev_type);
- if (!ssid.isEmpty())
- item->setData(ssid, peer_role_ssid);
- model.appendRow(item);
-
- lines = bss.split(QRegExp("\\n"));
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- if ((*it).startsWith("p2p_group_client:"))
- add_p2p_group_client(item,
- (*it).mid(18));
- }
- }
-
- return true;
-}
-
-
-void Peers::add_scan_results()
-{
- int index;
- char cmd[20];
-
- index = 0;
- while (wpagui) {
- snprintf(cmd, sizeof(cmd), "BSS %d", index++);
- if (index > 1000)
- break;
-
- if (!add_bss(cmd))
- break;
- }
-}
-
-
-void Peers::add_persistent(int id, const char *ssid, const char *bssid)
-{
- char cmd[100];
- char reply[100];
- size_t reply_len;
- int mode;
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d mode", id);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
- mode = atoi(reply);
-
- QString name = ssid;
- name = '[' + name + ']';
-
- QStandardItem *item = new QStandardItem(*group_icon, name);
- if (!item)
- return;
-
- int type;
- if (mode == 3)
- type = PEER_TYPE_P2P_PERSISTENT_GROUP_GO;
- else
- type = PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT;
- item->setData(type, peer_role_type);
- item->setToolTip(ItemType(type));
- item->setData(ssid, peer_role_ssid);
- if (bssid && strcmp(bssid, "any") == 0)
- bssid = NULL;
- if (bssid)
- item->setData(bssid, peer_role_address);
- item->setData(id, peer_role_network_id);
- item->setBackground(Qt::BDiagPattern);
-
- model.appendRow(item);
-}
-
-
-void Peers::add_persistent_groups()
-{
- char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
- size_t len;
-
- len = sizeof(buf) - 1;
- if (wpagui->ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
- return;
-
- buf[len] = '\0';
- start = strchr(buf, '\n');
- if (start == NULL)
- return;
- start++;
-
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- id = start;
- ssid = strchr(id, '\t');
- if (ssid == NULL)
- break;
- *ssid++ = '\0';
- bssid = strchr(ssid, '\t');
- if (bssid == NULL)
- break;
- *bssid++ = '\0';
- flags = strchr(bssid, '\t');
- if (flags == NULL)
- break;
- *flags++ = '\0';
-
- if (strstr(flags, "[DISABLED][P2P-PERSISTENT]"))
- add_persistent(atoi(id), ssid, bssid);
-
- if (last)
- break;
- start = end + 1;
- }
-}
-
-
-void Peers::update_peers()
-{
- model.clear();
- if (wpagui == NULL)
- return;
-
- char reply[20];
- size_t replylen = sizeof(reply) - 1;
- wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
-
- add_stations();
- add_scan_results();
- add_persistent_groups();
-}
-
-
-QStandardItem * Peers::find_addr(QString addr)
-{
- if (model.rowCount() == 0)
- return NULL;
-
- QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
- addr);
- if (lst.size() == 0)
- return NULL;
- return model.itemFromIndex(lst[0]);
-}
-
-
-QStandardItem * Peers::find_addr_type(QString addr, int type)
-{
- if (model.rowCount() == 0)
- return NULL;
-
- QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
- addr);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item = model.itemFromIndex(lst[i]);
- if (item->data(peer_role_type).toInt() == type)
- return item;
- }
- return NULL;
-}
-
-
-QStandardItem * Peers::find_uuid(QString uuid)
-{
- if (model.rowCount() == 0)
- return NULL;
-
- QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
- uuid);
- if (lst.size() == 0)
- return NULL;
- return model.itemFromIndex(lst[0]);
-}
-
-
-void Peers::event_notify(WpaMsg msg)
-{
- QString text = msg.getMsg();
-
- if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
- /*
- * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
- * 02:2a:c4:18:5b:f3
- * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
- */
- QStringList items = text.split(' ');
- QString uuid = items[1];
- QString addr = items[2];
- QString name = "";
-
- QStandardItem *item = find_addr(addr);
- if (item)
- return;
-
- int pos = text.indexOf('[');
- if (pos >= 0) {
- int pos2 = text.lastIndexOf(']');
- if (pos2 >= pos) {
- items = text.mid(pos + 1, pos2 - pos - 1).
- split('|');
- name = items[0];
- items.append(addr);
- }
- }
-
- item = new QStandardItem(*laptop_icon, name);
- if (item) {
- item->setData(addr, peer_role_address);
- item->setData(PEER_TYPE_WPS_PIN_NEEDED,
- peer_role_type);
- item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
- item->setData(items.join("\n"), peer_role_details);
- item->setData(items[5], peer_role_pri_dev_type);
- model.appendRow(item);
- }
- return;
- }
-
- if (text.startsWith(AP_STA_CONNECTED)) {
- /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
- QStringList items = text.split(' ');
- QString addr = items[1];
- QStandardItem *item = find_addr(addr);
- if (item == NULL || item->data(peer_role_type).toInt() !=
- PEER_TYPE_ASSOCIATED_STATION)
- add_single_station(addr.toLocal8Bit().constData());
- return;
- }
-
- if (text.startsWith(AP_STA_DISCONNECTED)) {
- /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
- QStringList items = text.split(' ');
- QString addr = items[1];
-
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_address, addr, -1);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item = model.itemFromIndex(lst[i]);
- if (item && item->data(peer_role_type).toInt() ==
- PEER_TYPE_ASSOCIATED_STATION) {
- model.removeRow(lst[i].row());
- break;
- }
- }
- return;
- }
-
- if (text.startsWith(P2P_EVENT_DEVICE_FOUND)) {
- /*
- * P2P-DEVICE-FOUND 02:b5:64:63:30:63
- * p2p_dev_addr=02:b5:64:63:30:63 pri_dev_type=1-0050f204-1
- * name='Wireless Client' config_methods=0x84 dev_capab=0x21
- * group_capab=0x0
- */
- QStringList items =
- text.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
- QString addr = items[1];
- QString name = "";
- QString pri_dev_type;
- int config_methods = 0;
- for (int i = 0; i < items.size(); i++) {
- QString str = items.at(i);
- if (str.startsWith("name='"))
- name = str.section('\'', 1, -2);
- else if (str.startsWith("config_methods="))
- config_methods =
- str.section('=', 1).toInt(0, 0);
- else if (str.startsWith("pri_dev_type="))
- pri_dev_type = str.section('=', 1);
- }
-
- QStandardItem *item = find_addr(addr);
- if (item) {
- int type = item->data(peer_role_type).toInt();
- if (type == PEER_TYPE_P2P)
- return;
- }
-
- item = new QStandardItem(*default_icon, name);
- if (item) {
- item->setData(addr, peer_role_address);
- item->setData(config_methods,
- peer_role_config_methods);
- item->setData(PEER_TYPE_P2P, peer_role_type);
- if (!pri_dev_type.isEmpty())
- item->setData(pri_dev_type,
- peer_role_pri_dev_type);
- item->setData(items.join(QString("\n")),
- peer_role_details);
- item->setToolTip(ItemType(PEER_TYPE_P2P));
- model.appendRow(item);
- }
-
- item = find_addr_type(addr,
- PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT);
- if (item)
- item->setBackground(Qt::NoBrush);
- }
-
- if (text.startsWith(P2P_EVENT_GROUP_STARTED)) {
- /* P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F"
- * passphrase="YOyTkxID" go_dev_addr=02:40:61:c2:f3:b7
- * [PERSISTENT] */
- QStringList items = text.split(' ');
- if (items.size() < 4)
- return;
-
- int pos = text.indexOf(" ssid=\"");
- if (pos < 0)
- return;
- QString ssid = text.mid(pos + 7);
- pos = ssid.indexOf(" passphrase=\"");
- if (pos < 0)
- pos = ssid.indexOf(" psk=");
- if (pos >= 0)
- ssid.truncate(pos);
- pos = ssid.lastIndexOf('"');
- if (pos >= 0)
- ssid.truncate(pos);
-
- QStandardItem *item = new QStandardItem(*group_icon, ssid);
- if (item) {
- item->setData(PEER_TYPE_P2P_GROUP, peer_role_type);
- item->setData(items[1], peer_role_ifname);
- QString details;
- if (items[2] == "GO") {
- details = tr("P2P GO for interface ") +
- items[1];
- } else {
- details = tr("P2P client for interface ") +
- items[1];
- }
- if (text.contains(" [PERSISTENT]"))
- details += "\nPersistent group";
- item->setData(details, peer_role_details);
- item->setToolTip(ItemType(PEER_TYPE_P2P_GROUP));
- model.appendRow(item);
- }
- }
-
- if (text.startsWith(P2P_EVENT_GROUP_REMOVED)) {
- /* P2P-GROUP-REMOVED wlan0-p2p-0 GO */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
-
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_ifname, items[1]);
- for (int i = 0; i < lst.size(); i++)
- model.removeRow(lst[i].row());
- return;
- }
-
- if (text.startsWith(P2P_EVENT_PROV_DISC_SHOW_PIN)) {
- /* P2P-PROV-DISC-SHOW-PIN 02:40:61:c2:f3:b7 12345670 */
- QStringList items = text.split(' ');
- if (items.size() < 3)
- return;
- QString addr = items[1];
- QString pin = items[2];
-
- QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
- if (item == NULL)
- return;
- item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
- peer_role_selected_method);
- item->setData(pin, peer_role_selected_pin);
- QVariant var = item->data(peer_role_requested_method);
- if (var.isValid() &&
- var.toInt() == SEL_METHOD_PIN_LOCAL_DISPLAY) {
- ctx_item = item;
- ctx_p2p_display_pin_pd();
- }
- return;
- }
-
- if (text.startsWith(P2P_EVENT_PROV_DISC_ENTER_PIN)) {
- /* P2P-PROV-DISC-ENTER-PIN 02:40:61:c2:f3:b7 */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
- QString addr = items[1];
-
- QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
- if (item == NULL)
- return;
- item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
- peer_role_selected_method);
- QVariant var = item->data(peer_role_requested_method);
- if (var.isValid() &&
- var.toInt() == SEL_METHOD_PIN_PEER_DISPLAY) {
- ctx_item = item;
- ctx_p2p_connect();
- }
- return;
- }
-
- if (text.startsWith(P2P_EVENT_INVITATION_RECEIVED)) {
- /* P2P-INVITATION-RECEIVED sa=02:f0:bc:44:87:62 persistent=4 */
- QStringList items = text.split(' ');
- if (items.size() < 3)
- return;
- if (!items[1].startsWith("sa=") ||
- !items[2].startsWith("persistent="))
- return;
- QString addr = items[1].mid(3);
- int id = items[2].mid(11).toInt();
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", id);
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
- QString name;
- char *pos = strrchr(reply, '"');
- if (pos && reply[0] == '"') {
- *pos = '\0';
- name = reply + 1;
- } else
- name = reply;
-
- QStandardItem *item;
- item = find_addr_type(addr, PEER_TYPE_P2P_INVITATION);
- if (item)
- model.removeRow(item->row());
-
- item = new QStandardItem(*invitation_icon, name);
- if (!item)
- return;
- item->setData(PEER_TYPE_P2P_INVITATION, peer_role_type);
- item->setToolTip(ItemType(PEER_TYPE_P2P_INVITATION));
- item->setData(addr, peer_role_address);
- item->setData(id, peer_role_network_id);
-
- model.appendRow(item);
-
- enable_persistent(id);
-
- return;
- }
-
- if (text.startsWith(P2P_EVENT_INVITATION_RESULT)) {
- /* P2P-INVITATION-RESULT status=1 */
- /* TODO */
- return;
- }
-
- if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
- /*
- * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
- * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
- * |Very friendly name|Company|Long description of the model|
- * WAP|http://w1.fi/|http://w1.fi/hostapd/
- */
- QStringList items = text.split(' ');
- if (items.size() < 5)
- return;
- QString uuid = items[1];
- QString addr = items[2];
- QString pri_dev_type = items[3].mid(13);
- int wps_state = items[4].mid(10).toInt();
-
- int pos = text.indexOf('|');
- if (pos < 0)
- return;
- items = text.mid(pos + 1).split('|');
- if (items.size() < 1)
- return;
-
- QStandardItem *item = find_uuid(uuid);
- if (item)
- return;
-
- item = new QStandardItem(*ap_icon, items[0]);
- if (item) {
- item->setData(uuid, peer_role_uuid);
- item->setData(addr, peer_role_address);
- int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
- PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
- item->setData(type, peer_role_type);
- item->setToolTip(ItemType(type));
- item->setData(pri_dev_type, peer_role_pri_dev_type);
- item->setData(items.join(QString("\n")),
- peer_role_details);
- model.appendRow(item);
- }
-
- return;
- }
-
- if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
- /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_uuid, items[1]);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item = model.itemFromIndex(lst[i]);
- if (item &&
- (item->data(peer_role_type).toInt() ==
- PEER_TYPE_WPS_ER_AP ||
- item->data(peer_role_type).toInt() ==
- PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
- model.removeRow(lst[i].row());
- }
- return;
- }
-
- if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
- /*
- * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
- * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
- * pri_dev_type=1-0050F204-1
- * |Wireless Client|Company|cmodel|123|12345|
- */
- QStringList items = text.split(' ');
- if (items.size() < 3)
- return;
- QString uuid = items[1];
- QString addr = items[2];
- QString pri_dev_type = items[6].mid(13);
- int config_methods = -1;
- int dev_passwd_id = -1;
-
- for (int i = 3; i < items.size(); i++) {
- int pos = items[i].indexOf('=') + 1;
- if (pos < 1)
- continue;
- QString val = items[i].mid(pos);
- if (items[i].startsWith("config_methods=")) {
- config_methods = val.toInt(0, 0);
- } else if (items[i].startsWith("dev_passwd_id=")) {
- dev_passwd_id = val.toInt();
- }
- }
-
- int pos = text.indexOf('|');
- if (pos < 0)
- return;
- items = text.mid(pos + 1).split('|');
- if (items.size() < 1)
- return;
- QString name = items[0];
- if (name.length() == 0)
- name = addr;
-
- remove_enrollee_uuid(uuid);
-
- QStandardItem *item;
- item = new QStandardItem(*laptop_icon, name);
- if (item) {
- item->setData(uuid, peer_role_uuid);
- item->setData(addr, peer_role_address);
- item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
- peer_role_type);
- item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
- item->setData(items.join(QString("\n")),
- peer_role_details);
- item->setData(pri_dev_type, peer_role_pri_dev_type);
- if (config_methods >= 0)
- item->setData(config_methods,
- peer_role_config_methods);
- if (dev_passwd_id >= 0)
- item->setData(dev_passwd_id,
- peer_role_dev_passwd_id);
- model.appendRow(item);
- }
-
- return;
- }
-
- if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
- /*
- * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
- * 02:66:a0:ee:17:27
- */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
- remove_enrollee_uuid(items[1]);
- return;
- }
-
- if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
- /* TODO: need to time out this somehow or remove on successful
- * WPS run, etc. */
- /*
- * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
- * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
- * [Wireless Client]
- * (MAC addr, UUID-E, pri dev type, config methods,
- * dev passwd id, request type, [dev name])
- */
- QStringList items = text.split(' ');
- if (items.size() < 7)
- return;
- QString addr = items[1];
- QString uuid = items[2];
- QString pri_dev_type = items[3];
- int config_methods = items[4].toInt(0, 0);
- int dev_passwd_id = items[5].toInt();
- QString name;
-
- QStandardItem *item = find_addr(addr);
- if (item) {
- int type = item->data(peer_role_type).toInt();
- if (type == PEER_TYPE_ASSOCIATED_STATION)
- return; /* already associated */
- }
-
- int pos = text.indexOf('[');
- if (pos >= 0) {
- int pos2 = text.lastIndexOf(']');
- if (pos2 >= pos) {
- QStringList items2 =
- text.mid(pos + 1, pos2 - pos - 1).
- split('|');
- name = items2[0];
- }
- }
- if (name.isEmpty())
- name = addr;
-
- item = find_uuid(uuid);
- if (item) {
- QVariant var = item->data(peer_role_config_methods);
- QVariant var2 = item->data(peer_role_dev_passwd_id);
- if ((var.isValid() && config_methods != var.toInt()) ||
- (var2.isValid() && dev_passwd_id != var2.toInt()))
- remove_enrollee_uuid(uuid);
- else
- return;
- }
-
- item = new QStandardItem(*laptop_icon, name);
- if (item) {
- item->setData(uuid, peer_role_uuid);
- item->setData(addr, peer_role_address);
- item->setData(PEER_TYPE_WPS_ENROLLEE,
- peer_role_type);
- item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
- item->setData(items.join(QString("\n")),
- peer_role_details);
- item->setData(pri_dev_type, peer_role_pri_dev_type);
- item->setData(config_methods,
- peer_role_config_methods);
- item->setData(dev_passwd_id, peer_role_dev_passwd_id);
- model.appendRow(item);
- }
-
- return;
- }
-
- if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
- /* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
- char cmd[20];
- snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
- add_bss(cmd);
- return;
- }
-
- if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
- /* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
- QStringList items = text.split(' ');
- if (items.size() < 2)
- return;
- remove_bss(items[1].toInt());
- return;
- }
-}
-
-
-void Peers::ctx_p2p_connect()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
- QString arg;
- int config_methods =
- ctx_item->data(peer_role_config_methods).toInt();
- enum selected_method method = SEL_METHOD_NONE;
- QVariant var = ctx_item->data(peer_role_selected_method);
- if (var.isValid())
- method = (enum selected_method) var.toInt();
- if (method == SEL_METHOD_PIN_LOCAL_DISPLAY) {
- arg = ctx_item->data(peer_role_selected_pin).toString();
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
- addr.toLocal8Bit().constData(),
- arg.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to initiate P2P connect.");
- msg.exec();
- return;
- }
- QMessageBox::information(this,
- tr("PIN for ") + ctx_item->text(),
- tr("Enter the following PIN on the\n"
- "peer device: ") + arg);
- } else if (method == SEL_METHOD_PIN_PEER_DISPLAY) {
- StringQuery input(tr("PIN from peer display:"));
- input.setWindowTitle(tr("PIN for ") + ctx_item->text());
- if (input.exec() != QDialog::Accepted)
- return;
- arg = input.get_string();
- } else if (config_methods == 0x0080 /* PBC */) {
- arg = "pbc";
- } else {
- StringQuery input(tr("PIN:"));
- input.setWindowTitle(tr("PIN for ") + ctx_item->text());
- if (input.exec() != QDialog::Accepted)
- return;
- arg = input.get_string();
- }
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
- addr.toLocal8Bit().constData(),
- arg.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to initiate P2P connect.");
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_req_pin()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
- ctx_item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
- peer_role_requested_method);
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s display",
- addr.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to request PIN from peer."));
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_show_pin()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
- ctx_item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
- peer_role_requested_method);
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s keypad",
- addr.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to request peer to enter PIN."));
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_display_pin()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pin",
- addr.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to initiate P2P connect.");
- msg.exec();
- return;
- }
- reply[reply_len] = '\0';
- QMessageBox::information(this,
- tr("PIN for ") + ctx_item->text(),
- tr("Enter the following PIN on the\n"
- "peer device: ") + reply);
-}
-
-
-void Peers::ctx_p2p_display_pin_pd()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
- QString arg = ctx_item->data(peer_role_selected_pin).toString();
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
- addr.toLocal8Bit().constData(),
- arg.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to initiate P2P connect.");
- msg.exec();
- return;
- }
- reply[reply_len] = '\0';
- QMessageBox::information(this,
- tr("PIN for ") + ctx_item->text(),
- tr("Enter the following PIN on the\n"
- "peer device: ") + arg);
-}
-
-
-void Peers::ctx_p2p_enter_pin()
-{
- if (ctx_item == NULL)
- return;
- QString addr = ctx_item->data(peer_role_address).toString();
- QString arg;
-
- StringQuery input(tr("PIN from peer:"));
- input.setWindowTitle(tr("PIN for ") + ctx_item->text());
- if (input.exec() != QDialog::Accepted)
- return;
- arg = input.get_string();
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s keypad",
- addr.toLocal8Bit().constData(),
- arg.toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to initiate P2P connect.");
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_remove_group()
-{
- if (ctx_item == NULL)
- return;
- char cmd[100];
- char reply[100];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s",
- ctx_item->data(peer_role_ifname).toString().toLocal8Bit().
- constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to remove P2P Group.");
- msg.exec();
- }
-}
-
-
-void Peers::closeEvent(QCloseEvent *)
-{
- if (wpagui) {
- char reply[20];
- size_t replylen = sizeof(reply) - 1;
- wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
- }
-}
-
-
-void Peers::done(int r)
-{
- QDialog::done(r);
- close();
-}
-
-
-void Peers::remove_enrollee_uuid(QString uuid)
-{
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_uuid, uuid);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item = model.itemFromIndex(lst[i]);
- if (item == NULL)
- continue;
- int type = item->data(peer_role_type).toInt();
- if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
- type == PEER_TYPE_WPS_ENROLLEE)
- model.removeRow(lst[i].row());
- }
-}
-
-
-void Peers::properties()
-{
- if (ctx_item == NULL)
- return;
-
- QMessageBox msg(this);
- msg.setStandardButtons(QMessageBox::Ok);
- msg.setDefaultButton(QMessageBox::Ok);
- msg.setEscapeButton(QMessageBox::Ok);
- msg.setWindowTitle(tr("Peer Properties"));
-
- int type = ctx_item->data(peer_role_type).toInt();
- QString title = Peers::ItemType(type);
-
- msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
-
- QVariant var;
- QString info;
-
- var = ctx_item->data(peer_role_address);
- if (var.isValid())
- info += tr("Address: ") + var.toString() + QString("\n");
-
- var = ctx_item->data(peer_role_uuid);
- if (var.isValid())
- info += tr("UUID: ") + var.toString() + QString("\n");
-
- var = ctx_item->data(peer_role_pri_dev_type);
- if (var.isValid())
- info += tr("Primary Device Type: ") + var.toString() +
- QString("\n");
-
- var = ctx_item->data(peer_role_ssid);
- if (var.isValid())
- info += tr("SSID: ") + var.toString() + QString("\n");
-
- var = ctx_item->data(peer_role_config_methods);
- if (var.isValid()) {
- int methods = var.toInt();
- info += tr("Configuration Methods: ");
- if (methods & 0x0001)
- info += tr("[USBA]");
- if (methods & 0x0002)
- info += tr("[Ethernet]");
- if (methods & 0x0004)
- info += tr("[Label]");
- if (methods & 0x0008)
- info += tr("[Display]");
- if (methods & 0x0010)
- info += tr("[Ext. NFC Token]");
- if (methods & 0x0020)
- info += tr("[Int. NFC Token]");
- if (methods & 0x0040)
- info += tr("[NFC Interface]");
- if (methods & 0x0080)
- info += tr("[Push Button]");
- if (methods & 0x0100)
- info += tr("[Keypad]");
- info += "\n";
- }
-
- var = ctx_item->data(peer_role_selected_method);
- if (var.isValid()) {
- enum selected_method method =
- (enum selected_method) var.toInt();
- switch (method) {
- case SEL_METHOD_NONE:
- break;
- case SEL_METHOD_PIN_PEER_DISPLAY:
- info += tr("Selected Method: PIN on peer display\n");
- break;
- case SEL_METHOD_PIN_LOCAL_DISPLAY:
- info += tr("Selected Method: PIN on local display\n");
- break;
- }
- }
-
- var = ctx_item->data(peer_role_selected_pin);
- if (var.isValid()) {
- info += tr("PIN to enter on peer: ") + var.toString() + "\n";
- }
-
- var = ctx_item->data(peer_role_dev_passwd_id);
- if (var.isValid()) {
- info += tr("Device Password ID: ") + var.toString();
- switch (var.toInt()) {
- case 0:
- info += tr(" (Default PIN)");
- break;
- case 1:
- info += tr(" (User-specified PIN)");
- break;
- case 2:
- info += tr(" (Machine-specified PIN)");
- break;
- case 3:
- info += tr(" (Rekey)");
- break;
- case 4:
- info += tr(" (Push Button)");
- break;
- case 5:
- info += tr(" (Registrar-specified)");
- break;
- }
- info += "\n";
- }
-
- msg.setInformativeText(info);
-
- var = ctx_item->data(peer_role_details);
- if (var.isValid())
- msg.setDetailedText(var.toString());
-
- msg.exec();
-}
-
-
-void Peers::connect_pbc()
-{
- if (ctx_item == NULL)
- return;
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- int peer_type = ctx_item->data(peer_role_type).toInt();
- if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
- snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
- ctx_item->data(peer_role_uuid).toString().toLocal8Bit().
- constData());
- } else if (peer_type == PEER_TYPE_P2P ||
- peer_type == PEER_TYPE_P2P_CLIENT) {
- snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pbc",
- ctx_item->data(peer_role_address).toString().
- toLocal8Bit().constData());
- } else {
- snprintf(cmd, sizeof(cmd), "WPS_PBC");
- }
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to start WPS PBC."));
- msg.exec();
- }
-}
-
-
-void Peers::learn_ap_config()
-{
- if (ctx_item == NULL)
- return;
-
- QString uuid = ctx_item->data(peer_role_uuid).toString();
-
- StringQuery input(tr("AP PIN:"));
- input.setWindowTitle(tr("AP PIN for ") + ctx_item->text());
- if (input.exec() != QDialog::Accepted)
- return;
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
- uuid.toLocal8Bit().constData(),
- input.get_string().toLocal8Bit().constData());
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to start learning AP configuration."));
- msg.exec();
- }
-}
-
-
-void Peers::ctx_hide_ap()
-{
- hide_ap = true;
-
- if (model.rowCount() == 0)
- return;
-
- do {
- QModelIndexList lst;
- lst = model.match(model.index(0, 0),
- peer_role_type, PEER_TYPE_AP);
- if (lst.size() == 0) {
- lst = model.match(model.index(0, 0),
- peer_role_type, PEER_TYPE_AP_WPS);
- if (lst.size() == 0)
- break;
- }
-
- model.removeRow(lst[0].row());
- } while (1);
-}
-
-
-void Peers::ctx_show_ap()
-{
- hide_ap = false;
- add_scan_results();
-}
-
-
-void Peers::ctx_p2p_show_passphrase()
-{
- char reply[64];
- size_t reply_len;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("P2P_GET_PASSPHRASE", reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText("Failed to get P2P group passphrase.");
- msg.exec();
- } else {
- reply[reply_len] = '\0';
- QMessageBox::information(this, tr("Passphrase"),
- tr("P2P group passphrase:\n") +
- reply);
- }
-}
-
-
-void Peers::ctx_p2p_start_persistent()
-{
- if (ctx_item == NULL)
- return;
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD persistent=%d",
- ctx_item->data(peer_role_network_id).toInt());
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to start persistent P2P Group."));
- msg.exec();
- } else if (ctx_item->data(peer_role_type).toInt() ==
- PEER_TYPE_P2P_INVITATION)
- model.removeRow(ctx_item->row());
-}
-
-
-void Peers::ctx_p2p_invite()
-{
- if (ctx_item == NULL)
- return;
-
- char cmd[100];
- char reply[100];
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "P2P_INVITE persistent=%d",
- ctx_item->data(peer_role_network_id).toInt());
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
- memcmp(reply, "FAIL", 4) == 0) {
- QMessageBox msg;
- msg.setIcon(QMessageBox::Warning);
- msg.setText(tr("Failed to invite peer to start persistent "
- "P2P Group."));
- msg.exec();
- }
-}
-
-
-void Peers::ctx_p2p_delete()
-{
- if (ctx_item == NULL)
- return;
- model.removeRow(ctx_item->row());
-}
-
-
-void Peers::enable_persistent(int id)
-{
- if (model.rowCount() == 0)
- return;
-
- QModelIndexList lst = model.match(model.index(0, 0),
- peer_role_network_id, id);
- for (int i = 0; i < lst.size(); i++) {
- QStandardItem *item = model.itemFromIndex(lst[i]);
- int type = item->data(peer_role_type).toInt();
- if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
- type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT)
- item->setBackground(Qt::NoBrush);
- }
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.h b/wpa_supplicant/wpa_gui-qt4/peers.h
deleted file mode 100644
index bb7373749c2f..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/peers.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * wpa_gui - Peers class
- * Copyright (c) 2009-2010, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef PEERS_H
-#define PEERS_H
-
-#include <QObject>
-#include <QStandardItemModel>
-#include "wpamsg.h"
-#include "ui_peers.h"
-
-class WpaGui;
-
-class Peers : public QDialog, public Ui::Peers
-{
- Q_OBJECT
-
-public:
- Peers(QWidget *parent = 0, const char *name = 0,
- bool modal = false, Qt::WindowFlags fl = 0);
- ~Peers();
- void setWpaGui(WpaGui *_wpagui);
- void event_notify(WpaMsg msg);
-
-public slots:
- virtual void context_menu(const QPoint &pos);
- virtual void enter_pin();
- virtual void connect_pbc();
- virtual void learn_ap_config();
- virtual void ctx_refresh();
- virtual void ctx_p2p_start();
- virtual void ctx_p2p_stop();
- virtual void ctx_p2p_listen();
- virtual void ctx_p2p_start_group();
- virtual void ctx_p2p_remove_group();
- virtual void ctx_p2p_connect();
- virtual void ctx_p2p_req_pin();
- virtual void ctx_p2p_show_pin();
- virtual void ctx_p2p_display_pin();
- virtual void ctx_p2p_display_pin_pd();
- virtual void ctx_p2p_enter_pin();
- virtual void properties();
- virtual void ctx_hide_ap();
- virtual void ctx_show_ap();
- virtual void ctx_p2p_show_passphrase();
- virtual void ctx_p2p_start_persistent();
- virtual void ctx_p2p_invite();
- virtual void ctx_p2p_delete();
-
-protected slots:
- virtual void languageChange();
- virtual void closeEvent(QCloseEvent *event);
-
-private:
- void add_station(QString info);
- void add_stations();
- void add_single_station(const char *addr);
- bool add_bss(const char *cmd);
- void remove_bss(int id);
- void add_scan_results();
- void add_persistent(int id, const char *ssid, const char *bssid);
- void add_persistent_groups();
- void update_peers();
- QStandardItem * find_addr(QString addr);
- QStandardItem * find_addr_type(QString addr, int type);
- void add_p2p_group_client(QStandardItem *parent, QString params);
- QStandardItem * find_uuid(QString uuid);
- void done(int r);
- void remove_enrollee_uuid(QString uuid);
- QString ItemType(int type);
- void enable_persistent(int id);
-
- WpaGui *wpagui;
- QStandardItemModel model;
- QIcon *default_icon;
- QIcon *ap_icon;
- QIcon *laptop_icon;
- QIcon *group_icon;
- QIcon *invitation_icon;
- QStandardItem *ctx_item;
-
- bool hide_ap;
-};
-
-#endif /* PEERS_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.ui b/wpa_supplicant/wpa_gui-qt4/peers.ui
deleted file mode 100644
index 9508c254b70e..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/peers.ui
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Peers</class>
- <widget class="QDialog" name="Peers">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Peers</string>
- </property>
- <layout class="QGridLayout">
- <item row="0" column="0">
- <widget class="QListView" name="peers">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="mouseTracking">
- <bool>true</bool>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- <property name="viewMode">
- <enum>QListView::IconMode</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp b/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
deleted file mode 100644
index a2e3072fb6e1..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * wpa_gui - ScanResults class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-
-#include "scanresults.h"
-#include "signalbar.h"
-#include "wpagui.h"
-#include "networkconfig.h"
-#include "scanresultsitem.h"
-
-
-ScanResults::ScanResults(QWidget *parent, const char *, bool, Qt::WindowFlags)
- : QDialog(parent)
-{
- setupUi(this);
-
- connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
- connect(scanButton, SIGNAL(clicked()), this, SLOT(scanRequest()));
- connect(scanResultsWidget,
- SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
- SLOT(bssSelected(QTreeWidgetItem *)));
-
- wpagui = NULL;
- scanResultsWidget->setItemsExpandable(false);
- scanResultsWidget->setRootIsDecorated(false);
- scanResultsWidget->setItemDelegate(new SignalBar(scanResultsWidget));
-}
-
-
-ScanResults::~ScanResults()
-{
-}
-
-
-void ScanResults::languageChange()
-{
- retranslateUi(this);
-}
-
-
-void ScanResults::setWpaGui(WpaGui *_wpagui)
-{
- wpagui = _wpagui;
- updateResults();
-}
-
-
-void ScanResults::updateResults()
-{
- char reply[2048];
- size_t reply_len;
- int index;
- char cmd[20];
-
- scanResultsWidget->clear();
-
- index = 0;
- while (wpagui) {
- snprintf(cmd, sizeof(cmd), "BSS %d", index++);
- if (index > 1000)
- break;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
- break;
- reply[reply_len] = '\0';
-
- QString bss(reply);
- if (bss.isEmpty() || bss.startsWith("FAIL"))
- break;
-
- QString ssid, bssid, freq, signal, flags;
-
- QStringList lines = bss.split(QRegExp("\\n"));
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- int pos = (*it).indexOf('=') + 1;
- if (pos < 1)
- continue;
-
- if ((*it).startsWith("bssid="))
- bssid = (*it).mid(pos);
- else if ((*it).startsWith("freq="))
- freq = (*it).mid(pos);
- else if ((*it).startsWith("level="))
- signal = (*it).mid(pos);
- else if ((*it).startsWith("flags="))
- flags = (*it).mid(pos);
- else if ((*it).startsWith("ssid="))
- ssid = (*it).mid(pos);
- }
-
- ScanResultsItem *item = new ScanResultsItem(scanResultsWidget);
- if (item) {
- item->setText(0, ssid);
- item->setText(1, bssid);
- item->setText(2, freq);
- item->setText(3, signal);
- item->setText(4, flags);
- }
-
- if (bssid.isEmpty())
- break;
- }
-}
-
-
-void ScanResults::scanRequest()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL)
- return;
-
- wpagui->ctrlRequest("SCAN", reply, &reply_len);
-}
-
-
-void ScanResults::getResults()
-{
- updateResults();
-}
-
-
-void ScanResults::bssSelected(QTreeWidgetItem *sel)
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(wpagui);
- nc->paramsFromScanResults(sel);
- nc->show();
- nc->exec();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.h b/wpa_supplicant/wpa_gui-qt4/scanresults.h
deleted file mode 100644
index 2cddd133fe2b..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * wpa_gui - ScanResults class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SCANRESULTS_H
-#define SCANRESULTS_H
-
-#include <QObject>
-#include "ui_scanresults.h"
-
-class WpaGui;
-
-class ScanResults : public QDialog, public Ui::ScanResults
-{
- Q_OBJECT
-
-public:
- ScanResults(QWidget *parent = 0, const char *name = 0,
- bool modal = false, Qt::WindowFlags fl = 0);
- ~ScanResults();
-
-public slots:
- virtual void setWpaGui(WpaGui *_wpagui);
- virtual void updateResults();
- virtual void scanRequest();
- virtual void getResults();
- virtual void bssSelected(QTreeWidgetItem *sel);
-
-protected slots:
- virtual void languageChange();
-
-private:
- WpaGui *wpagui;
-};
-
-#endif /* SCANRESULTS_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.ui b/wpa_supplicant/wpa_gui-qt4/scanresults.ui
deleted file mode 100644
index 81e405efc319..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.ui
+++ /dev/null
@@ -1,94 +0,0 @@
-<ui version="4.0" >
- <class>ScanResults</class>
- <widget class="QDialog" name="ScanResults" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>452</width>
- <height>244</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Scan results</string>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QTreeWidget" name="scanResultsWidget" >
- <property name="editTriggers" >
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- <property name="uniformRowHeights" >
- <bool>true</bool>
- </property>
- <property name="sortingEnabled" >
- <bool>true</bool>
- </property>
- <property name="columnCount" >
- <number>5</number>
- </property>
- <column>
- <property name="text" >
- <string>SSID</string>
- </property>
- </column>
- <column>
- <property name="text" >
- <string>BSSID</string>
- </property>
- </column>
- <column>
- <property name="text" >
- <string>frequency</string>
- </property>
- </column>
- <column>
- <property name="text" >
- <string>signal</string>
- </property>
- </column>
- <column>
- <property name="text" >
- <string>flags</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="scanButton" >
- <property name="text" >
- <string>Scan</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="closeButton" >
- <property name="text" >
- <string>Close</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <resources/>
- <connections/>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.cpp b/wpa_supplicant/wpa_gui-qt4/scanresultsitem.cpp
deleted file mode 100644
index 9cd937cd6e24..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * wpa_gui - ScanResultsItem class
- * Copyright (c) 2015, Adrian Nowicki <adinowicki@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "scanresultsitem.h"
-
-bool ScanResultsItem::operator< (const QTreeWidgetItem &other) const
-{
- int sortCol = treeWidget()->sortColumn();
- if (sortCol == 2 || sortCol == 3) {
- return text(sortCol).toInt() < other.text(sortCol).toInt();
- }
- return text(sortCol) < other.text(sortCol);
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h b/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h
deleted file mode 100644
index 74887eefb59c..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * wpa_gui - ScanResultsItem class
- * Copyright (c) 2015, Adrian Nowicki <adinowicki@gmail.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SCANRESULTSITEM_H
-#define SCANRESULTSITEM_H
-
-#include <QTreeWidgetItem>
-
-class ScanResultsItem : public QTreeWidgetItem
-{
-public:
- ScanResultsItem(QTreeWidget *tree) : QTreeWidgetItem(tree) {}
- bool operator< (const QTreeWidgetItem &other) const;
-};
-
-#endif /* SCANRESULTSITEM_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/signalbar.cpp b/wpa_supplicant/wpa_gui-qt4/signalbar.cpp
deleted file mode 100644
index 2bba582175e5..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/signalbar.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * wpa_gui - SignalBar class
- * Copyright (c) 2011, Kel Modderman <kel@otaku42.de>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-#include <qapplication.h>
-
-#include "signalbar.h"
-
-
-SignalBar::SignalBar(QObject *parent)
- : QStyledItemDelegate(parent)
-{
-}
-
-
-SignalBar::~SignalBar()
-{
-}
-
-
-void SignalBar::paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const
-{
- QStyleOptionProgressBar opts;
- int signal;
-
- if (index.column() != 3) {
- QStyledItemDelegate::paint(painter, option, index);
- return;
- }
-
- if (index.data().toInt() > 0)
- signal = 0 - (256 - index.data().toInt());
- else
- signal = index.data().toInt();
-
- opts.minimum = -95;
- opts.maximum = -35;
- if (signal < opts.minimum)
- opts.progress = opts.minimum;
- else if (signal > opts.maximum)
- opts.progress = opts.maximum;
- else
- opts.progress = signal;
-
- opts.text = QString::number(signal) + " dBm";
- opts.textVisible = true;
- opts.rect = option.rect;
-
- QApplication::style()->drawControl(QStyle::CE_ProgressBar,
- &opts, painter);
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/signalbar.h b/wpa_supplicant/wpa_gui-qt4/signalbar.h
deleted file mode 100644
index 37da5dd2ce94..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/signalbar.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * wpa_gui - SignalBar class
- * Copyright (c) 2011, Kel Modderman <kel@otaku42.de>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef SIGNALBAR_H
-#define SIGNALBAR_H
-
-#include <QObject>
-#include <QStyledItemDelegate>
-
-class SignalBar : public QStyledItemDelegate
-{
- Q_OBJECT
-
-public:
- SignalBar(QObject *parent = 0);
- ~SignalBar();
-
- virtual void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const ;
-};
-
-#endif /* SIGNALBAR_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/stringquery.cpp b/wpa_supplicant/wpa_gui-qt4/stringquery.cpp
deleted file mode 100644
index 420e0bec4d04..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/stringquery.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * wpa_gui - StringQuery class
- * Copyright (c) 2009, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <cstdio>
-#include <QLabel>
-
-#include "stringquery.h"
-
-
-StringQuery::StringQuery(QString label)
-{
- edit = new QLineEdit;
- edit->setFocus();
- QGridLayout *layout = new QGridLayout;
- layout->addWidget(new QLabel(label), 0, 0);
- layout->addWidget(edit, 0, 1);
- setLayout(layout);
-
- connect(edit, SIGNAL(returnPressed()), this, SLOT(accept()));
-}
-
-
-QString StringQuery::get_string()
-{
- return edit->text();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/stringquery.h b/wpa_supplicant/wpa_gui-qt4/stringquery.h
deleted file mode 100644
index 9d6bffd3e7b6..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/stringquery.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * wpa_gui - StringQuery class
- * Copyright (c) 2009, Atheros Communications
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef STRINGQUERY_H
-#define STRINGQUERY_H
-
-#include <QDialog>
-#include <QLineEdit>
-#include <QGridLayout>
-
-class StringQuery : public QDialog
-{
- Q_OBJECT
-
-public:
- StringQuery(QString label);
- QString get_string();
-
-private:
- QLineEdit *edit;
-};
-
-#endif /* STRINGQUERY_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp b/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp
deleted file mode 100644
index 9d933b012053..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * wpa_gui - UserDataRequest class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "userdatarequest.h"
-#include "wpagui.h"
-#include "common/wpa_ctrl.h"
-
-
-UserDataRequest::UserDataRequest(QWidget *parent, const char *, bool,
- Qt::WindowFlags)
- : QDialog(parent)
-{
- setupUi(this);
-
- connect(buttonOk, SIGNAL(clicked()), this, SLOT(sendReply()));
- connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
- connect(queryEdit, SIGNAL(returnPressed()), this, SLOT(sendReply()));
-}
-
-
-UserDataRequest::~UserDataRequest()
-{
-}
-
-
-void UserDataRequest::languageChange()
-{
- retranslateUi(this);
-}
-
-
-int UserDataRequest::setParams(WpaGui *_wpagui, const char *reqMsg)
-{
- char *tmp, *pos, *pos2;
- wpagui = _wpagui;
- tmp = strdup(reqMsg);
- if (tmp == NULL)
- return -1;
- pos = strchr(tmp, '-');
- if (pos == NULL) {
- free(tmp);
- return -1;
- }
- *pos++ = '\0';
- field = tmp;
- pos2 = strchr(pos, ':');
- if (pos2 == NULL) {
- free(tmp);
- return -1;
- }
- *pos2++ = '\0';
-
- networkid = atoi(pos);
- queryInfo->setText(pos2);
- if (strcmp(tmp, "PASSWORD") == 0) {
- queryField->setText(tr("Password: "));
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "NEW_PASSWORD") == 0) {
- queryField->setText(tr("New password: "));
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "IDENTITY") == 0)
- queryField->setText(tr("Identity: "));
- else if (strcmp(tmp, "PASSPHRASE") == 0) {
- queryField->setText(tr("Private key passphrase: "));
- queryEdit->setEchoMode(QLineEdit::Password);
- } else
- queryField->setText(field + ":");
- free(tmp);
-
- return 0;
-}
-
-
-void UserDataRequest::sendReply()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL) {
- reject();
- return;
- }
-
- QString cmd = QString(WPA_CTRL_RSP) + field + '-' +
- QString::number(networkid) + ':' +
- queryEdit->text();
- wpagui->ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
- accept();
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/userdatarequest.h b/wpa_supplicant/wpa_gui-qt4/userdatarequest.h
deleted file mode 100644
index b6d1ad2f4f1e..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/userdatarequest.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * wpa_gui - UserDataRequest class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef USERDATAREQUEST_H
-#define USERDATAREQUEST_H
-
-#include <QObject>
-#include "ui_userdatarequest.h"
-
-class WpaGui;
-
-class UserDataRequest : public QDialog, public Ui::UserDataRequest
-{
- Q_OBJECT
-
-public:
- UserDataRequest(QWidget *parent = 0, const char *name = 0,
- bool modal = false, Qt::WindowFlags fl = 0);
- ~UserDataRequest();
-
- int setParams(WpaGui *_wpagui, const char *reqMsg);
-
-public slots:
- virtual void sendReply();
-
-protected slots:
- virtual void languageChange();
-
-private:
- WpaGui *wpagui;
- int networkid;
- QString field;
-};
-
-#endif /* USERDATAREQUEST_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui b/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui
deleted file mode 100644
index 1de2a26da1cd..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui
+++ /dev/null
@@ -1,109 +0,0 @@
-<ui version="4.0" stdsetdef="1" >
- <author></author>
- <comment></comment>
- <exportmacro></exportmacro>
- <class>UserDataRequest</class>
- <widget class="QDialog" name="UserDataRequest" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>216</width>
- <height>103</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Authentication credentials required</string>
- </property>
- <property name="sizeGripEnabled" >
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QLabel" name="queryInfo" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="queryField" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="queryEdit" >
- <property name="enabled" >
- <bool>true</bool>
- </property>
- <property name="echoMode" >
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <spacer name="spacer4" >
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- <property name="sizeType" >
- <enum>Expanding</enum>
- </property>
- <property name="orientation" >
- <enum>Horizontal</enum>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="buttonOk" >
- <property name="text" >
- <string>&amp;OK</string>
- </property>
- <property name="shortcut" >
- <string/>
- </property>
- <property name="autoDefault" >
- <bool>true</bool>
- </property>
- <property name="default" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="buttonCancel" >
- <property name="text" >
- <string>&amp;Cancel</string>
- </property>
- <property name="shortcut" >
- <string/>
- </property>
- <property name="autoDefault" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop
deleted file mode 100644
index ccc7d8741d02..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop
+++ /dev/null
@@ -1,10 +0,0 @@
-[Desktop Entry]
-Version=1.0
-Name=wpa_gui
-Comment=Graphical user interface for wpa_supplicant
-Exec=wpa_gui
-Icon=wpa_gui
-GenericName=wpa_supplicant user interface
-Terminal=false
-Type=Application
-Categories=Qt;Network;
diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro b/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
deleted file mode 100644
index 3fa734b57758..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
+++ /dev/null
@@ -1,73 +0,0 @@
-TEMPLATE = app
-LANGUAGE = C++
-TRANSLATIONS = lang/wpa_gui_de.ts
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
-CONFIG += qt warn_on release
-
-DEFINES += CONFIG_CTRL_IFACE
-
-win32 {
- LIBS += -lws2_32 -static
- DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
- SOURCES += ../../src/utils/os_win32.c
-} else:win32-g++ {
- # cross compilation to win32
- LIBS += -lws2_32 -static -mwindows
- DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
- SOURCES += ../../src/utils/os_win32.c
- RESOURCES += icons_png.qrc
-} else:win32-x-g++ {
- # cross compilation to win32
- LIBS += -lws2_32 -static -mwindows
- DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
- DEFINES += _X86_
- SOURCES += ../../src/utils/os_win32.c
- RESOURCES += icons_png.qrc
-} else {
- DEFINES += CONFIG_CTRL_IFACE_UNIX
- SOURCES += ../../src/utils/os_unix.c
-}
-
-INCLUDEPATH += . .. ../../src ../../src/utils
-
-HEADERS += wpamsg.h \
- wpagui.h \
- eventhistory.h \
- scanresults.h \
- scanresultsitem.h \
- signalbar.h \
- userdatarequest.h \
- networkconfig.h \
- addinterface.h \
- peers.h \
- stringquery.h
-
-SOURCES += main.cpp \
- wpagui.cpp \
- eventhistory.cpp \
- scanresults.cpp \
- scanresultsitem.cpp \
- signalbar.cpp \
- userdatarequest.cpp \
- networkconfig.cpp \
- addinterface.cpp \
- peers.cpp \
- stringquery.cpp \
- ../../src/common/wpa_ctrl.c
-
-RESOURCES += icons.qrc
-
-FORMS = wpagui.ui \
- eventhistory.ui \
- scanresults.ui \
- userdatarequest.ui \
- networkconfig.ui \
- peers.ui
-
-
-unix {
- UI_DIR = .ui
- MOC_DIR = .moc
- OBJECTS_DIR = .obj
-}
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
deleted file mode 100644
index 9404ab4249b7..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
+++ /dev/null
@@ -1,1913 +0,0 @@
-/*
- * wpa_gui - WpaGui class
- * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <windows.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-#include <cstdio>
-#include <unistd.h>
-#include <chrono>
-#include <thread>
-#include <QMessageBox>
-#include <QCloseEvent>
-#include <QImageReader>
-#include <QSettings>
-
-#include "wpagui.h"
-#include "dirent.h"
-#include "common/wpa_ctrl.h"
-#include "userdatarequest.h"
-#include "networkconfig.h"
-
-
-#ifndef QT_NO_DEBUG
-#define debug(M, ...) qDebug("DEBUG %d: " M, __LINE__, ##__VA_ARGS__)
-#else
-#define debug(M, ...) do {} while (0)
-#endif
-
-
-WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *,
- Qt::WindowFlags)
- : QMainWindow(parent), app(_app)
-{
- setupUi(this);
- this->setWindowFlags(Qt::Dialog);
-
-#ifdef CONFIG_NATIVE_WINDOWS
- fileStopServiceAction = new QAction(this);
- fileStopServiceAction->setObjectName("Stop Service");
- fileStopServiceAction->setIconText(tr("Stop Service"));
- fileMenu->insertAction(actionWPS, fileStopServiceAction);
-
- fileStartServiceAction = new QAction(this);
- fileStartServiceAction->setObjectName("Start Service");
- fileStartServiceAction->setIconText(tr("Start Service"));
- fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
-
- connect(fileStartServiceAction, SIGNAL(triggered()), this,
- SLOT(startService()));
- connect(fileStopServiceAction, SIGNAL(triggered()), this,
- SLOT(stopService()));
-
- addInterfaceAction = new QAction(this);
- addInterfaceAction->setIconText(tr("Add Interface"));
- fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
-
- connect(addInterfaceAction, SIGNAL(triggered()), this,
- SLOT(addInterface()));
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- (void) statusBar();
-
- /*
- * Disable WPS tab by default; it will be enabled if wpa_supplicant is
- * built with WPS support.
- */
- wpsTab->setEnabled(false);
- wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), false);
-
- connect(fileEventHistoryAction, SIGNAL(triggered()), this,
- SLOT(eventHistory()));
- connect(fileSaveConfigAction, SIGNAL(triggered()), this,
- SLOT(saveConfig()));
- connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
- connect(actionPeers, SIGNAL(triggered()), this, SLOT(peersDialog()));
- connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
- connect(networkAddAction, SIGNAL(triggered()), this,
- SLOT(addNetwork()));
- connect(networkEditAction, SIGNAL(triggered()), this,
- SLOT(editSelectedNetwork()));
- connect(networkRemoveAction, SIGNAL(triggered()), this,
- SLOT(removeSelectedNetwork()));
- connect(networkEnableAllAction, SIGNAL(triggered()), this,
- SLOT(enableAllNetworks()));
- connect(networkDisableAllAction, SIGNAL(triggered()), this,
- SLOT(disableAllNetworks()));
- connect(networkRemoveAllAction, SIGNAL(triggered()), this,
- SLOT(removeAllNetworks()));
- connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
- connect(helpContentsAction, SIGNAL(triggered()), this,
- SLOT(helpContents()));
- connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
- connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
- connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
- connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
- connect(adapterSelect, SIGNAL(activated(const QString&)), this,
- SLOT(selectAdapter(const QString&)));
- connect(networkSelect, SIGNAL(activated(const QString&)), this,
- SLOT(selectNetwork(const QString&)));
- connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
- connect(editNetworkButton, SIGNAL(clicked()), this,
- SLOT(editListedNetwork()));
- connect(removeNetworkButton, SIGNAL(clicked()), this,
- SLOT(removeListedNetwork()));
- connect(networkList, SIGNAL(itemSelectionChanged()), this,
- SLOT(updateNetworkDisabledStatus()));
- connect(enableRadioButton, SIGNAL(toggled(bool)), this,
- SLOT(enableListedNetwork(bool)));
- connect(disableRadioButton, SIGNAL(toggled(bool)), this,
- SLOT(disableListedNetwork(bool)));
- connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
- connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
- this, SLOT(editListedNetwork()));
- connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
- SLOT(tabChanged(int)));
- connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
- connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
- connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
- SLOT(wpsApPinChanged(const QString &)));
- connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
-
- eh = NULL;
- scanres = NULL;
- peers = NULL;
- add_iface = NULL;
- udr = NULL;
- tray_icon = NULL;
- startInTray = false;
- quietMode = false;
- ctrl_iface = NULL;
- ctrl_conn = NULL;
- monitor_conn = NULL;
- msgNotifier = NULL;
- ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
- signalMeterInterval = 0;
-
- parse_argv();
-
-#ifndef QT_NO_SESSIONMANAGER
- if (app->isSessionRestored()) {
- QSettings settings("wpa_supplicant", "wpa_gui");
- settings.beginGroup("state");
- if (app->sessionId().compare(settings.value("session_id").
- toString()) == 0)
- startInTray = settings.value("in_tray").toBool();
- settings.endGroup();
- }
-#endif
-
- if (QSystemTrayIcon::isSystemTrayAvailable())
- createTrayIcon(startInTray);
- else
- show();
-
- connectedToService = false;
- textStatus->setText(tr("connecting to wpa_supplicant"));
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(ping()));
- timer->setSingleShot(false);
- timer->start(1000);
-
- signalMeterTimer = new QTimer(this);
- signalMeterTimer->setInterval(signalMeterInterval);
- connect(signalMeterTimer, SIGNAL(timeout()), SLOT(signalMeterUpdate()));
-
- if (openCtrlConnection(ctrl_iface) < 0) {
- debug("Failed to open control connection to "
- "wpa_supplicant.");
- }
-
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-WpaGui::~WpaGui()
-{
- delete msgNotifier;
-
- if (monitor_conn) {
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (eh) {
- eh->close();
- delete eh;
- eh = NULL;
- }
-
- if (scanres) {
- scanres->close();
- delete scanres;
- scanres = NULL;
- }
-
- if (peers) {
- peers->close();
- delete peers;
- peers = NULL;
- }
-
- if (add_iface) {
- add_iface->close();
- delete add_iface;
- add_iface = NULL;
- }
-
- if (udr) {
- udr->close();
- delete udr;
- udr = NULL;
- }
-
- free(ctrl_iface);
- ctrl_iface = NULL;
-
- free(ctrl_iface_dir);
- ctrl_iface_dir = NULL;
-}
-
-
-void WpaGui::languageChange()
-{
- retranslateUi(this);
-}
-
-
-void WpaGui::parse_argv()
-{
- int c;
- WpaGuiApp *app = qobject_cast<WpaGuiApp*>(qApp);
- for (;;) {
- c = getopt(app->argc, app->argv, "i:m:p:tq");
- if (c < 0)
- break;
- switch (c) {
- case 'i':
- free(ctrl_iface);
- ctrl_iface = strdup(optarg);
- break;
- case 'm':
- signalMeterInterval = atoi(optarg) * 1000;
- break;
- case 'p':
- free(ctrl_iface_dir);
- ctrl_iface_dir = strdup(optarg);
- break;
- case 't':
- startInTray = true;
- break;
- case 'q':
- quietMode = true;
- break;
- }
- }
-}
-
-
-int WpaGui::openCtrlConnection(const char *ifname)
-{
- char *cfile;
- int flen;
- char buf[2048], *pos, *pos2;
- size_t len;
-
- if (ifname) {
- if (ifname != ctrl_iface) {
- free(ctrl_iface);
- ctrl_iface = strdup(ifname);
- }
- } else {
-#ifdef CONFIG_CTRL_IFACE_UDP
- free(ctrl_iface);
- ctrl_iface = strdup("udp");
-#endif /* CONFIG_CTRL_IFACE_UDP */
-#ifdef CONFIG_CTRL_IFACE_UNIX
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- free(ctrl_iface);
- ctrl_iface = NULL;
- if (dir) {
- while ((dent = readdir(dir))) {
-#ifdef _DIRENT_HAVE_D_TYPE
- /* Skip the file if it is not a socket.
- * Also accept DT_UNKNOWN (0) in case
- * the C library or underlying file
- * system does not support d_type. */
- if (dent->d_type != DT_SOCK &&
- dent->d_type != DT_UNKNOWN)
- continue;
-#endif /* _DIRENT_HAVE_D_TYPE */
-
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- debug("Selected interface '%s'",
- dent->d_name);
- ctrl_iface = strdup(dent->d_name);
- break;
- }
- closedir(dir);
- }
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- struct wpa_ctrl *ctrl;
- int ret;
-
- free(ctrl_iface);
- ctrl_iface = NULL;
-
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl) {
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
- &len, NULL);
- if (ret >= 0) {
- connectedToService = true;
- buf[len] = '\0';
- pos = strchr(buf, '\n');
- if (pos)
- *pos = '\0';
- ctrl_iface = strdup(buf);
- }
- wpa_ctrl_close(ctrl);
- }
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- }
-
- if (ctrl_iface == NULL) {
-#ifdef CONFIG_NATIVE_WINDOWS
- static bool first = true;
- if (first && !serviceRunning()) {
- first = false;
- if (QMessageBox::warning(
- this, qAppName(),
- tr("wpa_supplicant service is not "
- "running.\n"
- "Do you want to start it?"),
- QMessageBox::Yes | QMessageBox::No) ==
- QMessageBox::Yes)
- startService();
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
- return -1;
- }
-
-#ifdef CONFIG_CTRL_IFACE_UNIX
- flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
- cfile = (char *) malloc(flen);
- if (cfile == NULL)
- return -1;
- snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
-#else /* CONFIG_CTRL_IFACE_UNIX */
- flen = strlen(ctrl_iface) + 1;
- cfile = (char *) malloc(flen);
- if (cfile == NULL)
- return -1;
- snprintf(cfile, flen, "%s", ctrl_iface);
-#endif /* CONFIG_CTRL_IFACE_UNIX */
-
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (monitor_conn) {
- delete msgNotifier;
- msgNotifier = NULL;
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
-
- debug("Trying to connect to '%s'", cfile);
- ctrl_conn = wpa_ctrl_open(cfile);
- if (ctrl_conn == NULL) {
- free(cfile);
- return -1;
- }
- monitor_conn = wpa_ctrl_open(cfile);
- free(cfile);
- if (monitor_conn == NULL) {
- wpa_ctrl_close(ctrl_conn);
- return -1;
- }
- if (wpa_ctrl_attach(monitor_conn)) {
- debug("Failed to attach to wpa_supplicant");
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- return -1;
- }
-
-#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
- msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
- QSocketNotifier::Read, this);
- connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
-#endif
-
- adapterSelect->clear();
- adapterSelect->addItem(ctrl_iface);
- adapterSelect->setCurrentIndex(0);
-
- len = sizeof(buf) - 1;
- if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
- 0) {
- buf[len] = '\0';
- pos = buf;
- while (*pos) {
- pos2 = strchr(pos, '\n');
- if (pos2)
- *pos2 = '\0';
- if (strcmp(pos, ctrl_iface) != 0)
- adapterSelect->addItem(pos);
- if (pos2)
- pos = pos2 + 1;
- else
- break;
- }
- }
-
- len = sizeof(buf) - 1;
- if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
- NULL) >= 0) {
- buf[len] = '\0';
-
- QString res(buf);
- QStringList types = res.split(QChar(' '));
- bool wps = types.contains("WSC");
- actionWPS->setEnabled(wps);
- wpsTab->setEnabled(wps);
- wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
- }
-
- return 0;
-}
-
-
-int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
-{
- int ret;
-
- if (ctrl_conn == NULL)
- return -3;
- ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL);
- if (ret == -2)
- debug("'%s' command timed out.", cmd);
- else if (ret < 0)
- debug("'%s' command failed.", cmd);
-
- return ret;
-}
-
-
-QString WpaGui::wpaStateTranslate(char *state)
-{
- if (!strcmp(state, "DISCONNECTED"))
- return tr("Disconnected");
- else if (!strcmp(state, "INACTIVE"))
- return tr("Inactive");
- else if (!strcmp(state, "SCANNING"))
- return tr("Scanning");
- else if (!strcmp(state, "AUTHENTICATING"))
- return tr("Authenticating");
- else if (!strcmp(state, "ASSOCIATING"))
- return tr("Associating");
- else if (!strcmp(state, "ASSOCIATED"))
- return tr("Associated");
- else if (!strcmp(state, "4WAY_HANDSHAKE"))
- return tr("4-Way Handshake");
- else if (!strcmp(state, "GROUP_HANDSHAKE"))
- return tr("Group Handshake");
- else if (!strcmp(state, "COMPLETED"))
- return tr("Completed");
- else
- return tr("Unknown");
-}
-
-
-void WpaGui::updateStatus()
-{
- char buf[2048], *start, *end, *pos;
- size_t len;
-
- pingsToStatusUpdate = 10;
-
- len = sizeof(buf) - 1;
- if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
- textStatus->setText(tr("Could not get status from "
- "wpa_supplicant"));
- textAuthentication->clear();
- textEncryption->clear();
- textSsid->clear();
- textBssid->clear();
- textIpAddress->clear();
- updateTrayToolTip(tr("no status information"));
- updateTrayIcon(TrayIconOffline);
- signalMeterTimer->stop();
-
-#ifdef CONFIG_NATIVE_WINDOWS
- static bool first = true;
- if (first && connectedToService &&
- (ctrl_iface == NULL || *ctrl_iface == '\0')) {
- first = false;
- if (QMessageBox::information(
- this, qAppName(),
- tr("No network interfaces in use.\n"
- "Would you like to add one?"),
- QMessageBox::Yes | QMessageBox::No) ==
- QMessageBox::Yes)
- addInterface();
- }
-#endif /* CONFIG_NATIVE_WINDOWS */
- return;
- }
-
- buf[len] = '\0';
-
- bool auth_updated = false, ssid_updated = false;
- bool bssid_updated = false, ipaddr_updated = false;
- bool status_updated = false;
- char *pairwise_cipher = NULL, *group_cipher = NULL;
- char *mode = NULL;
-
- start = buf;
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- pos = strchr(start, '=');
- if (pos) {
- *pos++ = '\0';
- if (strcmp(start, "bssid") == 0) {
- bssid_updated = true;
- textBssid->setText(pos);
- } else if (strcmp(start, "ssid") == 0) {
- ssid_updated = true;
- textSsid->setText(pos);
- updateTrayToolTip(pos + tr(" (associated)"));
- if (!signalMeterInterval) {
- /* if signal meter is not enabled show
- * full signal strength */
- updateTrayIcon(TrayIconSignalExcellent);
- }
- } else if (strcmp(start, "ip_address") == 0) {
- ipaddr_updated = true;
- textIpAddress->setText(pos);
- } else if (strcmp(start, "wpa_state") == 0) {
- status_updated = true;
- textStatus->setText(wpaStateTranslate(pos));
- } else if (strcmp(start, "key_mgmt") == 0) {
- auth_updated = true;
- textAuthentication->setText(pos);
- /* TODO: could add EAP status to this */
- } else if (strcmp(start, "pairwise_cipher") == 0) {
- pairwise_cipher = pos;
- } else if (strcmp(start, "group_cipher") == 0) {
- group_cipher = pos;
- } else if (strcmp(start, "mode") == 0) {
- mode = pos;
- }
- }
-
- if (last)
- break;
- start = end + 1;
- }
- if (status_updated && mode)
- textStatus->setText(textStatus->text() + " (" + mode + ")");
-
- if (pairwise_cipher || group_cipher) {
- QString encr;
- if (pairwise_cipher && group_cipher &&
- strcmp(pairwise_cipher, group_cipher) != 0) {
- encr.append(pairwise_cipher);
- encr.append(" + ");
- encr.append(group_cipher);
- } else if (pairwise_cipher) {
- encr.append(pairwise_cipher);
- } else {
- encr.append(group_cipher);
- encr.append(" [group key only]");
- }
- textEncryption->setText(encr);
- } else
- textEncryption->clear();
-
- if (signalMeterInterval) {
- /*
- * Handle signal meter service. When network is not associated,
- * deactivate timer, otherwise keep it going. Tray icon has to
- * be initialized here, because of the initial delay of the
- * timer.
- */
- if (ssid_updated) {
- if (!signalMeterTimer->isActive()) {
- updateTrayIcon(TrayIconConnected);
- signalMeterTimer->start();
- }
- } else {
- signalMeterTimer->stop();
- }
- }
-
- if (!status_updated)
- textStatus->clear();
- if (!auth_updated)
- textAuthentication->clear();
- if (!ssid_updated) {
- textSsid->clear();
- updateTrayToolTip(tr("(not-associated)"));
- updateTrayIcon(TrayIconOffline);
- }
- if (!bssid_updated)
- textBssid->clear();
- if (!ipaddr_updated)
- textIpAddress->clear();
-}
-
-
-void WpaGui::updateNetworks()
-{
- char buf[4096], *start, *end, *id, *ssid, *bssid, *flags;
- size_t len;
- int first_active = -1;
- int was_selected = -1;
- bool current = false;
-
- if (!networkMayHaveChanged)
- return;
-
- if (networkList->currentRow() >= 0)
- was_selected = networkList->currentRow();
-
- networkSelect->clear();
- networkList->clear();
-
- if (ctrl_conn == NULL)
- return;
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
- return;
-
- buf[len] = '\0';
- start = strchr(buf, '\n');
- if (start == NULL)
- return;
- start++;
-
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- id = start;
- ssid = strchr(id, '\t');
- if (ssid == NULL)
- break;
- *ssid++ = '\0';
- bssid = strchr(ssid, '\t');
- if (bssid == NULL)
- break;
- *bssid++ = '\0';
- flags = strchr(bssid, '\t');
- if (flags == NULL)
- break;
- *flags++ = '\0';
-
- if (strstr(flags, "[DISABLED][P2P-PERSISTENT]")) {
- if (last)
- break;
- start = end + 1;
- continue;
- }
-
- QString network(id);
- network.append(": ");
- network.append(ssid);
- networkSelect->addItem(network);
- networkList->addItem(network);
-
- if (strstr(flags, "[CURRENT]")) {
- networkSelect->setCurrentIndex(networkSelect->count() -
- 1);
- current = true;
- } else if (first_active < 0 &&
- strstr(flags, "[DISABLED]") == NULL)
- first_active = networkSelect->count() - 1;
-
- start = end + 1;
- if (*start && strchr(start, '\n'))
- continue;
-
- /* avoid race conditions */
- std::this_thread::sleep_for(std::chrono::milliseconds(200));
- QString cmd("LIST_NETWORKS LAST_ID=");
- cmd.append(id);
- if (ctrlRequest(cmd.toLocal8Bit().constData(), buf, &len) < 0)
- break;
-
- buf[len] = '\0';
- start = strchr(buf, '\n');
- if (!start)
- break;
- start++;
- }
-
- if (networkSelect->count() > 1)
- networkSelect->addItem(tr("Select any network"));
-
- if (!current && first_active >= 0)
- networkSelect->setCurrentIndex(first_active);
-
- if (was_selected >= 0 && networkList->count() > 0) {
- if (was_selected < networkList->count())
- networkList->setCurrentRow(was_selected);
- else
- networkList->setCurrentRow(networkList->count() - 1);
- }
- else
- networkList->setCurrentRow(networkSelect->currentIndex());
-
- networkMayHaveChanged = false;
-}
-
-
-void WpaGui::helpIndex()
-{
- debug("helpIndex");
-}
-
-
-void WpaGui::helpContents()
-{
- debug("helpContents");
-}
-
-
-void WpaGui::helpAbout()
-{
- QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2015,\n"
- "Jouni Malinen <j@w1.fi>\n"
- "and contributors.\n"
- "\n"
- "This software may be distributed under\n"
- "the terms of the BSD license.\n"
- "See README for more details.\n"
- "\n"
- "This product includes software developed\n"
- "by the OpenSSL Project for use in the\n"
- "OpenSSL Toolkit (http://www.openssl.org/)\n");
-}
-
-
-void WpaGui::disconnect()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("DISCONNECT", reply, &reply_len);
- stopWpsRun(false);
-}
-
-
-void WpaGui::scan()
-{
- if (scanres) {
- scanres->close();
- delete scanres;
- }
-
- scanres = new ScanResults();
- if (scanres == NULL)
- return;
- scanres->setWpaGui(this);
- scanres->show();
- scanres->exec();
-}
-
-
-void WpaGui::eventHistory()
-{
- if (eh) {
- eh->close();
- delete eh;
- }
-
- eh = new EventHistory();
- if (eh == NULL)
- return;
- eh->addEvents(msgs);
- eh->show();
- eh->exec();
-}
-
-
-void WpaGui::ping()
-{
- char buf[10];
- size_t len;
-
-#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- /*
- * QSocketNotifier cannot be used with Windows named pipes, so use a
- * timer to check for received messages for now. This could be
- * optimized be doing something specific to named pipes or Windows
- * events, but it is not clear what would be the best way of doing that
- * in Qt.
- */
- receiveMsgs();
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-
- if (scanres && !scanres->isVisible()) {
- delete scanres;
- scanres = NULL;
- }
-
- if (eh && !eh->isVisible()) {
- delete eh;
- eh = NULL;
- }
-
- if (udr && !udr->isVisible()) {
- delete udr;
- udr = NULL;
- }
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("PING", buf, &len) < 0) {
- debug("PING failed - trying to reconnect");
- if (openCtrlConnection(ctrl_iface) >= 0) {
- debug("Reconnected successfully");
- pingsToStatusUpdate = 0;
- }
- }
-
- pingsToStatusUpdate--;
- if (pingsToStatusUpdate <= 0) {
- updateStatus();
- updateNetworks();
- }
-
-#ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
- /* Use less frequent pings and status updates when the main window is
- * hidden (running in taskbar). */
- int interval = isHidden() ? 5000 : 1000;
- if (timer->interval() != interval)
- timer->setInterval(interval);
-#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
-}
-
-
-void WpaGui::signalMeterUpdate()
-{
- char reply[128];
- size_t reply_len = sizeof(reply);
- char *rssi;
- int rssi_value;
-
- ctrlRequest("SIGNAL_POLL", reply, &reply_len);
-
- /* In order to eliminate signal strength fluctuations, try
- * to obtain averaged RSSI value in the first place. */
- if ((rssi = strstr(reply, "AVG_RSSI=")) != NULL)
- rssi_value = atoi(&rssi[sizeof("AVG_RSSI")]);
- else if ((rssi = strstr(reply, "RSSI=")) != NULL)
- rssi_value = atoi(&rssi[sizeof("RSSI")]);
- else {
- debug("Failed to get RSSI value");
- updateTrayIcon(TrayIconSignalNone);
- return;
- }
-
- debug("RSSI value: %d", rssi_value);
-
- /*
- * NOTE: The code below assumes, that the unit of the value returned
- * by the SIGNAL POLL request is dBm. It might not be true for all
- * wpa_supplicant drivers.
- */
-
- /*
- * Calibration is based on "various Internet sources". Nonetheless,
- * it seems to be compatible with the Windows 8.1 strength meter -
- * tested on Intel Centrino Advanced-N 6235.
- */
- if (rssi_value >= -60)
- updateTrayIcon(TrayIconSignalExcellent);
- else if (rssi_value >= -68)
- updateTrayIcon(TrayIconSignalGood);
- else if (rssi_value >= -76)
- updateTrayIcon(TrayIconSignalOk);
- else if (rssi_value >= -84)
- updateTrayIcon(TrayIconSignalWeak);
- else
- updateTrayIcon(TrayIconSignalNone);
-}
-
-
-static int str_match(const char *a, const char *b)
-{
- return strncmp(a, b, strlen(b)) == 0;
-}
-
-
-void WpaGui::processMsg(char *msg)
-{
- char *pos = msg, *pos2;
- int priority = 2;
-
- if (*pos == '<') {
- /* skip priority */
- pos++;
- priority = atoi(pos);
- pos = strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = msg;
- }
-
- WpaMsg wm(pos, priority);
- if (eh)
- eh->addEvent(wm);
- if (peers)
- peers->event_notify(wm);
- msgs.append(wm);
- while (msgs.count() > 100)
- msgs.pop_front();
-
- /* Update last message with truncated version of the event */
- if (strncmp(pos, "CTRL-", 5) == 0) {
- pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
- if (pos2)
- pos2++;
- else
- pos2 = pos;
- } else
- pos2 = pos;
- QString lastmsg = pos2;
- lastmsg.truncate(40);
- textLastMessage->setText(lastmsg);
-
- pingsToStatusUpdate = 0;
- networkMayHaveChanged = true;
-
- if (str_match(pos, WPA_CTRL_REQ))
- processCtrlReq(pos + strlen(WPA_CTRL_REQ));
- else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
- scanres->updateResults();
- else if (str_match(pos, WPA_EVENT_DISCONNECTED))
- showTrayMessage(QSystemTrayIcon::Information, 3,
- tr("Disconnected from network."));
- else if (str_match(pos, WPA_EVENT_CONNECTED)) {
- showTrayMessage(QSystemTrayIcon::Information, 3,
- tr("Connection to network established."));
- QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
- stopWpsRun(true);
- } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
- wpsStatusText->setText(tr("WPS AP in active PBC mode found"));
- if (textStatus->text() == "INACTIVE" ||
- textStatus->text() == "DISCONNECTED")
- wpaguiTab->setCurrentWidget(wpsTab);
- wpsInstructions->setText(tr("Press the PBC button on the "
- "screen to start registration"));
- } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
- wpsStatusText->setText(tr("WPS AP with recently selected "
- "registrar"));
- if (textStatus->text() == "INACTIVE" ||
- textStatus->text() == "DISCONNECTED")
- wpaguiTab->setCurrentWidget(wpsTab);
- } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_AUTH)) {
- showTrayMessage(QSystemTrayIcon::Information, 3,
- "Wi-Fi Protected Setup (WPS) AP\n"
- "indicating this client is authorized.");
- wpsStatusText->setText("WPS AP indicating this client is "
- "authorized");
- if (textStatus->text() == "INACTIVE" ||
- textStatus->text() == "DISCONNECTED")
- wpaguiTab->setCurrentWidget(wpsTab);
- } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
- wpsStatusText->setText(tr("WPS AP detected"));
- } else if (str_match(pos, WPS_EVENT_OVERLAP)) {
- wpsStatusText->setText(tr("PBC mode overlap detected"));
- wpsInstructions->setText(tr("More than one AP is currently in "
- "active WPS PBC mode. Wait couple "
- "of minutes and try again"));
- wpaguiTab->setCurrentWidget(wpsTab);
- } else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
- wpsStatusText->setText(tr("Network configuration received"));
- wpaguiTab->setCurrentWidget(wpsTab);
- } else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
- if (strstr(pos, "(WSC)"))
- wpsStatusText->setText(tr("Registration started"));
- } else if (str_match(pos, WPS_EVENT_M2D)) {
- wpsStatusText->setText(tr("Registrar does not yet know PIN"));
- } else if (str_match(pos, WPS_EVENT_FAIL)) {
- wpsStatusText->setText(tr("Registration failed"));
- } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
- wpsStatusText->setText(tr("Registration succeeded"));
- }
-}
-
-
-void WpaGui::processCtrlReq(const char *req)
-{
- if (udr) {
- udr->close();
- delete udr;
- }
- udr = new UserDataRequest();
- if (udr == NULL)
- return;
- if (udr->setParams(this, req) < 0) {
- delete udr;
- udr = NULL;
- return;
- }
- udr->show();
- udr->exec();
-}
-
-
-void WpaGui::receiveMsgs()
-{
- char buf[256];
- size_t len;
-
- while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
- len = sizeof(buf) - 1;
- if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
- buf[len] = '\0';
- processMsg(buf);
- }
- }
-}
-
-
-void WpaGui::connectB()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("REASSOCIATE", reply, &reply_len);
-}
-
-
-void WpaGui::selectNetwork( const QString &sel )
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (cmd.contains(QRegExp("^\\d+:")))
- cmd.truncate(cmd.indexOf(':'));
- else
- cmd = "any";
- cmd.prepend("SELECT_NETWORK ");
- ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
- triggerUpdate();
- stopWpsRun(false);
-}
-
-
-void WpaGui::enableNetwork(const QString &sel)
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (cmd.contains(QRegExp("^\\d+:")))
- cmd.truncate(cmd.indexOf(':'));
- else if (!cmd.startsWith("all")) {
- debug("Invalid editNetwork '%s'",
- cmd.toLocal8Bit().constData());
- return;
- }
- cmd.prepend("ENABLE_NETWORK ");
- ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
- triggerUpdate();
-}
-
-
-void WpaGui::disableNetwork(const QString &sel)
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (cmd.contains(QRegExp("^\\d+:")))
- cmd.truncate(cmd.indexOf(':'));
- else if (!cmd.startsWith("all")) {
- debug("Invalid editNetwork '%s'",
- cmd.toLocal8Bit().constData());
- return;
- }
- cmd.prepend("DISABLE_NETWORK ");
- ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
- triggerUpdate();
-}
-
-
-void WpaGui::editNetwork(const QString &sel)
-{
- QString cmd(sel);
- int id = -1;
-
- if (cmd.contains(QRegExp("^\\d+:"))) {
- cmd.truncate(cmd.indexOf(':'));
- id = cmd.toInt();
- }
-
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
-
- if (id >= 0)
- nc->paramsFromConfig(id);
- else
- nc->newNetwork();
-
- nc->show();
- nc->exec();
-}
-
-
-void WpaGui::editSelectedNetwork()
-{
- if (networkSelect->count() < 1) {
- QMessageBox::information(
- this, tr("No Networks"),
- tr("There are no networks to edit.\n"));
- return;
- }
- QString sel(networkSelect->currentText());
- editNetwork(sel);
-}
-
-
-void WpaGui::editListedNetwork()
-{
- if (networkList->currentRow() < 0) {
- QMessageBox::information(this, tr("Select A Network"),
- tr("Select a network from the list to"
- " edit it.\n"));
- return;
- }
- QString sel(networkList->currentItem()->text());
- editNetwork(sel);
-}
-
-
-void WpaGui::triggerUpdate()
-{
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-void WpaGui::addNetwork()
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
- nc->newNetwork();
- nc->show();
- nc->exec();
-}
-
-
-void WpaGui::removeNetwork(const QString &sel)
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (cmd.contains(QRegExp("^\\d+:")))
- cmd.truncate(cmd.indexOf(':'));
- else if (!cmd.startsWith("all")) {
- debug("Invalid editNetwork '%s'",
- cmd.toLocal8Bit().constData());
- return;
- }
- cmd.prepend("REMOVE_NETWORK ");
- ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
- triggerUpdate();
-}
-
-
-void WpaGui::removeSelectedNetwork()
-{
- if (networkSelect->count() < 1) {
- QMessageBox::information(this, tr("No Networks"),
- tr("There are no networks to remove."
- "\n"));
- return;
- }
- QString sel(networkSelect->currentText());
- removeNetwork(sel);
-}
-
-
-void WpaGui::removeListedNetwork()
-{
- if (networkList->currentRow() < 0) {
- QMessageBox::information(this, tr("Select A Network"),
- tr("Select a network from the list "
- "to remove it.\n"));
- return;
- }
- QString sel(networkList->currentItem()->text());
- removeNetwork(sel);
-}
-
-
-void WpaGui::enableAllNetworks()
-{
- QString sel("all");
- enableNetwork(sel);
-}
-
-
-void WpaGui::disableAllNetworks()
-{
- QString sel("all");
- disableNetwork(sel);
-}
-
-
-void WpaGui::removeAllNetworks()
-{
- QString sel("all");
- removeNetwork(sel);
-}
-
-
-int WpaGui::getNetworkDisabled(const QString &sel)
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply) - 1;
- int pos = cmd.indexOf(':');
- if (pos < 0) {
- debug("Invalid getNetworkDisabled '%s'",
- cmd.toLocal8Bit().constData());
- return -1;
- }
- cmd.truncate(pos);
- cmd.prepend("GET_NETWORK ");
- cmd.append(" disabled");
-
- if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) >= 0
- && reply_len >= 1) {
- reply[reply_len] = '\0';
- if (!str_match(reply, "FAIL"))
- return atoi(reply);
- }
-
- return -1;
-}
-
-
-void WpaGui::updateNetworkDisabledStatus()
-{
- if (networkList->currentRow() < 0)
- return;
-
- QString sel(networkList->currentItem()->text());
-
- switch (getNetworkDisabled(sel)) {
- case 0:
- if (!enableRadioButton->isChecked())
- enableRadioButton->setChecked(true);
- return;
- case 1:
- if (!disableRadioButton->isChecked())
- disableRadioButton->setChecked(true);
- return;
- }
-}
-
-
-void WpaGui::enableListedNetwork(bool enabled)
-{
- if (networkList->currentRow() < 0 || !enabled)
- return;
-
- QString sel(networkList->currentItem()->text());
-
- if (getNetworkDisabled(sel) == 1)
- enableNetwork(sel);
-}
-
-
-void WpaGui::disableListedNetwork(bool disabled)
-{
- if (networkList->currentRow() < 0 || !disabled)
- return;
-
- QString sel(networkList->currentItem()->text());
-
- if (getNetworkDisabled(sel) == 0)
- disableNetwork(sel);
-}
-
-
-void WpaGui::saveConfig()
-{
- char buf[10];
- size_t len;
-
- len = sizeof(buf) - 1;
- ctrlRequest("SAVE_CONFIG", buf, &len);
-
- buf[len] = '\0';
-
- if (str_match(buf, "FAIL"))
- QMessageBox::warning(
- this, tr("Failed to save configuration"),
- tr("The configuration could not be saved.\n"
- "\n"
- "The update_config=1 configuration option\n"
- "must be used for configuration saving to\n"
- "be permitted.\n"));
- else
- QMessageBox::information(
- this, tr("Saved configuration"),
- tr("The current configuration was saved."
- "\n"));
-}
-
-
-void WpaGui::selectAdapter( const QString & sel )
-{
- if (openCtrlConnection(sel.toLocal8Bit().constData()) < 0)
- debug("Failed to open control connection to "
- "wpa_supplicant.");
- updateStatus();
- updateNetworks();
-}
-
-
-void WpaGui::createTrayIcon(bool trayOnly)
-{
- QApplication::setQuitOnLastWindowClosed(false);
-
- tray_icon = new QSystemTrayIcon(this);
- updateTrayIcon(TrayIconOffline);
-
- connect(tray_icon,
- SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
- this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
-
- ackTrayIcon = false;
-
- tray_menu = new QMenu(this);
-
- disconnectAction = new QAction(tr("&Disconnect"), this);
- reconnectAction = new QAction(tr("Re&connect"), this);
- connect(disconnectAction, SIGNAL(triggered()), this,
- SLOT(disconnect()));
- connect(reconnectAction, SIGNAL(triggered()), this,
- SLOT(connectB()));
- tray_menu->addAction(disconnectAction);
- tray_menu->addAction(reconnectAction);
- tray_menu->addSeparator();
-
- eventAction = new QAction(tr("&Event History"), this);
- scanAction = new QAction(tr("Scan &Results"), this);
- statAction = new QAction(tr("S&tatus"), this);
- connect(eventAction, SIGNAL(triggered()), this, SLOT(eventHistory()));
- connect(scanAction, SIGNAL(triggered()), this, SLOT(scan()));
- connect(statAction, SIGNAL(triggered()), this, SLOT(showTrayStatus()));
- tray_menu->addAction(eventAction);
- tray_menu->addAction(scanAction);
- tray_menu->addAction(statAction);
- tray_menu->addSeparator();
-
- showAction = new QAction(tr("&Show Window"), this);
- hideAction = new QAction(tr("&Hide Window"), this);
- quitAction = new QAction(tr("&Quit"), this);
- connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
- connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));
- connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
- tray_menu->addAction(showAction);
- tray_menu->addAction(hideAction);
- tray_menu->addSeparator();
- tray_menu->addAction(quitAction);
-
- tray_icon->setContextMenu(tray_menu);
-
- tray_icon->show();
-
- if (!trayOnly)
- show();
- inTray = trayOnly;
-}
-
-
-void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec,
- const QString & msg)
-{
- if (!QSystemTrayIcon::supportsMessages())
- return;
-
- if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode)
- return;
-
- tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
-}
-
-
-void WpaGui::trayActivated(QSystemTrayIcon::ActivationReason how)
- {
- switch (how) {
- /* use close() here instead of hide() and allow the
- * custom closeEvent handler take care of children */
- case QSystemTrayIcon::Trigger:
- ackTrayIcon = true;
- if (isVisible()) {
- close();
- inTray = true;
- } else {
- show();
- inTray = false;
- }
- break;
- case QSystemTrayIcon::MiddleClick:
- showTrayStatus();
- break;
- default:
- break;
- }
-}
-
-
-void WpaGui::showTrayStatus()
-{
- char buf[2048];
- size_t len;
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("STATUS", buf, &len) < 0)
- return;
- buf[len] = '\0';
-
- QString msg, status(buf);
-
- QStringList lines = status.split(QRegExp("\\n"));
- for (QStringList::Iterator it = lines.begin();
- it != lines.end(); it++) {
- int pos = (*it).indexOf('=') + 1;
- if (pos < 1)
- continue;
-
- if ((*it).startsWith("bssid="))
- msg.append("BSSID:\t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("ssid="))
- msg.append("SSID: \t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("pairwise_cipher="))
- msg.append("PAIR: \t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("group_cipher="))
- msg.append("GROUP:\t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("key_mgmt="))
- msg.append("AUTH: \t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("wpa_state="))
- msg.append("STATE:\t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("ip_address="))
- msg.append("IP: \t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("Supplicant PAE state="))
- msg.append("PAE: \t" + (*it).mid(pos) + "\n");
- else if ((*it).startsWith("EAP state="))
- msg.append("EAP: \t" + (*it).mid(pos) + "\n");
- }
-
- if (!msg.isEmpty())
- showTrayMessage(QSystemTrayIcon::Information, 10, msg);
-}
-
-
-void WpaGui::updateTrayToolTip(const QString &msg)
-{
- if (tray_icon)
- tray_icon->setToolTip(msg);
-}
-
-
-void WpaGui::updateTrayIcon(TrayIconType type)
-{
- if (!tray_icon || currentIconType == type)
- return;
-
- QIcon fallback_icon;
- QStringList names;
-
- if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
- fallback_icon = QIcon(":/icons/wpa_gui.svg");
- else
- fallback_icon = QIcon(":/icons/wpa_gui.png");
-
- switch (type) {
- case TrayIconOffline:
- names << "network-wireless-offline-symbolic"
- << "network-wireless-offline"
- << "network-wireless-signal-none-symbolic"
- << "network-wireless-signal-none";
- break;
- case TrayIconAcquiring:
- names << "network-wireless-acquiring-symbolic"
- << "network-wireless-acquiring";
- break;
- case TrayIconConnected:
- names << "network-wireless-connected-symbolic"
- << "network-wireless-connected";
- break;
- case TrayIconSignalNone:
- names << "network-wireless-signal-none-symbolic"
- << "network-wireless-signal-none";
- break;
- case TrayIconSignalWeak:
- names << "network-wireless-signal-weak-symbolic"
- << "network-wireless-signal-weak";
- break;
- case TrayIconSignalOk:
- names << "network-wireless-signal-ok-symbolic"
- << "network-wireless-signal-ok";
- break;
- case TrayIconSignalGood:
- names << "network-wireless-signal-good-symbolic"
- << "network-wireless-signal-good";
- break;
- case TrayIconSignalExcellent:
- names << "network-wireless-signal-excellent-symbolic"
- << "network-wireless-signal-excellent";
- break;
- }
-
- currentIconType = type;
- tray_icon->setIcon(loadThemedIcon(names, fallback_icon));
-}
-
-
-QIcon WpaGui::loadThemedIcon(const QStringList &names,
- const QIcon &fallback)
-{
- QIcon icon;
-
- for (QStringList::ConstIterator it = names.begin();
- it != names.end(); it++) {
- icon = QIcon::fromTheme(*it);
- if (!icon.isNull())
- return icon;
- }
-
- return fallback;
-}
-
-
-void WpaGui::closeEvent(QCloseEvent *event)
-{
- if (eh) {
- eh->close();
- delete eh;
- eh = NULL;
- }
-
- if (scanres) {
- scanres->close();
- delete scanres;
- scanres = NULL;
- }
-
- if (peers) {
- peers->close();
- delete peers;
- peers = NULL;
- }
-
- if (udr) {
- udr->close();
- delete udr;
- udr = NULL;
- }
-
- if (tray_icon && !ackTrayIcon) {
- /* give user a visual hint that the tray icon exists */
- if (QSystemTrayIcon::supportsMessages()) {
- hide();
- showTrayMessage(QSystemTrayIcon::Information, 3,
- qAppName() +
- tr(" will keep running in "
- "the system tray."));
- } else {
- QMessageBox::information(this, qAppName() +
- tr(" systray"),
- tr("The program will keep "
- "running in the system "
- "tray."));
- }
- ackTrayIcon = true;
- }
-
- event->accept();
-}
-
-
-void WpaGui::wpsDialog()
-{
- wpaguiTab->setCurrentWidget(wpsTab);
-}
-
-
-void WpaGui::peersDialog()
-{
- if (peers) {
- peers->close();
- delete peers;
- }
-
- peers = new Peers();
- if (peers == NULL)
- return;
- peers->setWpaGui(this);
- peers->show();
- peers->exec();
-}
-
-
-void WpaGui::tabChanged(int index)
-{
- if (index != 2)
- return;
-
- if (wpsRunning)
- return;
-
- wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
- if (bssFromScan.isEmpty())
- wpsApPinButton->setEnabled(false);
-}
-
-
-void WpaGui::wpsPbc()
-{
- char reply[20];
- size_t reply_len = sizeof(reply);
-
- if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
- return;
-
- wpsPinEdit->setEnabled(false);
- if (wpsStatusText->text().compare(tr("WPS AP in active PBC mode found"))) {
- wpsInstructions->setText(tr("Press the push button on the AP to "
- "start the PBC mode."));
- } else {
- wpsInstructions->setText(tr("If you have not yet done so, press "
- "the push button on the AP to start "
- "the PBC mode."));
- }
- wpsStatusText->setText(tr("Waiting for Registrar"));
- wpsRunning = true;
-}
-
-
-void WpaGui::wpsGeneratePin()
-{
- char reply[20];
- size_t reply_len = sizeof(reply) - 1;
-
- if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
- return;
-
- reply[reply_len] = '\0';
-
- wpsPinEdit->setText(reply);
- wpsPinEdit->setEnabled(true);
- wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
- "(either the internal one in the AP or an "
- "external one)."));
- wpsStatusText->setText(tr("Waiting for Registrar"));
- wpsRunning = true;
-}
-
-
-void WpaGui::setBssFromScan(const QString &bssid)
-{
- bssFromScan = bssid;
- wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
- wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
- wpsStatusText->setText(tr("WPS AP selected from scan results"));
- wpsInstructions->setText(tr("If you want to use an AP device PIN, e.g., "
- "from a label in the device, enter the eight "
- "digit AP PIN and click Use AP PIN button."));
-}
-
-
-void WpaGui::wpsApPinChanged(const QString &text)
-{
- wpsApPinButton->setEnabled(text.length() == 8);
-}
-
-
-void WpaGui::wpsApPin()
-{
- char reply[20];
- size_t reply_len = sizeof(reply);
-
- QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
- if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) < 0)
- return;
-
- wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
- wpsRunning = true;
-}
-
-
-void WpaGui::stopWpsRun(bool success)
-{
- if (wpsRunning)
- wpsStatusText->setText(success ? tr("Connected to the network") :
- tr("Stopped"));
- else
- wpsStatusText->setText("");
- wpsPinEdit->setEnabled(false);
- wpsInstructions->setText("");
- wpsRunning = false;
- bssFromScan = "";
- wpsApPinEdit->setEnabled(false);
- wpsApPinButton->setEnabled(false);
-}
-
-
-#ifdef CONFIG_NATIVE_WINDOWS
-
-#ifndef WPASVC_NAME
-#define WPASVC_NAME TEXT("wpasvc")
-#endif
-
-class ErrorMsg : public QMessageBox {
-public:
- ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
- void showMsg(QString msg);
-private:
- DWORD err;
-};
-
-ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
- QMessageBox(parent), err(last_err)
-{
- setWindowTitle(tr("wpa_gui error"));
- setIcon(QMessageBox::Warning);
-}
-
-void ErrorMsg::showMsg(QString msg)
-{
- LPTSTR buf;
-
- setText(msg);
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, err, 0, (LPTSTR) (void *) &buf,
- 0, NULL) > 0) {
- QString msg = QString::fromWCharArray(buf);
- setInformativeText(QString("[%1] %2").arg(err).arg(msg));
- LocalFree(buf);
- } else {
- setInformativeText(QString("[%1]").arg(err));
- }
-
- exec();
-}
-
-
-void WpaGui::startService()
-{
- SC_HANDLE svc, scm;
-
- scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (!scm) {
- ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
- return;
- }
-
- svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
- if (!svc) {
- ErrorMsg(this).showMsg(tr("OpenService failed"));
- CloseServiceHandle(scm);
- return;
- }
-
- if (!StartService(svc, 0, NULL)) {
- ErrorMsg(this).showMsg(tr("Failed to start wpa_supplicant "
- "service"));
- }
-
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
-}
-
-
-void WpaGui::stopService()
-{
- SC_HANDLE svc, scm;
- SERVICE_STATUS status;
-
- scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (!scm) {
- ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
- return;
- }
-
- svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
- if (!svc) {
- ErrorMsg(this).showMsg(tr("OpenService failed"));
- CloseServiceHandle(scm);
- return;
- }
-
- if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
- ErrorMsg(this).showMsg(tr("Failed to stop wpa_supplicant "
- "service"));
- }
-
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
-}
-
-
-bool WpaGui::serviceRunning()
-{
- SC_HANDLE svc, scm;
- SERVICE_STATUS status;
- bool running = false;
-
- scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (!scm) {
- debug("OpenSCManager failed: %d", (int) GetLastError());
- return false;
- }
-
- svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
- if (!svc) {
- debug("OpenService failed: %d", (int) GetLastError());
- CloseServiceHandle(scm);
- return false;
- }
-
- if (QueryServiceStatus(svc, &status)) {
- if (status.dwCurrentState != SERVICE_STOPPED)
- running = true;
- }
-
- CloseServiceHandle(svc);
- CloseServiceHandle(scm);
-
- return running;
-}
-
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-
-void WpaGui::addInterface()
-{
- if (add_iface) {
- add_iface->close();
- delete add_iface;
- }
- add_iface = new AddInterface(this, this);
- add_iface->show();
- add_iface->exec();
-}
-
-
-#ifndef QT_NO_SESSIONMANAGER
-void WpaGui::saveState()
-{
- QSettings settings("wpa_supplicant", "wpa_gui");
- settings.beginGroup("state");
- settings.setValue("session_id", app->sessionId());
- settings.setValue("in_tray", inTray);
- settings.endGroup();
-}
-#endif
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.h b/wpa_supplicant/wpa_gui-qt4/wpagui.h
deleted file mode 100644
index f0a34c97ebe8..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * wpa_gui - WpaGui class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPAGUI_H
-#define WPAGUI_H
-
-#include <QSystemTrayIcon>
-#include <QObject>
-#include "ui_wpagui.h"
-#include "addinterface.h"
-
-class UserDataRequest;
-
-class WpaGuiApp : public QApplication
-{
- Q_OBJECT
-public:
- WpaGuiApp(int &argc, char **argv);
-
-#if !defined(QT_NO_SESSIONMANAGER) && QT_VERSION < 0x050000
- virtual void saveState(QSessionManager &manager);
-#endif
-
- WpaGui *w;
- int argc;
- char **argv;
-};
-
-class WpaGui : public QMainWindow, public Ui::WpaGui
-{
- Q_OBJECT
-
-public:
-
- enum TrayIconType {
- TrayIconOffline = 0,
- TrayIconAcquiring,
- TrayIconConnected,
- TrayIconSignalNone,
- TrayIconSignalWeak,
- TrayIconSignalOk,
- TrayIconSignalGood,
- TrayIconSignalExcellent,
- };
-
- WpaGui(QApplication *app, QWidget *parent = 0, const char *name = 0,
- Qt::WindowFlags fl = 0);
- ~WpaGui();
-
- virtual int ctrlRequest(const char *cmd, char *buf, size_t *buflen);
- virtual void triggerUpdate();
- virtual void editNetwork(const QString &sel);
- virtual void removeNetwork(const QString &sel);
- virtual void enableNetwork(const QString &sel);
- virtual void disableNetwork(const QString &sel);
- virtual int getNetworkDisabled(const QString &sel);
- void setBssFromScan(const QString &bssid);
-#ifndef QT_NO_SESSIONMANAGER
- void saveState();
-#endif
-
-public slots:
- virtual void parse_argv();
- virtual void updateStatus();
- virtual void updateNetworks();
- virtual void helpIndex();
- virtual void helpContents();
- virtual void helpAbout();
- virtual void disconnect();
- virtual void scan();
- virtual void eventHistory();
- virtual void ping();
- virtual void signalMeterUpdate();
- virtual void processMsg(char *msg);
- virtual void processCtrlReq(const char *req);
- virtual void receiveMsgs();
- virtual void connectB();
- virtual void selectNetwork(const QString &sel);
- virtual void editSelectedNetwork();
- virtual void editListedNetwork();
- virtual void removeSelectedNetwork();
- virtual void removeListedNetwork();
- virtual void addNetwork();
- virtual void enableAllNetworks();
- virtual void disableAllNetworks();
- virtual void removeAllNetworks();
- virtual void saveConfig();
- virtual void selectAdapter(const QString &sel);
- virtual void updateNetworkDisabledStatus();
- virtual void enableListedNetwork(bool);
- virtual void disableListedNetwork(bool);
- virtual void showTrayMessage(QSystemTrayIcon::MessageIcon type,
- int sec, const QString &msg);
- virtual void showTrayStatus();
- virtual void updateTrayIcon(TrayIconType type);
- virtual void updateTrayToolTip(const QString &msg);
- virtual QIcon loadThemedIcon(const QStringList &names,
- const QIcon &fallback);
- virtual void wpsDialog();
- virtual void peersDialog();
- virtual void tabChanged(int index);
- virtual void wpsPbc();
- virtual void wpsGeneratePin();
- virtual void wpsApPinChanged(const QString &text);
- virtual void wpsApPin();
-#ifdef CONFIG_NATIVE_WINDOWS
- virtual void startService();
- virtual void stopService();
-#endif /* CONFIG_NATIVE_WINDOWS */
- virtual void addInterface();
-
-protected slots:
- virtual void languageChange();
- virtual void trayActivated(QSystemTrayIcon::ActivationReason how);
- virtual void closeEvent(QCloseEvent *event);
-
-private:
- ScanResults *scanres;
- Peers *peers;
- bool networkMayHaveChanged;
- char *ctrl_iface;
- EventHistory *eh;
- struct wpa_ctrl *ctrl_conn;
- QSocketNotifier *msgNotifier;
- QTimer *timer;
- int pingsToStatusUpdate;
- WpaMsgList msgs;
- char *ctrl_iface_dir;
- struct wpa_ctrl *monitor_conn;
- UserDataRequest *udr;
- QAction *disconnectAction;
- QAction *reconnectAction;
- QAction *eventAction;
- QAction *scanAction;
- QAction *statAction;
- QAction *showAction;
- QAction *hideAction;
- QAction *quitAction;
- QMenu *tray_menu;
- QSystemTrayIcon *tray_icon;
- TrayIconType currentIconType;
- QString wpaStateTranslate(char *state);
- void createTrayIcon(bool);
- bool ackTrayIcon;
- bool startInTray;
- bool quietMode;
-
- int openCtrlConnection(const char *ifname);
-
- bool wpsRunning;
-
- QString bssFromScan;
-
- void stopWpsRun(bool success);
-
- QTimer *signalMeterTimer;
- int signalMeterInterval;
-
-#ifdef CONFIG_NATIVE_WINDOWS
- QAction *fileStartServiceAction;
- QAction *fileStopServiceAction;
-
- bool serviceRunning();
-#endif /* CONFIG_NATIVE_WINDOWS */
-
- QAction *addInterfaceAction;
- AddInterface *add_iface;
-
- bool connectedToService;
-
- QApplication *app;
- bool inTray;
-};
-
-#endif /* WPAGUI_H */
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.ui b/wpa_supplicant/wpa_gui-qt4/wpagui.ui
deleted file mode 100644
index 9f9039f6c916..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.ui
+++ /dev/null
@@ -1,524 +0,0 @@
-<ui version="4.0" >
- <class>WpaGui</class>
- <widget class="QMainWindow" name="WpaGui" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>345</width>
- <height>330</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>wpa_gui</string>
- </property>
- <property name="windowIcon" >
- <iconset resource="icons.qrc" >
- <normaloff>:/icons/wpa_gui.svg</normaloff>:/icons/wpa_gui.svg</iconset>
- </property>
- <widget class="QWidget" name="widget" >
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="adapterLabel" >
- <property name="text" >
- <string>Adapter:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QComboBox" name="adapterSelect" />
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="networkLabel" >
- <property name="text" >
- <string>Network:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QComboBox" name="networkSelect" />
- </item>
- <item row="2" column="0" colspan="2" >
- <widget class="QTabWidget" name="wpaguiTab" >
- <property name="currentIndex" >
- <number>0</number>
- </property>
- <widget class="QWidget" name="statusTab" >
- <attribute name="title" >
- <string>Current Status</string>
- </attribute>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="5" >
- <widget class="QFrame" name="frame3" >
- <property name="frameShape" >
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow" >
- <enum>QFrame::Plain</enum>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="statusLabel" >
- <property name="text" >
- <string>Status:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="lastMessageLabel" >
- <property name="text" >
- <string>Last message:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="authenticationLabel" >
- <property name="text" >
- <string>Authentication:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QLabel" name="encryptionLabel" >
- <property name="text" >
- <string>Encryption:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0" >
- <widget class="QLabel" name="ssidLabel" >
- <property name="text" >
- <string>SSID:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0" >
- <widget class="QLabel" name="bssidLabel" >
- <property name="text" >
- <string>BSSID:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0" >
- <widget class="QLabel" name="ipAddressLabel" >
- <property name="text" >
- <string>IP address:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLabel" name="textStatus" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1" colspan="3" >
- <widget class="QLabel" name="textLastMessage" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="QLabel" name="textAuthentication" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="3" column="1" >
- <widget class="QLabel" name="textEncryption" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="4" column="1" >
- <widget class="QLabel" name="textSsid" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="5" column="1" >
- <widget class="QLabel" name="textBssid" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="6" column="1" >
- <widget class="QLabel" name="textIpAddress" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1" >
- <widget class="QPushButton" name="connectButton" >
- <property name="text" >
- <string>Connect</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="disconnectButton" >
- <property name="text" >
- <string>Disconnect</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3" >
- <widget class="QPushButton" name="scanButton" >
- <property name="text" >
- <string>Scan</string>
- </property>
- </widget>
- </item>
- <item row="1" column="4" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="networkconfigTab" >
- <attribute name="title" >
- <string>Manage Networks</string>
- </attribute>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="5" >
- <widget class="QListWidget" name="networkList" >
- <property name="selectionRectVisible" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item rowspan="2" row="1" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>61</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1" >
- <widget class="QRadioButton" name="enableRadioButton" >
- <property name="text" >
- <string>Enabled</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="editNetworkButton" >
- <property name="text" >
- <string>Edit</string>
- </property>
- </widget>
- </item>
- <item row="1" column="3" >
- <widget class="QPushButton" name="removeNetworkButton" >
- <property name="text" >
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item rowspan="2" row="1" column="4" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>61</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="1" >
- <widget class="QRadioButton" name="disableRadioButton" >
- <property name="text" >
- <string>Disabled</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2" >
- <widget class="QPushButton" name="addNetworkButton" >
- <property name="text" >
- <string>Add</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3" >
- <widget class="QPushButton" name="scanNetworkButton" >
- <property name="text" >
- <string>Scan</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="wpsTab" >
- <attribute name="title" >
- <string>WPS</string>
- </attribute>
- <layout class="QGridLayout" name="wpsGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>Status:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" colspan="3" >
- <widget class="QLabel" name="wpsStatusText" >
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2" >
- <widget class="QPushButton" name="wpsPbcButton" >
- <property name="text" >
- <string>PBC - push button</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2" >
- <widget class="QPushButton" name="wpsPinButton" >
- <property name="text" >
- <string>Generate PIN</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>PIN:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3" >
- <widget class="QLineEdit" name="wpsPinEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="readOnly" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="2" >
- <widget class="QPushButton" name="wpsApPinButton" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>Use AP PIN</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string>AP PIN:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="3" >
- <widget class="QLineEdit" name="wpsApPinEdit" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="4" >
- <widget class="QTextEdit" name="wpsInstructions" >
- <property name="readOnly" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QMenuBar" name="MenuBar" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>345</width>
- <height>24</height>
- </rect>
- </property>
- <widget class="QMenu" name="fileMenu" >
- <property name="title" >
- <string>&amp;File</string>
- </property>
- <addaction name="fileEventHistoryAction" />
- <addaction name="fileSaveConfigAction" />
- <addaction name="actionWPS" />
- <addaction name="actionPeers" />
- <addaction name="separator" />
- <addaction name="fileExitAction" />
- </widget>
- <widget class="QMenu" name="networkMenu" >
- <property name="title" >
- <string>&amp;Network</string>
- </property>
- <addaction name="networkAddAction" />
- <addaction name="networkEditAction" />
- <addaction name="networkRemoveAction" />
- <addaction name="separator" />
- <addaction name="networkEnableAllAction" />
- <addaction name="networkDisableAllAction" />
- <addaction name="networkRemoveAllAction" />
- </widget>
- <widget class="QMenu" name="helpMenu" >
- <property name="title" >
- <string>&amp;Help</string>
- </property>
- <addaction name="helpContentsAction" />
- <addaction name="helpIndexAction" />
- <addaction name="separator" />
- <addaction name="helpAboutAction" />
- </widget>
- <addaction name="fileMenu" />
- <addaction name="networkMenu" />
- <addaction name="helpMenu" />
- </widget>
- <action name="fileEventHistoryAction" >
- <property name="text" >
- <string>Event &amp;History</string>
- </property>
- </action>
- <action name="fileSaveConfigAction" >
- <property name="text" >
- <string>&amp;Save Configuration</string>
- </property>
- <property name="shortcut" >
- <string>Ctrl+S</string>
- </property>
- </action>
- <action name="fileExitAction" >
- <property name="text" >
- <string>E&amp;xit</string>
- </property>
- <property name="shortcut" >
- <string>Ctrl+Q</string>
- </property>
- </action>
- <action name="networkAddAction" >
- <property name="text" >
- <string>&amp;Add</string>
- </property>
- </action>
- <action name="networkEditAction" >
- <property name="text" >
- <string>&amp;Edit</string>
- </property>
- </action>
- <action name="networkRemoveAction" >
- <property name="text" >
- <string>&amp;Remove</string>
- </property>
- </action>
- <action name="networkEnableAllAction" >
- <property name="text" >
- <string>E&amp;nable All</string>
- </property>
- </action>
- <action name="networkDisableAllAction" >
- <property name="text" >
- <string>&amp;Disable All</string>
- </property>
- </action>
- <action name="networkRemoveAllAction" >
- <property name="text" >
- <string>Re&amp;move All</string>
- </property>
- </action>
- <action name="helpContentsAction" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&amp;Contents...</string>
- </property>
- </action>
- <action name="helpIndexAction" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&amp;Index...</string>
- </property>
- </action>
- <action name="helpAboutAction" >
- <property name="text" >
- <string>&amp;About</string>
- </property>
- </action>
- <action name="actionWPS" >
- <property name="enabled" >
- <bool>false</bool>
- </property>
- <property name="text" >
- <string>&amp;Wi-Fi Protected Setup</string>
- </property>
- </action>
- <action name="actionPeers" >
- <property name="text" >
- <string>&amp;Peers</string>
- </property>
- </action>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <includes>
- <include location="global" >qtimer.h</include>
- <include location="global" >qsocketnotifier.h</include>
- <include location="local" >wpamsg.h</include>
- <include location="local" >eventhistory.h</include>
- <include location="local" >scanresults.h</include>
- <include location="local" >peers.h</include>
- </includes>
- <resources>
- <include location="icons.qrc" />
- </resources>
- <connections/>
-</ui>
diff --git a/wpa_supplicant/wpa_gui-qt4/wpamsg.h b/wpa_supplicant/wpa_gui-qt4/wpamsg.h
deleted file mode 100644
index 8f2fcdc41988..000000000000
--- a/wpa_supplicant/wpa_gui-qt4/wpamsg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * wpa_gui - WpaMsg class for storing event messages
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPAMSG_H
-#define WPAMSG_H
-
-#include <QDateTime>
-#include <QLinkedList>
-
-class WpaMsg {
-public:
- WpaMsg(const QString &_msg, int _priority = 2)
- : msg(_msg), priority(_priority)
- {
- timestamp = QDateTime::currentDateTime();
- }
-
- QString getMsg() const { return msg; }
- int getPriority() const { return priority; }
- QDateTime getTimestamp() const { return timestamp; }
-
-private:
- QString msg;
- int priority;
- QDateTime timestamp;
-};
-
-typedef QLinkedList<WpaMsg> WpaMsgList;
-
-#endif /* WPAMSG_H */
diff --git a/wpa_supplicant/wpa_passphrase.c b/wpa_supplicant/wpa_passphrase.c
deleted file mode 100644
index 538997e62580..000000000000
--- a/wpa_supplicant/wpa_passphrase.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * WPA Supplicant - ASCII passphrase to WPA PSK tool
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "crypto/sha1.h"
-
-
-int main(int argc, char *argv[])
-{
- unsigned char psk[32];
- int i;
- char *ssid, *passphrase, buf[64], *pos;
- size_t len;
-
- if (argc < 2) {
- printf("usage: wpa_passphrase <ssid> [passphrase]\n"
- "\nIf passphrase is left out, it will be read from "
- "stdin\n");
- return 1;
- }
-
- ssid = argv[1];
-
- if (argc > 2) {
- passphrase = argv[2];
- } else {
- fprintf(stderr, "# reading passphrase from stdin\n");
- if (fgets(buf, sizeof(buf), stdin) == NULL) {
- fprintf(stderr, "Failed to read passphrase\n");
- return 1;
- }
- buf[sizeof(buf) - 1] = '\0';
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\r' || *pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- passphrase = buf;
- }
-
- len = os_strlen(passphrase);
- if (len < 8 || len > 63) {
- fprintf(stderr, "Passphrase must be 8..63 characters\n");
- return 1;
- }
- if (has_ctrl_char((u8 *) passphrase, len)) {
- fprintf(stderr, "Invalid passphrase character\n");
- return 1;
- }
-
- pbkdf2_sha1(passphrase, (u8 *) ssid, os_strlen(ssid), 4096, psk, 32);
-
- printf("network={\n");
- printf("\tssid=\"%s\"\n", ssid);
- printf("\t#psk=\"%s\"\n", passphrase);
- printf("\tpsk=");
- for (i = 0; i < 32; i++)
- printf("%02x", psk[i]);
- printf("\n");
- printf("}\n");
-
- return 0;
-}
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
deleted file mode 100644
index c5d7168690f7..000000000000
--- a/wpa_supplicant/wpa_priv.c
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * WPA Supplicant / privileged helper program
- * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-#ifdef __linux__
-#include <fcntl.h>
-#endif /* __linux__ */
-#include <sys/un.h>
-#include <sys/stat.h>
-
-#include "common.h"
-#include "eloop.h"
-#include "common/version.h"
-#include "drivers/driver.h"
-#include "l2_packet/l2_packet.h"
-#include "common/privsep_commands.h"
-#include "common/ieee802_11_defs.h"
-
-#define WPA_PRIV_MAX_L2 3
-
-struct wpa_priv_interface {
- struct wpa_priv_interface *next;
- char *driver_name;
- char *ifname;
- char *sock_name;
- int fd;
-
- void *ctx;
-
- const struct wpa_driver_ops *driver;
- void *drv_priv;
- void *drv_global_priv;
- struct sockaddr_un drv_addr;
- socklen_t drv_addr_len;
- int wpas_registered;
-
- struct l2_packet_data *l2[WPA_PRIV_MAX_L2];
- struct sockaddr_un l2_addr[WPA_PRIV_MAX_L2];
- socklen_t l2_addr_len[WPA_PRIV_MAX_L2];
- struct wpa_priv_l2 {
- struct wpa_priv_interface *parent;
- int idx;
- } l2_ctx[WPA_PRIV_MAX_L2];
-};
-
-struct wpa_priv_global {
- struct wpa_priv_interface *interfaces;
-};
-
-
-static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
- struct sockaddr_un *from, socklen_t fromlen)
-{
- int i;
-
- if (iface->drv_priv) {
- wpa_printf(MSG_DEBUG, "Cleaning up forgotten driver instance");
- if (iface->driver->deinit)
- iface->driver->deinit(iface->drv_priv);
- iface->drv_priv = NULL;
- if (iface->drv_global_priv) {
- iface->driver->global_deinit(iface->drv_global_priv);
- iface->drv_global_priv = NULL;
- }
- iface->wpas_registered = 0;
- }
-
- for (i = 0; i < WPA_PRIV_MAX_L2; i++) {
- if (iface->l2[i]) {
- wpa_printf(MSG_DEBUG,
- "Cleaning up forgotten l2_packet instance");
- l2_packet_deinit(iface->l2[i]);
- iface->l2[i] = NULL;
- }
- }
-
- if (iface->driver->init2) {
- if (iface->driver->global_init) {
- iface->drv_global_priv =
- iface->driver->global_init(iface->ctx);
- if (!iface->drv_global_priv) {
- wpa_printf(MSG_INFO,
- "Failed to initialize driver global context");
- return;
- }
- } else {
- iface->drv_global_priv = NULL;
- }
- iface->drv_priv = iface->driver->init2(iface, iface->ifname,
- iface->drv_global_priv);
- } else if (iface->driver->init) {
- iface->drv_priv = iface->driver->init(iface, iface->ifname);
- } else {
- return;
- }
- if (iface->drv_priv == NULL) {
- wpa_printf(MSG_DEBUG, "Failed to initialize driver wrapper");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "Driver wrapper '%s' initialized for interface "
- "'%s'", iface->driver_name, iface->ifname);
-
- os_memcpy(&iface->drv_addr, from, fromlen);
- iface->drv_addr_len = fromlen;
- iface->wpas_registered = 1;
-
- if (iface->driver->set_param &&
- iface->driver->set_param(iface->drv_priv, NULL) < 0) {
- wpa_printf(MSG_ERROR, "Driver interface rejected param");
- }
-}
-
-
-static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface,
- struct sockaddr_un *from)
-{
- if (iface->drv_priv) {
- if (iface->driver->deinit)
- iface->driver->deinit(iface->drv_priv);
- iface->drv_priv = NULL;
- if (iface->drv_global_priv) {
- iface->driver->global_deinit(iface->drv_global_priv);
- iface->drv_global_priv = NULL;
- }
- iface->wpas_registered = 0;
- }
-}
-
-
-static void wpa_priv_cmd_scan(struct wpa_priv_interface *iface,
- void *buf, size_t len)
-{
- struct wpa_driver_scan_params params;
- struct privsep_cmd_scan *scan;
- unsigned int i;
- int freqs[PRIVSEP_MAX_SCAN_FREQS + 1];
-
- if (iface->drv_priv == NULL)
- return;
-
- if (len < sizeof(*scan)) {
- wpa_printf(MSG_DEBUG, "Invalid scan request");
- return;
- }
-
- scan = buf;
-
- os_memset(&params, 0, sizeof(params));
- if (scan->num_ssids > WPAS_MAX_SCAN_SSIDS) {
- wpa_printf(MSG_DEBUG, "Invalid scan request (num_ssids)");
- return;
- }
- params.num_ssids = scan->num_ssids;
- for (i = 0; i < scan->num_ssids; i++) {
- params.ssids[i].ssid = scan->ssids[i];
- params.ssids[i].ssid_len = scan->ssid_lens[i];
- }
-
- if (scan->num_freqs > PRIVSEP_MAX_SCAN_FREQS) {
- wpa_printf(MSG_DEBUG, "Invalid scan request (num_freqs)");
- return;
- }
- if (scan->num_freqs) {
- for (i = 0; i < scan->num_freqs; i++)
- freqs[i] = scan->freqs[i];
- freqs[i] = 0;
- params.freqs = freqs;
- }
-
- if (iface->driver->scan2)
- iface->driver->scan2(iface->drv_priv, &params);
-}
-
-
-static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface,
- struct sockaddr_un *from,
- socklen_t fromlen)
-{
- struct wpa_scan_results *res;
- u8 *buf = NULL, *pos, *end;
- int val;
- size_t i;
-
- res = iface->driver->get_scan_results2(iface->drv_priv);
- if (res == NULL)
- goto fail;
-
- buf = os_malloc(60000);
- if (buf == NULL)
- goto fail;
- pos = buf;
- end = buf + 60000;
- val = res->num;
- os_memcpy(pos, &val, sizeof(int));
- pos += sizeof(int);
-
- for (i = 0; i < res->num; i++) {
- struct wpa_scan_res *r = res->res[i];
- val = sizeof(*r) + r->ie_len + r->beacon_ie_len;
- if (end - pos < (int) sizeof(int) + val)
- break;
- os_memcpy(pos, &val, sizeof(int));
- pos += sizeof(int);
- os_memcpy(pos, r, val);
- pos += val;
- }
-
- sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, fromlen);
-
- os_free(buf);
- wpa_scan_results_free(res);
- return;
-
-fail:
- os_free(buf);
- wpa_scan_results_free(res);
- sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
-}
-
-
-static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface,
- struct sockaddr_un *from,
- socklen_t fromlen)
-{
- if (iface->drv_priv == NULL)
- return;
-
- if (iface->driver->get_scan_results2)
- wpa_priv_get_scan_results2(iface, from, fromlen);
- else
- sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
-}
-
-
-static void wpa_priv_cmd_authenticate(struct wpa_priv_interface *iface,
- void *buf, size_t len)
-{
- struct wpa_driver_auth_params params;
- struct privsep_cmd_authenticate *auth;
- int res, i;
-
- if (iface->drv_priv == NULL || iface->driver->authenticate == NULL)
- return;
-
- if (len < sizeof(*auth)) {
- wpa_printf(MSG_DEBUG, "Invalid authentication request");
- return;
- }
-
- auth = buf;
- if (sizeof(*auth) + auth->ie_len + auth->auth_data_len > len) {
- wpa_printf(MSG_DEBUG, "Authentication request overflow");
- return;
- }
-
- os_memset(&params, 0, sizeof(params));
- params.freq = auth->freq;
- params.bssid = auth->bssid;
- params.ssid = auth->ssid;
- if (auth->ssid_len > SSID_MAX_LEN)
- return;
- params.ssid_len = auth->ssid_len;
- params.auth_alg = auth->auth_alg;
- for (i = 0; i < 4; i++) {
- if (auth->wep_key_len[i]) {
- params.wep_key[i] = auth->wep_key[i];
- params.wep_key_len[i] = auth->wep_key_len[i];
- }
- }
- params.wep_tx_keyidx = auth->wep_tx_keyidx;
- params.local_state_change = auth->local_state_change;
- params.p2p = auth->p2p;
- if (auth->ie_len) {
- params.ie = (u8 *) (auth + 1);
- params.ie_len = auth->ie_len;
- }
- if (auth->auth_data_len) {
- params.auth_data = ((u8 *) (auth + 1)) + auth->ie_len;
- params.auth_data_len = auth->auth_data_len;
- }
-
- res = iface->driver->authenticate(iface->drv_priv, &params);
- wpa_printf(MSG_DEBUG, "drv->authenticate: res=%d", res);
-}
-
-
-static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface,
- void *buf, size_t len)
-{
- struct wpa_driver_associate_params params;
- struct privsep_cmd_associate *assoc;
- u8 *bssid;
- int res;
-
- if (iface->drv_priv == NULL || iface->driver->associate == NULL)
- return;
-
- if (len < sizeof(*assoc)) {
- wpa_printf(MSG_DEBUG, "Invalid association request");
- return;
- }
-
- assoc = buf;
- if (sizeof(*assoc) + assoc->wpa_ie_len > len) {
- wpa_printf(MSG_DEBUG, "Association request overflow");
- return;
- }
-
- os_memset(&params, 0, sizeof(params));
- bssid = assoc->bssid;
- if (bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5])
- params.bssid = bssid;
- params.ssid = assoc->ssid;
- if (assoc->ssid_len > SSID_MAX_LEN)
- return;
- params.ssid_len = assoc->ssid_len;
- params.freq.mode = assoc->hwmode;
- params.freq.freq = assoc->freq;
- params.freq.channel = assoc->channel;
- if (assoc->wpa_ie_len) {
- params.wpa_ie = (u8 *) (assoc + 1);
- params.wpa_ie_len = assoc->wpa_ie_len;
- }
- params.pairwise_suite = assoc->pairwise_suite;
- params.group_suite = assoc->group_suite;
- params.key_mgmt_suite = assoc->key_mgmt_suite;
- params.auth_alg = assoc->auth_alg;
- params.mode = assoc->mode;
-
- res = iface->driver->associate(iface->drv_priv, &params);
- wpa_printf(MSG_DEBUG, "drv->associate: res=%d", res);
-}
-
-
-static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface,
- struct sockaddr_un *from, socklen_t fromlen)
-{
- u8 bssid[ETH_ALEN];
-
- if (iface->drv_priv == NULL)
- goto fail;
-
- if (iface->driver->get_bssid == NULL ||
- iface->driver->get_bssid(iface->drv_priv, bssid) < 0)
- goto fail;
-
- sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from,
- fromlen);
- return;
-
-fail:
- sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
-}
-
-
-static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface,
- struct sockaddr_un *from, socklen_t fromlen)
-{
- u8 ssid[sizeof(int) + SSID_MAX_LEN];
- int res;
-
- if (iface->drv_priv == NULL)
- goto fail;
-
- if (iface->driver->get_ssid == NULL)
- goto fail;
-
- os_memset(ssid, 0, sizeof(ssid));
- res = iface->driver->get_ssid(iface->drv_priv, &ssid[sizeof(int)]);
- if (res < 0 || res > SSID_MAX_LEN)
- goto fail;
- os_memcpy(ssid, &res, sizeof(int));
-
- sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from,
- fromlen);
- return;
-
-fail:
- sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
-}
-
-
-static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface,
- void *buf, size_t len)
-{
- struct privsep_cmd_set_key *params;
- int res;
- struct wpa_driver_set_key_params p;
-
- if (iface->drv_priv == NULL || iface->driver->set_key == NULL)
- return;
-
- if (len != sizeof(*params)) {
- wpa_printf(MSG_DEBUG, "Invalid set_key request");
- return;
- }
-
- params = buf;
-
- os_memset(&p, 0, sizeof(p));
- p.ifname = iface->ifname;
- p.alg = params->alg;
- p.addr = params->addr;
- p.key_idx = params->key_idx;
- p.set_tx = params->set_tx;
- p.seq = params->seq_len ? params->seq : NULL;
- p.seq_len = params->seq_len;
- p.key = params->key_len ? params->key : NULL;
- p.key_len = params->key_len;
- p.key_flag = params->key_flag;
-
- res = iface->driver->set_key(iface->drv_priv, &p);
- wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res);
-}
-
-
-static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface,
- struct sockaddr_un *from, socklen_t fromlen)
-{
- struct wpa_driver_capa capa;
-
- if (iface->drv_priv == NULL)
- goto fail;
-
- if (iface->driver->get_capa == NULL ||
- iface->driver->get_capa(iface->drv_priv, &capa) < 0)
- goto fail;
-
- /* For now, no support for passing extended_capa pointers */
- capa.extended_capa = NULL;
- capa.extended_capa_mask = NULL;
- capa.extended_capa_len = 0;
- sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from,
- fromlen);
- return;
-
-fail:
- sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, fromlen);
-}
-
-
-static void wpa_priv_l2_rx(void *ctx, const u8 *src_addr, const u8 *buf,
- size_t len)
-{
- struct wpa_priv_l2 *l2_ctx = ctx;
- struct wpa_priv_interface *iface = l2_ctx->parent;
- struct msghdr msg;
- struct iovec io[2];
-
- io[0].iov_base = (u8 *) src_addr;
- io[0].iov_len = ETH_ALEN;
- io[1].iov_base = (u8 *) buf;
- io[1].iov_len = len;
-
- os_memset(&msg, 0, sizeof(msg));
- msg.msg_iov = io;
- msg.msg_iovlen = 2;
- msg.msg_name = &iface->l2_addr[l2_ctx->idx];
- msg.msg_namelen = iface->l2_addr_len[l2_ctx->idx];
-
- if (sendmsg(iface->fd, &msg, 0) < 0) {
- wpa_printf(MSG_ERROR, "sendmsg(l2 rx): %s", strerror(errno));
- }
-}
-
-
-static int wpa_priv_allowed_l2_proto(u16 proto)
-{
- return proto == ETH_P_EAPOL || proto == ETH_P_RSN_PREAUTH ||
- proto == ETH_P_80211_ENCAP;
-}
-
-
-static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface,
- struct sockaddr_un *from,
- socklen_t fromlen,
- void *buf, size_t len)
-{
- int *reg_cmd = buf;
- u8 own_addr[ETH_ALEN];
- int res;
- u16 proto;
- int idx;
-
- if (len != 2 * sizeof(int)) {
- wpa_printf(MSG_DEBUG, "Invalid l2_register length %lu",
- (unsigned long) len);
- return;
- }
-
- proto = reg_cmd[0];
- if (!wpa_priv_allowed_l2_proto(proto)) {
- wpa_printf(MSG_DEBUG, "Refused l2_packet connection for "
- "ethertype 0x%x", proto);
- return;
- }
-
- for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
- if (!iface->l2[idx])
- break;
- }
- if (idx == WPA_PRIV_MAX_L2) {
- wpa_printf(MSG_DEBUG, "No free l2_packet connection found");
- return;
- }
-
- os_memcpy(&iface->l2_addr[idx], from, fromlen);
- iface->l2_addr_len[idx] = fromlen;
-
- iface->l2_ctx[idx].idx = idx;
- iface->l2_ctx[idx].parent = iface;
- iface->l2[idx] = l2_packet_init(iface->ifname, NULL, proto,
- wpa_priv_l2_rx, &iface->l2_ctx[idx],
- reg_cmd[1]);
- if (!iface->l2[idx]) {
- wpa_printf(MSG_DEBUG, "Failed to initialize l2_packet "
- "instance for protocol %d", proto);
- return;
- }
-
- if (l2_packet_get_own_addr(iface->l2[idx], own_addr) < 0) {
- wpa_printf(MSG_DEBUG, "Failed to get own address from "
- "l2_packet");
- l2_packet_deinit(iface->l2[idx]);
- iface->l2[idx] = NULL;
- return;
- }
-
- res = sendto(iface->fd, own_addr, ETH_ALEN, 0,
- (struct sockaddr *) from, fromlen);
- wpa_printf(MSG_DEBUG, "L2 registration[idx=%d]: res=%d", idx, res);
-}
-
-
-static void wpa_priv_cmd_l2_unregister(struct wpa_priv_interface *iface,
- struct sockaddr_un *from,
- socklen_t fromlen)
-{
- int idx;
-
- for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
- if (iface->l2_addr_len[idx] == fromlen &&
- os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0)
- break;
- }
- if (idx == WPA_PRIV_MAX_L2) {
- wpa_printf(MSG_DEBUG,
- "No registered l2_packet socket found for unregister request");
- return;
- }
-
- if (iface->l2[idx]) {
- l2_packet_deinit(iface->l2[idx]);
- iface->l2[idx] = NULL;
- }
-}
-
-
-static void wpa_priv_cmd_l2_notify_auth_start(struct wpa_priv_interface *iface,
- struct sockaddr_un *from)
-{
- int idx;
-
- for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
- if (iface->l2[idx])
- l2_packet_notify_auth_start(iface->l2[idx]);
- }
-}
-
-
-static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface,
- struct sockaddr_un *from, socklen_t fromlen,
- void *buf, size_t len)
-{
- u8 *dst_addr;
- u16 proto;
- int res;
- int idx;
-
- for (idx = 0; idx < WPA_PRIV_MAX_L2; idx++) {
- if (iface->l2_addr_len[idx] == fromlen &&
- os_memcmp(&iface->l2_addr[idx], from, fromlen) == 0)
- break;
- }
- if (idx == WPA_PRIV_MAX_L2) {
- wpa_printf(MSG_DEBUG,
- "No registered l2_packet socket found for send request");
- return;
- }
-
- if (iface->l2[idx] == NULL)
- return;
-
- if (len < ETH_ALEN + 2) {
- wpa_printf(MSG_DEBUG, "Too short L2 send packet (len=%lu)",
- (unsigned long) len);
- return;
- }
-
- dst_addr = buf;
- os_memcpy(&proto, (char *) buf + ETH_ALEN, 2);
-
- if (!wpa_priv_allowed_l2_proto(proto)) {
- wpa_printf(MSG_DEBUG, "Refused l2_packet send for ethertype "
- "0x%x", proto);
- return;
- }
-
- res = l2_packet_send(iface->l2[idx], dst_addr, proto,
- (unsigned char *) buf + ETH_ALEN + 2,
- len - ETH_ALEN - 2);
- wpa_printf(MSG_DEBUG, "L2 send[idx=%d]: res=%d", idx, res);
-}
-
-
-static void wpa_priv_cmd_set_country(struct wpa_priv_interface *iface,
- char *buf)
-{
- if (iface->drv_priv == NULL || iface->driver->set_country == NULL ||
- *buf == '\0')
- return;
-
- iface->driver->set_country(iface->drv_priv, buf);
-}
-
-
-static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_priv_interface *iface = eloop_ctx;
- char buf[2000], *pos;
- void *cmd_buf;
- size_t cmd_len;
- int res, cmd;
- struct sockaddr_un from;
- socklen_t fromlen = sizeof(from);
-
- res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from,
- &fromlen);
- if (res < 0) {
- wpa_printf(MSG_ERROR, "recvfrom: %s", strerror(errno));
- return;
- }
-
- if (res < (int) sizeof(int)) {
- wpa_printf(MSG_DEBUG, "Too short command (len=%d)", res);
- return;
- }
-
- os_memcpy(&cmd, buf, sizeof(int));
- wpa_printf(MSG_DEBUG, "Command %d for interface %s",
- cmd, iface->ifname);
- cmd_buf = &buf[sizeof(int)];
- cmd_len = res - sizeof(int);
-
- switch (cmd) {
- case PRIVSEP_CMD_REGISTER:
- wpa_priv_cmd_register(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_UNREGISTER:
- wpa_priv_cmd_unregister(iface, &from);
- break;
- case PRIVSEP_CMD_SCAN:
- wpa_priv_cmd_scan(iface, cmd_buf, cmd_len);
- break;
- case PRIVSEP_CMD_GET_SCAN_RESULTS:
- wpa_priv_cmd_get_scan_results(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_ASSOCIATE:
- wpa_priv_cmd_associate(iface, cmd_buf, cmd_len);
- break;
- case PRIVSEP_CMD_GET_BSSID:
- wpa_priv_cmd_get_bssid(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_GET_SSID:
- wpa_priv_cmd_get_ssid(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_SET_KEY:
- wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len);
- break;
- case PRIVSEP_CMD_GET_CAPA:
- wpa_priv_cmd_get_capa(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_L2_REGISTER:
- wpa_priv_cmd_l2_register(iface, &from, fromlen,
- cmd_buf, cmd_len);
- break;
- case PRIVSEP_CMD_L2_UNREGISTER:
- wpa_priv_cmd_l2_unregister(iface, &from, fromlen);
- break;
- case PRIVSEP_CMD_L2_NOTIFY_AUTH_START:
- wpa_priv_cmd_l2_notify_auth_start(iface, &from);
- break;
- case PRIVSEP_CMD_L2_SEND:
- wpa_priv_cmd_l2_send(iface, &from, fromlen, cmd_buf, cmd_len);
- break;
- case PRIVSEP_CMD_SET_COUNTRY:
- pos = cmd_buf;
- if (pos + cmd_len >= buf + sizeof(buf))
- break;
- pos[cmd_len] = '\0';
- wpa_priv_cmd_set_country(iface, pos);
- break;
- case PRIVSEP_CMD_AUTHENTICATE:
- wpa_priv_cmd_authenticate(iface, cmd_buf, cmd_len);
- break;
- }
-}
-
-
-static void wpa_priv_interface_deinit(struct wpa_priv_interface *iface)
-{
- int i;
-
- if (iface->drv_priv) {
- if (iface->driver->deinit)
- iface->driver->deinit(iface->drv_priv);
- if (iface->drv_global_priv)
- iface->driver->global_deinit(iface->drv_global_priv);
- }
-
- if (iface->fd >= 0) {
- eloop_unregister_read_sock(iface->fd);
- close(iface->fd);
- unlink(iface->sock_name);
- }
-
- for (i = 0; i < WPA_PRIV_MAX_L2; i++) {
- if (iface->l2[i])
- l2_packet_deinit(iface->l2[i]);
- }
-
- os_free(iface->ifname);
- os_free(iface->driver_name);
- os_free(iface->sock_name);
- os_free(iface);
-}
-
-
-static struct wpa_priv_interface *
-wpa_priv_interface_init(void *ctx, const char *dir, const char *params)
-{
- struct wpa_priv_interface *iface;
- char *pos;
- size_t len;
- struct sockaddr_un addr;
- int i;
-
- pos = os_strchr(params, ':');
- if (pos == NULL)
- return NULL;
-
- iface = os_zalloc(sizeof(*iface));
- if (iface == NULL)
- return NULL;
- iface->fd = -1;
- iface->ctx = ctx;
-
- len = pos - params;
- iface->driver_name = dup_binstr(params, len);
- if (iface->driver_name == NULL) {
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- for (i = 0; wpa_drivers[i]; i++) {
- if (os_strcmp(iface->driver_name,
- wpa_drivers[i]->name) == 0) {
- iface->driver = wpa_drivers[i];
- break;
- }
- }
- if (iface->driver == NULL) {
- wpa_printf(MSG_ERROR, "Unsupported driver '%s'",
- iface->driver_name);
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- pos++;
- iface->ifname = os_strdup(pos);
- if (iface->ifname == NULL) {
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- len = os_strlen(dir) + 1 + os_strlen(iface->ifname);
- iface->sock_name = os_malloc(len + 1);
- if (iface->sock_name == NULL) {
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname);
- if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) {
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (iface->fd < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
- wpa_priv_interface_deinit(iface);
- return NULL;
- }
-
- os_memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path));
-
- if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s",
- strerror(errno));
- if (connect(iface->fd, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_DEBUG, "Socket exists, but does not "
- "allow connections - assuming it was "
- "leftover from forced program termination");
- if (unlink(iface->sock_name) < 0) {
- wpa_printf(MSG_ERROR,
- "Could not unlink existing ctrl_iface socket '%s': %s",
- iface->sock_name, strerror(errno));
- goto fail;
- }
- if (bind(iface->fd, (struct sockaddr *) &addr,
- sizeof(addr)) < 0) {
- wpa_printf(MSG_ERROR,
- "wpa-priv-iface-init: bind(PF_UNIX): %s",
- strerror(errno));
- goto fail;
- }
- wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
- "socket '%s'", iface->sock_name);
- } else {
- wpa_printf(MSG_INFO, "Socket exists and seems to be "
- "in use - cannot override it");
- wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
- "not used anymore", iface->sock_name);
- goto fail;
- }
- }
-
- if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
- wpa_printf(MSG_ERROR, "chmod: %s", strerror(errno));
- goto fail;
- }
-
- eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL);
-
- return iface;
-
-fail:
- wpa_priv_interface_deinit(iface);
- return NULL;
-}
-
-
-static int wpa_priv_send_event(struct wpa_priv_interface *iface, int event,
- const void *data, size_t data_len)
-{
- struct msghdr msg;
- struct iovec io[2];
-
- io[0].iov_base = &event;
- io[0].iov_len = sizeof(event);
- io[1].iov_base = (u8 *) data;
- io[1].iov_len = data_len;
-
- os_memset(&msg, 0, sizeof(msg));
- msg.msg_iov = io;
- msg.msg_iovlen = data ? 2 : 1;
- msg.msg_name = &iface->drv_addr;
- msg.msg_namelen = iface->drv_addr_len;
-
- if (sendmsg(iface->fd, &msg, 0) < 0) {
- wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
- strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-
-static void wpa_priv_send_auth(struct wpa_priv_interface *iface,
- union wpa_event_data *data)
-{
- size_t buflen = sizeof(struct privsep_event_auth) + data->auth.ies_len;
- struct privsep_event_auth *auth;
- u8 *buf, *pos;
-
- buf = os_zalloc(buflen);
- if (buf == NULL)
- return;
-
- auth = (struct privsep_event_auth *) buf;
- pos = (u8 *) (auth + 1);
-
- os_memcpy(auth->peer, data->auth.peer, ETH_ALEN);
- os_memcpy(auth->bssid, data->auth.bssid, ETH_ALEN);
- auth->auth_type = data->auth.auth_type;
- auth->auth_transaction = data->auth.auth_transaction;
- auth->status_code = data->auth.status_code;
- if (data->auth.ies) {
- os_memcpy(pos, data->auth.ies, data->auth.ies_len);
- auth->ies_len = data->auth.ies_len;
- }
-
- wpa_priv_send_event(iface, PRIVSEP_EVENT_AUTH, buf, buflen);
-
- os_free(buf);
-}
-
-
-static void wpa_priv_send_assoc(struct wpa_priv_interface *iface, int event,
- union wpa_event_data *data)
-{
- size_t buflen = 3 * sizeof(int);
- u8 *buf, *pos;
- int len;
-
- if (data) {
- buflen += data->assoc_info.req_ies_len +
- data->assoc_info.resp_ies_len +
- data->assoc_info.beacon_ies_len;
- }
-
- buf = os_malloc(buflen);
- if (buf == NULL)
- return;
-
- pos = buf;
-
- if (data && data->assoc_info.req_ies) {
- len = data->assoc_info.req_ies_len;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- os_memcpy(pos, data->assoc_info.req_ies, len);
- pos += len;
- } else {
- len = 0;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- }
-
- if (data && data->assoc_info.resp_ies) {
- len = data->assoc_info.resp_ies_len;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- os_memcpy(pos, data->assoc_info.resp_ies, len);
- pos += len;
- } else {
- len = 0;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- }
-
- if (data && data->assoc_info.beacon_ies) {
- len = data->assoc_info.beacon_ies_len;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- os_memcpy(pos, data->assoc_info.beacon_ies, len);
- pos += len;
- } else {
- len = 0;
- os_memcpy(pos, &len, sizeof(int));
- pos += sizeof(int);
- }
-
- wpa_priv_send_event(iface, event, buf, buflen);
-
- os_free(buf);
-}
-
-
-static void wpa_priv_send_interface_status(struct wpa_priv_interface *iface,
- union wpa_event_data *data)
-{
- int ievent;
- size_t len, maxlen;
- u8 *buf;
- char *ifname;
-
- if (data == NULL)
- return;
-
- ievent = data->interface_status.ievent;
- maxlen = sizeof(data->interface_status.ifname);
- ifname = data->interface_status.ifname;
- for (len = 0; len < maxlen && ifname[len]; len++)
- ;
-
- buf = os_malloc(sizeof(int) + len);
- if (buf == NULL)
- return;
-
- os_memcpy(buf, &ievent, sizeof(int));
- os_memcpy(buf + sizeof(int), ifname, len);
-
- wpa_priv_send_event(iface, PRIVSEP_EVENT_INTERFACE_STATUS,
- buf, sizeof(int) + len);
-
- os_free(buf);
-
-}
-
-
-static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface,
- union wpa_event_data *data)
-{
- size_t len;
- u8 *buf, *pos;
-
- if (data == NULL || data->ft_ies.ies == NULL)
- return;
-
- len = sizeof(int) + ETH_ALEN + data->ft_ies.ies_len;
- buf = os_malloc(len);
- if (buf == NULL)
- return;
-
- pos = buf;
- os_memcpy(pos, &data->ft_ies.ft_action, sizeof(int));
- pos += sizeof(int);
- os_memcpy(pos, data->ft_ies.target_ap, ETH_ALEN);
- pos += ETH_ALEN;
- os_memcpy(pos, data->ft_ies.ies, data->ft_ies.ies_len);
-
- wpa_priv_send_event(iface, PRIVSEP_EVENT_FT_RESPONSE, buf, len);
-
- os_free(buf);
-
-}
-
-
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
- union wpa_event_data *data)
-{
- struct wpa_priv_interface *iface = ctx;
-
- wpa_printf(MSG_DEBUG, "%s - event=%d", __func__, event);
-
- if (!iface->wpas_registered) {
- wpa_printf(MSG_DEBUG, "Driver event received, but "
- "wpa_supplicant not registered");
- return;
- }
-
- switch (event) {
- case EVENT_ASSOC:
- wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOC, data);
- break;
- case EVENT_DISASSOC:
- wpa_priv_send_event(iface, PRIVSEP_EVENT_DISASSOC, NULL, 0);
- break;
- case EVENT_ASSOCINFO:
- if (data == NULL)
- return;
- wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOCINFO, data);
- break;
- case EVENT_MICHAEL_MIC_FAILURE:
- if (data == NULL)
- return;
- wpa_priv_send_event(iface, PRIVSEP_EVENT_MICHAEL_MIC_FAILURE,
- &data->michael_mic_failure.unicast,
- sizeof(int));
- break;
- case EVENT_SCAN_STARTED:
- wpa_priv_send_event(iface, PRIVSEP_EVENT_SCAN_STARTED, NULL,
- 0);
- break;
- case EVENT_SCAN_RESULTS:
- wpa_priv_send_event(iface, PRIVSEP_EVENT_SCAN_RESULTS, NULL,
- 0);
- break;
- case EVENT_INTERFACE_STATUS:
- wpa_priv_send_interface_status(iface, data);
- break;
- case EVENT_PMKID_CANDIDATE:
- if (data == NULL)
- return;
- wpa_priv_send_event(iface, PRIVSEP_EVENT_PMKID_CANDIDATE,
- &data->pmkid_candidate,
- sizeof(struct pmkid_candidate));
- break;
- case EVENT_FT_RESPONSE:
- wpa_priv_send_ft_response(iface, data);
- break;
- case EVENT_AUTH:
- wpa_priv_send_auth(iface, data);
- break;
- default:
- wpa_printf(MSG_DEBUG, "Unsupported driver event %d (%s) - TODO",
- event, event_to_string(event));
- break;
- }
-}
-
-
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
- union wpa_event_data *data)
-{
- struct wpa_priv_global *global = ctx;
- struct wpa_priv_interface *iface;
-
- if (event != EVENT_INTERFACE_STATUS)
- return;
-
- for (iface = global->interfaces; iface; iface = iface->next) {
- if (os_strcmp(iface->ifname, data->interface_status.ifname) ==
- 0)
- break;
- }
- if (iface && iface->driver->get_ifindex) {
- unsigned int ifindex;
-
- ifindex = iface->driver->get_ifindex(iface->drv_priv);
- if (ifindex != data->interface_status.ifindex) {
- wpa_printf(MSG_DEBUG,
- "%s: interface status ifindex %d mismatch (%d)",
- iface->ifname, ifindex,
- data->interface_status.ifindex);
- return;
- }
- }
- if (iface)
- wpa_supplicant_event(iface, event, data);
-}
-
-
-void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len)
-{
- struct wpa_priv_interface *iface = ctx;
- struct msghdr msg;
- struct iovec io[3];
- int event = PRIVSEP_EVENT_RX_EAPOL;
-
- wpa_printf(MSG_DEBUG, "RX EAPOL from driver");
- io[0].iov_base = &event;
- io[0].iov_len = sizeof(event);
- io[1].iov_base = (u8 *) src_addr;
- io[1].iov_len = ETH_ALEN;
- io[2].iov_base = (u8 *) buf;
- io[2].iov_len = len;
-
- os_memset(&msg, 0, sizeof(msg));
- msg.msg_iov = io;
- msg.msg_iovlen = 3;
- msg.msg_name = &iface->drv_addr;
- msg.msg_namelen = iface->drv_addr_len;
-
- if (sendmsg(iface->fd, &msg, 0) < 0)
- wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
- strerror(errno));
-}
-
-
-static void wpa_priv_terminate(int sig, void *signal_ctx)
-{
- wpa_printf(MSG_DEBUG, "wpa_priv termination requested");
- eloop_terminate();
-}
-
-
-static void wpa_priv_fd_workaround(void)
-{
-#ifdef __linux__
- int s, i;
- /* When started from pcmcia-cs scripts, wpa_supplicant might start with
- * fd 0, 1, and 2 closed. This will cause some issues because many
- * places in wpa_supplicant are still printing out to stdout. As a
- * workaround, make sure that fd's 0, 1, and 2 are not used for other
- * sockets. */
- for (i = 0; i < 3; i++) {
- s = open("/dev/null", O_RDWR);
- if (s > 2) {
- close(s);
- break;
- }
- }
-#endif /* __linux__ */
-}
-
-
-static void usage(void)
-{
- printf("wpa_priv v%s\n"
- "Copyright (c) 2007-2017, Jouni Malinen <j@w1.fi> and "
- "contributors\n"
- "\n"
- "usage:\n"
- " wpa_priv [-Bdd] [-c<ctrl dir>] [-P<pid file>] "
- "<driver:ifname> \\\n"
- " [driver:ifname ...]\n",
- VERSION_STR);
-}
-
-
-int main(int argc, char *argv[])
-{
- int c, i;
- int ret = -1;
- char *pid_file = NULL;
- int daemonize = 0;
- char *ctrl_dir = "/var/run/wpa_priv";
- struct wpa_priv_global global;
- struct wpa_priv_interface *iface;
-
- if (os_program_init())
- return -1;
-
- wpa_priv_fd_workaround();
-
- os_memset(&global, 0, sizeof(global));
- global.interfaces = NULL;
-
- for (;;) {
- c = getopt(argc, argv, "Bc:dP:");
- if (c < 0)
- break;
- switch (c) {
- case 'B':
- daemonize++;
- break;
- case 'c':
- ctrl_dir = optarg;
- break;
- case 'd':
- wpa_debug_level--;
- break;
- case 'P':
- pid_file = os_rel2abs_path(optarg);
- break;
- default:
- usage();
- goto out2;
- }
- }
-
- if (optind >= argc) {
- usage();
- goto out2;
- }
-
- wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir);
-
- if (eloop_init()) {
- wpa_printf(MSG_ERROR, "Failed to initialize event loop");
- goto out2;
- }
-
- for (i = optind; i < argc; i++) {
- wpa_printf(MSG_DEBUG, "Adding driver:interface %s", argv[i]);
- iface = wpa_priv_interface_init(&global, ctrl_dir, argv[i]);
- if (iface == NULL)
- goto out;
- iface->next = global.interfaces;
- global.interfaces = iface;
- }
-
- if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
- goto out;
-
- eloop_register_signal_terminate(wpa_priv_terminate, NULL);
- eloop_run();
-
- ret = 0;
-
-out:
- iface = global.interfaces;
- while (iface) {
- struct wpa_priv_interface *prev = iface;
- iface = iface->next;
- wpa_priv_interface_deinit(prev);
- }
-
- eloop_destroy();
-
-out2:
- if (daemonize)
- os_daemonize_terminate(pid_file);
- os_free(pid_file);
- os_program_deinit();
-
- return ret;
-}
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
deleted file mode 100644
index 1785f88ab73d..000000000000
--- a/wpa_supplicant/wpa_supplicant.c
+++ /dev/null
@@ -1,8658 +0,0 @@
-/*
- * WPA Supplicant
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- *
- * This file implements functions for registering and unregistering
- * %wpa_supplicant interfaces. In addition, this file contains number of
- * functions for managing network connections.
- */
-
-#include "includes.h"
-#ifdef CONFIG_MATCH_IFACE
-#include <net/if.h>
-#include <fnmatch.h>
-#endif /* CONFIG_MATCH_IFACE */
-
-#include "common.h"
-#include "crypto/random.h"
-#include "crypto/sha1.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "eap_peer/eap.h"
-#include "eap_peer/eap_proxy.h"
-#include "eap_server/eap_methods.h"
-#include "rsn_supp/wpa.h"
-#include "eloop.h"
-#include "config.h"
-#include "utils/ext_password.h"
-#include "l2_packet/l2_packet.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "ctrl_iface.h"
-#include "pcsc_funcs.h"
-#include "common/version.h"
-#include "rsn_supp/preauth.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "common/wpa_ctrl.h"
-#include "common/ieee802_11_common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/hw_features_common.h"
-#include "common/gas_server.h"
-#include "common/dpp.h"
-#include "common/ptksa_cache.h"
-#include "p2p/p2p.h"
-#include "fst/fst.h"
-#include "bssid_ignore.h"
-#include "wpas_glue.h"
-#include "wps_supplicant.h"
-#include "ibss_rsn.h"
-#include "sme.h"
-#include "gas_query.h"
-#include "ap.h"
-#include "p2p_supplicant.h"
-#include "wifi_display.h"
-#include "notify.h"
-#include "bgscan.h"
-#include "autoscan.h"
-#include "bss.h"
-#include "scan.h"
-#include "offchannel.h"
-#include "hs20_supplicant.h"
-#include "wnm_sta.h"
-#include "wpas_kay.h"
-#include "mesh.h"
-#include "dpp_supplicant.h"
-#ifdef CONFIG_MESH
-#include "ap/ap_config.h"
-#include "ap/hostapd.h"
-#endif /* CONFIG_MESH */
-
-const char *const wpa_supplicant_version =
-"wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors";
-
-const char *const wpa_supplicant_license =
-"This software may be distributed under the terms of the BSD license.\n"
-"See README for more details.\n"
-#ifdef EAP_TLS_OPENSSL
-"\nThis product includes software developed by the OpenSSL Project\n"
-"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
-#endif /* EAP_TLS_OPENSSL */
-;
-
-#ifndef CONFIG_NO_STDOUT_DEBUG
-/* Long text divided into parts in order to fit in C89 strings size limits. */
-const char *const wpa_supplicant_full_license1 =
-"";
-const char *const wpa_supplicant_full_license2 =
-"This software may be distributed under the terms of the BSD license.\n"
-"\n"
-"Redistribution and use in source and binary forms, with or without\n"
-"modification, are permitted provided that the following conditions are\n"
-"met:\n"
-"\n";
-const char *const wpa_supplicant_full_license3 =
-"1. Redistributions of source code must retain the above copyright\n"
-" notice, this list of conditions and the following disclaimer.\n"
-"\n"
-"2. Redistributions in binary form must reproduce the above copyright\n"
-" notice, this list of conditions and the following disclaimer in the\n"
-" documentation and/or other materials provided with the distribution.\n"
-"\n";
-const char *const wpa_supplicant_full_license4 =
-"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
-" names of its contributors may be used to endorse or promote products\n"
-" derived from this software without specific prior written permission.\n"
-"\n"
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
-"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
-"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
-const char *const wpa_supplicant_full_license5 =
-"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
-"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
-"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
-"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
-"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
-"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
-"\n";
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
-
-static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx);
-#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
-static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s);
-#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
-#ifdef CONFIG_OWE
-static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s);
-#endif /* CONFIG_OWE */
-
-
-#ifdef CONFIG_WEP
-/* Configure default/group WEP keys for static WEP */
-int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- int i, set = 0;
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i] == 0)
- continue;
-
- set = 1;
- wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
- i, i == ssid->wep_tx_keyidx, NULL, 0,
- ssid->wep_key[i], ssid->wep_key_len[i],
- i == ssid->wep_tx_keyidx ?
- KEY_FLAG_GROUP_RX_TX_DEFAULT :
- KEY_FLAG_GROUP_RX_TX);
- }
-
- return set;
-}
-#endif /* CONFIG_WEP */
-
-
-int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- u8 key[32];
- size_t keylen;
- enum wpa_alg alg;
- u8 seq[6] = { 0 };
- int ret;
-
- /* IBSS/WPA-None uses only one key (Group) for both receiving and
- * sending unicast and multicast packets. */
-
- if (ssid->mode != WPAS_MODE_IBSS) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
- "IBSS/ad-hoc) for WPA-None", ssid->mode);
- return -1;
- }
-
- if (!ssid->psk_set) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
- "WPA-None");
- return -1;
- }
-
- switch (wpa_s->group_cipher) {
- case WPA_CIPHER_CCMP:
- os_memcpy(key, ssid->psk, 16);
- keylen = 16;
- alg = WPA_ALG_CCMP;
- break;
- case WPA_CIPHER_GCMP:
- os_memcpy(key, ssid->psk, 16);
- keylen = 16;
- alg = WPA_ALG_GCMP;
- break;
- case WPA_CIPHER_TKIP:
- /* WPA-None uses the same Michael MIC key for both TX and RX */
- os_memcpy(key, ssid->psk, 16 + 8);
- os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
- keylen = 32;
- alg = WPA_ALG_TKIP;
- break;
- default:
- wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
- "WPA-None", wpa_s->group_cipher);
- return -1;
- }
-
- /* TODO: should actually remember the previously used seq#, both for TX
- * and RX from each STA.. */
-
- ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen,
- KEY_FLAG_GROUP_RX_TX_DEFAULT);
- os_memset(key, 0, sizeof(key));
- return ret;
-}
-
-
-static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- const u8 *bssid = wpa_s->bssid;
- if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
- (wpa_s->wpa_state == WPA_AUTHENTICATING ||
- wpa_s->wpa_state == WPA_ASSOCIATING))
- bssid = wpa_s->pending_bssid;
- wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
- MAC2STR(bssid));
- wpa_bssid_ignore_add(wpa_s, bssid);
- wpa_sm_notify_disassoc(wpa_s->wpa);
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- wpa_s->reassociate = 1;
-
- /*
- * If we timed out, the AP or the local radio may be busy.
- * So, wait a second until scanning again.
- */
- wpa_supplicant_req_scan(wpa_s, 1, 0);
-}
-
-
-/**
- * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
- * @wpa_s: Pointer to wpa_supplicant data
- * @sec: Number of seconds after which to time out authentication
- * @usec: Number of microseconds after which to time out authentication
- *
- * This function is used to schedule a timeout for the current authentication
- * attempt.
- */
-void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
- int sec, int usec)
-{
- if (wpa_s->conf->ap_scan == 0 &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
- return;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
- "%d usec", sec, usec);
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
- wpa_s->last_auth_timeout_sec = sec;
- eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
-}
-
-
-/*
- * wpas_auth_timeout_restart - Restart and change timeout for authentication
- * @wpa_s: Pointer to wpa_supplicant data
- * @sec_diff: difference in seconds applied to original timeout value
- */
-void wpas_auth_timeout_restart(struct wpa_supplicant *wpa_s, int sec_diff)
-{
- int new_sec = wpa_s->last_auth_timeout_sec + sec_diff;
-
- if (eloop_is_timeout_registered(wpa_supplicant_timeout, wpa_s, NULL)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Authentication timeout restart: %d sec", new_sec);
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
- eloop_register_timeout(new_sec, 0, wpa_supplicant_timeout,
- wpa_s, NULL);
- }
-}
-
-
-/**
- * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to cancel authentication timeout scheduled with
- * wpa_supplicant_req_auth_timeout() and it is called when authentication has
- * been completed.
- */
-void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
-{
- wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
- wpa_bssid_ignore_del(wpa_s, wpa_s->bssid);
- os_free(wpa_s->last_con_fail_realm);
- wpa_s->last_con_fail_realm = NULL;
- wpa_s->last_con_fail_realm_len = 0;
-}
-
-
-/**
- * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to configure EAPOL state machine based on the selected
- * authentication mode.
- */
-void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
-{
-#ifdef IEEE8021X_EAPOL
- struct eapol_config eapol_conf;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
-
-#ifdef CONFIG_IBSS_RSN
- if (ssid->mode == WPAS_MODE_IBSS &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
- /*
- * RSN IBSS authentication is per-STA and we can disable the
- * per-BSSID EAPOL authentication.
- */
- eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
- eapol_sm_notify_eap_success(wpa_s->eapol, true);
- eapol_sm_notify_eap_fail(wpa_s->eapol, false);
- return;
- }
-#endif /* CONFIG_IBSS_RSN */
-
- eapol_sm_notify_eap_success(wpa_s->eapol, false);
- eapol_sm_notify_eap_fail(wpa_s->eapol, false);
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
- eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
- else
- eapol_sm_notify_portControl(wpa_s->eapol, Auto);
-
- os_memset(&eapol_conf, 0, sizeof(eapol_conf));
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- eapol_conf.accept_802_1x_keys = 1;
- eapol_conf.required_keys = 0;
- if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
- eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
- }
- if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
- eapol_conf.required_keys |=
- EAPOL_REQUIRE_KEY_BROADCAST;
- }
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
- eapol_conf.required_keys = 0;
- }
- eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
- eapol_conf.workaround = ssid->eap_workaround;
- eapol_conf.eap_disabled =
- !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
- eapol_conf.external_sim = wpa_s->conf->external_sim;
-
-#ifdef CONFIG_WPS
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
- eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
- if (wpa_s->current_bss) {
- struct wpabuf *ie;
- ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
- WPS_IE_VENDOR_TYPE);
- if (ie) {
- if (wps_is_20(ie))
- eapol_conf.wps |=
- EAPOL_PEER_IS_WPS20_AP;
- wpabuf_free(ie);
- }
- }
- }
-#endif /* CONFIG_WPS */
-
- eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
-
-#ifdef CONFIG_MACSEC
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE && ssid->mka_psk_set)
- ieee802_1x_create_preshared_mka(wpa_s, ssid);
- else
- ieee802_1x_alloc_kay_sm(wpa_s, ssid);
-#endif /* CONFIG_MACSEC */
-#endif /* IEEE8021X_EAPOL */
-}
-
-
-/**
- * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
- * @wpa_s: Pointer to wpa_supplicant data
- * @ssid: Configuration data for the network
- *
- * This function is used to configure WPA state machine and related parameters
- * to a mode where WPA is not enabled. This is called as part of the
- * authentication configuration when the selected network does not use WPA.
- */
-void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_WEP
- int i;
-#endif /* CONFIG_WEP */
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
- wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
- else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
- else
- wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
- wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
- wpa_s->rsnxe_len = 0;
- wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
- wpa_s->group_cipher = WPA_CIPHER_NONE;
- wpa_s->mgmt_group_cipher = 0;
-
-#ifdef CONFIG_WEP
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i] > 5) {
- wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
- wpa_s->group_cipher = WPA_CIPHER_WEP104;
- break;
- } else if (ssid->wep_key_len[i] > 0) {
- wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
- wpa_s->group_cipher = WPA_CIPHER_WEP40;
- break;
- }
- }
-#endif /* CONFIG_WEP */
-
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
- wpa_s->pairwise_cipher);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
- wpa_s->mgmt_group_cipher);
-
- pmksa_cache_clear_current(wpa_s->wpa);
-}
-
-
-void free_hw_features(struct wpa_supplicant *wpa_s)
-{
- int i;
- if (wpa_s->hw.modes == NULL)
- return;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- os_free(wpa_s->hw.modes[i].channels);
- os_free(wpa_s->hw.modes[i].rates);
- }
-
- os_free(wpa_s->hw.modes);
- wpa_s->hw.modes = NULL;
-}
-
-
-static void remove_bss_tmp_disallowed_entry(struct wpa_supplicant *wpa_s,
- struct wpa_bss_tmp_disallowed *bss)
-{
- eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss);
- dl_list_del(&bss->list);
- os_free(bss);
-}
-
-
-void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss_tmp_disallowed *bss, *prev;
-
- dl_list_for_each_safe(bss, prev, &wpa_s->bss_tmp_disallowed,
- struct wpa_bss_tmp_disallowed, list)
- remove_bss_tmp_disallowed_entry(wpa_s, bss);
-}
-
-
-void wpas_flush_fils_hlp_req(struct wpa_supplicant *wpa_s)
-{
- struct fils_hlp_req *req;
-
- while ((req = dl_list_first(&wpa_s->fils_hlp_req, struct fils_hlp_req,
- list)) != NULL) {
- dl_list_del(&req->list);
- wpabuf_free(req->pkt);
- os_free(req);
- }
-}
-
-
-void wpas_clear_disabled_interface(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
- return;
- wpa_dbg(wpa_s, MSG_DEBUG, "Clear cached state on disabled interface");
- wpa_bss_flush(wpa_s);
-}
-
-
-#ifdef CONFIG_TESTING_OPTIONS
-void wpas_clear_driver_signal_override(struct wpa_supplicant *wpa_s)
-{
- struct driver_signal_override *dso;
-
- while ((dso = dl_list_first(&wpa_s->drv_signal_override,
- struct driver_signal_override, list))) {
- dl_list_del(&dso->list);
- os_free(dso);
- }
-}
-#endif /* CONFIG_TESTING_OPTIONS */
-
-
-static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
-{
- int i;
-
- bgscan_deinit(wpa_s);
- autoscan_deinit(wpa_s);
- scard_deinit(wpa_s->scard);
- wpa_s->scard = NULL;
- wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
- eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
- l2_packet_deinit(wpa_s->l2);
- wpa_s->l2 = NULL;
- if (wpa_s->l2_br) {
- l2_packet_deinit(wpa_s->l2_br);
- wpa_s->l2_br = NULL;
- }
-#ifdef CONFIG_TESTING_OPTIONS
- l2_packet_deinit(wpa_s->l2_test);
- wpa_s->l2_test = NULL;
- os_free(wpa_s->get_pref_freq_list_override);
- wpa_s->get_pref_freq_list_override = NULL;
- wpabuf_free(wpa_s->last_assoc_req_wpa_ie);
- wpa_s->last_assoc_req_wpa_ie = NULL;
- os_free(wpa_s->extra_sae_rejected_groups);
- wpa_s->extra_sae_rejected_groups = NULL;
- wpabuf_free(wpa_s->rsne_override_eapol);
- wpa_s->rsne_override_eapol = NULL;
- wpabuf_free(wpa_s->rsnxe_override_assoc);
- wpa_s->rsnxe_override_assoc = NULL;
- wpabuf_free(wpa_s->rsnxe_override_eapol);
- wpa_s->rsnxe_override_eapol = NULL;
- wpas_clear_driver_signal_override(wpa_s);
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->conf != NULL) {
- struct wpa_ssid *ssid;
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
- wpas_notify_network_removed(wpa_s, ssid);
- }
-
- os_free(wpa_s->confname);
- wpa_s->confname = NULL;
-
- os_free(wpa_s->confanother);
- wpa_s->confanother = NULL;
-
- os_free(wpa_s->last_con_fail_realm);
- wpa_s->last_con_fail_realm = NULL;
- wpa_s->last_con_fail_realm_len = 0;
-
- wpa_sm_set_eapol(wpa_s->wpa, NULL);
- eapol_sm_deinit(wpa_s->eapol);
- wpa_s->eapol = NULL;
-
- rsn_preauth_deinit(wpa_s->wpa);
-
-#ifdef CONFIG_TDLS
- wpa_tdls_deinit(wpa_s->wpa);
-#endif /* CONFIG_TDLS */
-
- wmm_ac_clear_saved_tspecs(wpa_s);
- pmksa_candidate_free(wpa_s->wpa);
- ptksa_cache_deinit(wpa_s->ptksa);
- wpa_s->ptksa = NULL;
- wpa_sm_deinit(wpa_s->wpa);
- wpa_s->wpa = NULL;
- wpa_bssid_ignore_clear(wpa_s);
-
-#ifdef CONFIG_PASN
- wpas_pasn_auth_stop(wpa_s);
-#endif /* CONFIG_PASN */
-
- wpa_bss_deinit(wpa_s);
-
- wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
-#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
- eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
- wpa_s, NULL);
-#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
-
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
- eloop_cancel_timeout(wpas_clear_disabled_interface, wpa_s, NULL);
-
- wpas_wps_deinit(wpa_s);
-
- wpabuf_free(wpa_s->pending_eapol_rx);
- wpa_s->pending_eapol_rx = NULL;
-
-#ifdef CONFIG_IBSS_RSN
- ibss_rsn_deinit(wpa_s->ibss_rsn);
- wpa_s->ibss_rsn = NULL;
-#endif /* CONFIG_IBSS_RSN */
-
- sme_deinit(wpa_s);
-
-#ifdef CONFIG_AP
- wpa_supplicant_ap_deinit(wpa_s);
-#endif /* CONFIG_AP */
-
- wpas_p2p_deinit(wpa_s);
-
-#ifdef CONFIG_OFFCHANNEL
- offchannel_deinit(wpa_s);
-#endif /* CONFIG_OFFCHANNEL */
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
-
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = NULL;
-
- os_free(wpa_s->manual_scan_freqs);
- wpa_s->manual_scan_freqs = NULL;
- os_free(wpa_s->select_network_scan_freqs);
- wpa_s->select_network_scan_freqs = NULL;
-
- os_free(wpa_s->manual_sched_scan_freqs);
- wpa_s->manual_sched_scan_freqs = NULL;
-
- wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
-
- /*
- * Need to remove any pending gas-query radio work before the
- * gas_query_deinit() call because gas_query::work has not yet been set
- * for works that have not been started. gas_query_free() will be unable
- * to cancel such pending radio works and once the pending gas-query
- * radio work eventually gets removed, the deinit notification call to
- * gas_query_start_cb() would result in dereferencing freed memory.
- */
- if (wpa_s->radio)
- radio_remove_works(wpa_s, "gas-query", 0);
- gas_query_deinit(wpa_s->gas);
- wpa_s->gas = NULL;
- gas_server_deinit(wpa_s->gas_server);
- wpa_s->gas_server = NULL;
-
- free_hw_features(wpa_s);
-
- ieee802_1x_dealloc_kay_sm(wpa_s);
-
- os_free(wpa_s->bssid_filter);
- wpa_s->bssid_filter = NULL;
-
- os_free(wpa_s->disallow_aps_bssid);
- wpa_s->disallow_aps_bssid = NULL;
- os_free(wpa_s->disallow_aps_ssid);
- wpa_s->disallow_aps_ssid = NULL;
-
- wnm_bss_keep_alive_deinit(wpa_s);
-#ifdef CONFIG_WNM
- wnm_deallocate_memory(wpa_s);
-#endif /* CONFIG_WNM */
-
- ext_password_deinit(wpa_s->ext_pw);
- wpa_s->ext_pw = NULL;
-
- wpabuf_free(wpa_s->last_gas_resp);
- wpa_s->last_gas_resp = NULL;
- wpabuf_free(wpa_s->prev_gas_resp);
- wpa_s->prev_gas_resp = NULL;
-
- os_free(wpa_s->last_scan_res);
- wpa_s->last_scan_res = NULL;
-
-#ifdef CONFIG_HS20
- if (wpa_s->drv_priv)
- wpa_drv_configure_frame_filters(wpa_s, 0);
- hs20_deinit(wpa_s);
-#endif /* CONFIG_HS20 */
-
- for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
- wpabuf_free(wpa_s->vendor_elem[i]);
- wpa_s->vendor_elem[i] = NULL;
- }
-
- wmm_ac_notify_disassoc(wpa_s);
-
- wpa_s->sched_scan_plans_num = 0;
- os_free(wpa_s->sched_scan_plans);
- wpa_s->sched_scan_plans = NULL;
-
-#ifdef CONFIG_MBO
- wpa_s->non_pref_chan_num = 0;
- os_free(wpa_s->non_pref_chan);
- wpa_s->non_pref_chan = NULL;
-#endif /* CONFIG_MBO */
-
- free_bss_tmp_disallowed(wpa_s);
-
- wpabuf_free(wpa_s->lci);
- wpa_s->lci = NULL;
- wpas_clear_beacon_rep_data(wpa_s);
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-#ifdef CONFIG_MESH
- {
- struct external_pmksa_cache *entry;
-
- while ((entry = dl_list_last(&wpa_s->mesh_external_pmksa_cache,
- struct external_pmksa_cache,
- list)) != NULL) {
- dl_list_del(&entry->list);
- os_free(entry->pmksa_cache);
- os_free(entry);
- }
- }
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
- wpas_flush_fils_hlp_req(wpa_s);
-
- wpabuf_free(wpa_s->ric_ies);
- wpa_s->ric_ies = NULL;
-
-#ifdef CONFIG_DPP
- wpas_dpp_deinit(wpa_s);
- dpp_global_deinit(wpa_s->dpp);
- wpa_s->dpp = NULL;
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_PASN
- wpas_pasn_auth_stop(wpa_s);
-#endif /* CONFIG_PASN */
- wpas_scs_deinit(wpa_s);
- wpas_dscp_deinit(wpa_s);
-}
-
-
-/**
- * wpa_clear_keys - Clear keys configured for the driver
- * @wpa_s: Pointer to wpa_supplicant data
- * @addr: Previously used BSSID or %NULL if not available
- *
- * This function clears the encryption keys that has been previously configured
- * for the driver.
- */
-void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- int i, max = 6;
-
- /* MLME-DELETEKEYS.request */
- for (i = 0; i < max; i++) {
- if (wpa_s->keys_cleared & BIT(i))
- continue;
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
- NULL, 0, KEY_FLAG_GROUP);
- }
- /* Pairwise Key ID 1 for Extended Key ID is tracked in bit 15 */
- if (~wpa_s->keys_cleared & (BIT(0) | BIT(15)) && addr &&
- !is_zero_ether_addr(addr)) {
- if (!(wpa_s->keys_cleared & BIT(0)))
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL,
- 0, NULL, 0, KEY_FLAG_PAIRWISE);
- if (!(wpa_s->keys_cleared & BIT(15)))
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 1, 0, NULL,
- 0, NULL, 0, KEY_FLAG_PAIRWISE);
- /* MLME-SETPROTECTION.request(None) */
- wpa_drv_mlme_setprotection(
- wpa_s, addr,
- MLME_SETPROTECTION_PROTECT_TYPE_NONE,
- MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
- }
- wpa_s->keys_cleared = (u32) -1;
-}
-
-
-/**
- * wpa_supplicant_state_txt - Get the connection state name as a text string
- * @state: State (wpa_state; WPA_*)
- * Returns: The state name as a printable text string
- */
-const char * wpa_supplicant_state_txt(enum wpa_states state)
-{
- switch (state) {
- case WPA_DISCONNECTED:
- return "DISCONNECTED";
- case WPA_INACTIVE:
- return "INACTIVE";
- case WPA_INTERFACE_DISABLED:
- return "INTERFACE_DISABLED";
- case WPA_SCANNING:
- return "SCANNING";
- case WPA_AUTHENTICATING:
- return "AUTHENTICATING";
- case WPA_ASSOCIATING:
- return "ASSOCIATING";
- case WPA_ASSOCIATED:
- return "ASSOCIATED";
- case WPA_4WAY_HANDSHAKE:
- return "4WAY_HANDSHAKE";
- case WPA_GROUP_HANDSHAKE:
- return "GROUP_HANDSHAKE";
- case WPA_COMPLETED:
- return "COMPLETED";
- default:
- return "UNKNOWN";
- }
-}
-
-
-#ifdef CONFIG_BGSCAN
-
-static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->bgscan_ssid) {
- bgscan_deinit(wpa_s);
- wpa_s->bgscan_ssid = NULL;
- }
-}
-
-
-/**
- * wpa_supplicant_reset_bgscan - Reset the bgscan for the current SSID.
- * @wpa_s: Pointer to the wpa_supplicant data
- *
- * Stop, start, or reconfigure the scan parameters depending on the method.
- */
-void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s)
-{
- const char *name;
-
- if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
- name = wpa_s->current_ssid->bgscan;
- else
- name = wpa_s->conf->bgscan;
- if (!name || name[0] == '\0') {
- wpa_supplicant_stop_bgscan(wpa_s);
- return;
- }
- if (wpas_driver_bss_selection(wpa_s))
- return;
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
- return;
-#endif /* CONFIG_P2P */
-
- bgscan_deinit(wpa_s);
- if (wpa_s->current_ssid) {
- if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
- "bgscan");
- /*
- * Live without bgscan; it is only used as a roaming
- * optimization, so the initial connection is not
- * affected.
- */
- } else {
- struct wpa_scan_results *scan_res;
- wpa_s->bgscan_ssid = wpa_s->current_ssid;
- scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
- 0);
- if (scan_res) {
- bgscan_notify_scan(wpa_s, scan_res);
- wpa_scan_results_free(scan_res);
- }
- }
- } else
- wpa_s->bgscan_ssid = NULL;
-}
-
-#endif /* CONFIG_BGSCAN */
-
-
-static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
-{
- if (autoscan_init(wpa_s, 0))
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
-}
-
-
-static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
-{
- autoscan_deinit(wpa_s);
-}
-
-
-void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->wpa_state == WPA_DISCONNECTED ||
- wpa_s->wpa_state == WPA_SCANNING) {
- autoscan_deinit(wpa_s);
- wpa_supplicant_start_autoscan(wpa_s);
- }
-}
-
-
-/**
- * wpa_supplicant_set_state - Set current connection state
- * @wpa_s: Pointer to wpa_supplicant data
- * @state: The new connection state
- *
- * This function is called whenever the connection state changes, e.g.,
- * association is completed for WPA/WPA2 4-Way Handshake is started.
- */
-void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
- enum wpa_states state)
-{
- enum wpa_states old_state = wpa_s->wpa_state;
-#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
- bool update_fils_connect_params = false;
-#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
-
- wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
- wpa_supplicant_state_txt(wpa_s->wpa_state),
- wpa_supplicant_state_txt(state));
-
- if (state == WPA_COMPLETED &&
- os_reltime_initialized(&wpa_s->roam_start)) {
- os_reltime_age(&wpa_s->roam_start, &wpa_s->roam_time);
- wpa_s->roam_start.sec = 0;
- wpa_s->roam_start.usec = 0;
- wpas_notify_auth_changed(wpa_s);
- wpas_notify_roam_time(wpa_s);
- wpas_notify_roam_complete(wpa_s);
- } else if (state == WPA_DISCONNECTED &&
- os_reltime_initialized(&wpa_s->roam_start)) {
- wpa_s->roam_start.sec = 0;
- wpa_s->roam_start.usec = 0;
- wpa_s->roam_time.sec = 0;
- wpa_s->roam_time.usec = 0;
- wpas_notify_roam_complete(wpa_s);
- }
-
- if (state == WPA_INTERFACE_DISABLED) {
- /* Assure normal scan when interface is restored */
- wpa_s->normal_scans = 0;
- }
-
- if (state == WPA_COMPLETED) {
- wpas_connect_work_done(wpa_s);
- /* Reinitialize normal_scan counter */
- wpa_s->normal_scans = 0;
- }
-
-#ifdef CONFIG_P2P
- /*
- * P2PS client has to reply to Probe Request frames received on the
- * group operating channel. Enable Probe Request frame reporting for
- * P2P connected client in case p2p_cli_probe configuration property is
- * set to 1.
- */
- if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
- wpa_s->current_ssid->p2p_group) {
- if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Enable CLI Probe Request RX reporting");
- wpa_s->p2p_cli_probe =
- wpa_drv_probe_req_report(wpa_s, 1) >= 0;
- } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "P2P: Disable CLI Probe Request RX reporting");
- wpa_s->p2p_cli_probe = 0;
- wpa_drv_probe_req_report(wpa_s, 0);
- }
- }
-#endif /* CONFIG_P2P */
-
- if (state != WPA_SCANNING)
- wpa_supplicant_notify_scanning(wpa_s, 0);
-
- if (state == WPA_COMPLETED && wpa_s->new_connection) {
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int fils_hlp_sent = 0;
-
-#ifdef CONFIG_SME
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- wpa_auth_alg_fils(wpa_s->sme.auth_alg))
- fils_hlp_sent = 1;
-#endif /* CONFIG_SME */
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- wpa_auth_alg_fils(wpa_s->auth_alg))
- fils_hlp_sent = 1;
-
-#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
- MACSTR " completed [id=%d id_str=%s%s]",
- MAC2STR(wpa_s->bssid),
- ssid ? ssid->id : -1,
- ssid && ssid->id_str ? ssid->id_str : "",
- fils_hlp_sent ? " FILS_HLP_SENT" : "");
-#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
- wpas_clear_temp_disabled(wpa_s, ssid, 1);
- wpa_s->consecutive_conn_failures = 0;
- wpa_s->new_connection = 0;
- wpa_drv_set_operstate(wpa_s, 1);
-#ifndef IEEE8021X_EAPOL
- wpa_drv_set_supp_port(wpa_s, 1);
-#endif /* IEEE8021X_EAPOL */
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
- wpas_p2p_completed(wpa_s);
-
- sme_sched_obss_scan(wpa_s, 1);
-
-#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
- if (!fils_hlp_sent && ssid && ssid->eap.erp)
- update_fils_connect_params = true;
-#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
-#ifdef CONFIG_OWE
- if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_OWE))
- wpas_update_owe_connect_params(wpa_s);
-#endif /* CONFIG_OWE */
- } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
- state == WPA_ASSOCIATED) {
- wpa_s->new_connection = 1;
- wpa_drv_set_operstate(wpa_s, 0);
-#ifndef IEEE8021X_EAPOL
- wpa_drv_set_supp_port(wpa_s, 0);
-#endif /* IEEE8021X_EAPOL */
- sme_sched_obss_scan(wpa_s, 0);
- }
- wpa_s->wpa_state = state;
-
-#ifdef CONFIG_BGSCAN
- if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
- wpa_supplicant_reset_bgscan(wpa_s);
- else if (state < WPA_ASSOCIATED)
- wpa_supplicant_stop_bgscan(wpa_s);
-#endif /* CONFIG_BGSCAN */
-
- if (state > WPA_SCANNING)
- wpa_supplicant_stop_autoscan(wpa_s);
-
- if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
- wpa_supplicant_start_autoscan(wpa_s);
-
- if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
- wmm_ac_notify_disassoc(wpa_s);
-
- if (wpa_s->wpa_state != old_state) {
- wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
-
- /*
- * Notify the P2P Device interface about a state change in one
- * of the interfaces.
- */
- wpas_p2p_indicate_state_change(wpa_s);
-
- if (wpa_s->wpa_state == WPA_COMPLETED ||
- old_state == WPA_COMPLETED)
- wpas_notify_auth_changed(wpa_s);
-#ifdef CONFIG_DPP2
- if (wpa_s->wpa_state == WPA_COMPLETED)
- wpas_dpp_connected(wpa_s);
-#endif /* CONFIG_DPP2 */
- }
-#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
- if (update_fils_connect_params)
- wpas_update_fils_connect_params(wpa_s);
-#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
-}
-
-
-void wpa_supplicant_terminate_proc(struct wpa_global *global)
-{
- int pending = 0;
-#ifdef CONFIG_WPS
- struct wpa_supplicant *wpa_s = global->ifaces;
- while (wpa_s) {
- struct wpa_supplicant *next = wpa_s->next;
- if (wpas_wps_terminate_pending(wpa_s) == 1)
- pending = 1;
-#ifdef CONFIG_P2P
- if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
- (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
- wpas_p2p_disconnect(wpa_s);
-#endif /* CONFIG_P2P */
- wpa_s = next;
- }
-#endif /* CONFIG_WPS */
- if (pending)
- return;
- eloop_terminate();
-}
-
-
-static void wpa_supplicant_terminate(int sig, void *signal_ctx)
-{
- struct wpa_global *global = signal_ctx;
- wpa_supplicant_terminate_proc(global);
-}
-
-
-void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
-{
- enum wpa_states old_state = wpa_s->wpa_state;
- enum wpa_states new_state;
-
- if (old_state == WPA_SCANNING)
- new_state = WPA_SCANNING;
- else
- new_state = WPA_DISCONNECTED;
-
- wpa_s->pairwise_cipher = 0;
- wpa_s->group_cipher = 0;
- wpa_s->mgmt_group_cipher = 0;
- wpa_s->key_mgmt = 0;
- if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
- wpa_supplicant_set_state(wpa_s, new_state);
-
- if (wpa_s->wpa_state != old_state)
- wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
-}
-
-
-/**
- * wpa_supplicant_reload_configuration - Reload configuration data
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success or -1 if configuration parsing failed
- *
- * This function can be used to request that the configuration data is reloaded
- * (e.g., after configuration file change). This function is reloading
- * configuration only for one interface, so this may need to be called multiple
- * times if %wpa_supplicant is controlling multiple interfaces and all
- * interfaces need reconfiguration.
- */
-int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
-{
- struct wpa_config *conf;
- int reconf_ctrl;
- int old_ap_scan;
-
- if (wpa_s->confname == NULL)
- return -1;
- conf = wpa_config_read(wpa_s->confname, NULL);
- if (conf == NULL) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
- "file '%s' - exiting", wpa_s->confname);
- return -1;
- }
- if (wpa_s->confanother &&
- !wpa_config_read(wpa_s->confanother, conf)) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Failed to parse the configuration file '%s' - exiting",
- wpa_s->confanother);
- return -1;
- }
-
- conf->changed_parameters = (unsigned int) -1;
-
- reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
- || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
- os_strcmp(conf->ctrl_interface,
- wpa_s->conf->ctrl_interface) != 0);
-
- if (reconf_ctrl) {
- wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
- wpa_s->ctrl_iface = NULL;
- }
-
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- if (wpa_s->current_ssid) {
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- }
-
- /*
- * TODO: should notify EAPOL SM about changes in opensc_engine_path,
- * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
- */
- if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
- /*
- * Clear forced success to clear EAP state for next
- * authentication.
- */
- eapol_sm_notify_eap_success(wpa_s->eapol, false);
- }
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_sm_set_config(wpa_s->wpa, NULL);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
- wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
- rsn_preauth_deinit(wpa_s->wpa);
-
- old_ap_scan = wpa_s->conf->ap_scan;
- wpa_config_free(wpa_s->conf);
- wpa_s->conf = conf;
- if (old_ap_scan != wpa_s->conf->ap_scan)
- wpas_notify_ap_scan_changed(wpa_s);
-
- if (reconf_ctrl)
- wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
-
- wpa_supplicant_update_config(wpa_s);
-
- wpa_supplicant_clear_status(wpa_s);
- if (wpa_supplicant_enabled_networks(wpa_s)) {
- wpa_s->reassociate = 1;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
- wpa_bssid_ignore_clear(wpa_s);
- wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
- return 0;
-}
-
-
-static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
-{
- struct wpa_global *global = signal_ctx;
- struct wpa_supplicant *wpa_s;
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
- sig);
- if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
- wpa_supplicant_terminate_proc(global);
- }
- }
-
- if (wpa_debug_reopen_file() < 0) {
- /* Ignore errors since we cannot really do much to fix this */
- wpa_printf(MSG_DEBUG, "Could not reopen debug log file");
- }
-}
-
-
-static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_ie_data *ie)
-{
- int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
- if (ret) {
- if (ret == -2) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
- "from association info");
- }
- return -1;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
- "cipher suites");
- if (!(ie->group_cipher & ssid->group_cipher)) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
- "cipher 0x%x (mask 0x%x) - reject",
- ie->group_cipher, ssid->group_cipher);
- return -1;
- }
- if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
- "cipher 0x%x (mask 0x%x) - reject",
- ie->pairwise_cipher, ssid->pairwise_cipher);
- return -1;
- }
- if (!(ie->key_mgmt & ssid->key_mgmt)) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
- "management 0x%x (mask 0x%x) - reject",
- ie->key_mgmt, ssid->key_mgmt);
- return -1;
- }
-
- if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
- wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
- "that does not support management frame protection - "
- "reject");
- return -1;
- }
-
- return 0;
-}
-
-
-static int matching_ciphers(struct wpa_ssid *ssid, struct wpa_ie_data *ie,
- int freq)
-{
- if (!ie->has_group)
- ie->group_cipher = wpa_default_rsn_cipher(freq);
- if (!ie->has_pairwise)
- ie->pairwise_cipher = wpa_default_rsn_cipher(freq);
- return (ie->group_cipher & ssid->group_cipher) &&
- (ie->pairwise_cipher & ssid->pairwise_cipher);
-}
-
-
-void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct wpa_ie_data *ie)
-{
- int sel;
-
- sel = ie->mgmt_group_cipher;
- if (ssid->group_mgmt_cipher)
- sel &= ssid->group_mgmt_cipher;
- if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
- !(ie->capabilities & WPA_CAPABILITY_MFPC))
- sel = 0;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP mgmt_group_cipher 0x%x network profile mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
- ie->mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
- if (sel & WPA_CIPHER_AES_128_CMAC) {
- wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using MGMT group cipher AES-128-CMAC");
- } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
- wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using MGMT group cipher BIP-GMAC-128");
- } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
- wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using MGMT group cipher BIP-GMAC-256");
- } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
- wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using MGMT group cipher BIP-CMAC-256");
- } else {
- wpa_s->mgmt_group_cipher = 0;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
- }
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
- wpa_s->mgmt_group_cipher);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
- wpas_get_ssid_pmf(wpa_s, ssid));
-}
-
-
-/**
- * wpa_supplicant_set_suites - Set authentication and encryption parameters
- * @wpa_s: Pointer to wpa_supplicant data
- * @bss: Scan results for the selected BSS, or %NULL if not available
- * @ssid: Configuration data for the selected network
- * @wpa_ie: Buffer for the WPA/RSN IE
- * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
- * used buffer length in case the functions returns success.
- * Returns: 0 on success or -1 on failure
- *
- * This function is used to configure authentication and encryption parameters
- * based on the network configuration and scan result for the selected BSS (if
- * available).
- */
-int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid,
- u8 *wpa_ie, size_t *wpa_ie_len)
-{
- struct wpa_ie_data ie;
- int sel, proto, sae_pwe;
- const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
-
- if (bss) {
- bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
- } else {
- bss_wpa = bss_rsn = bss_rsnx = bss_osen = NULL;
- }
-
- if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
- wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
- matching_ciphers(ssid, &ie, bss->freq) &&
- (ie.key_mgmt & ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
- proto = WPA_PROTO_RSN;
- } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
- wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
- (ie.group_cipher & ssid->group_cipher) &&
- (ie.pairwise_cipher & ssid->pairwise_cipher) &&
- (ie.key_mgmt & ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
- proto = WPA_PROTO_WPA;
-#ifdef CONFIG_HS20
- } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN) &&
- wpa_parse_wpa_ie(bss_osen, 2 + bss_osen[1], &ie) == 0 &&
- (ie.group_cipher & ssid->group_cipher) &&
- (ie.pairwise_cipher & ssid->pairwise_cipher) &&
- (ie.key_mgmt & ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
- proto = WPA_PROTO_OSEN;
- } else if (bss_rsn && (ssid->proto & WPA_PROTO_OSEN) &&
- wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
- (ie.group_cipher & ssid->group_cipher) &&
- (ie.pairwise_cipher & ssid->pairwise_cipher) &&
- (ie.key_mgmt & ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using OSEN (within RSN)");
- proto = WPA_PROTO_RSN;
-#endif /* CONFIG_HS20 */
- } else if (bss) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
- ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
- ssid->key_mgmt);
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
- MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len),
- bss_wpa ? " WPA" : "",
- bss_rsn ? " RSN" : "",
- bss_osen ? " OSEN" : "");
- if (bss_rsn) {
- wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
- if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Could not parse RSN element");
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
- ie.pairwise_cipher, ie.group_cipher,
- ie.key_mgmt);
- }
- }
- if (bss_wpa) {
- wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
- if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Could not parse WPA element");
- } else {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
- ie.pairwise_cipher, ie.group_cipher,
- ie.key_mgmt);
- }
- }
- return -1;
- } else {
- if (ssid->proto & WPA_PROTO_OSEN)
- proto = WPA_PROTO_OSEN;
- else if (ssid->proto & WPA_PROTO_RSN)
- proto = WPA_PROTO_RSN;
- else
- proto = WPA_PROTO_WPA;
- if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
- os_memset(&ie, 0, sizeof(ie));
- ie.group_cipher = ssid->group_cipher;
- ie.pairwise_cipher = ssid->pairwise_cipher;
- ie.key_mgmt = ssid->key_mgmt;
- ie.mgmt_group_cipher = 0;
- if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
- if (ssid->group_mgmt_cipher &
- WPA_CIPHER_BIP_GMAC_256)
- ie.mgmt_group_cipher =
- WPA_CIPHER_BIP_GMAC_256;
- else if (ssid->group_mgmt_cipher &
- WPA_CIPHER_BIP_CMAC_256)
- ie.mgmt_group_cipher =
- WPA_CIPHER_BIP_CMAC_256;
- else if (ssid->group_mgmt_cipher &
- WPA_CIPHER_BIP_GMAC_128)
- ie.mgmt_group_cipher =
- WPA_CIPHER_BIP_GMAC_128;
- else
- ie.mgmt_group_cipher =
- WPA_CIPHER_AES_128_CMAC;
- }
-#ifdef CONFIG_OWE
- if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- !ssid->owe_only &&
- !bss_wpa && !bss_rsn && !bss_osen) {
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- wpa_s->wpa_proto = 0;
- *wpa_ie_len = 0;
- return 0;
- }
-#endif /* CONFIG_OWE */
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
- "based on configuration");
- } else
- proto = ie.proto;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
- "pairwise %d key_mgmt %d proto %d",
- ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
- if (ssid->ieee80211w) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
- ie.mgmt_group_cipher);
- }
-
- wpa_s->wpa_proto = proto;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
- !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
-
- if (bss || !wpa_s->ap_ies_from_associnfo) {
- if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
- bss_wpa ? 2 + bss_wpa[1] : 0) ||
- wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
- bss_rsn ? 2 + bss_rsn[1] : 0) ||
- wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
- bss_rsnx ? 2 + bss_rsnx[1] : 0))
- return -1;
- }
-
-#ifdef CONFIG_NO_WPA
- wpa_s->group_cipher = WPA_CIPHER_NONE;
- wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
-#else /* CONFIG_NO_WPA */
- sel = ie.group_cipher & ssid->group_cipher;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP group 0x%x network profile group 0x%x; available group 0x%x",
- ie.group_cipher, ssid->group_cipher, sel);
- wpa_s->group_cipher = wpa_pick_group_cipher(sel);
- if (wpa_s->group_cipher < 0) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
- "cipher");
- return -1;
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
- wpa_cipher_txt(wpa_s->group_cipher));
-
- sel = ie.pairwise_cipher & ssid->pairwise_cipher;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP pairwise 0x%x network profile pairwise 0x%x; available pairwise 0x%x",
- ie.pairwise_cipher, ssid->pairwise_cipher, sel);
- wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
- if (wpa_s->pairwise_cipher < 0) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
- "cipher");
- return -1;
- }
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
- wpa_cipher_txt(wpa_s->pairwise_cipher));
-#endif /* CONFIG_NO_WPA */
-
- sel = ie.key_mgmt & ssid->key_mgmt;
-#ifdef CONFIG_SAE
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
- sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_IEEE80211R
- if (!(wpa_s->drv_flags & (WPA_DRIVER_FLAGS_SME |
- WPA_DRIVER_FLAGS_UPDATE_FT_IES)))
- sel &= ~WPA_KEY_MGMT_FT;
-#endif /* CONFIG_IEEE80211R */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP key_mgmt 0x%x network profile key_mgmt 0x%x; available key_mgmt 0x%x",
- ie.key_mgmt, ssid->key_mgmt, sel);
- if (0) {
-#ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SHA384
- } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
- os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT FT/802.1X-SHA384");
- if (!ssid->ft_eap_pmksa_caching &&
- pmksa_cache_get_current(wpa_s->wpa)) {
- /* PMKSA caching with FT may have interoperability
- * issues, so disable that case by default for now. */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: Disable PMKSA caching for FT/802.1X connection");
- pmksa_cache_clear_current(wpa_s->wpa);
- }
-#endif /* CONFIG_SHA384 */
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_SUITEB192
- } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
-#endif /* CONFIG_SUITEB192 */
-#ifdef CONFIG_SUITEB
- } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT 802.1X with Suite B");
-#endif /* CONFIG_SUITEB */
-#ifdef CONFIG_FILS
-#ifdef CONFIG_IEEE80211R
- } else if (sel & WPA_KEY_MGMT_FT_FILS_SHA384) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA384");
- } else if (sel & WPA_KEY_MGMT_FT_FILS_SHA256) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA256");
-#endif /* CONFIG_IEEE80211R */
- } else if (sel & WPA_KEY_MGMT_FILS_SHA384) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA384");
- } else if (sel & WPA_KEY_MGMT_FILS_SHA256) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_IEEE80211R
- } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X) &&
- os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
- if (!ssid->ft_eap_pmksa_caching &&
- pmksa_cache_get_current(wpa_s->wpa)) {
- /* PMKSA caching with FT may have interoperability
- * issues, so disable that case by default for now. */
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: Disable PMKSA caching for FT/802.1X connection");
- pmksa_cache_clear_current(wpa_s->wpa);
- }
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_DPP
- } else if (sel & WPA_KEY_MGMT_DPP) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_DPP;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT DPP");
-#endif /* CONFIG_DPP */
-#ifdef CONFIG_SAE
- } else if (sel & WPA_KEY_MGMT_FT_SAE) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
- } else if (sel & WPA_KEY_MGMT_SAE) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_IEEE80211R
- } else if (sel & WPA_KEY_MGMT_FT_PSK) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
-#endif /* CONFIG_IEEE80211R */
- } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT 802.1X with SHA256");
- } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: using KEY_MGMT PSK with SHA256");
- } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
- } else if (sel & WPA_KEY_MGMT_PSK) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
- } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
-#ifdef CONFIG_HS20
- } else if (sel & WPA_KEY_MGMT_OSEN) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
- wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_OWE
- } else if (sel & WPA_KEY_MGMT_OWE) {
- wpa_s->key_mgmt = WPA_KEY_MGMT_OWE;
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT OWE");
-#endif /* CONFIG_OWE */
- } else {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
- "authenticated key management type");
- return -1;
- }
-
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
- wpa_s->pairwise_cipher);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
-
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
- wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
- wpa_msg(wpa_s, MSG_INFO,
- "RSN: Management frame protection required but the selected AP does not enable it");
- return -1;
- }
-
- wpas_set_mgmt_group_cipher(wpa_s, ssid, &ie);
-#ifdef CONFIG_OCV
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
- (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV))
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
-#endif /* CONFIG_OCV */
- sae_pwe = wpa_s->conf->sae_pwe;
- if (ssid->sae_password_id && sae_pwe != 3)
- sae_pwe = 1;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, sae_pwe);
-#ifdef CONFIG_SAE_PK
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PK,
- wpa_key_mgmt_sae(ssid->key_mgmt) &&
- ssid->sae_pk != SAE_PK_MODE_DISABLED &&
- ((ssid->sae_password &&
- sae_pk_valid_password(ssid->sae_password)) ||
- (!ssid->sae_password && ssid->passphrase &&
- sae_pk_valid_password(ssid->passphrase))));
-#endif /* CONFIG_SAE_PK */
-#ifdef CONFIG_TESTING_OPTIONS
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_FT_RSNXE_USED,
- wpa_s->ft_rsnxe_used);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_EAPOL,
- wpa_s->oci_freq_override_eapol);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_EAPOL_G2,
- wpa_s->oci_freq_override_eapol_g2);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_FT_ASSOC,
- wpa_s->oci_freq_override_ft_assoc);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCI_FREQ_FILS_ASSOC,
- wpa_s->oci_freq_override_fils_assoc);
-#endif /* CONFIG_TESTING_OPTIONS */
-
- /* Extended Key ID is only supported in infrastructure BSS so far */
- if (ssid->mode == WPAS_MODE_INFRA && wpa_s->conf->extended_key_id &&
- (ssid->proto & WPA_PROTO_RSN) &&
- ssid->pairwise_cipher & (WPA_CIPHER_CCMP | WPA_CIPHER_CCMP_256 |
- WPA_CIPHER_GCMP | WPA_CIPHER_GCMP_256) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_EXTENDED_KEY_ID)) {
- int use_ext_key_id = 0;
-
- wpa_msg(wpa_s, MSG_DEBUG,
- "WPA: Enable Extended Key ID support");
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_EXT_KEY_ID,
- wpa_s->conf->extended_key_id);
- if (bss_rsn &&
- wpa_s->conf->extended_key_id &&
- wpa_s->pairwise_cipher != WPA_CIPHER_TKIP &&
- (ie.capabilities & WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST))
- use_ext_key_id = 1;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID,
- use_ext_key_id);
- } else {
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_EXT_KEY_ID, 0);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID, 0);
- }
-
- if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
- return -1;
- }
-
- wpa_s->rsnxe_len = sizeof(wpa_s->rsnxe);
- if (wpa_sm_set_assoc_rsnxe_default(wpa_s->wpa, wpa_s->rsnxe,
- &wpa_s->rsnxe_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "RSN: Failed to generate RSNXE");
- return -1;
- }
-
- if (0) {
-#ifdef CONFIG_DPP
- } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
- /* Use PMK from DPP network introduction (PMKSA entry) */
- wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
-#ifdef CONFIG_DPP2
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DPP_PFS, ssid->dpp_pfs);
-#endif /* CONFIG_DPP2 */
-#endif /* CONFIG_DPP */
- } else if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
- int psk_set = 0;
- int sae_only;
-
- sae_only = (ssid->key_mgmt & (WPA_KEY_MGMT_PSK |
- WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_PSK_SHA256)) == 0;
-
- if (ssid->psk_set && !sae_only) {
- wpa_hexdump_key(MSG_MSGDUMP, "PSK (set in config)",
- ssid->psk, PMK_LEN);
- wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL,
- NULL);
- psk_set = 1;
- }
-
- if (wpa_key_mgmt_sae(ssid->key_mgmt) &&
- (ssid->sae_password || ssid->passphrase))
- psk_set = 1;
-
-#ifndef CONFIG_NO_PBKDF2
- if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
- ssid->passphrase && !sae_only) {
- u8 psk[PMK_LEN];
- pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
- 4096, psk, PMK_LEN);
- wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
- psk, PMK_LEN);
- wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL);
- psk_set = 1;
- os_memset(psk, 0, sizeof(psk));
- }
-#endif /* CONFIG_NO_PBKDF2 */
-#ifdef CONFIG_EXT_PASSWORD
- if (ssid->ext_psk && !sae_only) {
- struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
- ssid->ext_psk);
- char pw_str[64 + 1];
- u8 psk[PMK_LEN];
-
- if (pw == NULL) {
- wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
- "found from external storage");
- return -1;
- }
-
- if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
- wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
- "PSK length %d in external storage",
- (int) wpabuf_len(pw));
- ext_password_free(pw);
- return -1;
- }
-
- os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
- pw_str[wpabuf_len(pw)] = '\0';
-
-#ifndef CONFIG_NO_PBKDF2
- if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
- {
- pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
- 4096, psk, PMK_LEN);
- os_memset(pw_str, 0, sizeof(pw_str));
- wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
- "external passphrase)",
- psk, PMK_LEN);
- wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
- NULL);
- psk_set = 1;
- os_memset(psk, 0, sizeof(psk));
- } else
-#endif /* CONFIG_NO_PBKDF2 */
- if (wpabuf_len(pw) == 2 * PMK_LEN) {
- if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
- wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
- "Invalid PSK hex string");
- os_memset(pw_str, 0, sizeof(pw_str));
- ext_password_free(pw);
- return -1;
- }
- wpa_hexdump_key(MSG_MSGDUMP,
- "PSK (from external PSK)",
- psk, PMK_LEN);
- wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
- NULL);
- psk_set = 1;
- os_memset(psk, 0, sizeof(psk));
- } else {
- wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
- "PSK available");
- os_memset(pw_str, 0, sizeof(pw_str));
- ext_password_free(pw);
- return -1;
- }
-
- os_memset(pw_str, 0, sizeof(pw_str));
- ext_password_free(pw);
- }
-#endif /* CONFIG_EXT_PASSWORD */
-
- if (!psk_set) {
- wpa_msg(wpa_s, MSG_INFO,
- "No PSK available for association");
- wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE");
- return -1;
- }
-#ifdef CONFIG_OWE
- } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
- /* OWE Diffie-Hellman exchange in (Re)Association
- * Request/Response frames set the PMK, so do not override it
- * here. */
-#endif /* CONFIG_OWE */
- } else
- wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
-
- if (ssid->mode != WPAS_MODE_IBSS &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED) &&
- (ssid->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_NEVER ||
- (ssid->wpa_deny_ptk0_rekey == PTK0_REKEY_ALLOW_LOCAL_OK &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS)))) {
- wpa_msg(wpa_s, MSG_INFO,
- "Disable PTK0 rekey support - replaced with reconnect");
- wpa_s->deny_ptk0_rekey = 1;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 1);
- } else {
- wpa_s->deny_ptk0_rekey = 0;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 0);
- }
-
- return 0;
-}
-
-
-static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
-{
- bool scs = true, mscs = true;
-
- *pos = 0x00;
-
- switch (idx) {
- case 0: /* Bits 0-7 */
- break;
- case 1: /* Bits 8-15 */
- if (wpa_s->conf->coloc_intf_reporting) {
- /* Bit 13 - Collocated Interference Reporting */
- *pos |= 0x20;
- }
- break;
- case 2: /* Bits 16-23 */
-#ifdef CONFIG_WNM
- *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
- if (!wpa_s->disable_mbo_oce && !wpa_s->conf->disable_btm)
- *pos |= 0x08; /* Bit 19 - BSS Transition */
-#endif /* CONFIG_WNM */
- break;
- case 3: /* Bits 24-31 */
-#ifdef CONFIG_WNM
- *pos |= 0x02; /* Bit 25 - SSID List */
-#endif /* CONFIG_WNM */
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->conf->interworking)
- *pos |= 0x80; /* Bit 31 - Interworking */
-#endif /* CONFIG_INTERWORKING */
- break;
- case 4: /* Bits 32-39 */
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)
- *pos |= 0x01; /* Bit 32 - QoS Map */
-#endif /* CONFIG_INTERWORKING */
- break;
- case 5: /* Bits 40-47 */
-#ifdef CONFIG_HS20
- if (wpa_s->conf->hs20)
- *pos |= 0x40; /* Bit 46 - WNM-Notification */
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_MBO
- *pos |= 0x40; /* Bit 46 - WNM-Notification */
-#endif /* CONFIG_MBO */
- break;
- case 6: /* Bits 48-55 */
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->disable_scs_support)
- scs = false;
-#endif /* CONFIG_TESTING_OPTIONS */
- if (scs)
- *pos |= 0x40; /* Bit 54 - SCS */
- break;
- case 7: /* Bits 56-63 */
- break;
- case 8: /* Bits 64-71 */
- if (wpa_s->conf->ftm_responder)
- *pos |= 0x40; /* Bit 70 - FTM responder */
- if (wpa_s->conf->ftm_initiator)
- *pos |= 0x80; /* Bit 71 - FTM initiator */
- break;
- case 9: /* Bits 72-79 */
-#ifdef CONFIG_FILS
- if (!wpa_s->disable_fils)
- *pos |= 0x01;
-#endif /* CONFIG_FILS */
- break;
- case 10: /* Bits 80-87 */
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->disable_mscs_support)
- mscs = false;
-#endif /* CONFIG_TESTING_OPTIONS */
- if (mscs)
- *pos |= 0x20; /* Bit 85 - Mirrored SCS */
- break;
- }
-}
-
-
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
-{
- u8 *pos = buf;
- u8 len = 11, i;
-
- if (len < wpa_s->extended_capa_len)
- len = wpa_s->extended_capa_len;
- if (buflen < (size_t) len + 2) {
- wpa_printf(MSG_INFO,
- "Not enough room for building extended capabilities element");
- return -1;
- }
-
- *pos++ = WLAN_EID_EXT_CAPAB;
- *pos++ = len;
- for (i = 0; i < len; i++, pos++) {
- wpas_ext_capab_byte(wpa_s, pos, i);
-
- if (i < wpa_s->extended_capa_len) {
- *pos &= ~wpa_s->extended_capa_mask[i];
- *pos |= wpa_s->extended_capa[i];
- }
- }
-
- while (len > 0 && buf[1 + len] == 0) {
- len--;
- buf[1] = len;
- }
- if (len == 0)
- return 0;
-
- return 2 + len;
-}
-
-
-static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
- struct wpa_bss *test_bss)
-{
- struct wpa_bss *bss;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (bss == test_bss)
- return 1;
- }
-
- return 0;
-}
-
-
-static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *test_ssid)
-{
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid == test_ssid)
- return 1;
- }
-
- return 0;
-}
-
-
-int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
- struct wpa_ssid *test_ssid)
-{
- if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
- return 0;
-
- return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
-}
-
-
-void wpas_connect_work_free(struct wpa_connect_work *cwork)
-{
- if (cwork == NULL)
- return;
- os_free(cwork);
-}
-
-
-void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
-{
- struct wpa_connect_work *cwork;
- struct wpa_radio_work *work = wpa_s->connect_work;
-
- if (!work)
- return;
-
- wpa_s->connect_work = NULL;
- cwork = work->ctx;
- work->ctx = NULL;
- wpas_connect_work_free(cwork);
- radio_work_done(work);
-}
-
-
-int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
-{
- struct os_reltime now;
- u8 addr[ETH_ALEN];
-
- os_get_reltime(&now);
- if (wpa_s->last_mac_addr_style == style &&
- wpa_s->last_mac_addr_change.sec != 0 &&
- !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
- wpa_s->conf->rand_addr_lifetime)) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "Previously selected random MAC address has not yet expired");
- return 0;
- }
-
- switch (style) {
- case 1:
- if (random_mac_addr(addr) < 0)
- return -1;
- break;
- case 2:
- os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
- if (random_mac_addr_keep_oui(addr) < 0)
- return -1;
- break;
- default:
- return -1;
- }
-
- if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Failed to set random MAC address");
- return -1;
- }
-
- os_get_reltime(&wpa_s->last_mac_addr_change);
- wpa_s->mac_addr_changed = 1;
- wpa_s->last_mac_addr_style = style;
-
- if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Could not update MAC address information");
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
- MAC2STR(addr));
-
- return 0;
-}
-
-
-int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
- !wpa_s->conf->preassoc_mac_addr)
- return 0;
-
- return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
-}
-
-
-static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_SAE
- int *groups = conf->sae_groups;
- int default_groups[] = { 19, 20, 21, 0 };
- const char *password;
-
- if (!groups || groups[0] <= 0)
- groups = default_groups;
-
- password = ssid->sae_password;
- if (!password)
- password = ssid->passphrase;
-
- if (!password ||
- (conf->sae_pwe == 0 && !ssid->sae_password_id &&
- !sae_pk_valid_password(password)) ||
- conf->sae_pwe == 3) {
- /* PT derivation not needed */
- sae_deinit_pt(ssid->pt);
- ssid->pt = NULL;
- return;
- }
-
- if (ssid->pt)
- return; /* PT already derived */
- ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
- (const u8 *) password, os_strlen(password),
- ssid->sae_password_id);
-#endif /* CONFIG_SAE */
-}
-
-
-static void wpa_s_clear_sae_rejected(struct wpa_supplicant *wpa_s)
-{
-#if defined(CONFIG_SAE) && defined(CONFIG_SME)
- os_free(wpa_s->sme.sae_rejected_groups);
- wpa_s->sme.sae_rejected_groups = NULL;
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->extra_sae_rejected_groups) {
- int i, *groups = wpa_s->extra_sae_rejected_groups;
-
- for (i = 0; groups[i]; i++) {
- wpa_printf(MSG_DEBUG,
- "TESTING: Indicate rejection of an extra SAE group %d",
- groups[i]);
- int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
- groups[i]);
- }
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_SAE && CONFIG_SME */
-}
-
-
-int wpas_restore_permanent_mac_addr(struct wpa_supplicant *wpa_s)
-{
- if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Could not restore permanent MAC address");
- return -1;
- }
- wpa_s->mac_addr_changed = 0;
- if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_INFO,
- "Could not update MAC address information");
- return -1;
- }
- wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
- return 0;
-}
-
-
-static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
-
-/**
- * wpa_supplicant_associate - Request association
- * @wpa_s: Pointer to wpa_supplicant data
- * @bss: Scan results for the selected BSS, or %NULL if not available
- * @ssid: Configuration data for the selected network
- *
- * This function is used to request %wpa_supplicant to associate with a BSS.
- */
-void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid)
-{
- struct wpa_connect_work *cwork;
- int rand_style;
-
- wpa_s->own_disconnect_req = 0;
- wpa_s->own_reconnect_req = 0;
-
- /*
- * If we are starting a new connection, any previously pending EAPOL
- * RX cannot be valid anymore.
- */
- wpabuf_free(wpa_s->pending_eapol_rx);
- wpa_s->pending_eapol_rx = NULL;
-
- if (ssid->mac_addr == -1)
- rand_style = wpa_s->conf->mac_addr;
- else
- rand_style = ssid->mac_addr;
-
- wpa_s->multi_ap_ie = 0;
- wmm_ac_clear_saved_tspecs(wpa_s);
- wpa_s->reassoc_same_bss = 0;
- wpa_s->reassoc_same_ess = 0;
-#ifdef CONFIG_TESTING_OPTIONS
- wpa_s->testing_resend_assoc = 0;
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->last_ssid == ssid) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
- wpa_s->reassoc_same_ess = 1;
- if (wpa_s->current_bss && wpa_s->current_bss == bss) {
- wmm_ac_save_tspecs(wpa_s);
- wpa_s->reassoc_same_bss = 1;
- } else if (wpa_s->current_bss && wpa_s->current_bss != bss) {
- os_get_reltime(&wpa_s->roam_start);
- }
- } else {
-#ifdef CONFIG_SAE
- wpa_s_clear_sae_rejected(wpa_s);
-#endif /* CONFIG_SAE */
- }
-#ifdef CONFIG_SAE
- wpa_s_setup_sae_pt(wpa_s->conf, ssid);
-#endif /* CONFIG_SAE */
-
- if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
- if (wpas_update_random_addr(wpa_s, rand_style) < 0)
- return;
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
- } else if (rand_style == 0 && wpa_s->mac_addr_changed) {
- if (wpas_restore_permanent_mac_addr(wpa_s) < 0)
- return;
- }
- wpa_s->last_ssid = ssid;
-
-#ifdef CONFIG_IBSS_RSN
- ibss_rsn_deinit(wpa_s->ibss_rsn);
- wpa_s->ibss_rsn = NULL;
-#else /* CONFIG_IBSS_RSN */
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPA_NONE))) {
- wpa_msg(wpa_s, MSG_INFO,
- "IBSS RSN not supported in the build");
- return;
- }
-#endif /* CONFIG_IBSS_RSN */
-
- if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
- ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
-#ifdef CONFIG_AP
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
- wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
- "mode");
- return;
- }
- if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
- wpas_p2p_ap_setup_failed(wpa_s);
- return;
- }
- wpa_s->current_bss = bss;
-#else /* CONFIG_AP */
- wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
- "the build");
-#endif /* CONFIG_AP */
- return;
- }
-
- if (ssid->mode == WPAS_MODE_MESH) {
-#ifdef CONFIG_MESH
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
- wpa_msg(wpa_s, MSG_INFO,
- "Driver does not support mesh mode");
- return;
- }
- if (bss)
- ssid->frequency = bss->freq;
- if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
- wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
- return;
- }
- wpa_s->current_bss = bss;
-#else /* CONFIG_MESH */
- wpa_msg(wpa_s, MSG_ERROR,
- "mesh mode support not included in the build");
-#endif /* CONFIG_MESH */
- return;
- }
-
- /*
- * Set WPA state machine configuration to match the selected network now
- * so that the information is available before wpas_start_assoc_cb()
- * gets called. This is needed at least for RSN pre-authentication where
- * candidate APs are added to a list based on scan result processing
- * before completion of the first association.
- */
- wpa_supplicant_rsn_supp_set_config(wpa_s, ssid);
-
-#ifdef CONFIG_DPP
- if (wpas_dpp_check_connect(wpa_s, ssid, bss) != 0)
- return;
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_TDLS
- if (bss)
- wpa_tdls_ap_ies(wpa_s->wpa, wpa_bss_ie_ptr(bss), bss->ie_len);
-#endif /* CONFIG_TDLS */
-
-#ifdef CONFIG_MBO
- wpas_mbo_check_pmf(wpa_s, bss, ssid);
-#endif /* CONFIG_MBO */
-
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- ssid->mode == WPAS_MODE_INFRA) {
- sme_authenticate(wpa_s, bss, ssid);
- return;
- }
-
- if (wpa_s->connect_work) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
- return;
- }
-
- if (radio_work_pending(wpa_s, "connect")) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
- return;
- }
-
-#ifdef CONFIG_SME
- if (ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) {
- /* Clear possibly set auth_alg, if any, from last attempt. */
- wpa_s->sme.auth_alg = WPA_AUTH_ALG_OPEN;
- }
-#endif /* CONFIG_SME */
-
- wpas_abort_ongoing_scan(wpa_s);
-
- cwork = os_zalloc(sizeof(*cwork));
- if (cwork == NULL)
- return;
-
- cwork->bss = bss;
- cwork->ssid = ssid;
-
- if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
- wpas_start_assoc_cb, cwork) < 0) {
- os_free(cwork);
- }
-}
-
-
-static int bss_is_ibss(struct wpa_bss *bss)
-{
- return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
- IEEE80211_CAP_IBSS;
-}
-
-
-static int drv_supports_vht(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid)
-{
- enum hostapd_hw_mode hw_mode;
- struct hostapd_hw_modes *mode = NULL;
- u8 channel;
- int i;
-
- hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
- if (hw_mode == NUM_HOSTAPD_MODES)
- return 0;
- for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode) {
- mode = &wpa_s->hw.modes[i];
- break;
- }
- }
-
- if (!mode)
- return 0;
-
- return mode->vht_capab != 0;
-}
-
-
-static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode)
-{
- int i;
-
- for (i = channel; i < channel + 16; i += 4) {
- struct hostapd_channel_data *chan;
-
- chan = hw_get_channel_chan(mode, i, NULL);
- if (!chan ||
- chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
- return false;
- }
-
- return true;
-}
-
-
-void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- struct hostapd_freq_params *freq)
-{
- int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
- enum hostapd_hw_mode hw_mode;
- struct hostapd_hw_modes *mode = NULL;
- int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
- 184, 192 };
- int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955,
- 6035, 6115, 6195, 6275, 6355, 6435, 6515,
- 6595, 6675, 6755, 6835, 6915, 6995 };
- int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
- struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
- u8 channel;
- int i, chan_idx, ht40 = -1, res, obss_scan = 1;
- unsigned int j, k;
- struct hostapd_freq_params vht_freq;
- int chwidth, seg0, seg1;
- u32 vht_caps = 0;
- bool is_24ghz, is_6ghz;
-
- freq->freq = ssid->frequency;
-
- for (j = 0; j < wpa_s->last_scan_res_used; j++) {
- struct wpa_bss *bss = wpa_s->last_scan_res[j];
-
- if (ssid->mode != WPAS_MODE_IBSS)
- break;
-
- /* Don't adjust control freq in case of fixed_freq */
- if (ssid->fixed_freq)
- break;
-
- if (!bss_is_ibss(bss))
- continue;
-
- if (ssid->ssid_len == bss->ssid_len &&
- os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
- wpa_printf(MSG_DEBUG,
- "IBSS already found in scan results, adjust control freq: %d",
- bss->freq);
- freq->freq = bss->freq;
- obss_scan = 0;
- break;
- }
- }
-
- /* For IBSS check HT_IBSS flag */
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
- return;
-
- if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
- wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
- wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
- wpa_printf(MSG_DEBUG,
- "IBSS: WEP/TKIP detected, do not try to enable HT");
- return;
- }
-
- hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
- for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode) {
- mode = &wpa_s->hw.modes[i];
- break;
- }
- }
-
- if (!mode)
- return;
-
- freq->channel = channel;
-
- is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
- hw_mode == HOSTAPD_MODE_IEEE80211B;
-
- /* HT/VHT and corresponding overrides are not applicable to 6 GHz.
- * However, HE is mandatory for 6 GHz.
- */
- is_6ghz = is_6ghz_freq(freq->freq);
- if (is_6ghz)
- goto skip_to_6ghz;
-
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht) {
- freq->ht_enabled = 0;
- return;
- }
-#endif /* CONFIG_HT_OVERRIDES */
-
- freq->ht_enabled = ht_supported(mode);
- if (!freq->ht_enabled)
- return;
-
- /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */
- if (is_24ghz)
- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
-#ifdef CONFIG_HE_OVERRIDES
- if (is_24ghz && ssid->disable_he)
- freq->he_enabled = 0;
-#endif /* CONFIG_HE_OVERRIDES */
-
- /* Setup higher BW only for 5 GHz */
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
- return;
-
- for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
- pri_chan = &mode->channels[chan_idx];
- if (pri_chan->chan == channel)
- break;
- pri_chan = NULL;
- }
- if (!pri_chan)
- return;
-
- /* Check primary channel flags */
- if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
- return;
-
- freq->channel = pri_chan->chan;
-
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht40) {
-#ifdef CONFIG_VHT_OVERRIDES
- if (ssid->disable_vht)
- return;
-#endif /* CONFIG_VHT_OVERRIDES */
- goto skip_ht40;
- }
-#endif /* CONFIG_HT_OVERRIDES */
-
- /* Check/setup HT40+/HT40- */
- for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
- if (ht40plus[j] == channel) {
- ht40 = 1;
- break;
- }
- }
-
- /* Find secondary channel */
- for (i = 0; i < mode->num_channels; i++) {
- sec_chan = &mode->channels[i];
- if (sec_chan->chan == channel + ht40 * 4)
- break;
- sec_chan = NULL;
- }
- if (!sec_chan)
- return;
-
- /* Check secondary channel flags */
- if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
- return;
-
- if (ht40 == -1) {
- if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
- return;
- } else {
- if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
- return;
- }
- freq->sec_channel_offset = ht40;
-
- if (obss_scan) {
- struct wpa_scan_results *scan_res;
-
- scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
- if (scan_res == NULL) {
- /* Back to HT20 */
- freq->sec_channel_offset = 0;
- return;
- }
-
- res = check_40mhz_5g(scan_res, pri_chan, sec_chan);
- switch (res) {
- case 0:
- /* Back to HT20 */
- freq->sec_channel_offset = 0;
- break;
- case 1:
- /* Configuration allowed */
- break;
- case 2:
- /* Switch pri/sec channels */
- freq->freq = hw_get_freq(mode, sec_chan->chan);
- freq->sec_channel_offset = -freq->sec_channel_offset;
- freq->channel = sec_chan->chan;
- break;
- default:
- freq->sec_channel_offset = 0;
- break;
- }
-
- wpa_scan_results_free(scan_res);
- }
-
-#ifdef CONFIG_HT_OVERRIDES
-skip_ht40:
-#endif /* CONFIG_HT_OVERRIDES */
- wpa_printf(MSG_DEBUG,
- "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
- freq->channel, freq->sec_channel_offset);
-
- if (!drv_supports_vht(wpa_s, ssid))
- return;
-
- /* For IBSS check VHT_IBSS flag */
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
- return;
-
-#ifdef CONFIG_VHT_OVERRIDES
- if (ssid->disable_vht) {
- freq->vht_enabled = 0;
- return;
- }
-#endif /* CONFIG_VHT_OVERRIDES */
-
-skip_to_6ghz:
- vht_freq = *freq;
-
- /* 6 GHz does not have VHT enabled, so allow that exception here. */
- vht_freq.vht_enabled = vht_supported(mode);
- if (!vht_freq.vht_enabled && !is_6ghz)
- return;
-
- /* Enable HE with VHT for 5 GHz */
- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
-
- /* setup center_freq1, bandwidth */
- for (j = 0; j < ARRAY_SIZE(bw80); j++) {
- if (freq->freq >= bw80[j] &&
- freq->freq < bw80[j] + 80)
- break;
- }
-
- if (j == ARRAY_SIZE(bw80) ||
- ieee80211_freq_to_chan(bw80[j], &channel) == NUM_HOSTAPD_MODES)
- return;
-
- /* Back to HT configuration if channel not usable */
- if (!ibss_mesh_is_80mhz_avail(channel, mode))
- return;
-
- chwidth = CHANWIDTH_80MHZ;
- seg0 = channel + 6;
- seg1 = 0;
-
- if ((mode->he_capab[ieee80211_mode].phy_cap[
- HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
- /* In 160 MHz, the initial four 20 MHz channels were validated
- * above; check the remaining four 20 MHz channels for the total
- * of 160 MHz bandwidth.
- */
- if (!ibss_mesh_is_80mhz_avail(channel + 16, mode))
- return;
-
- for (j = 0; j < ARRAY_SIZE(bw160); j++) {
- if (freq->freq == bw160[j]) {
- chwidth = CHANWIDTH_160MHZ;
- seg0 = channel + 14;
- break;
- }
- }
- }
-
- if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) {
- /* setup center_freq2, bandwidth */
- for (k = 0; k < ARRAY_SIZE(bw80); k++) {
- /* Only accept 80 MHz segments separated by a gap */
- if (j == k || abs(bw80[j] - bw80[k]) == 80)
- continue;
-
- if (ieee80211_freq_to_chan(bw80[k], &channel) ==
- NUM_HOSTAPD_MODES)
- return;
-
- for (i = channel; i < channel + 16; i += 4) {
- struct hostapd_channel_data *chan;
-
- chan = hw_get_channel_chan(mode, i, NULL);
- if (!chan)
- continue;
-
- if (chan->flag & (HOSTAPD_CHAN_DISABLED |
- HOSTAPD_CHAN_NO_IR |
- HOSTAPD_CHAN_RADAR))
- continue;
-
- /* Found a suitable second segment for 80+80 */
- chwidth = CHANWIDTH_80P80MHZ;
- if (!is_6ghz)
- vht_caps |=
- VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
- seg1 = channel + 6;
- }
-
- if (chwidth == CHANWIDTH_80P80MHZ)
- break;
- }
- } else if (ssid->max_oper_chwidth == CHANWIDTH_160MHZ) {
- if (freq->freq == 5180) {
- chwidth = CHANWIDTH_160MHZ;
- vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- seg0 = 50;
- } else if (freq->freq == 5520) {
- chwidth = CHANWIDTH_160MHZ;
- vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- seg0 = 114;
- }
- } else if (ssid->max_oper_chwidth == CHANWIDTH_USE_HT) {
- chwidth = CHANWIDTH_USE_HT;
- seg0 = channel + 2;
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht40)
- seg0 = 0;
-#endif /* CONFIG_HT_OVERRIDES */
- }
-
-#ifdef CONFIG_HE_OVERRIDES
- if (ssid->disable_he) {
- vht_freq.he_enabled = 0;
- freq->he_enabled = 0;
- }
-#endif /* CONFIG_HE_OVERRIDES */
- if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
- freq->channel, ssid->enable_edmg,
- ssid->edmg_channel, freq->ht_enabled,
- vht_freq.vht_enabled, freq->he_enabled,
- freq->sec_channel_offset,
- chwidth, seg0, seg1, vht_caps,
- &mode->he_capab[ieee80211_mode]) != 0)
- return;
-
- *freq = vht_freq;
-
- wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
- freq->center_freq1, freq->center_freq2, freq->bandwidth);
-}
-
-
-#ifdef CONFIG_FILS
-static size_t wpas_add_fils_hlp_req(struct wpa_supplicant *wpa_s, u8 *ie_buf,
- size_t ie_buf_len)
-{
- struct fils_hlp_req *req;
- size_t rem_len, hdr_len, hlp_len, len, ie_len = 0;
- const u8 *pos;
- u8 *buf = ie_buf;
-
- dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
- list) {
- rem_len = ie_buf_len - ie_len;
- pos = wpabuf_head(req->pkt);
- hdr_len = 1 + 2 * ETH_ALEN + 6;
- hlp_len = wpabuf_len(req->pkt);
-
- if (rem_len < 2 + hdr_len + hlp_len) {
- wpa_printf(MSG_ERROR,
- "FILS: Cannot fit HLP - rem_len=%lu to_fill=%lu",
- (unsigned long) rem_len,
- (unsigned long) (2 + hdr_len + hlp_len));
- break;
- }
-
- len = (hdr_len + hlp_len) > 255 ? 255 : hdr_len + hlp_len;
- /* Element ID */
- *buf++ = WLAN_EID_EXTENSION;
- /* Length */
- *buf++ = len;
- /* Element ID Extension */
- *buf++ = WLAN_EID_EXT_FILS_HLP_CONTAINER;
- /* Destination MAC address */
- os_memcpy(buf, req->dst, ETH_ALEN);
- buf += ETH_ALEN;
- /* Source MAC address */
- os_memcpy(buf, wpa_s->own_addr, ETH_ALEN);
- buf += ETH_ALEN;
- /* LLC/SNAP Header */
- os_memcpy(buf, "\xaa\xaa\x03\x00\x00\x00", 6);
- buf += 6;
- /* HLP Packet */
- os_memcpy(buf, pos, len - hdr_len);
- buf += len - hdr_len;
- pos += len - hdr_len;
-
- hlp_len -= len - hdr_len;
- ie_len += 2 + len;
- rem_len -= 2 + len;
-
- while (hlp_len) {
- len = (hlp_len > 255) ? 255 : hlp_len;
- if (rem_len < 2 + len)
- break;
- *buf++ = WLAN_EID_FRAGMENT;
- *buf++ = len;
- os_memcpy(buf, pos, len);
- buf += len;
- pos += len;
-
- hlp_len -= len;
- ie_len += 2 + len;
- rem_len -= 2 + len;
- }
- }
-
- return ie_len;
-}
-
-
-int wpa_is_fils_supported(struct wpa_supplicant *wpa_s)
-{
- return (((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS)) ||
- (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)));
-}
-
-
-int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_FILS_SK_PFS
- return (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_FILS);
-#else /* CONFIG_FILS_SK_PFS */
- return 0;
-#endif /* CONFIG_FILS_SK_PFS */
-}
-
-#endif /* CONFIG_FILS */
-
-
-static int wpas_populate_wfa_capa(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- u8 *wpa_ie, size_t wpa_ie_len,
- size_t max_wpa_ie_len)
-{
- struct wpabuf *wfa_ie = NULL;
- u8 wfa_capa[1];
- size_t wfa_ie_len, buf_len;
-
- os_memset(wfa_capa, 0, sizeof(wfa_capa));
- if (wpa_s->enable_dscp_policy_capa)
- wfa_capa[0] |= WFA_CAPA_QM_DSCP_POLICY;
-
- if (!wfa_capa[0])
- return wpa_ie_len;
-
- /* Wi-Fi Alliance element */
- buf_len = 1 + /* Element ID */
- 1 + /* Length */
- 3 + /* OUI */
- 1 + /* OUI Type */
- 1 + /* Capabilities Length */
- sizeof(wfa_capa); /* Capabilities */
- wfa_ie = wpabuf_alloc(buf_len);
- if (!wfa_ie)
- return wpa_ie_len;
-
- wpabuf_put_u8(wfa_ie, WLAN_EID_VENDOR_SPECIFIC);
- wpabuf_put_u8(wfa_ie, buf_len - 2);
- wpabuf_put_be24(wfa_ie, OUI_WFA);
- wpabuf_put_u8(wfa_ie, WFA_CAPA_OUI_TYPE);
- wpabuf_put_u8(wfa_ie, sizeof(wfa_capa));
- wpabuf_put_data(wfa_ie, wfa_capa, sizeof(wfa_capa));
-
- wfa_ie_len = wpabuf_len(wfa_ie);
- if (wpa_ie_len + wfa_ie_len <= max_wpa_ie_len) {
- wpa_hexdump_buf(MSG_MSGDUMP, "WFA Capabilities element",
- wfa_ie);
- os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(wfa_ie),
- wfa_ie_len);
- wpa_ie_len += wfa_ie_len;
- }
-
- wpabuf_free(wfa_ie);
- return wpa_ie_len;
-}
-
-
-static u8 * wpas_populate_assoc_ies(
- struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params,
- enum wpa_drv_update_connect_params_mask *mask)
-{
- u8 *wpa_ie;
- size_t max_wpa_ie_len = 500;
- size_t wpa_ie_len;
- int algs = WPA_AUTH_ALG_OPEN;
-#ifdef CONFIG_MBO
- const u8 *mbo_ie;
-#endif
-#if defined(CONFIG_SAE) || defined(CONFIG_FILS)
- int pmksa_cached = 0;
-#endif /* CONFIG_SAE || CONFIG_FILS */
-#ifdef CONFIG_FILS
- const u8 *realm, *username, *rrk;
- size_t realm_len, username_len, rrk_len;
- u16 next_seq_num;
- struct fils_hlp_req *req;
-
- dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
- list) {
- max_wpa_ie_len += 3 + 2 * ETH_ALEN + 6 + wpabuf_len(req->pkt) +
- 2 + 2 * wpabuf_len(req->pkt) / 255;
- }
-#endif /* CONFIG_FILS */
-
- wpa_ie = os_malloc(max_wpa_ie_len);
- if (!wpa_ie) {
- wpa_printf(MSG_ERROR,
- "Failed to allocate connect IE buffer for %lu bytes",
- (unsigned long) max_wpa_ie_len);
- return NULL;
- }
-
- if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
- wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
- wpa_key_mgmt_wpa(ssid->key_mgmt)) {
- int try_opportunistic;
- const u8 *cache_id = NULL;
-
- try_opportunistic = (ssid->proactive_key_caching < 0 ?
- wpa_s->conf->okc :
- ssid->proactive_key_caching) &&
- (ssid->proto & WPA_PROTO_RSN);
-#ifdef CONFIG_FILS
- if (wpa_key_mgmt_fils(ssid->key_mgmt))
- cache_id = wpa_bss_get_fils_cache_id(bss);
-#endif /* CONFIG_FILS */
- if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
- ssid, try_opportunistic,
- cache_id, 0) == 0) {
- eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
-#if defined(CONFIG_SAE) || defined(CONFIG_FILS)
- pmksa_cached = 1;
-#endif /* CONFIG_SAE || CONFIG_FILS */
- }
- wpa_ie_len = max_wpa_ie_len;
- if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
- wpa_ie, &wpa_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
- "key management and encryption suites");
- os_free(wpa_ie);
- return NULL;
- }
-#ifdef CONFIG_HS20
- } else if (bss && wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE) &&
- (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)) {
- /* No PMKSA caching, but otherwise similar to RSN/WPA */
- wpa_ie_len = max_wpa_ie_len;
- if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
- wpa_ie, &wpa_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
- "key management and encryption suites");
- os_free(wpa_ie);
- return NULL;
- }
-#endif /* CONFIG_HS20 */
- } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
- wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
- /*
- * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
- * use non-WPA since the scan results did not indicate that the
- * AP is using WPA or WPA2.
- */
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- wpa_ie_len = 0;
- wpa_s->wpa_proto = 0;
- } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
- wpa_ie_len = max_wpa_ie_len;
- if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
- wpa_ie, &wpa_ie_len)) {
- wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
- "key management and encryption suites (no "
- "scan results)");
- os_free(wpa_ie);
- return NULL;
- }
-#ifdef CONFIG_WPS
- } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- struct wpabuf *wps_ie;
- wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
- if (wps_ie && wpabuf_len(wps_ie) <= max_wpa_ie_len) {
- wpa_ie_len = wpabuf_len(wps_ie);
- os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
- } else
- wpa_ie_len = 0;
- wpabuf_free(wps_ie);
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
- params->wps = WPS_MODE_PRIVACY;
- else
- params->wps = WPS_MODE_OPEN;
- wpa_s->wpa_proto = 0;
-#endif /* CONFIG_WPS */
- } else {
- wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
- wpa_ie_len = 0;
- wpa_s->wpa_proto = 0;
- }
-
-#ifdef IEEE8021X_EAPOL
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- if (ssid->leap) {
- if (ssid->non_leap == 0)
- algs = WPA_AUTH_ALG_LEAP;
- else
- algs |= WPA_AUTH_ALG_LEAP;
- }
- }
-
-#ifdef CONFIG_FILS
- /* Clear FILS association */
- wpa_sm_set_reset_fils_completed(wpa_s->wpa, 0);
-
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD) &&
- ssid->eap.erp && wpa_key_mgmt_fils(wpa_s->key_mgmt) &&
- eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap, &username,
- &username_len, &realm, &realm_len,
- &next_seq_num, &rrk, &rrk_len) == 0 &&
- (!wpa_s->last_con_fail_realm ||
- wpa_s->last_con_fail_realm_len != realm_len ||
- os_memcmp(wpa_s->last_con_fail_realm, realm, realm_len) != 0)) {
- algs = WPA_AUTH_ALG_FILS;
- params->fils_erp_username = username;
- params->fils_erp_username_len = username_len;
- params->fils_erp_realm = realm;
- params->fils_erp_realm_len = realm_len;
- params->fils_erp_next_seq_num = next_seq_num;
- params->fils_erp_rrk = rrk;
- params->fils_erp_rrk_len = rrk_len;
-
- if (mask)
- *mask |= WPA_DRV_UPDATE_FILS_ERP_INFO;
- } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD) &&
- ssid->eap.erp && wpa_key_mgmt_fils(wpa_s->key_mgmt) &&
- pmksa_cached) {
- algs = WPA_AUTH_ALG_FILS;
- }
-#endif /* CONFIG_FILS */
-#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_SAE
- if (wpa_s->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE))
- algs = WPA_AUTH_ALG_SAE;
-#endif /* CONFIG_SAE */
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
- if (ssid->auth_alg) {
- algs = ssid->auth_alg;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Overriding auth_alg selection: 0x%x", algs);
- }
-
-#ifdef CONFIG_SAE
- if (pmksa_cached && algs == WPA_AUTH_ALG_SAE) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SAE: Use WPA_AUTH_ALG_OPEN for PMKSA caching attempt");
- algs = WPA_AUTH_ALG_OPEN;
- }
-#endif /* CONFIG_SAE */
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p) {
- u8 *pos;
- size_t len;
- int res;
- pos = wpa_ie + wpa_ie_len;
- len = max_wpa_ie_len - wpa_ie_len;
- res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
- ssid->p2p_group);
- if (res >= 0)
- wpa_ie_len += res;
- }
-
- wpa_s->cross_connect_disallowed = 0;
- if (bss) {
- struct wpabuf *p2p;
- p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
- if (p2p) {
- wpa_s->cross_connect_disallowed =
- p2p_get_cross_connect_disallowed(p2p);
- wpabuf_free(p2p);
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
- "connection",
- wpa_s->cross_connect_disallowed ?
- "disallows" : "allows");
- }
- }
-
- os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
-#endif /* CONFIG_P2P */
-
- if (bss) {
- wpa_ie_len += wpas_supp_op_class_ie(wpa_s, ssid, bss,
- wpa_ie + wpa_ie_len,
- max_wpa_ie_len -
- wpa_ie_len);
- }
-
- /*
- * Workaround: Add Extended Capabilities element only if the AP
- * included this element in Beacon/Probe Response frames. Some older
- * APs seem to have interoperability issues if this element is
- * included, so while the standard may require us to include the
- * element in all cases, it is justifiable to skip it to avoid
- * interoperability issues.
- */
- if (ssid->p2p_group)
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
- else
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
-
- if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
- u8 ext_capab[18];
- int ext_capab_len;
- ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
- if (ext_capab_len > 0 &&
- wpa_ie_len + ext_capab_len <= max_wpa_ie_len) {
- u8 *pos = wpa_ie;
- if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
- pos += 2 + pos[1];
- os_memmove(pos + ext_capab_len, pos,
- wpa_ie_len - (pos - wpa_ie));
- wpa_ie_len += ext_capab_len;
- os_memcpy(pos, ext_capab, ext_capab_len);
- }
- }
-
-#ifdef CONFIG_HS20
- if (is_hs20_network(wpa_s, ssid, bss)) {
- struct wpabuf *hs20;
-
- hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
- if (hs20) {
- int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
- size_t len;
-
- wpas_hs20_add_indication(hs20, pps_mo_id,
- get_hs20_version(bss));
- wpas_hs20_add_roam_cons_sel(hs20, ssid);
- len = max_wpa_ie_len - wpa_ie_len;
- if (wpabuf_len(hs20) <= len) {
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(hs20), wpabuf_len(hs20));
- wpa_ie_len += wpabuf_len(hs20);
- }
- wpabuf_free(hs20);
-
- hs20_configure_frame_filters(wpa_s);
- }
- }
-#endif /* CONFIG_HS20 */
-
- if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
- struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
- size_t len;
-
- len = max_wpa_ie_len - wpa_ie_len;
- if (wpabuf_len(buf) <= len) {
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(buf), wpabuf_len(buf));
- wpa_ie_len += wpabuf_len(buf);
- }
- }
-
-#ifdef CONFIG_FST
- if (wpa_s->fst_ies) {
- int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
-
- if (wpa_ie_len + fst_ies_len <= max_wpa_ie_len) {
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(wpa_s->fst_ies), fst_ies_len);
- wpa_ie_len += fst_ies_len;
- }
- }
-#endif /* CONFIG_FST */
-
-#ifdef CONFIG_MBO
- mbo_ie = bss ? wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE) : NULL;
- if (!wpa_s->disable_mbo_oce && mbo_ie) {
- int len;
-
- len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
- max_wpa_ie_len - wpa_ie_len,
- !!mbo_attr_from_mbo_ie(mbo_ie,
- OCE_ATTR_ID_CAPA_IND));
- if (len >= 0)
- wpa_ie_len += len;
- }
-#endif /* CONFIG_MBO */
-
-#ifdef CONFIG_FILS
- if (algs == WPA_AUTH_ALG_FILS) {
- size_t len;
-
- len = wpas_add_fils_hlp_req(wpa_s, wpa_ie + wpa_ie_len,
- max_wpa_ie_len - wpa_ie_len);
- wpa_ie_len += len;
- }
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_OWE
-#ifdef CONFIG_TESTING_OPTIONS
- if (get_ie_ext(wpa_ie, wpa_ie_len, WLAN_EID_EXT_OWE_DH_PARAM)) {
- wpa_printf(MSG_INFO, "TESTING: Override OWE DH element");
- } else
-#endif /* CONFIG_TESTING_OPTIONS */
- if (algs == WPA_AUTH_ALG_OPEN &&
- ssid->key_mgmt == WPA_KEY_MGMT_OWE) {
- struct wpabuf *owe_ie;
- u16 group;
-
- if (ssid->owe_group) {
- group = ssid->owe_group;
- } else if (wpa_s->assoc_status_code ==
- WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
- if (wpa_s->last_owe_group == 19)
- group = 20;
- else if (wpa_s->last_owe_group == 20)
- group = 21;
- else
- group = OWE_DH_GROUP;
- } else {
- group = OWE_DH_GROUP;
- }
-
- wpa_s->last_owe_group = group;
- wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group);
- owe_ie = owe_build_assoc_req(wpa_s->wpa, group);
- if (owe_ie &&
- wpabuf_len(owe_ie) <= max_wpa_ie_len - wpa_ie_len) {
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(owe_ie), wpabuf_len(owe_ie));
- wpa_ie_len += wpabuf_len(owe_ie);
- }
- wpabuf_free(owe_ie);
- }
-#endif /* CONFIG_OWE */
-
-#ifdef CONFIG_DPP2
- if (DPP_VERSION > 1 &&
- wpa_sm_get_key_mgmt(wpa_s->wpa) == WPA_KEY_MGMT_DPP &&
- ssid->dpp_netaccesskey &&
- ssid->dpp_pfs != 2 && !ssid->dpp_pfs_fallback) {
- struct rsn_pmksa_cache_entry *pmksa;
-
- pmksa = pmksa_cache_get_current(wpa_s->wpa);
- if (!pmksa || !pmksa->dpp_pfs)
- goto pfs_fail;
-
- dpp_pfs_free(wpa_s->dpp_pfs);
- wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
- ssid->dpp_netaccesskey_len);
- if (!wpa_s->dpp_pfs) {
- wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
- /* Try to continue without PFS */
- goto pfs_fail;
- }
- if (wpabuf_len(wpa_s->dpp_pfs->ie) <=
- max_wpa_ie_len - wpa_ie_len) {
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(wpa_s->dpp_pfs->ie),
- wpabuf_len(wpa_s->dpp_pfs->ie));
- wpa_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
- }
- }
-pfs_fail:
-#endif /* CONFIG_DPP2 */
-
-#ifdef CONFIG_IEEE80211R
- /*
- * Add MDIE under these conditions: the network profile allows FT,
- * the AP supports FT, and the mobility domain ID matches.
- */
- if (bss && wpa_key_mgmt_ft(wpa_sm_get_key_mgmt(wpa_s->wpa))) {
- const u8 *mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
-
- if (mdie && mdie[1] >= MOBILITY_DOMAIN_ID_LEN) {
- size_t len = 0;
- const u8 *md = mdie + 2;
- const u8 *wpa_md = wpa_sm_get_ft_md(wpa_s->wpa);
-
- if (os_memcmp(md, wpa_md,
- MOBILITY_DOMAIN_ID_LEN) == 0) {
- /* Add mobility domain IE */
- len = wpa_ft_add_mdie(
- wpa_s->wpa, wpa_ie + wpa_ie_len,
- max_wpa_ie_len - wpa_ie_len, mdie);
- wpa_ie_len += len;
- }
-#ifdef CONFIG_SME
- if (len > 0 && wpa_s->sme.ft_used &&
- wpa_sm_has_ptk(wpa_s->wpa)) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "SME: Trying to use FT over-the-air");
- algs |= WPA_AUTH_ALG_FT;
- }
-#endif /* CONFIG_SME */
- }
- }
-#endif /* CONFIG_IEEE80211R */
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->rsnxe_override_assoc &&
- wpabuf_len(wpa_s->rsnxe_override_assoc) <=
- max_wpa_ie_len - wpa_ie_len) {
- wpa_printf(MSG_DEBUG, "TESTING: RSNXE AssocReq override");
- os_memcpy(wpa_ie + wpa_ie_len,
- wpabuf_head(wpa_s->rsnxe_override_assoc),
- wpabuf_len(wpa_s->rsnxe_override_assoc));
- wpa_ie_len += wpabuf_len(wpa_s->rsnxe_override_assoc);
- } else
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_s->rsnxe_len > 0 &&
- wpa_s->rsnxe_len <= max_wpa_ie_len - wpa_ie_len) {
- os_memcpy(wpa_ie + wpa_ie_len, wpa_s->rsnxe, wpa_s->rsnxe_len);
- wpa_ie_len += wpa_s->rsnxe_len;
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->disable_mscs_support)
- goto mscs_end;
-#endif /* CONFIG_TESTING_OPTIONS */
- if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_MSCS) &&
- wpa_s->robust_av.valid_config) {
- struct wpabuf *mscs_ie;
- size_t mscs_ie_len, buf_len;
-
- buf_len = 3 + /* MSCS descriptor IE header */
- 1 + /* Request type */
- 2 + /* User priority control */
- 4 + /* Stream timeout */
- 3 + /* TCLAS Mask IE header */
- wpa_s->robust_av.frame_classifier_len;
- mscs_ie = wpabuf_alloc(buf_len);
- if (!mscs_ie) {
- wpa_printf(MSG_INFO,
- "MSCS: Failed to allocate MSCS IE");
- goto mscs_end;
- }
-
- wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, mscs_ie);
- if ((wpa_ie_len + wpabuf_len(mscs_ie)) <= max_wpa_ie_len) {
- wpa_hexdump_buf(MSG_MSGDUMP, "MSCS IE", mscs_ie);
- mscs_ie_len = wpabuf_len(mscs_ie);
- os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(mscs_ie),
- mscs_ie_len);
- wpa_ie_len += mscs_ie_len;
- }
-
- wpabuf_free(mscs_ie);
- }
-mscs_end:
-
- wpa_ie_len = wpas_populate_wfa_capa(wpa_s, bss, wpa_ie, wpa_ie_len,
- max_wpa_ie_len);
-
- if (ssid->multi_ap_backhaul_sta) {
- size_t multi_ap_ie_len;
-
- multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
- max_wpa_ie_len - wpa_ie_len,
- MULTI_AP_BACKHAUL_STA);
- if (multi_ap_ie_len == 0) {
- wpa_printf(MSG_ERROR,
- "Multi-AP: Failed to build Multi-AP IE");
- os_free(wpa_ie);
- return NULL;
- }
- wpa_ie_len += multi_ap_ie_len;
- }
-
- params->wpa_ie = wpa_ie;
- params->wpa_ie_len = wpa_ie_len;
- params->auth_alg = algs;
- if (mask)
- *mask |= WPA_DRV_UPDATE_ASSOC_IES | WPA_DRV_UPDATE_AUTH_TYPE;
-
- return wpa_ie;
-}
-
-
-#ifdef CONFIG_OWE
-static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_associate_params params;
- u8 *wpa_ie;
-
- os_memset(&params, 0, sizeof(params));
- wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, &params, NULL);
- if (!wpa_ie)
- return;
-
- wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
- os_free(wpa_ie);
-}
-#endif /* CONFIG_OWE */
-
-
-#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
-static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_associate_params params;
- enum wpa_drv_update_connect_params_mask mask = 0;
- u8 *wpa_ie;
-
- if (wpa_s->auth_alg != WPA_AUTH_ALG_OPEN)
- return; /* nothing to do */
-
- os_memset(&params, 0, sizeof(params));
- wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, &params, &mask);
- if (!wpa_ie)
- return;
-
- if (params.auth_alg == WPA_AUTH_ALG_FILS) {
- wpa_s->auth_alg = params.auth_alg;
- wpa_drv_update_connect_params(wpa_s, &params, mask);
- }
-
- os_free(wpa_ie);
-}
-#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
-
-
-static u8 wpa_ie_get_edmg_oper_chans(const u8 *edmg_ie)
-{
- if (!edmg_ie || edmg_ie[1] < 6)
- return 0;
- return edmg_ie[EDMG_BSS_OPERATING_CHANNELS_OFFSET];
-}
-
-
-static u8 wpa_ie_get_edmg_oper_chan_width(const u8 *edmg_ie)
-{
- if (!edmg_ie || edmg_ie[1] < 6)
- return 0;
- return edmg_ie[EDMG_OPERATING_CHANNEL_WIDTH_OFFSET];
-}
-
-
-/* Returns the intersection of two EDMG configurations.
- * Note: The current implementation is limited to CB2 only (CB1 included),
- * i.e., the implementation supports up to 2 contiguous channels.
- * For supporting non-contiguous (aggregated) channels and for supporting
- * CB3 and above, this function will need to be extended.
- */
-static struct ieee80211_edmg_config
-get_edmg_intersection(struct ieee80211_edmg_config a,
- struct ieee80211_edmg_config b,
- u8 primary_channel)
-{
- struct ieee80211_edmg_config result;
- int i, contiguous = 0;
- int max_contiguous = 0;
-
- result.channels = b.channels & a.channels;
- if (!result.channels) {
- wpa_printf(MSG_DEBUG,
- "EDMG not possible: cannot intersect channels 0x%x and 0x%x",
- a.channels, b.channels);
- goto fail;
- }
-
- if (!(result.channels & BIT(primary_channel - 1))) {
- wpa_printf(MSG_DEBUG,
- "EDMG not possible: the primary channel %d is not one of the intersected channels 0x%x",
- primary_channel, result.channels);
- goto fail;
- }
-
- /* Find max contiguous channels */
- for (i = 0; i < 6; i++) {
- if (result.channels & BIT(i))
- contiguous++;
- else
- contiguous = 0;
-
- if (contiguous > max_contiguous)
- max_contiguous = contiguous;
- }
-
- /* Assuming AP and STA supports ONLY contiguous channels,
- * bw configuration can have value between 4-7.
- */
- if ((b.bw_config < a.bw_config))
- result.bw_config = b.bw_config;
- else
- result.bw_config = a.bw_config;
-
- if ((max_contiguous >= 2 && result.bw_config < EDMG_BW_CONFIG_5) ||
- (max_contiguous >= 1 && result.bw_config < EDMG_BW_CONFIG_4)) {
- wpa_printf(MSG_DEBUG,
- "EDMG not possible: not enough contiguous channels %d for supporting CB1 or CB2",
- max_contiguous);
- goto fail;
- }
-
- return result;
-
-fail:
- result.channels = 0;
- result.bw_config = 0;
- return result;
-}
-
-
-static struct ieee80211_edmg_config
-get_supported_edmg(struct wpa_supplicant *wpa_s,
- struct hostapd_freq_params *freq,
- struct ieee80211_edmg_config request_edmg)
-{
- enum hostapd_hw_mode hw_mode;
- struct hostapd_hw_modes *mode = NULL;
- u8 primary_channel;
-
- if (!wpa_s->hw.modes)
- goto fail;
-
- hw_mode = ieee80211_freq_to_chan(freq->freq, &primary_channel);
- if (hw_mode == NUM_HOSTAPD_MODES)
- goto fail;
-
- mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, false);
- if (!mode)
- goto fail;
-
- return get_edmg_intersection(mode->edmg, request_edmg, primary_channel);
-
-fail:
- request_edmg.channels = 0;
- request_edmg.bw_config = 0;
- return request_edmg;
-}
-
-
-#ifdef CONFIG_MBO
-void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s)
-{
- struct wpa_driver_associate_params params;
- u8 *wpa_ie;
-
- /*
- * Update MBO connect params only in case of change of MBO attributes
- * when connected, if the AP support MBO.
- */
-
- if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid ||
- !wpa_s->current_bss ||
- !wpa_bss_get_vendor_ie(wpa_s->current_bss, MBO_IE_VENDOR_TYPE))
- return;
-
- os_memset(&params, 0, sizeof(params));
- wpa_ie = wpas_populate_assoc_ies(wpa_s, wpa_s->current_bss,
- wpa_s->current_ssid, &params, NULL);
- if (!wpa_ie)
- return;
-
- wpa_drv_update_connect_params(wpa_s, &params, WPA_DRV_UPDATE_ASSOC_IES);
- os_free(wpa_ie);
-}
-#endif /* CONFIG_MBO */
-
-
-static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_connect_work *cwork = work->ctx;
- struct wpa_bss *bss = cwork->bss;
- struct wpa_ssid *ssid = cwork->ssid;
- struct wpa_supplicant *wpa_s = work->wpa_s;
- u8 *wpa_ie;
- const u8 *edmg_ie_oper;
- int use_crypt, ret, bssid_changed;
- unsigned int cipher_pairwise, cipher_group, cipher_group_mgmt;
- struct wpa_driver_associate_params params;
-#if defined(CONFIG_WEP) || defined(IEEE8021X_EAPOL)
- int wep_keys_set = 0;
-#endif /* CONFIG_WEP || IEEE8021X_EAPOL */
- int assoc_failed = 0;
- struct wpa_ssid *old_ssid;
- u8 prev_bssid[ETH_ALEN];
-#ifdef CONFIG_HT_OVERRIDES
- struct ieee80211_ht_capabilities htcaps;
- struct ieee80211_ht_capabilities htcaps_mask;
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- struct ieee80211_vht_capabilities vhtcaps;
- struct ieee80211_vht_capabilities vhtcaps_mask;
-#endif /* CONFIG_VHT_OVERRIDES */
-
- if (deinit) {
- if (work->started) {
- wpa_s->connect_work = NULL;
-
- /* cancel possible auth. timeout */
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
- NULL);
- }
- wpas_connect_work_free(cwork);
- return;
- }
-
- wpa_s->connect_work = work;
-
- if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
- wpas_network_disabled(wpa_s, ssid)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
- wpas_connect_work_done(wpa_s);
- return;
- }
-
- os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
- os_memset(&params, 0, sizeof(params));
- wpa_s->reassociate = 0;
- wpa_s->eap_expected_failure = 0;
-
- /* Starting new association, so clear the possibly used WPA IE from the
- * previous association. */
- wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
- wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
- wpa_s->rsnxe_len = 0;
- wpa_s->mscs_setup_done = false;
-
- wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, &params, NULL);
- if (!wpa_ie) {
- wpas_connect_work_done(wpa_s);
- return;
- }
-
- if (bss &&
- (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
-#ifdef CONFIG_IEEE80211R
- const u8 *ie, *md = NULL;
-#endif /* CONFIG_IEEE80211R */
- wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
- " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
- bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
- os_memset(wpa_s->bssid, 0, ETH_ALEN);
- os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
- if (bssid_changed)
- wpas_notify_bssid_changed(wpa_s);
-#ifdef CONFIG_IEEE80211R
- ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
- if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
- md = ie + 2;
- wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
- if (md) {
- /* Prepare for the next transition */
- wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
- }
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_WPS
- } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
- wpa_s->conf->ap_scan == 2 &&
- (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
- /* Use ap_scan==1 style network selection to find the network
- */
- wpas_connect_work_done(wpa_s);
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- wpa_s->reassociate = 1;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- os_free(wpa_ie);
- return;
-#endif /* CONFIG_WPS */
- } else {
- wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- if (bss)
- os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
- else
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- }
- if (!wpa_s->pno)
- wpa_supplicant_cancel_sched_scan(wpa_s);
-
- wpa_supplicant_cancel_scan(wpa_s);
-
- wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
- use_crypt = 1;
- cipher_pairwise = wpa_s->pairwise_cipher;
- cipher_group = wpa_s->group_cipher;
- cipher_group_mgmt = wpa_s->mgmt_group_cipher;
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
- use_crypt = 0;
-#ifdef CONFIG_WEP
- if (wpa_set_wep_keys(wpa_s, ssid)) {
- use_crypt = 1;
- wep_keys_set = 1;
- }
-#endif /* CONFIG_WEP */
- }
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
- use_crypt = 0;
-
-#ifdef IEEE8021X_EAPOL
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- if ((ssid->eapol_flags &
- (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
- EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
- !wep_keys_set) {
- use_crypt = 0;
- } else {
- /* Assume that dynamic WEP-104 keys will be used and
- * set cipher suites in order for drivers to expect
- * encryption. */
- cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
- }
- }
-#endif /* IEEE8021X_EAPOL */
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
- /* Set the key before (and later after) association */
- wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
- }
-
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
- if (bss) {
- params.ssid = bss->ssid;
- params.ssid_len = bss->ssid_len;
- if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
- wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
- MACSTR " freq=%u MHz based on scan results "
- "(bssid_set=%d wps=%d)",
- MAC2STR(bss->bssid), bss->freq,
- ssid->bssid_set,
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
- params.bssid = bss->bssid;
- params.freq.freq = bss->freq;
- }
- params.bssid_hint = bss->bssid;
- params.freq_hint = bss->freq;
- params.pbss = bss_is_pbss(bss);
- } else {
- if (ssid->bssid_hint_set)
- params.bssid_hint = ssid->bssid_hint;
-
- params.ssid = ssid->ssid;
- params.ssid_len = ssid->ssid_len;
- params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
- }
-
- if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
- wpa_s->conf->ap_scan == 2) {
- params.bssid = ssid->bssid;
- params.fixed_bssid = 1;
- }
-
- /* Initial frequency for IBSS/mesh */
- if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
- ssid->frequency > 0 && params.freq.freq == 0)
- ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
-
- if (ssid->mode == WPAS_MODE_IBSS) {
- params.fixed_freq = ssid->fixed_freq;
- if (ssid->beacon_int)
- params.beacon_int = ssid->beacon_int;
- else
- params.beacon_int = wpa_s->conf->beacon_int;
- }
-
- if (bss && ssid->enable_edmg)
- edmg_ie_oper = wpa_bss_get_ie_ext(bss,
- WLAN_EID_EXT_EDMG_OPERATION);
- else
- edmg_ie_oper = NULL;
-
- if (edmg_ie_oper) {
- params.freq.edmg.channels =
- wpa_ie_get_edmg_oper_chans(edmg_ie_oper);
- params.freq.edmg.bw_config =
- wpa_ie_get_edmg_oper_chan_width(edmg_ie_oper);
- wpa_printf(MSG_DEBUG,
- "AP supports EDMG channels 0x%x, bw_config %d",
- params.freq.edmg.channels,
- params.freq.edmg.bw_config);
-
- /* User may ask for specific EDMG channel for EDMG connection
- * (must be supported by AP)
- */
- if (ssid->edmg_channel) {
- struct ieee80211_edmg_config configured_edmg;
- enum hostapd_hw_mode hw_mode;
- u8 primary_channel;
-
- hw_mode = ieee80211_freq_to_chan(bss->freq,
- &primary_channel);
- if (hw_mode == NUM_HOSTAPD_MODES)
- goto edmg_fail;
-
- hostapd_encode_edmg_chan(ssid->enable_edmg,
- ssid->edmg_channel,
- primary_channel,
- &configured_edmg);
-
- if (ieee802_edmg_is_allowed(params.freq.edmg,
- configured_edmg)) {
- params.freq.edmg = configured_edmg;
- wpa_printf(MSG_DEBUG,
- "Use EDMG channel %d for connection",
- ssid->edmg_channel);
- } else {
- edmg_fail:
- params.freq.edmg.channels = 0;
- params.freq.edmg.bw_config = 0;
- wpa_printf(MSG_WARNING,
- "EDMG channel %d not supported by AP, fallback to DMG",
- ssid->edmg_channel);
- }
- }
-
- if (params.freq.edmg.channels) {
- wpa_printf(MSG_DEBUG,
- "EDMG before: channels 0x%x, bw_config %d",
- params.freq.edmg.channels,
- params.freq.edmg.bw_config);
- params.freq.edmg = get_supported_edmg(wpa_s,
- &params.freq,
- params.freq.edmg);
- wpa_printf(MSG_DEBUG,
- "EDMG after: channels 0x%x, bw_config %d",
- params.freq.edmg.channels,
- params.freq.edmg.bw_config);
- }
- }
-
- params.pairwise_suite = cipher_pairwise;
- params.group_suite = cipher_group;
- params.mgmt_group_suite = cipher_group_mgmt;
- params.key_mgmt_suite = wpa_s->key_mgmt;
- params.wpa_proto = wpa_s->wpa_proto;
- wpa_s->auth_alg = params.auth_alg;
- params.mode = ssid->mode;
- params.bg_scan_period = ssid->bg_scan_period;
-#ifdef CONFIG_WEP
- {
- int i;
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i])
- params.wep_key[i] = ssid->wep_key[i];
- params.wep_key_len[i] = ssid->wep_key_len[i];
- }
- params.wep_tx_keyidx = ssid->wep_tx_keyidx;
- }
-#endif /* CONFIG_WEP */
-
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
- (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
- params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
- params.passphrase = ssid->passphrase;
- if (ssid->psk_set)
- params.psk = ssid->psk;
- }
-
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) &&
- (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192))
- params.req_handshake_offload = 1;
-
- if (wpa_s->conf->key_mgmt_offload) {
- if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
- params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
- params.req_key_mgmt_offload =
- ssid->proactive_key_caching < 0 ?
- wpa_s->conf->okc : ssid->proactive_key_caching;
- else
- params.req_key_mgmt_offload = 1;
-
- if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
- params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
- params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
- ssid->psk_set)
- params.psk = ssid->psk;
- }
-
- params.drop_unencrypted = use_crypt;
-
- params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
- if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
- const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- struct wpa_ie_data ie;
- if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
- ie.capabilities &
- (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
- "MFP: require MFP");
- params.mgmt_frame_protection =
- MGMT_FRAME_PROTECTION_REQUIRED;
-#ifdef CONFIG_OWE
- } else if (!rsn && (ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- !ssid->owe_only) {
- params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION;
-#endif /* CONFIG_OWE */
- }
- }
-
- params.p2p = ssid->p2p_group;
-
- if (wpa_s->p2pdev->set_sta_uapsd)
- params.uapsd = wpa_s->p2pdev->sta_uapsd;
- else
- params.uapsd = -1;
-
-#ifdef CONFIG_HT_OVERRIDES
- os_memset(&htcaps, 0, sizeof(htcaps));
- os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
- params.htcaps = (u8 *) &htcaps;
- params.htcaps_mask = (u8 *) &htcaps_mask;
- wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_HT_OVERRIDES */
-#ifdef CONFIG_VHT_OVERRIDES
- os_memset(&vhtcaps, 0, sizeof(vhtcaps));
- os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
- params.vhtcaps = &vhtcaps;
- params.vhtcaps_mask = &vhtcaps_mask;
- wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_VHT_OVERRIDES */
-#ifdef CONFIG_HE_OVERRIDES
- wpa_supplicant_apply_he_overrides(wpa_s, ssid, &params);
-#endif /* CONFIG_HE_OVERRIDES */
-
-#ifdef CONFIG_P2P
- /*
- * If multi-channel concurrency is not supported, check for any
- * frequency conflict. In case of any frequency conflict, remove the
- * least prioritized connection.
- */
- if (wpa_s->num_multichan_concurrent < 2) {
- int freq, num;
- num = get_shared_radio_freqs(wpa_s, &freq, 1);
- if (num > 0 && freq > 0 && freq != params.freq.freq) {
- wpa_printf(MSG_DEBUG,
- "Assoc conflicting freq found (%d != %d)",
- freq, params.freq.freq);
- if (wpas_p2p_handle_frequency_conflicts(
- wpa_s, params.freq.freq, ssid) < 0) {
- wpas_connect_work_done(wpa_s);
- os_free(wpa_ie);
- return;
- }
- }
- }
-#endif /* CONFIG_P2P */
-
- if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
- wpa_s->current_ssid)
- params.prev_bssid = prev_bssid;
-
-#ifdef CONFIG_SAE
- params.sae_pwe = wpa_s->conf->sae_pwe;
-#endif /* CONFIG_SAE */
-
- ret = wpa_drv_associate(wpa_s, &params);
- os_free(wpa_ie);
- if (ret < 0) {
- wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
- "failed");
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_VALID_ERROR_CODES) {
- /*
- * The driver is known to mean what is saying, so we
- * can stop right here; the association will not
- * succeed.
- */
- wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
- return;
- }
- /* try to continue anyway; new association will be tried again
- * after timeout */
- assoc_failed = 1;
- }
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
- /* Set the key after the association just in case association
- * cleared the previously configured key. */
- wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
- /* No need to timeout authentication since there is no key
- * management. */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-#ifdef CONFIG_IBSS_RSN
- } else if (ssid->mode == WPAS_MODE_IBSS &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
- /*
- * RSN IBSS authentication is per-STA and we can disable the
- * per-BSSID authentication.
- */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
-#endif /* CONFIG_IBSS_RSN */
- } else {
- /* Timeout for IEEE 802.11 authentication and association */
- int timeout = 60;
-
- if (assoc_failed) {
- /* give IBSS a bit more time */
- timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
- } else if (wpa_s->conf->ap_scan == 1) {
- /* give IBSS a bit more time */
- timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
- }
- wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
- }
-
-#ifdef CONFIG_WEP
- if (wep_keys_set &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
- /* Set static WEP keys again */
- wpa_set_wep_keys(wpa_s, ssid);
- }
-#endif /* CONFIG_WEP */
-
- if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
- /*
- * Do not allow EAP session resumption between different
- * network configurations.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
- old_ssid = wpa_s->current_ssid;
- wpa_s->current_ssid = ssid;
-
- if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
- wpa_s->current_bss = bss;
-#ifdef CONFIG_HS20
- hs20_configure_frame_filters(wpa_s);
-#endif /* CONFIG_HS20 */
- }
-
- wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
- wpa_supplicant_initiate_eapol(wpa_s);
- if (old_ssid != wpa_s->current_ssid)
- wpas_notify_network_changed(wpa_s);
-}
-
-
-static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
- const u8 *addr)
-{
- struct wpa_ssid *old_ssid;
-
- wpas_connect_work_done(wpa_s);
- wpa_clear_keys(wpa_s, addr);
- old_ssid = wpa_s->current_ssid;
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- if (old_ssid != wpa_s->current_ssid)
- wpas_notify_network_changed(wpa_s);
-
- wpas_scs_deinit(wpa_s);
- wpas_dscp_deinit(wpa_s);
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
-}
-
-
-/**
- * wpa_supplicant_deauthenticate - Deauthenticate the current connection
- * @wpa_s: Pointer to wpa_supplicant data
- * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
- *
- * This function is used to request %wpa_supplicant to deauthenticate from the
- * current AP.
- */
-void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
- u16 reason_code)
-{
- u8 *addr = NULL;
- union wpa_event_data event;
- int zero_addr = 0;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
- " pending_bssid=" MACSTR " reason=%d (%s) state=%s",
- MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
- reason_code, reason2str(reason_code),
- wpa_supplicant_state_txt(wpa_s->wpa_state));
-
- if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
- (wpa_s->wpa_state == WPA_AUTHENTICATING ||
- wpa_s->wpa_state == WPA_ASSOCIATING))
- addr = wpa_s->pending_bssid;
- else if (!is_zero_ether_addr(wpa_s->bssid))
- addr = wpa_s->bssid;
- else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
- /*
- * When using driver-based BSS selection, we may not know the
- * BSSID with which we are currently trying to associate. We
- * need to notify the driver of this disconnection even in such
- * a case, so use the all zeros address here.
- */
- addr = wpa_s->bssid;
- zero_addr = 1;
- }
-
- if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
- wpa_s->enabled_4addr_mode = 0;
-
-#ifdef CONFIG_TDLS
- wpa_tdls_teardown_peers(wpa_s->wpa);
-#endif /* CONFIG_TDLS */
-
-#ifdef CONFIG_MESH
- if (wpa_s->ifmsh) {
- struct mesh_conf *mconf;
-
- mconf = wpa_s->ifmsh->mconf;
- wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
- wpa_s->ifname);
- wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
- mconf->meshid_len, reason_code);
- wpa_supplicant_leave_mesh(wpa_s, true);
- }
-#endif /* CONFIG_MESH */
-
- if (addr) {
- wpa_drv_deauthenticate(wpa_s, addr, reason_code);
- os_memset(&event, 0, sizeof(event));
- event.deauth_info.reason_code = reason_code;
- event.deauth_info.locally_generated = 1;
- wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
- if (zero_addr)
- addr = NULL;
- }
-
- wpa_supplicant_clear_connection(wpa_s, addr);
-}
-
-
-void wpa_supplicant_reconnect(struct wpa_supplicant *wpa_s)
-{
- wpa_s->own_reconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
-
-}
-
-
-static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (!ssid || !ssid->disabled || ssid->disabled == 2)
- return;
-
- ssid->disabled = 0;
- ssid->owe_transition_bss_select_count = 0;
- wpas_clear_temp_disabled(wpa_s, ssid, 1);
- wpas_notify_network_enabled_changed(wpa_s, ssid);
-
- /*
- * Try to reassociate since there is no current configuration and a new
- * network was made available.
- */
- if (!wpa_s->current_ssid && !wpa_s->disconnected)
- wpa_s->reassociate = 1;
-}
-
-
-/**
- * wpa_supplicant_add_network - Add a new network
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: The new network configuration or %NULL if operation failed
- *
- * This function performs the following operations:
- * 1. Adds a new network.
- * 2. Send network addition notification.
- * 3. Marks the network disabled.
- * 4. Set network default parameters.
- */
-struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (!ssid)
- return NULL;
- wpas_notify_network_added(wpa_s, ssid);
- ssid->disabled = 1;
- wpa_config_set_network_defaults(ssid);
-
- return ssid;
-}
-
-
-/**
- * wpa_supplicant_remove_network - Remove a configured network based on id
- * @wpa_s: wpa_supplicant structure for a network interface
- * @id: Unique network id to search for
- * Returns: 0 on success, or -1 if the network was not found, -2 if the network
- * could not be removed
- *
- * This function performs the following operations:
- * 1. Removes the network.
- * 2. Send network removal notification.
- * 3. Update internal state machines.
- * 4. Stop any running sched scans.
- */
-int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
-{
- struct wpa_ssid *ssid;
- int was_disabled;
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (!ssid)
- return -1;
- wpas_notify_network_removed(wpa_s, ssid);
-
- if (wpa_s->last_ssid == ssid)
- wpa_s->last_ssid = NULL;
-
- if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- /*
- * Invalidate the EAP session cache if the current or
- * previously used network is removed.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
-
- if (ssid == wpa_s->current_ssid) {
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- }
-
- was_disabled = ssid->disabled;
-
- if (wpa_config_remove_network(wpa_s->conf, id) < 0)
- return -2;
-
- if (!was_disabled && wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG,
- "Stop ongoing sched_scan to remove network from filters");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_remove_all_networks - Remove all configured networks
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: 0 on success (errors are currently ignored)
- *
- * This function performs the following operations:
- * 1. Remove all networks.
- * 2. Send network removal notifications.
- * 3. Update internal state machines.
- * 4. Stop any running sched scans.
- */
-int wpa_supplicant_remove_all_networks(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
-
- if (wpa_s->sched_scanning)
- wpa_supplicant_cancel_sched_scan(wpa_s);
-
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- if (wpa_s->current_ssid) {
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- struct wpa_ssid *remove_ssid = ssid;
- int id;
-
- id = ssid->id;
- ssid = ssid->next;
- if (wpa_s->last_ssid == remove_ssid)
- wpa_s->last_ssid = NULL;
- wpas_notify_network_removed(wpa_s, remove_ssid);
- wpa_config_remove_network(wpa_s->conf, id);
- }
- return 0;
-}
-
-
-/**
- * wpa_supplicant_enable_network - Mark a configured network as enabled
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network or %NULL
- *
- * Enables the specified network or all networks if no network specified.
- */
-void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- if (ssid == NULL) {
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
- wpa_supplicant_enable_one_network(wpa_s, ssid);
- } else
- wpa_supplicant_enable_one_network(wpa_s, ssid);
-
- if (wpa_s->reassociate && !wpa_s->disconnected &&
- (!wpa_s->current_ssid ||
- wpa_s->wpa_state == WPA_DISCONNECTED ||
- wpa_s->wpa_state == WPA_SCANNING)) {
- if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
- "new network to scan filters");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
-
- if (wpa_supplicant_fast_associate(wpa_s) != 1) {
- wpa_s->scan_req = NORMAL_SCAN_REQ;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
- }
-}
-
-
-/**
- * wpa_supplicant_disable_network - Mark a configured network as disabled
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network or %NULL
- *
- * Disables the specified network or all networks if no network specified.
- */
-void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct wpa_ssid *other_ssid;
- int was_disabled;
-
- if (ssid == NULL) {
- if (wpa_s->sched_scanning)
- wpa_supplicant_cancel_sched_scan(wpa_s);
-
- for (other_ssid = wpa_s->conf->ssid; other_ssid;
- other_ssid = other_ssid->next) {
- was_disabled = other_ssid->disabled;
- if (was_disabled == 2)
- continue; /* do not change persistent P2P group
- * data */
-
- other_ssid->disabled = 1;
-
- if (was_disabled != other_ssid->disabled)
- wpas_notify_network_enabled_changed(
- wpa_s, other_ssid);
- }
- if (wpa_s->current_ssid) {
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
- } else if (ssid->disabled != 2) {
- if (ssid == wpa_s->current_ssid) {
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
-
- was_disabled = ssid->disabled;
-
- ssid->disabled = 1;
-
- if (was_disabled != ssid->disabled) {
- wpas_notify_network_enabled_changed(wpa_s, ssid);
- if (wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
- "to remove network from filters");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
- }
- }
-}
-
-
-/**
- * wpa_supplicant_select_network - Attempt association with a network
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ssid: wpa_ssid structure for a configured network or %NULL for any network
- */
-void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
-
- struct wpa_ssid *other_ssid;
- int disconnected = 0;
-
- if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- disconnected = 1;
- }
-
- if (ssid)
- wpas_clear_temp_disabled(wpa_s, ssid, 1);
-
- /*
- * Mark all other networks disabled or mark all networks enabled if no
- * network specified.
- */
- for (other_ssid = wpa_s->conf->ssid; other_ssid;
- other_ssid = other_ssid->next) {
- int was_disabled = other_ssid->disabled;
- if (was_disabled == 2)
- continue; /* do not change persistent P2P group data */
-
- other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
- if (was_disabled && !other_ssid->disabled)
- wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
-
- if (was_disabled != other_ssid->disabled)
- wpas_notify_network_enabled_changed(wpa_s, other_ssid);
- }
-
- if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
- wpa_s->wpa_state >= WPA_AUTHENTICATING) {
- /* We are already associated with the selected network */
- wpa_printf(MSG_DEBUG, "Already associated with the "
- "selected network - do nothing");
- return;
- }
-
- if (ssid) {
- wpa_s->current_ssid = ssid;
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- wpa_s->connect_without_scan =
- (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
-
- /*
- * Don't optimize next scan freqs since a new ESS has been
- * selected.
- */
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = NULL;
- } else {
- wpa_s->connect_without_scan = NULL;
- }
-
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- wpa_s_clear_sae_rejected(wpa_s);
- wpa_s->last_owe_group = 0;
- if (ssid) {
- ssid->owe_transition_bss_select_count = 0;
- wpa_s_setup_sae_pt(wpa_s->conf, ssid);
- }
-
- if (wpa_s->connect_without_scan ||
- wpa_supplicant_fast_associate(wpa_s) != 1) {
- wpa_s->scan_req = NORMAL_SCAN_REQ;
- wpas_scan_reset_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
- }
-
- if (ssid)
- wpas_notify_network_selected(wpa_s, ssid);
-}
-
-
-/**
- * wpas_remove_cred - Remove the specified credential and all the network
- * entries created based on the removed credential
- * @wpa_s: wpa_supplicant structure for a network interface
- * @cred: The credential to remove
- * Returns: 0 on success, -1 on failure
- */
-int wpas_remove_cred(struct wpa_supplicant *wpa_s, struct wpa_cred *cred)
-{
- struct wpa_ssid *ssid, *next;
- int id;
-
- if (!cred) {
- wpa_printf(MSG_DEBUG, "Could not find cred");
- return -1;
- }
-
- id = cred->id;
- if (wpa_config_remove_cred(wpa_s->conf, id) < 0) {
- wpa_printf(MSG_DEBUG, "Could not find cred %d", id);
- return -1;
- }
-
- wpa_msg(wpa_s, MSG_INFO, CRED_REMOVED "%d", id);
-
- /* Remove any network entry created based on the removed credential */
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- next = ssid->next;
-
- if (ssid->parent_cred == cred) {
- wpa_printf(MSG_DEBUG,
- "Remove network id %d since it used the removed credential",
- ssid->id);
- if (wpa_supplicant_remove_network(wpa_s, ssid->id) ==
- -1) {
- wpa_printf(MSG_DEBUG,
- "Could not find network id=%d",
- ssid->id);
- }
- }
-
- ssid = next;
- }
-
- return 0;
-}
-
-
-/**
- * wpas_remove_cred - Remove all the Interworking credentials
- * @wpa_s: wpa_supplicant structure for a network interface
- * Returns: 0 on success, -1 on failure
- */
-int wpas_remove_all_creds(struct wpa_supplicant *wpa_s)
-{
- int res, ret = 0;
- struct wpa_cred *cred, *prev;
-
- cred = wpa_s->conf->cred;
- while (cred) {
- prev = cred;
- cred = cred->next;
- res = wpas_remove_cred(wpa_s, prev);
- if (res < 0) {
- wpa_printf(MSG_DEBUG,
- "Removal of all credentials failed - failed to remove credential id=%d",
- prev->id);
- ret = -1;
- }
- }
-
- return ret;
-}
-
-
-/**
- * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
- * @wpa_s: wpa_supplicant structure for a network interface
- * @pkcs11_engine_path: PKCS #11 engine path or NULL
- * @pkcs11_module_path: PKCS #11 module path or NULL
- * Returns: 0 on success; -1 on failure
- *
- * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
- * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
- * module path fails the paths will be reset to the default value (NULL).
- */
-int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
- const char *pkcs11_engine_path,
- const char *pkcs11_module_path)
-{
- char *pkcs11_engine_path_copy = NULL;
- char *pkcs11_module_path_copy = NULL;
-
- if (pkcs11_engine_path != NULL) {
- pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
- if (pkcs11_engine_path_copy == NULL)
- return -1;
- }
- if (pkcs11_module_path != NULL) {
- pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
- if (pkcs11_module_path_copy == NULL) {
- os_free(pkcs11_engine_path_copy);
- return -1;
- }
- }
-
- os_free(wpa_s->conf->pkcs11_engine_path);
- os_free(wpa_s->conf->pkcs11_module_path);
- wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
- wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
-
- wpa_sm_set_eapol(wpa_s->wpa, NULL);
- eapol_sm_deinit(wpa_s->eapol);
- wpa_s->eapol = NULL;
- if (wpa_supplicant_init_eapol(wpa_s)) {
- /* Error -> Reset paths to the default value (NULL) once. */
- if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
- wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
- NULL);
-
- return -1;
- }
- wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
- * @wpa_s: wpa_supplicant structure for a network interface
- * @ap_scan: AP scan mode
- * Returns: 0 if succeed or -1 if ap_scan has an invalid value
- *
- */
-int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
-{
-
- int old_ap_scan;
-
- if (ap_scan < 0 || ap_scan > 2)
- return -1;
-
- if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
- wpa_printf(MSG_INFO,
- "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
- }
-
-#ifdef ANDROID
- if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
- wpa_s->wpa_state >= WPA_ASSOCIATING &&
- wpa_s->wpa_state < WPA_COMPLETED) {
- wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
- "associating", wpa_s->conf->ap_scan, ap_scan);
- return 0;
- }
-#endif /* ANDROID */
-
- old_ap_scan = wpa_s->conf->ap_scan;
- wpa_s->conf->ap_scan = ap_scan;
-
- if (old_ap_scan != wpa_s->conf->ap_scan)
- wpas_notify_ap_scan_changed(wpa_s);
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
- * @wpa_s: wpa_supplicant structure for a network interface
- * @expire_age: Expiration age in seconds
- * Returns: 0 if succeed or -1 if expire_age has an invalid value
- *
- */
-int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
- unsigned int bss_expire_age)
-{
- if (bss_expire_age < 10) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
- bss_expire_age);
- return -1;
- }
- wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
- bss_expire_age);
- wpa_s->conf->bss_expiration_age = bss_expire_age;
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
- * @wpa_s: wpa_supplicant structure for a network interface
- * @expire_count: number of scans after which an unseen BSS is reclaimed
- * Returns: 0 if succeed or -1 if expire_count has an invalid value
- *
- */
-int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
- unsigned int bss_expire_count)
-{
- if (bss_expire_count < 1) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
- bss_expire_count);
- return -1;
- }
- wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
- bss_expire_count);
- wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_set_scan_interval - Set scan interval
- * @wpa_s: wpa_supplicant structure for a network interface
- * @scan_interval: scan interval in seconds
- * Returns: 0 if succeed or -1 if scan_interval has an invalid value
- *
- */
-int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
- int scan_interval)
-{
- if (scan_interval < 0) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
- scan_interval);
- return -1;
- }
- wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
- scan_interval);
- wpa_supplicant_update_scan_int(wpa_s, scan_interval);
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_set_debug_params - Set global debug params
- * @global: wpa_global structure
- * @debug_level: debug level
- * @debug_timestamp: determines if show timestamp in debug data
- * @debug_show_keys: determines if show keys in debug data
- * Returns: 0 if succeed or -1 if debug_level has wrong value
- */
-int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
- int debug_timestamp, int debug_show_keys)
-{
-
- int old_level, old_timestamp, old_show_keys;
-
- /* check for allowed debuglevels */
- if (debug_level != MSG_EXCESSIVE &&
- debug_level != MSG_MSGDUMP &&
- debug_level != MSG_DEBUG &&
- debug_level != MSG_INFO &&
- debug_level != MSG_WARNING &&
- debug_level != MSG_ERROR)
- return -1;
-
- old_level = wpa_debug_level;
- old_timestamp = wpa_debug_timestamp;
- old_show_keys = wpa_debug_show_keys;
-
- wpa_debug_level = debug_level;
- wpa_debug_timestamp = debug_timestamp ? 1 : 0;
- wpa_debug_show_keys = debug_show_keys ? 1 : 0;
-
- if (wpa_debug_level != old_level)
- wpas_notify_debug_level_changed(global);
- if (wpa_debug_timestamp != old_timestamp)
- wpas_notify_debug_timestamp_changed(global);
- if (wpa_debug_show_keys != old_show_keys)
- wpas_notify_debug_show_keys_changed(global);
-
- return 0;
-}
-
-
-#ifdef CONFIG_OWE
-static int owe_trans_ssid_match(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *entry_ssid, size_t entry_ssid_len)
-{
- const u8 *owe, *pos, *end;
- u8 ssid_len;
- struct wpa_bss *bss;
-
- /* Check network profile SSID aganst the SSID in the
- * OWE Transition Mode element. */
-
- bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- if (!bss)
- return 0;
-
- owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (!owe)
- return 0;
-
- pos = owe + 6;
- end = owe + 2 + owe[1];
-
- if (end - pos < ETH_ALEN + 1)
- return 0;
- pos += ETH_ALEN;
- ssid_len = *pos++;
- if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN)
- return 0;
-
- return entry_ssid_len == ssid_len &&
- os_memcmp(pos, entry_ssid, ssid_len) == 0;
-}
-#endif /* CONFIG_OWE */
-
-
-/**
- * wpa_supplicant_get_ssid - Get a pointer to the current network structure
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: A pointer to the current network structure or %NULL on failure
- */
-struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *entry;
- u8 ssid[SSID_MAX_LEN];
- int res;
- size_t ssid_len;
- u8 bssid[ETH_ALEN];
- int wired;
-
- res = wpa_drv_get_ssid(wpa_s, ssid);
- if (res < 0) {
- wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
- "driver");
- return NULL;
- }
- ssid_len = res;
-
- if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
- wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
- "driver");
- return NULL;
- }
-
- wired = wpa_s->conf->ap_scan == 0 &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
-
- entry = wpa_s->conf->ssid;
- while (entry) {
- if (!wpas_network_disabled(wpa_s, entry) &&
- ((ssid_len == entry->ssid_len &&
- (!entry->ssid ||
- os_memcmp(ssid, entry->ssid, ssid_len) == 0)) ||
- wired) &&
- (!entry->bssid_set ||
- os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
- return entry;
-#ifdef CONFIG_WPS
- if (!wpas_network_disabled(wpa_s, entry) &&
- (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
- (entry->ssid == NULL || entry->ssid_len == 0) &&
- (!entry->bssid_set ||
- os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
- return entry;
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_OWE
- if (!wpas_network_disabled(wpa_s, entry) &&
- owe_trans_ssid_match(wpa_s, bssid, entry->ssid,
- entry->ssid_len) &&
- (!entry->bssid_set ||
- os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
- return entry;
-#endif /* CONFIG_OWE */
-
- if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
- entry->ssid_len == 0 &&
- os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
- return entry;
-
- entry = entry->next;
- }
-
- return NULL;
-}
-
-
-static int select_driver(struct wpa_supplicant *wpa_s, int i)
-{
- struct wpa_global *global = wpa_s->global;
-
- if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
- global->drv_priv[i] = wpa_drivers[i]->global_init(global);
- if (global->drv_priv[i] == NULL) {
- wpa_printf(MSG_ERROR, "Failed to initialize driver "
- "'%s'", wpa_drivers[i]->name);
- return -1;
- }
- }
-
- wpa_s->driver = wpa_drivers[i];
- wpa_s->global_drv_priv = global->drv_priv[i];
-
- return 0;
-}
-
-
-static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
- const char *name)
-{
- int i;
- size_t len;
- const char *pos, *driver = name;
-
- if (wpa_s == NULL)
- return -1;
-
- if (wpa_drivers[0] == NULL) {
- wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
- "wpa_supplicant");
- return -1;
- }
-
- if (name == NULL) {
- /* Default to first successful driver in the list */
- for (i = 0; wpa_drivers[i]; i++) {
- if (select_driver(wpa_s, i) == 0)
- return 0;
- }
- /* Drivers have each reported failure, so no wpa_msg() here. */
- return -1;
- }
-
- do {
- pos = os_strchr(driver, ',');
- if (pos)
- len = pos - driver;
- else
- len = os_strlen(driver);
-
- for (i = 0; wpa_drivers[i]; i++) {
- if (os_strlen(wpa_drivers[i]->name) == len &&
- os_strncmp(driver, wpa_drivers[i]->name, len) ==
- 0) {
- /* First driver that succeeds wins */
- if (select_driver(wpa_s, i) == 0)
- return 0;
- }
- }
-
- driver = pos + 1;
- } while (pos);
-
- wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
- return -1;
-}
-
-
-/**
- * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
- * @ctx: Context pointer (wpa_s); this is the ctx variable registered
- * with struct wpa_driver_ops::init()
- * @src_addr: Source address of the EAPOL frame
- * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
- * @len: Length of the EAPOL data
- *
- * This function is called for each received EAPOL frame. Most driver
- * interfaces rely on more generic OS mechanism for receiving frames through
- * l2_packet, but if such a mechanism is not available, the driver wrapper may
- * take care of received EAPOL frames and deliver them to the core supplicant
- * code by calling this function.
- */
-void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
- wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
-
- if (wpa_s->own_disconnect_req) {
- wpa_printf(MSG_DEBUG,
- "Drop received EAPOL frame as we are disconnecting");
- return;
- }
-
-#ifdef CONFIG_TESTING_OPTIONS
- wpa_msg_ctrl(wpa_s, MSG_INFO, "EAPOL-RX " MACSTR " %zu",
- MAC2STR(src_addr), len);
- if (wpa_s->ignore_auth_resp) {
- wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
- return;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->wpa_state < WPA_ASSOCIATED ||
- (wpa_s->last_eapol_matches_bssid &&
-#ifdef CONFIG_AP
- !wpa_s->ap_iface &&
-#endif /* CONFIG_AP */
- os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
- /*
- * There is possible race condition between receiving the
- * association event and the EAPOL frame since they are coming
- * through different paths from the driver. In order to avoid
- * issues in trying to process the EAPOL frame before receiving
- * association information, lets queue it for processing until
- * the association event is received. This may also be needed in
- * driver-based roaming case, so also use src_addr != BSSID as a
- * trigger if we have previously confirmed that the
- * Authenticator uses BSSID as the src_addr (which is not the
- * case with wired IEEE 802.1X).
- */
- wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
- "of received EAPOL frame (state=%s bssid=" MACSTR ")",
- wpa_supplicant_state_txt(wpa_s->wpa_state),
- MAC2STR(wpa_s->bssid));
- wpabuf_free(wpa_s->pending_eapol_rx);
- wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
- if (wpa_s->pending_eapol_rx) {
- os_get_reltime(&wpa_s->pending_eapol_rx_time);
- os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
- ETH_ALEN);
- }
- return;
- }
-
- wpa_s->last_eapol_matches_bssid =
- os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
- return;
- }
-#endif /* CONFIG_AP */
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
- "no key management is configured");
- return;
- }
-
- if (wpa_s->eapol_received == 0 &&
- (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) ||
- !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_s->wpa_state != WPA_COMPLETED) &&
- (wpa_s->current_ssid == NULL ||
- wpa_s->current_ssid->mode != WPAS_MODE_IBSS)) {
- /* Timeout for completing IEEE 802.1X and WPA authentication */
- int timeout = 10;
-
- if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
- /* Use longer timeout for IEEE 802.1X/EAP */
- timeout = 70;
- }
-
-#ifdef CONFIG_WPS
- if (wpa_s->current_ssid && wpa_s->current_bss &&
- (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
- eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
- /*
- * Use shorter timeout if going through WPS AP iteration
- * for PIN config method with an AP that does not
- * advertise Selected Registrar.
- */
- struct wpabuf *wps_ie;
-
- wps_ie = wpa_bss_get_vendor_ie_multi(
- wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
- if (wps_ie &&
- !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
- timeout = 10;
- wpabuf_free(wps_ie);
- }
-#endif /* CONFIG_WPS */
-
- wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
- }
- wpa_s->eapol_received++;
-
- if (wpa_s->countermeasures) {
- wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
- "EAPOL packet");
- return;
- }
-
-#ifdef CONFIG_IBSS_RSN
- if (wpa_s->current_ssid &&
- wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
- ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
- return;
- }
-#endif /* CONFIG_IBSS_RSN */
-
- /* Source address of the incoming EAPOL frame could be compared to the
- * current BSSID. However, it is possible that a centralized
- * Authenticator could be using another MAC address than the BSSID of
- * an AP, so just allow any address to be used for now. The replies are
- * still sent to the current BSSID (if available), though. */
-
- os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
- if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_OWE &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_DPP &&
- eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
- return;
- wpa_drv_poll(wpa_s);
- if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK))
- wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
- else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
- /*
- * Set portValid = true here since we are going to skip 4-way
- * handshake processing which would normally set portValid. We
- * need this to allow the EAPOL state machines to be completed
- * without going through EAPOL-Key handshake.
- */
- eapol_sm_notify_portValid(wpa_s->eapol, true);
- }
-}
-
-
-static int wpas_eapol_needs_l2_packet(struct wpa_supplicant *wpa_s)
-{
- return !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT) ||
- !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX);
-}
-
-
-int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
-{
- if ((!wpa_s->p2p_mgmt ||
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
- l2_packet_deinit(wpa_s->l2);
- wpa_s->l2 = l2_packet_init(wpa_s->ifname,
- wpa_drv_get_mac_addr(wpa_s),
- ETH_P_EAPOL,
- wpas_eapol_needs_l2_packet(wpa_s) ?
- wpa_supplicant_rx_eapol : NULL,
- wpa_s, 0);
- if (wpa_s->l2 == NULL)
- return -1;
-
- if (l2_packet_set_packet_filter(wpa_s->l2,
- L2_PACKET_FILTER_PKTTYPE))
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Failed to attach pkt_type filter");
-
- if (l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Failed to get own L2 address");
- return -1;
- }
- } else {
- const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
- if (addr)
- os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
- }
-
- wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
- wpas_wps_update_mac_addr(wpa_s);
-
-#ifdef CONFIG_FST
- if (wpa_s->fst)
- fst_update_mac_addr(wpa_s->fst, wpa_s->own_addr);
-#endif /* CONFIG_FST */
-
- return 0;
-}
-
-
-static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const struct l2_ethhdr *eth;
-
- if (len < sizeof(*eth))
- return;
- eth = (const struct l2_ethhdr *) buf;
-
- if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
- !(eth->h_dest[0] & 0x01)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
- " (bridge - not for this interface - ignore)",
- MAC2STR(src_addr), MAC2STR(eth->h_dest));
- return;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
- " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
- wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
- len - sizeof(*eth));
-}
-
-
-int wpa_supplicant_update_bridge_ifname(struct wpa_supplicant *wpa_s,
- const char *bridge_ifname)
-{
- if (wpa_s->wpa_state > WPA_SCANNING)
- return -EBUSY;
-
- if (bridge_ifname &&
- os_strlen(bridge_ifname) >= sizeof(wpa_s->bridge_ifname))
- return -EINVAL;
-
- if (!bridge_ifname)
- bridge_ifname = "";
-
- if (os_strcmp(wpa_s->bridge_ifname, bridge_ifname) == 0)
- return 0;
-
- if (wpa_s->l2_br) {
- l2_packet_deinit(wpa_s->l2_br);
- wpa_s->l2_br = NULL;
- }
-
- os_strlcpy(wpa_s->bridge_ifname, bridge_ifname,
- sizeof(wpa_s->bridge_ifname));
-
- if (wpa_s->bridge_ifname[0]) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Receiving packets from bridge interface '%s'",
- wpa_s->bridge_ifname);
- wpa_s->l2_br = l2_packet_init_bridge(
- wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
- ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
- if (!wpa_s->l2_br) {
- wpa_msg(wpa_s, MSG_ERROR,
- "Failed to open l2_packet connection for the bridge interface '%s'",
- wpa_s->bridge_ifname);
- goto fail;
- }
- }
-
-#ifdef CONFIG_TDLS
- if (!wpa_s->p2p_mgmt && wpa_tdls_init(wpa_s->wpa))
- goto fail;
-#endif /* CONFIG_TDLS */
-
- return 0;
-fail:
- wpa_s->bridge_ifname[0] = 0;
- if (wpa_s->l2_br) {
- l2_packet_deinit(wpa_s->l2_br);
- wpa_s->l2_br = NULL;
- }
-#ifdef CONFIG_TDLS
- if (!wpa_s->p2p_mgmt)
- wpa_tdls_init(wpa_s->wpa);
-#endif /* CONFIG_TDLS */
- return -EIO;
-}
-
-
-/**
- * wpa_supplicant_driver_init - Initialize driver interface parameters
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: 0 on success, -1 on failure
- *
- * This function is called to initialize driver interface parameters.
- * wpa_drv_init() must have been called before this function to initialize the
- * driver interface.
- */
-int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
-{
- static int interface_count = 0;
-
- if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
- return -1;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
- MAC2STR(wpa_s->own_addr));
- os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
- wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-
- if (wpa_s->bridge_ifname[0] && wpas_eapol_needs_l2_packet(wpa_s)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
- "interface '%s'", wpa_s->bridge_ifname);
- wpa_s->l2_br = l2_packet_init_bridge(
- wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
- ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
- if (wpa_s->l2_br == NULL) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
- "connection for the bridge interface '%s'",
- wpa_s->bridge_ifname);
- return -1;
- }
- }
-
- if (wpa_s->conf->ap_scan == 2 &&
- os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
- wpa_printf(MSG_INFO,
- "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
- }
-
- wpa_clear_keys(wpa_s, NULL);
-
- /* Make sure that TKIP countermeasures are not left enabled (could
- * happen if wpa_supplicant is killed during countermeasures. */
- wpa_drv_set_countermeasures(wpa_s, 0);
-
- wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
- wpa_drv_flush_pmkid(wpa_s);
-
- wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
- wpa_s->prev_scan_wildcard = 0;
-
- if (wpa_supplicant_enabled_networks(wpa_s)) {
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- interface_count = 0;
- }
-#ifndef ANDROID
- if (!wpa_s->p2p_mgmt &&
- wpa_supplicant_delayed_sched_scan(wpa_s,
- interface_count % 3,
- 100000))
- wpa_supplicant_req_scan(wpa_s, interface_count % 3,
- 100000);
-#endif /* ANDROID */
- interface_count++;
- } else
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
-
- return 0;
-}
-
-
-static int wpa_supplicant_daemon(const char *pid_file)
-{
- wpa_printf(MSG_DEBUG, "Daemonize..");
- return os_daemonize(pid_file);
-}
-
-
-static struct wpa_supplicant *
-wpa_supplicant_alloc(struct wpa_supplicant *parent)
-{
- struct wpa_supplicant *wpa_s;
-
- wpa_s = os_zalloc(sizeof(*wpa_s));
- if (wpa_s == NULL)
- return NULL;
- wpa_s->scan_req = INITIAL_SCAN_REQ;
- wpa_s->scan_interval = 5;
- wpa_s->new_connection = 1;
- wpa_s->parent = parent ? parent : wpa_s;
- wpa_s->p2pdev = wpa_s->parent;
- wpa_s->sched_scanning = 0;
- wpa_s->setband_mask = WPA_SETBAND_AUTO;
-
- dl_list_init(&wpa_s->bss_tmp_disallowed);
- dl_list_init(&wpa_s->fils_hlp_req);
-#ifdef CONFIG_TESTING_OPTIONS
- dl_list_init(&wpa_s->drv_signal_override);
-#endif /* CONFIG_TESTING_OPTIONS */
- dl_list_init(&wpa_s->active_scs_ids);
-
- return wpa_s;
-}
-
-
-#ifdef CONFIG_HT_OVERRIDES
-
-static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- const char *ht_mcs)
-{
- /* parse ht_mcs into hex array */
- int i;
- const char *tmp = ht_mcs;
- char *end = NULL;
-
- /* If ht_mcs is null, do not set anything */
- if (!ht_mcs)
- return 0;
-
- /* This is what we are setting in the kernel */
- os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
-
- for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
- long v;
-
- errno = 0;
- v = strtol(tmp, &end, 16);
-
- if (errno == 0) {
- wpa_msg(wpa_s, MSG_DEBUG,
- "htcap value[%i]: %ld end: %p tmp: %p",
- i, v, end, tmp);
- if (end == tmp)
- break;
-
- htcaps->supported_mcs_set[i] = v;
- tmp = end;
- } else {
- wpa_msg(wpa_s, MSG_ERROR,
- "Failed to parse ht-mcs: %s, error: %s\n",
- ht_mcs, strerror(errno));
- return -1;
- }
- }
-
- /*
- * If we were able to parse any values, then set mask for the MCS set.
- */
- if (i) {
- os_memset(&htcaps_mask->supported_mcs_set, 0xff,
- IEEE80211_HT_MCS_MASK_LEN - 1);
- /* skip the 3 reserved bits */
- htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
- 0x1f;
- }
-
- return 0;
-}
-
-
-static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int disabled)
-{
- le16 msk;
-
- if (disabled == -1)
- return 0;
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
-
- msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
- htcaps_mask->ht_capabilities_info |= msk;
- if (disabled)
- htcaps->ht_capabilities_info &= msk;
- else
- htcaps->ht_capabilities_info |= msk;
-
- return 0;
-}
-
-
-static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int factor)
-{
- if (factor == -1)
- return 0;
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
-
- if (factor < 0 || factor > 3) {
- wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
- "Must be 0-3 or -1", factor);
- return -EINVAL;
- }
-
- htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
- htcaps->a_mpdu_params &= ~0x3;
- htcaps->a_mpdu_params |= factor & 0x3;
-
- return 0;
-}
-
-
-static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int density)
-{
- if (density == -1)
- return 0;
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
-
- if (density < 0 || density > 7) {
- wpa_msg(wpa_s, MSG_ERROR,
- "ampdu_density: %d out of range. Must be 0-7 or -1.",
- density);
- return -EINVAL;
- }
-
- htcaps_mask->a_mpdu_params |= 0x1C;
- htcaps->a_mpdu_params &= ~(0x1C);
- htcaps->a_mpdu_params |= (density << 2) & 0x1C;
-
- return 0;
-}
-
-
-static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int disabled)
-{
- if (disabled)
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
-
- set_disable_ht40(htcaps, disabled);
- set_disable_ht40(htcaps_mask, 0);
-
- return 0;
-}
-
-
-static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int disabled)
-{
- /* Masking these out disables SGI */
- le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
- HT_CAP_INFO_SHORT_GI40MHZ);
-
- if (disabled)
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
-
- if (disabled)
- htcaps->ht_capabilities_info &= ~msk;
- else
- htcaps->ht_capabilities_info |= msk;
-
- htcaps_mask->ht_capabilities_info |= msk;
-
- return 0;
-}
-
-
-static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int disabled)
-{
- /* Masking these out disables LDPC */
- le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
-
- if (disabled)
- wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
-
- if (disabled)
- htcaps->ht_capabilities_info &= ~msk;
- else
- htcaps->ht_capabilities_info |= msk;
-
- htcaps_mask->ht_capabilities_info |= msk;
-
- return 0;
-}
-
-
-static int wpa_set_tx_stbc(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int tx_stbc)
-{
- le16 msk = host_to_le16(HT_CAP_INFO_TX_STBC);
-
- if (tx_stbc == -1)
- return 0;
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_tx_stbc: %d", tx_stbc);
-
- if (tx_stbc < 0 || tx_stbc > 1) {
- wpa_msg(wpa_s, MSG_ERROR,
- "tx_stbc: %d out of range. Must be 0-1 or -1", tx_stbc);
- return -EINVAL;
- }
-
- htcaps_mask->ht_capabilities_info |= msk;
- htcaps->ht_capabilities_info &= ~msk;
- htcaps->ht_capabilities_info |= (tx_stbc << 7) & msk;
-
- return 0;
-}
-
-
-static int wpa_set_rx_stbc(struct wpa_supplicant *wpa_s,
- struct ieee80211_ht_capabilities *htcaps,
- struct ieee80211_ht_capabilities *htcaps_mask,
- int rx_stbc)
-{
- le16 msk = host_to_le16(HT_CAP_INFO_RX_STBC_MASK);
-
- if (rx_stbc == -1)
- return 0;
-
- wpa_msg(wpa_s, MSG_DEBUG, "set_rx_stbc: %d", rx_stbc);
-
- if (rx_stbc < 0 || rx_stbc > 3) {
- wpa_msg(wpa_s, MSG_ERROR,
- "rx_stbc: %d out of range. Must be 0-3 or -1", rx_stbc);
- return -EINVAL;
- }
-
- htcaps_mask->ht_capabilities_info |= msk;
- htcaps->ht_capabilities_info &= ~msk;
- htcaps->ht_capabilities_info |= (rx_stbc << 8) & msk;
-
- return 0;
-}
-
-
-void wpa_supplicant_apply_ht_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params)
-{
- struct ieee80211_ht_capabilities *htcaps;
- struct ieee80211_ht_capabilities *htcaps_mask;
-
- if (!ssid)
- return;
-
- params->disable_ht = ssid->disable_ht;
- if (!params->htcaps || !params->htcaps_mask)
- return;
-
- htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
- htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
- wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
- wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
- ssid->disable_max_amsdu);
- wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
- wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
- wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
- wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
- wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
- wpa_set_rx_stbc(wpa_s, htcaps, htcaps_mask, ssid->rx_stbc);
- wpa_set_tx_stbc(wpa_s, htcaps, htcaps_mask, ssid->tx_stbc);
-
- if (ssid->ht40_intolerant) {
- le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
- htcaps->ht_capabilities_info |= bit;
- htcaps_mask->ht_capabilities_info |= bit;
- }
-}
-
-#endif /* CONFIG_HT_OVERRIDES */
-
-
-#ifdef CONFIG_VHT_OVERRIDES
-void wpa_supplicant_apply_vht_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params)
-{
- struct ieee80211_vht_capabilities *vhtcaps;
- struct ieee80211_vht_capabilities *vhtcaps_mask;
-
- if (!ssid)
- return;
-
- params->disable_vht = ssid->disable_vht;
-
- vhtcaps = (void *) params->vhtcaps;
- vhtcaps_mask = (void *) params->vhtcaps_mask;
-
- if (!vhtcaps || !vhtcaps_mask)
- return;
-
- vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
- vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
-
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_sgi) {
- vhtcaps_mask->vht_capabilities_info |= (VHT_CAP_SHORT_GI_80 |
- VHT_CAP_SHORT_GI_160);
- vhtcaps->vht_capabilities_info &= ~(VHT_CAP_SHORT_GI_80 |
- VHT_CAP_SHORT_GI_160);
- wpa_msg(wpa_s, MSG_DEBUG,
- "disable-sgi override specified, vht-caps: 0x%x",
- vhtcaps->vht_capabilities_info);
- }
-
- /* if max ampdu is <= 3, we have to make the HT cap the same */
- if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
- int max_ampdu;
-
- max_ampdu = (ssid->vht_capa &
- VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
- VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
-
- max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
- wpa_set_ampdu_factor(wpa_s,
- (void *) params->htcaps,
- (void *) params->htcaps_mask,
- max_ampdu);
- }
-#endif /* CONFIG_HT_OVERRIDES */
-
-#define OVERRIDE_MCS(i) \
- if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
- vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
- host_to_le16(3 << 2 * (i - 1)); \
- vhtcaps->vht_supported_mcs_set.tx_map |= \
- host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
- 2 * (i - 1)); \
- } \
- if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
- vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
- host_to_le16(3 << 2 * (i - 1)); \
- vhtcaps->vht_supported_mcs_set.rx_map |= \
- host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
- 2 * (i - 1)); \
- }
-
- OVERRIDE_MCS(1);
- OVERRIDE_MCS(2);
- OVERRIDE_MCS(3);
- OVERRIDE_MCS(4);
- OVERRIDE_MCS(5);
- OVERRIDE_MCS(6);
- OVERRIDE_MCS(7);
- OVERRIDE_MCS(8);
-}
-#endif /* CONFIG_VHT_OVERRIDES */
-
-
-#ifdef CONFIG_HE_OVERRIDES
-void wpa_supplicant_apply_he_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params)
-{
- if (!ssid)
- return;
-
- params->disable_he = ssid->disable_he;
-}
-#endif /* CONFIG_HE_OVERRIDES */
-
-
-static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
-{
-#ifdef PCSC_FUNCS
- size_t len;
-
- if (!wpa_s->conf->pcsc_reader)
- return 0;
-
- wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
- if (!wpa_s->scard)
- return 1;
-
- if (wpa_s->conf->pcsc_pin &&
- scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
- scard_deinit(wpa_s->scard);
- wpa_s->scard = NULL;
- wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
- return -1;
- }
-
- len = sizeof(wpa_s->imsi) - 1;
- if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
- scard_deinit(wpa_s->scard);
- wpa_s->scard = NULL;
- wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
- return -1;
- }
- wpa_s->imsi[len] = '\0';
-
- wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
-
- wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
- wpa_s->imsi, wpa_s->mnc_len);
-
- wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
- eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
-#endif /* PCSC_FUNCS */
-
- return 0;
-}
-
-
-int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
-{
- char *val, *pos;
-
- ext_password_deinit(wpa_s->ext_pw);
- wpa_s->ext_pw = NULL;
- eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
-
- if (!wpa_s->conf->ext_password_backend)
- return 0;
-
- val = os_strdup(wpa_s->conf->ext_password_backend);
- if (val == NULL)
- return -1;
- pos = os_strchr(val, ':');
- if (pos)
- *pos++ = '\0';
-
- wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
-
- wpa_s->ext_pw = ext_password_init(val, pos);
- os_free(val);
- if (wpa_s->ext_pw == NULL) {
- wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
- return -1;
- }
- eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
-
- return 0;
-}
-
-
-#ifdef CONFIG_FST
-
-static const u8 * wpas_fst_get_bssid_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- return (is_zero_ether_addr(wpa_s->bssid) ||
- wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
-}
-
-
-static void wpas_fst_get_channel_info_cb(void *ctx,
- enum hostapd_hw_mode *hw_mode,
- u8 *channel)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->current_bss) {
- *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
- channel);
- } else if (wpa_s->hw.num_modes) {
- *hw_mode = wpa_s->hw.modes[0].mode;
- } else {
- WPA_ASSERT(0);
- *hw_mode = 0;
- }
-}
-
-
-static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- *modes = wpa_s->hw.modes;
- return wpa_s->hw.num_modes;
-}
-
-
-static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
- wpa_s->fst_ies = fst_ies;
-}
-
-
-static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (os_memcmp(wpa_s->bssid, da, ETH_ALEN) != 0) {
- wpa_printf(MSG_INFO, "FST:%s:bssid=" MACSTR " != da=" MACSTR,
- __func__, MAC2STR(wpa_s->bssid), MAC2STR(da));
- return -1;
- }
- return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
- wpa_s->own_addr, wpa_s->bssid,
- wpabuf_head(data), wpabuf_len(data),
- 0);
-}
-
-
-static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
- return wpa_s->received_mb_ies;
-}
-
-
-static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
- const u8 *buf, size_t size)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct mb_ies_info info;
-
- WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
-
- if (!mb_ies_info_by_ies(&info, buf, size)) {
- wpabuf_free(wpa_s->received_mb_ies);
- wpa_s->received_mb_ies = mb_ies_by_info(&info);
- }
-}
-
-
-static const u8 * wpas_fst_get_peer_first(void *ctx,
- struct fst_get_peer_ctx **get_ctx,
- bool mb_only)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- *get_ctx = NULL;
- if (!is_zero_ether_addr(wpa_s->bssid))
- return (wpa_s->received_mb_ies || !mb_only) ?
- wpa_s->bssid : NULL;
- return NULL;
-}
-
-
-static const u8 * wpas_fst_get_peer_next(void *ctx,
- struct fst_get_peer_ctx **get_ctx,
- bool mb_only)
-{
- return NULL;
-}
-
-void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
- struct fst_wpa_obj *iface_obj)
-{
- iface_obj->ctx = wpa_s;
- iface_obj->get_bssid = wpas_fst_get_bssid_cb;
- iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
- iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
- iface_obj->set_ies = wpas_fst_set_ies_cb;
- iface_obj->send_action = wpas_fst_send_action_cb;
- iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
- iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
- iface_obj->get_peer_first = wpas_fst_get_peer_first;
- iface_obj->get_peer_next = wpas_fst_get_peer_next;
-}
-#endif /* CONFIG_FST */
-
-static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
- const struct wpa_driver_capa *capa)
-{
- struct wowlan_triggers *triggers;
- int ret = 0;
-
- if (!wpa_s->conf->wowlan_triggers)
- return 0;
-
- triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
- if (triggers) {
- ret = wpa_drv_wowlan(wpa_s, triggers);
- os_free(triggers);
- }
- return ret;
-}
-
-
-enum wpa_radio_work_band wpas_freq_to_band(int freq)
-{
- if (freq < 3000)
- return BAND_2_4_GHZ;
- if (freq > 50000)
- return BAND_60_GHZ;
- return BAND_5_GHZ;
-}
-
-
-unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
-{
- int i;
- unsigned int band = 0;
-
- if (freqs) {
- /* freqs are specified for the radio work */
- for (i = 0; freqs[i]; i++)
- band |= wpas_freq_to_band(freqs[i]);
- } else {
- /*
- * freqs are not specified, implies all
- * the supported freqs by HW
- */
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].num_channels != 0) {
- if (wpa_s->hw.modes[i].mode ==
- HOSTAPD_MODE_IEEE80211B ||
- wpa_s->hw.modes[i].mode ==
- HOSTAPD_MODE_IEEE80211G)
- band |= BAND_2_4_GHZ;
- else if (wpa_s->hw.modes[i].mode ==
- HOSTAPD_MODE_IEEE80211A)
- band |= BAND_5_GHZ;
- else if (wpa_s->hw.modes[i].mode ==
- HOSTAPD_MODE_IEEE80211AD)
- band |= BAND_60_GHZ;
- else if (wpa_s->hw.modes[i].mode ==
- HOSTAPD_MODE_IEEE80211ANY)
- band = BAND_2_4_GHZ | BAND_5_GHZ |
- BAND_60_GHZ;
- }
- }
- }
-
- return band;
-}
-
-
-static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
- const char *rn)
-{
- struct wpa_supplicant *iface = wpa_s->global->ifaces;
- struct wpa_radio *radio;
-
- while (rn && iface) {
- radio = iface->radio;
- if (radio && os_strcmp(rn, radio->name) == 0) {
- wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
- wpa_s->ifname, rn);
- dl_list_add(&radio->ifaces, &wpa_s->radio_list);
- return radio;
- }
-
- iface = iface->next;
- }
-
- wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
- wpa_s->ifname, rn ? rn : "N/A");
- radio = os_zalloc(sizeof(*radio));
- if (radio == NULL)
- return NULL;
-
- if (rn)
- os_strlcpy(radio->name, rn, sizeof(radio->name));
- dl_list_init(&radio->ifaces);
- dl_list_init(&radio->work);
- dl_list_add(&radio->ifaces, &wpa_s->radio_list);
-
- return radio;
-}
-
-
-static void radio_work_free(struct wpa_radio_work *work)
-{
- if (work->wpa_s->scan_work == work) {
- /* This should not really happen. */
- wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
- work->type, work, work->started);
- work->wpa_s->scan_work = NULL;
- }
-
-#ifdef CONFIG_P2P
- if (work->wpa_s->p2p_scan_work == work) {
- /* This should not really happen. */
- wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
- work->type, work, work->started);
- work->wpa_s->p2p_scan_work = NULL;
- }
-#endif /* CONFIG_P2P */
-
- if (work->started) {
- work->wpa_s->radio->num_active_works--;
- wpa_dbg(work->wpa_s, MSG_DEBUG,
- "radio_work_free('%s'@%p): num_active_works --> %u",
- work->type, work,
- work->wpa_s->radio->num_active_works);
- }
-
- dl_list_del(&work->list);
- os_free(work);
-}
-
-
-static int radio_work_is_connect(struct wpa_radio_work *work)
-{
- return os_strcmp(work->type, "sme-connect") == 0 ||
- os_strcmp(work->type, "connect") == 0;
-}
-
-
-static int radio_work_is_scan(struct wpa_radio_work *work)
-{
- return os_strcmp(work->type, "scan") == 0 ||
- os_strcmp(work->type, "p2p-scan") == 0;
-}
-
-
-static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
-{
- struct wpa_radio_work *active_work = NULL;
- struct wpa_radio_work *tmp;
-
- /* Get the active work to know the type and band. */
- dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
- if (tmp->started) {
- active_work = tmp;
- break;
- }
- }
-
- if (!active_work) {
- /* No active work, start one */
- radio->num_active_works = 0;
- dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
- list) {
- if (os_strcmp(tmp->type, "scan") == 0 &&
- external_scan_running(radio) &&
- (((struct wpa_driver_scan_params *)
- tmp->ctx)->only_new_results ||
- tmp->wpa_s->clear_driver_scan_cache))
- continue;
- return tmp;
- }
- return NULL;
- }
-
- if (radio_work_is_connect(active_work)) {
- /*
- * If the active work is either connect or sme-connect,
- * do not parallelize them with other radio works.
- */
- wpa_dbg(active_work->wpa_s, MSG_DEBUG,
- "Do not parallelize radio work with %s",
- active_work->type);
- return NULL;
- }
-
- dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
- if (tmp->started)
- continue;
-
- /*
- * If connect or sme-connect are enqueued, parallelize only
- * those operations ahead of them in the queue.
- */
- if (radio_work_is_connect(tmp))
- break;
-
- /* Serialize parallel scan and p2p_scan operations on the same
- * interface since the driver_nl80211 mechanism for tracking
- * scan cookies does not yet have support for this. */
- if (active_work->wpa_s == tmp->wpa_s &&
- radio_work_is_scan(active_work) &&
- radio_work_is_scan(tmp)) {
- wpa_dbg(active_work->wpa_s, MSG_DEBUG,
- "Do not start work '%s' when another work '%s' is already scheduled",
- tmp->type, active_work->type);
- continue;
- }
- /*
- * Check that the radio works are distinct and
- * on different bands.
- */
- if (os_strcmp(active_work->type, tmp->type) != 0 &&
- (active_work->bands != tmp->bands)) {
- /*
- * If a scan has to be scheduled through nl80211 scan
- * interface and if an external scan is already running,
- * do not schedule the scan since it is likely to get
- * rejected by kernel.
- */
- if (os_strcmp(tmp->type, "scan") == 0 &&
- external_scan_running(radio) &&
- (((struct wpa_driver_scan_params *)
- tmp->ctx)->only_new_results ||
- tmp->wpa_s->clear_driver_scan_cache))
- continue;
-
- wpa_dbg(active_work->wpa_s, MSG_DEBUG,
- "active_work:%s new_work:%s",
- active_work->type, tmp->type);
- return tmp;
- }
- }
-
- /* Did not find a radio work to schedule in parallel. */
- return NULL;
-}
-
-
-static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_radio *radio = eloop_ctx;
- struct wpa_radio_work *work;
- struct os_reltime now, diff;
- struct wpa_supplicant *wpa_s;
-
- work = dl_list_first(&radio->work, struct wpa_radio_work, list);
- if (work == NULL) {
- radio->num_active_works = 0;
- return;
- }
-
- wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
- radio_list);
-
- if (!(wpa_s &&
- wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
- if (work->started)
- return; /* already started and still in progress */
-
- if (wpa_s && external_scan_running(wpa_s->radio)) {
- wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
- return;
- }
- } else {
- work = NULL;
- if (radio->num_active_works < MAX_ACTIVE_WORKS) {
- /* get the work to schedule next */
- work = radio_work_get_next_work(radio);
- }
- if (!work)
- return;
- }
-
- wpa_s = work->wpa_s;
- os_get_reltime(&now);
- os_reltime_sub(&now, &work->time, &diff);
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Starting radio work '%s'@%p after %ld.%06ld second wait",
- work->type, work, diff.sec, diff.usec);
- work->started = 1;
- work->time = now;
- radio->num_active_works++;
-
- work->cb(work, 0);
-
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
- radio->num_active_works < MAX_ACTIVE_WORKS)
- radio_work_check_next(wpa_s);
-}
-
-
-/*
- * This function removes both started and pending radio works running on
- * the provided interface's radio.
- * Prior to the removal of the radio work, its callback (cb) is called with
- * deinit set to be 1. Each work's callback is responsible for clearing its
- * internal data and restoring to a correct state.
- * @wpa_s: wpa_supplicant data
- * @type: type of works to be removed
- * @remove_all: 1 to remove all the works on this radio, 0 to remove only
- * this interface's works.
- */
-void radio_remove_works(struct wpa_supplicant *wpa_s,
- const char *type, int remove_all)
-{
- struct wpa_radio_work *work, *tmp;
- struct wpa_radio *radio = wpa_s->radio;
-
- dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
- list) {
- if (type && os_strcmp(type, work->type) != 0)
- continue;
-
- /* skip other ifaces' works */
- if (!remove_all && work->wpa_s != wpa_s)
- continue;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
- work->type, work, work->started ? " (started)" : "");
- work->cb(work, 1);
- radio_work_free(work);
- }
-
- /* in case we removed the started work */
- radio_work_check_next(wpa_s);
-}
-
-
-void radio_remove_pending_work(struct wpa_supplicant *wpa_s, void *ctx)
-{
- struct wpa_radio_work *work;
- struct wpa_radio *radio = wpa_s->radio;
-
- dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
- if (work->ctx != ctx)
- continue;
- wpa_dbg(wpa_s, MSG_DEBUG, "Free pending radio work '%s'@%p%s",
- work->type, work, work->started ? " (started)" : "");
- radio_work_free(work);
- break;
- }
-}
-
-
-static void radio_remove_interface(struct wpa_supplicant *wpa_s)
-{
- struct wpa_radio *radio = wpa_s->radio;
-
- if (!radio)
- return;
-
- wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
- wpa_s->ifname, radio->name);
- dl_list_del(&wpa_s->radio_list);
- radio_remove_works(wpa_s, NULL, 0);
- /* If the interface that triggered the external scan was removed, the
- * external scan is no longer running. */
- if (wpa_s == radio->external_scan_req_interface)
- radio->external_scan_req_interface = NULL;
- wpa_s->radio = NULL;
- if (!dl_list_empty(&radio->ifaces))
- return; /* Interfaces remain for this radio */
-
- wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
- eloop_cancel_timeout(radio_start_next_work, radio, NULL);
- os_free(radio);
-}
-
-
-void radio_work_check_next(struct wpa_supplicant *wpa_s)
-{
- struct wpa_radio *radio = wpa_s->radio;
-
- if (dl_list_empty(&radio->work))
- return;
- if (wpa_s->ext_work_in_progress) {
- wpa_printf(MSG_DEBUG,
- "External radio work in progress - delay start of pending item");
- return;
- }
- eloop_cancel_timeout(radio_start_next_work, radio, NULL);
- eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
-}
-
-
-/**
- * radio_add_work - Add a radio work item
- * @wpa_s: Pointer to wpa_supplicant data
- * @freq: Frequency of the offchannel operation in MHz or 0
- * @type: Unique identifier for each type of work
- * @next: Force as the next work to be executed
- * @cb: Callback function for indicating when radio is available
- * @ctx: Context pointer for the work (work->ctx in cb())
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to request time for an operation that requires
- * exclusive radio control. Once the radio is available, the registered callback
- * function will be called. radio_work_done() must be called once the exclusive
- * radio operation has been completed, so that the radio is freed for other
- * operations. The special case of deinit=1 is used to free the context data
- * during interface removal. That does not allow the callback function to start
- * the radio operation, i.e., it must free any resources allocated for the radio
- * work and return.
- *
- * The @freq parameter can be used to indicate a single channel on which the
- * offchannel operation will occur. This may allow multiple radio work
- * operations to be performed in parallel if they apply for the same channel.
- * Setting this to 0 indicates that the work item may use multiple channels or
- * requires exclusive control of the radio.
- */
-int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
- const char *type, int next,
- void (*cb)(struct wpa_radio_work *work, int deinit),
- void *ctx)
-{
- struct wpa_radio *radio = wpa_s->radio;
- struct wpa_radio_work *work;
- int was_empty;
-
- work = os_zalloc(sizeof(*work));
- if (work == NULL)
- return -1;
- wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
- os_get_reltime(&work->time);
- work->freq = freq;
- work->type = type;
- work->wpa_s = wpa_s;
- work->cb = cb;
- work->ctx = ctx;
-
- if (freq)
- work->bands = wpas_freq_to_band(freq);
- else if (os_strcmp(type, "scan") == 0 ||
- os_strcmp(type, "p2p-scan") == 0)
- work->bands = wpas_get_bands(wpa_s,
- ((struct wpa_driver_scan_params *)
- ctx)->freqs);
- else
- work->bands = wpas_get_bands(wpa_s, NULL);
-
- was_empty = dl_list_empty(&wpa_s->radio->work);
- if (next)
- dl_list_add(&wpa_s->radio->work, &work->list);
- else
- dl_list_add_tail(&wpa_s->radio->work, &work->list);
- if (was_empty) {
- wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
- radio_work_check_next(wpa_s);
- } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
- && radio->num_active_works < MAX_ACTIVE_WORKS) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Try to schedule a radio work (num_active_works=%u)",
- radio->num_active_works);
- radio_work_check_next(wpa_s);
- }
-
- return 0;
-}
-
-
-/**
- * radio_work_done - Indicate that a radio work item has been completed
- * @work: Completed work
- *
- * This function is called once the callback function registered with
- * radio_add_work() has completed its work.
- */
-void radio_work_done(struct wpa_radio_work *work)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct os_reltime now, diff;
- unsigned int started = work->started;
-
- os_get_reltime(&now);
- os_reltime_sub(&now, &work->time, &diff);
- wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
- work->type, work, started ? "done" : "canceled",
- diff.sec, diff.usec);
- radio_work_free(work);
- if (started)
- radio_work_check_next(wpa_s);
-}
-
-
-struct wpa_radio_work *
-radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
-{
- struct wpa_radio_work *work;
- struct wpa_radio *radio = wpa_s->radio;
-
- dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
- if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
- return work;
- }
-
- return NULL;
-}
-
-
-static int wpas_init_driver(struct wpa_supplicant *wpa_s,
- const struct wpa_interface *iface)
-{
- const char *ifname, *driver, *rn;
-
- driver = iface->driver;
-next_driver:
- if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
- return -1;
-
- wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
- if (wpa_s->drv_priv == NULL) {
- const char *pos;
- int level = MSG_ERROR;
-
- pos = driver ? os_strchr(driver, ',') : NULL;
- if (pos) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
- "driver interface - try next driver wrapper");
- driver = pos + 1;
- goto next_driver;
- }
-
-#ifdef CONFIG_MATCH_IFACE
- if (wpa_s->matched == WPA_IFACE_MATCHED_NULL)
- level = MSG_DEBUG;
-#endif /* CONFIG_MATCH_IFACE */
- wpa_msg(wpa_s, level, "Failed to initialize driver interface");
- return -1;
- }
- if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
- wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
- "driver_param '%s'", wpa_s->conf->driver_param);
- return -1;
- }
-
- ifname = wpa_drv_get_ifname(wpa_s);
- if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
- "interface name with '%s'", ifname);
- os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
- }
-
- rn = wpa_driver_get_radio_name(wpa_s);
- if (rn && rn[0] == '\0')
- rn = NULL;
-
- wpa_s->radio = radio_add_interface(wpa_s, rn);
- if (wpa_s->radio == NULL)
- return -1;
-
- return 0;
-}
-
-
-#ifdef CONFIG_GAS_SERVER
-
-static void wpas_gas_server_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- wpa_printf(MSG_DEBUG, "GAS: TX status: freq=%u dst=" MACSTR
- " result=%s",
- freq, MAC2STR(dst),
- result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
- (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
- "FAILED"));
- gas_server_tx_status(wpa_s->gas_server, dst, data, data_len,
- result == OFFCHANNEL_SEND_ACTION_SUCCESS);
-}
-
-
-static void wpas_gas_server_tx(void *ctx, int freq, const u8 *da,
- struct wpabuf *buf, unsigned int wait_time)
-{
- struct wpa_supplicant *wpa_s = ctx;
- const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- if (wait_time > wpa_s->max_remain_on_chan)
- wait_time = wpa_s->max_remain_on_chan;
-
- offchannel_send_action(wpa_s, freq, da, wpa_s->own_addr, broadcast,
- wpabuf_head(buf), wpabuf_len(buf),
- wait_time, wpas_gas_server_tx_status, 0);
-}
-
-#endif /* CONFIG_GAS_SERVER */
-
-static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
- const struct wpa_interface *iface)
-{
- struct wpa_driver_capa capa;
- int capa_res;
- u8 dfs_domain;
-
- wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
- "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
- iface->confname ? iface->confname : "N/A",
- iface->driver ? iface->driver : "default",
- iface->ctrl_interface ? iface->ctrl_interface : "N/A",
- iface->bridge_ifname ? iface->bridge_ifname : "N/A");
-
- if (iface->confname) {
-#ifdef CONFIG_BACKEND_FILE
- wpa_s->confname = os_rel2abs_path(iface->confname);
- if (wpa_s->confname == NULL) {
- wpa_printf(MSG_ERROR, "Failed to get absolute path "
- "for configuration file '%s'.",
- iface->confname);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
- iface->confname, wpa_s->confname);
-#else /* CONFIG_BACKEND_FILE */
- wpa_s->confname = os_strdup(iface->confname);
-#endif /* CONFIG_BACKEND_FILE */
- wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
- if (wpa_s->conf == NULL) {
- wpa_printf(MSG_ERROR, "Failed to read or parse "
- "configuration '%s'.", wpa_s->confname);
- return -1;
- }
- wpa_s->confanother = os_rel2abs_path(iface->confanother);
- if (wpa_s->confanother &&
- !wpa_config_read(wpa_s->confanother, wpa_s->conf)) {
- wpa_printf(MSG_ERROR,
- "Failed to read or parse configuration '%s'.",
- wpa_s->confanother);
- return -1;
- }
-
- /*
- * Override ctrl_interface and driver_param if set on command
- * line.
- */
- if (iface->ctrl_interface) {
- os_free(wpa_s->conf->ctrl_interface);
- wpa_s->conf->ctrl_interface =
- os_strdup(iface->ctrl_interface);
- }
-
- if (iface->driver_param) {
- os_free(wpa_s->conf->driver_param);
- wpa_s->conf->driver_param =
- os_strdup(iface->driver_param);
- }
-
- if (iface->p2p_mgmt && !iface->ctrl_interface) {
- os_free(wpa_s->conf->ctrl_interface);
- wpa_s->conf->ctrl_interface = NULL;
- }
- } else
- wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
- iface->driver_param);
-
- if (wpa_s->conf == NULL) {
- wpa_printf(MSG_ERROR, "\nNo configuration found.");
- return -1;
- }
-
- if (iface->ifname == NULL) {
- wpa_printf(MSG_ERROR, "\nInterface name is required.");
- return -1;
- }
- if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
- wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
- iface->ifname);
- return -1;
- }
- os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
-#ifdef CONFIG_MATCH_IFACE
- wpa_s->matched = iface->matched;
-#endif /* CONFIG_MATCH_IFACE */
-
- if (iface->bridge_ifname) {
- if (os_strlen(iface->bridge_ifname) >=
- sizeof(wpa_s->bridge_ifname)) {
- wpa_printf(MSG_ERROR, "\nToo long bridge interface "
- "name '%s'.", iface->bridge_ifname);
- return -1;
- }
- os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
- sizeof(wpa_s->bridge_ifname));
- }
-
- /* RSNA Supplicant Key Management - INITIALIZE */
- eapol_sm_notify_portEnabled(wpa_s->eapol, false);
- eapol_sm_notify_portValid(wpa_s->eapol, false);
-
- /* Initialize driver interface and register driver event handler before
- * L2 receive handler so that association events are processed before
- * EAPOL-Key packets if both become available for the same select()
- * call. */
- if (wpas_init_driver(wpa_s, iface) < 0)
- return -1;
-
- if (wpa_supplicant_init_wpa(wpa_s) < 0)
- return -1;
-
- wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
- wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
- NULL);
- wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
-
- if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
- wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKLifetime");
- return -1;
- }
-
- if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
- wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKReauthThreshold");
- return -1;
- }
-
- if (wpa_s->conf->dot11RSNAConfigSATimeout &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
- wpa_s->conf->dot11RSNAConfigSATimeout)) {
- wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigSATimeout");
- return -1;
- }
-
- wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
- &wpa_s->hw.num_modes,
- &wpa_s->hw.flags,
- &dfs_domain);
- if (wpa_s->hw.modes) {
- u16 i;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].vht_capab) {
- wpa_s->hw_capab = CAPAB_VHT;
- break;
- }
-
- if (wpa_s->hw.modes[i].ht_capab &
- HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
- wpa_s->hw_capab = CAPAB_HT40;
- else if (wpa_s->hw.modes[i].ht_capab &&
- wpa_s->hw_capab == CAPAB_NO_HT_VHT)
- wpa_s->hw_capab = CAPAB_HT;
- }
- }
-
- capa_res = wpa_drv_get_capa(wpa_s, &capa);
- if (capa_res == 0) {
- wpa_s->drv_capa_known = 1;
- wpa_s->drv_flags = capa.flags;
- wpa_s->drv_flags2 = capa.flags2;
- wpa_s->drv_enc = capa.enc;
- wpa_s->drv_rrm_flags = capa.rrm_flags;
- wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
- wpa_s->max_scan_ssids = capa.max_scan_ssids;
- wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
- wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
- wpa_s->max_sched_scan_plan_interval =
- capa.max_sched_scan_plan_interval;
- wpa_s->max_sched_scan_plan_iterations =
- capa.max_sched_scan_plan_iterations;
- wpa_s->sched_scan_supported = capa.sched_scan_supported;
- wpa_s->max_match_sets = capa.max_match_sets;
- wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
- wpa_s->max_stations = capa.max_stations;
- wpa_s->extended_capa = capa.extended_capa;
- wpa_s->extended_capa_mask = capa.extended_capa_mask;
- wpa_s->extended_capa_len = capa.extended_capa_len;
- wpa_s->num_multichan_concurrent =
- capa.num_multichan_concurrent;
- wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
-
- if (capa.mac_addr_rand_scan_supported)
- wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
- if (wpa_s->sched_scan_supported &&
- capa.mac_addr_rand_sched_scan_supported)
- wpa_s->mac_addr_rand_supported |=
- (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
-
- wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
- if (wpa_s->extended_capa &&
- wpa_s->extended_capa_len >= 3 &&
- wpa_s->extended_capa[2] & 0x40)
- wpa_s->multi_bss_support = 1;
- }
- if (wpa_s->max_remain_on_chan == 0)
- wpa_s->max_remain_on_chan = 1000;
-
- /*
- * Only take p2p_mgmt parameters when P2P Device is supported.
- * Doing it here as it determines whether l2_packet_init() will be done
- * during wpa_supplicant_driver_init().
- */
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
- wpa_s->p2p_mgmt = iface->p2p_mgmt;
-
- if (wpa_s->num_multichan_concurrent == 0)
- wpa_s->num_multichan_concurrent = 1;
-
- if (wpa_supplicant_driver_init(wpa_s) < 0)
- return -1;
-
-#ifdef CONFIG_TDLS
- if (!iface->p2p_mgmt && wpa_tdls_init(wpa_s->wpa))
- return -1;
-#endif /* CONFIG_TDLS */
-
- if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
- wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
- return -1;
- }
-
-#ifdef CONFIG_FST
- if (wpa_s->conf->fst_group_id) {
- struct fst_iface_cfg cfg;
- struct fst_wpa_obj iface_obj;
-
- fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
- os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
- sizeof(cfg.group_id));
- cfg.priority = wpa_s->conf->fst_priority;
- cfg.llt = wpa_s->conf->fst_llt;
-
- wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
- &iface_obj, &cfg);
- if (!wpa_s->fst) {
- wpa_msg(wpa_s, MSG_ERROR,
- "FST: Cannot attach iface %s to group %s",
- wpa_s->ifname, cfg.group_id);
- return -1;
- }
- }
-#endif /* CONFIG_FST */
-
- if (wpas_wps_init(wpa_s))
- return -1;
-
-#ifdef CONFIG_GAS_SERVER
- wpa_s->gas_server = gas_server_init(wpa_s, wpas_gas_server_tx);
- if (!wpa_s->gas_server) {
- wpa_printf(MSG_ERROR, "Failed to initialize GAS server");
- return -1;
- }
-#endif /* CONFIG_GAS_SERVER */
-
-#ifdef CONFIG_DPP
- if (wpas_dpp_init(wpa_s) < 0)
- return -1;
-#endif /* CONFIG_DPP */
-
- if (wpa_supplicant_init_eapol(wpa_s) < 0)
- return -1;
- wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
-
- wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
- if (wpa_s->ctrl_iface == NULL) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize control interface '%s'.\n"
- "You may have another wpa_supplicant process "
- "already running or the file was\n"
- "left by an unclean termination of wpa_supplicant "
- "in which case you will need\n"
- "to manually remove this file before starting "
- "wpa_supplicant again.\n",
- wpa_s->conf->ctrl_interface);
- return -1;
- }
-
- wpa_s->gas = gas_query_init(wpa_s);
- if (wpa_s->gas == NULL) {
- wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
- return -1;
- }
-
- if ((!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) ||
- wpa_s->p2p_mgmt) &&
- wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
- return -1;
- }
-
- if (wpa_bss_init(wpa_s) < 0)
- return -1;
-
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
-#ifdef CONFIG_MESH
- dl_list_init(&wpa_s->mesh_external_pmksa_cache);
-#endif /* CONFIG_MESH */
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-
- /*
- * Set Wake-on-WLAN triggers, if configured.
- * Note: We don't restore/remove the triggers on shutdown (it doesn't
- * have effect anyway when the interface is down).
- */
- if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
- return -1;
-
-#ifdef CONFIG_EAP_PROXY
-{
- size_t len;
- wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, -1,
- wpa_s->imsi, &len);
- if (wpa_s->mnc_len > 0) {
- wpa_s->imsi[len] = '\0';
- wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
- wpa_s->imsi, wpa_s->mnc_len);
- } else {
- wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
- }
-}
-#endif /* CONFIG_EAP_PROXY */
-
- if (pcsc_reader_init(wpa_s) < 0)
- return -1;
-
- if (wpas_init_ext_pw(wpa_s) < 0)
- return -1;
-
- wpas_rrm_reset(wpa_s);
-
- wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
-
-#ifdef CONFIG_HS20
- hs20_init(wpa_s);
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_MBO
- if (!wpa_s->disable_mbo_oce && wpa_s->conf->oce) {
- if ((wpa_s->conf->oce & OCE_STA) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
- wpa_s->enable_oce = OCE_STA;
- if ((wpa_s->conf->oce & OCE_STA_CFON) &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA_CFON)) {
- /* TODO: Need to add STA-CFON support */
- wpa_printf(MSG_ERROR,
- "OCE STA-CFON feature is not yet supported");
- }
- }
- wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
-#endif /* CONFIG_MBO */
-
- wpa_supplicant_set_default_scan_ies(wpa_s);
-
- return 0;
-}
-
-
-static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
- int notify, int terminate)
-{
- struct wpa_global *global = wpa_s->global;
- struct wpa_supplicant *iface, *prev;
-
- if (wpa_s == wpa_s->parent)
- wpas_p2p_group_remove(wpa_s, "*");
-
- iface = global->ifaces;
- while (iface) {
- if (iface->p2pdev == wpa_s)
- iface->p2pdev = iface->parent;
- if (iface == wpa_s || iface->parent != wpa_s) {
- iface = iface->next;
- continue;
- }
- wpa_printf(MSG_DEBUG,
- "Remove remaining child interface %s from parent %s",
- iface->ifname, wpa_s->ifname);
- prev = iface;
- iface = iface->next;
- wpa_supplicant_remove_iface(global, prev, terminate);
- }
-
- wpa_s->disconnected = 1;
- if (wpa_s->drv_priv) {
- /*
- * Don't deauthenticate if WoWLAN is enable and not explicitly
- * been configured to disconnect.
- */
- if (!wpa_drv_get_wowlan(wpa_s) ||
- wpa_s->conf->wowlan_disconnect_on_deinit) {
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-
- wpa_drv_set_countermeasures(wpa_s, 0);
- wpa_clear_keys(wpa_s, NULL);
- } else {
- wpa_msg(wpa_s, MSG_INFO,
- "Do not deauthenticate as part of interface deinit since WoWLAN is enabled");
- }
- }
-
- wpa_supplicant_cleanup(wpa_s);
- wpas_p2p_deinit_iface(wpa_s);
-
- wpas_ctrl_radio_work_flush(wpa_s);
- radio_remove_interface(wpa_s);
-
-#ifdef CONFIG_FST
- if (wpa_s->fst) {
- fst_detach(wpa_s->fst);
- wpa_s->fst = NULL;
- }
- if (wpa_s->received_mb_ies) {
- wpabuf_free(wpa_s->received_mb_ies);
- wpa_s->received_mb_ies = NULL;
- }
-#endif /* CONFIG_FST */
-
- if (wpa_s->drv_priv)
- wpa_drv_deinit(wpa_s);
-
- if (notify)
- wpas_notify_iface_removed(wpa_s);
-
- if (terminate)
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
-
- wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
- wpa_s->ctrl_iface = NULL;
-
-#ifdef CONFIG_MESH
- if (wpa_s->ifmsh) {
- wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
- wpa_s->ifmsh = NULL;
- }
-#endif /* CONFIG_MESH */
-
- if (wpa_s->conf != NULL) {
- wpa_config_free(wpa_s->conf);
- wpa_s->conf = NULL;
- }
-
- os_free(wpa_s->ssids_from_scan_req);
- os_free(wpa_s->last_scan_freqs);
-
- os_free(wpa_s);
-}
-
-
-#ifdef CONFIG_MATCH_IFACE
-
-/**
- * wpa_supplicant_match_iface - Match an interface description to a name
- * @global: Pointer to global data from wpa_supplicant_init()
- * @ifname: Name of the interface to match
- * Returns: Pointer to the created interface description or %NULL on failure
- */
-struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
- const char *ifname)
-{
- int i;
- struct wpa_interface *iface, *miface;
-
- for (i = 0; i < global->params.match_iface_count; i++) {
- miface = &global->params.match_ifaces[i];
- if (!miface->ifname ||
- fnmatch(miface->ifname, ifname, 0) == 0) {
- iface = os_zalloc(sizeof(*iface));
- if (!iface)
- return NULL;
- *iface = *miface;
- if (!miface->ifname)
- iface->matched = WPA_IFACE_MATCHED_NULL;
- else
- iface->matched = WPA_IFACE_MATCHED;
- iface->ifname = ifname;
- return iface;
- }
- }
-
- return NULL;
-}
-
-
-/**
- * wpa_supplicant_match_existing - Match existing interfaces
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: 0 on success, -1 on failure
- */
-static int wpa_supplicant_match_existing(struct wpa_global *global)
-{
- struct if_nameindex *ifi, *ifp;
- struct wpa_supplicant *wpa_s;
- struct wpa_interface *iface;
-
- ifp = if_nameindex();
- if (!ifp) {
- wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
- return -1;
- }
-
- for (ifi = ifp; ifi->if_name; ifi++) {
- wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
- if (wpa_s)
- continue;
- iface = wpa_supplicant_match_iface(global, ifi->if_name);
- if (iface) {
- wpa_supplicant_add_iface(global, iface, NULL);
- os_free(iface);
- }
- }
-
- if_freenameindex(ifp);
- return 0;
-}
-
-#endif /* CONFIG_MATCH_IFACE */
-
-
-/**
- * wpa_supplicant_add_iface - Add a new network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @iface: Interface configuration options
- * @parent: Parent interface or %NULL to assign new interface as parent
- * Returns: Pointer to the created interface or %NULL on failure
- *
- * This function is used to add new network interfaces for %wpa_supplicant.
- * This can be called before wpa_supplicant_run() to add interfaces before the
- * main event loop has been started. In addition, new interfaces can be added
- * dynamically while %wpa_supplicant is already running. This could happen,
- * e.g., when a hotplug network adapter is inserted.
- */
-struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
- struct wpa_interface *iface,
- struct wpa_supplicant *parent)
-{
- struct wpa_supplicant *wpa_s;
- struct wpa_interface t_iface;
- struct wpa_ssid *ssid;
-
- if (global == NULL || iface == NULL)
- return NULL;
-
- wpa_s = wpa_supplicant_alloc(parent);
- if (wpa_s == NULL)
- return NULL;
-
- wpa_s->global = global;
-
- t_iface = *iface;
- if (global->params.override_driver) {
- wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
- "('%s' -> '%s')",
- iface->driver, global->params.override_driver);
- t_iface.driver = global->params.override_driver;
- }
- if (global->params.override_ctrl_interface) {
- wpa_printf(MSG_DEBUG, "Override interface parameter: "
- "ctrl_interface ('%s' -> '%s')",
- iface->ctrl_interface,
- global->params.override_ctrl_interface);
- t_iface.ctrl_interface =
- global->params.override_ctrl_interface;
- }
- if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
- wpa_printf(MSG_DEBUG, "Failed to add interface %s",
- iface->ifname);
- wpa_supplicant_deinit_iface(wpa_s, 0, 0);
- return NULL;
- }
-
- if (iface->p2p_mgmt == 0) {
- /* Notify the control interfaces about new iface */
- if (wpas_notify_iface_added(wpa_s)) {
- wpa_supplicant_deinit_iface(wpa_s, 1, 0);
- return NULL;
- }
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
- wpas_notify_network_added(wpa_s, ssid);
- }
-
- wpa_s->next = global->ifaces;
- global->ifaces = wpa_s;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
-
-#ifdef CONFIG_P2P
- if (wpa_s->global->p2p == NULL &&
- !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
- wpas_p2p_add_p2pdev_interface(
- wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
- wpa_printf(MSG_INFO,
- "P2P: Failed to enable P2P Device interface");
- /* Try to continue without. P2P will be disabled. */
- }
-#endif /* CONFIG_P2P */
-
- return wpa_s;
-}
-
-
-/**
- * wpa_supplicant_remove_iface - Remove a network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @wpa_s: Pointer to the network interface to be removed
- * Returns: 0 if interface was removed, -1 if interface was not found
- *
- * This function can be used to dynamically remove network interfaces from
- * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
- * addition, this function is used to remove all remaining interfaces when
- * %wpa_supplicant is terminated.
- */
-int wpa_supplicant_remove_iface(struct wpa_global *global,
- struct wpa_supplicant *wpa_s,
- int terminate)
-{
- struct wpa_supplicant *prev;
-#ifdef CONFIG_MESH
- unsigned int mesh_if_created = wpa_s->mesh_if_created;
- char *ifname = NULL;
- struct wpa_supplicant *parent = wpa_s->parent;
-#endif /* CONFIG_MESH */
-
- /* Remove interface from the global list of interfaces */
- prev = global->ifaces;
- if (prev == wpa_s) {
- global->ifaces = wpa_s->next;
- } else {
- while (prev && prev->next != wpa_s)
- prev = prev->next;
- if (prev == NULL)
- return -1;
- prev->next = wpa_s->next;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
-
-#ifdef CONFIG_MESH
- if (mesh_if_created) {
- ifname = os_strdup(wpa_s->ifname);
- if (ifname == NULL) {
- wpa_dbg(wpa_s, MSG_ERROR,
- "mesh: Failed to malloc ifname");
- return -1;
- }
- }
-#endif /* CONFIG_MESH */
-
- if (global->p2p_group_formation == wpa_s)
- global->p2p_group_formation = NULL;
- if (global->p2p_invite_group == wpa_s)
- global->p2p_invite_group = NULL;
- wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
-
-#ifdef CONFIG_MESH
- if (mesh_if_created) {
- wpa_drv_if_remove(parent, WPA_IF_MESH, ifname);
- os_free(ifname);
- }
-#endif /* CONFIG_MESH */
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_get_eap_mode - Get the current EAP mode
- * @wpa_s: Pointer to the network interface
- * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
- */
-const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
-{
- const char *eapol_method;
-
- if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- return "NO-EAP";
- }
-
- eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
- if (eapol_method == NULL)
- return "UNKNOWN-EAP";
-
- return eapol_method;
-}
-
-
-/**
- * wpa_supplicant_get_iface - Get a new network interface
- * @global: Pointer to global data from wpa_supplicant_init()
- * @ifname: Interface name
- * Returns: Pointer to the interface or %NULL if not found
- */
-struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
- const char *ifname)
-{
- struct wpa_supplicant *wpa_s;
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (os_strcmp(wpa_s->ifname, ifname) == 0)
- return wpa_s;
- }
- return NULL;
-}
-
-
-#ifndef CONFIG_NO_WPA_MSG
-static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s == NULL)
- return NULL;
- return wpa_s->ifname;
-}
-#endif /* CONFIG_NO_WPA_MSG */
-
-
-#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
-#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
-#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
-
-/* Periodic cleanup tasks */
-static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_global *global = eloop_ctx;
- struct wpa_supplicant *wpa_s;
-
- eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
- wpas_periodic, global, NULL);
-
-#ifdef CONFIG_P2P
- if (global->p2p)
- p2p_expire_peers(global->p2p);
-#endif /* CONFIG_P2P */
-
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
-#ifdef CONFIG_AP
- ap_periodic(wpa_s);
-#endif /* CONFIG_AP */
- }
-}
-
-
-/**
- * wpa_supplicant_init - Initialize %wpa_supplicant
- * @params: Parameters for %wpa_supplicant
- * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
- *
- * This function is used to initialize %wpa_supplicant. After successful
- * initialization, the returned data pointer can be used to add and remove
- * network interfaces, and eventually, to deinitialize %wpa_supplicant.
- */
-struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
-{
- struct wpa_global *global;
- int ret, i;
-
- if (params == NULL)
- return NULL;
-
-#ifdef CONFIG_DRIVER_NDIS
- {
- void driver_ndis_init_ops(void);
- driver_ndis_init_ops();
- }
-#endif /* CONFIG_DRIVER_NDIS */
-
-#ifndef CONFIG_NO_WPA_MSG
- wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
-#endif /* CONFIG_NO_WPA_MSG */
-
- if (params->wpa_debug_file_path)
- wpa_debug_open_file(params->wpa_debug_file_path);
- if (!params->wpa_debug_file_path && !params->wpa_debug_syslog)
- wpa_debug_setup_stdout();
- if (params->wpa_debug_syslog)
- wpa_debug_open_syslog();
- if (params->wpa_debug_tracing) {
- ret = wpa_debug_open_linux_tracing();
- if (ret) {
- wpa_printf(MSG_ERROR,
- "Failed to enable trace logging");
- return NULL;
- }
- }
-
- ret = eap_register_methods();
- if (ret) {
- wpa_printf(MSG_ERROR, "Failed to register EAP methods");
- if (ret == -2)
- wpa_printf(MSG_ERROR, "Two or more EAP methods used "
- "the same EAP type.");
- return NULL;
- }
-
- global = os_zalloc(sizeof(*global));
- if (global == NULL)
- return NULL;
- dl_list_init(&global->p2p_srv_bonjour);
- dl_list_init(&global->p2p_srv_upnp);
- global->params.daemonize = params->daemonize;
- global->params.wait_for_monitor = params->wait_for_monitor;
- global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
- if (params->pid_file)
- global->params.pid_file = os_strdup(params->pid_file);
- if (params->ctrl_interface)
- global->params.ctrl_interface =
- os_strdup(params->ctrl_interface);
- if (params->ctrl_interface_group)
- global->params.ctrl_interface_group =
- os_strdup(params->ctrl_interface_group);
- if (params->override_driver)
- global->params.override_driver =
- os_strdup(params->override_driver);
- if (params->override_ctrl_interface)
- global->params.override_ctrl_interface =
- os_strdup(params->override_ctrl_interface);
-#ifdef CONFIG_MATCH_IFACE
- global->params.match_iface_count = params->match_iface_count;
- if (params->match_iface_count) {
- global->params.match_ifaces =
- os_calloc(params->match_iface_count,
- sizeof(struct wpa_interface));
- os_memcpy(global->params.match_ifaces,
- params->match_ifaces,
- params->match_iface_count *
- sizeof(struct wpa_interface));
- }
-#endif /* CONFIG_MATCH_IFACE */
-#ifdef CONFIG_P2P
- if (params->conf_p2p_dev)
- global->params.conf_p2p_dev =
- os_strdup(params->conf_p2p_dev);
-#endif /* CONFIG_P2P */
- wpa_debug_level = global->params.wpa_debug_level =
- params->wpa_debug_level;
- wpa_debug_show_keys = global->params.wpa_debug_show_keys =
- params->wpa_debug_show_keys;
- wpa_debug_timestamp = global->params.wpa_debug_timestamp =
- params->wpa_debug_timestamp;
-
- wpa_printf(MSG_DEBUG, "wpa_supplicant v%s", VERSION_STR);
-
- if (eloop_init()) {
- wpa_printf(MSG_ERROR, "Failed to initialize event loop");
- wpa_supplicant_deinit(global);
- return NULL;
- }
-
- random_init(params->entropy_file);
-
- global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
- if (global->ctrl_iface == NULL) {
- wpa_supplicant_deinit(global);
- return NULL;
- }
-
- if (wpas_notify_supplicant_initialized(global)) {
- wpa_supplicant_deinit(global);
- return NULL;
- }
-
- for (i = 0; wpa_drivers[i]; i++)
- global->drv_count++;
- if (global->drv_count == 0) {
- wpa_printf(MSG_ERROR, "No drivers enabled");
- wpa_supplicant_deinit(global);
- return NULL;
- }
- global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
- if (global->drv_priv == NULL) {
- wpa_supplicant_deinit(global);
- return NULL;
- }
-
-#ifdef CONFIG_WIFI_DISPLAY
- if (wifi_display_init(global) < 0) {
- wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
- wpa_supplicant_deinit(global);
- return NULL;
- }
-#endif /* CONFIG_WIFI_DISPLAY */
-
- eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
- wpas_periodic, global, NULL);
-
- return global;
-}
-
-
-/**
- * wpa_supplicant_run - Run the %wpa_supplicant main event loop
- * @global: Pointer to global data from wpa_supplicant_init()
- * Returns: 0 after successful event loop run, -1 on failure
- *
- * This function starts the main event loop and continues running as long as
- * there are any remaining events. In most cases, this function is running as
- * long as the %wpa_supplicant process in still in use.
- */
-int wpa_supplicant_run(struct wpa_global *global)
-{
- struct wpa_supplicant *wpa_s;
-
- if (global->params.daemonize &&
- (wpa_supplicant_daemon(global->params.pid_file) ||
- eloop_sock_requeue()))
- return -1;
-
-#ifdef CONFIG_MATCH_IFACE
- if (wpa_supplicant_match_existing(global))
- return -1;
-#endif
-
- if (global->params.wait_for_monitor) {
- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
- if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
- wpa_supplicant_ctrl_iface_wait(
- wpa_s->ctrl_iface);
- }
-
- eloop_register_signal_terminate(wpa_supplicant_terminate, global);
- eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
-
- eloop_run();
-
- return 0;
-}
-
-
-/**
- * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
- * @global: Pointer to global data from wpa_supplicant_init()
- *
- * This function is called to deinitialize %wpa_supplicant and to free all
- * allocated resources. Remaining network interfaces will also be removed.
- */
-void wpa_supplicant_deinit(struct wpa_global *global)
-{
- int i;
-
- if (global == NULL)
- return;
-
- eloop_cancel_timeout(wpas_periodic, global, NULL);
-
-#ifdef CONFIG_WIFI_DISPLAY
- wifi_display_deinit(global);
-#endif /* CONFIG_WIFI_DISPLAY */
-
- while (global->ifaces)
- wpa_supplicant_remove_iface(global, global->ifaces, 1);
-
- if (global->ctrl_iface)
- wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
-
- wpas_notify_supplicant_deinitialized(global);
-
- eap_peer_unregister_methods();
-#ifdef CONFIG_AP
- eap_server_unregister_methods();
-#endif /* CONFIG_AP */
-
- for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
- if (!global->drv_priv[i])
- continue;
- wpa_drivers[i]->global_deinit(global->drv_priv[i]);
- }
- os_free(global->drv_priv);
-
- random_deinit();
-
- eloop_destroy();
-
- if (global->params.pid_file) {
- os_daemonize_terminate(global->params.pid_file);
- os_free(global->params.pid_file);
- }
- os_free(global->params.ctrl_interface);
- os_free(global->params.ctrl_interface_group);
- os_free(global->params.override_driver);
- os_free(global->params.override_ctrl_interface);
-#ifdef CONFIG_MATCH_IFACE
- os_free(global->params.match_ifaces);
-#endif /* CONFIG_MATCH_IFACE */
-#ifdef CONFIG_P2P
- os_free(global->params.conf_p2p_dev);
-#endif /* CONFIG_P2P */
-
- os_free(global->p2p_disallow_freq.range);
- os_free(global->p2p_go_avoid_freq.range);
- os_free(global->add_psk);
-
- os_free(global);
- wpa_debug_close_syslog();
- wpa_debug_close_file();
- wpa_debug_close_linux_tracing();
-}
-
-
-void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
-{
- if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
- wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
- char country[3];
- country[0] = wpa_s->conf->country[0];
- country[1] = wpa_s->conf->country[1];
- country[2] = '\0';
- if (wpa_drv_set_country(wpa_s, country) < 0) {
- wpa_printf(MSG_ERROR, "Failed to set country code "
- "'%s'", country);
- }
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
- wpas_init_ext_pw(wpa_s);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
- wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_WOWLAN_TRIGGERS) {
- struct wpa_driver_capa capa;
- int res = wpa_drv_get_capa(wpa_s, &capa);
-
- if (res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
- wpa_printf(MSG_ERROR,
- "Failed to update wowlan_triggers to '%s'",
- wpa_s->conf->wowlan_triggers);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_DISABLE_BTM)
- wpa_supplicant_set_default_scan_ies(wpa_s);
-
-#ifdef CONFIG_BGSCAN
- /*
- * We default to global bgscan parameters only when per-network bgscan
- * parameters aren't set. Only bother resetting bgscan parameters if
- * this is the case.
- */
- if ((wpa_s->conf->changed_parameters & CFG_CHANGED_BGSCAN) &&
- wpa_s->current_ssid && !wpa_s->current_ssid->bgscan &&
- wpa_s->wpa_state == WPA_COMPLETED)
- wpa_supplicant_reset_bgscan(wpa_s);
-#endif /* CONFIG_BGSCAN */
-
-#ifdef CONFIG_WPS
- wpas_wps_update_config(wpa_s);
-#endif /* CONFIG_WPS */
- wpas_p2p_update_config(wpa_s);
- wpa_s->conf->changed_parameters = 0;
-}
-
-
-void add_freq(int *freqs, int *num_freqs, int freq)
-{
- int i;
-
- for (i = 0; i < *num_freqs; i++) {
- if (freqs[i] == freq)
- return;
- }
-
- freqs[*num_freqs] = freq;
- (*num_freqs)++;
-}
-
-
-static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss, *cbss;
- const int max_freqs = 10;
- int *freqs;
- int num_freqs = 0;
-
- freqs = os_calloc(max_freqs + 1, sizeof(int));
- if (freqs == NULL)
- return NULL;
-
- cbss = wpa_s->current_bss;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (bss == cbss)
- continue;
- if (bss->ssid_len == cbss->ssid_len &&
- os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
- !wpa_bssid_ignore_is_listed(wpa_s, bss->bssid)) {
- add_freq(freqs, &num_freqs, bss->freq);
- if (num_freqs == max_freqs)
- break;
- }
- }
-
- if (num_freqs == 0) {
- os_free(freqs);
- freqs = NULL;
- }
-
- return freqs;
-}
-
-
-void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- int timeout;
- int count;
- int *freqs = NULL;
-
- wpas_connect_work_done(wpa_s);
-
- /*
- * Remove possible authentication timeout since the connection failed.
- */
- eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
-
- /*
- * There is no point in ignoring the AP temporarily if this event is
- * generated based on local request to disconnect.
- */
- if (wpa_s->own_disconnect_req || wpa_s->own_reconnect_req) {
- wpa_s->own_disconnect_req = 0;
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Ignore connection failure due to local request to disconnect");
- return;
- }
- if (wpa_s->disconnected) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
- "indication since interface has been put into "
- "disconnected state");
- return;
- }
-
- /*
- * Add the failed BSSID into the ignore list and speed up next scan
- * attempt if there could be other APs that could accept association.
- */
- count = wpa_bssid_ignore_add(wpa_s, bssid);
- if (count == 1 && wpa_s->current_bss) {
- /*
- * This BSS was not in the ignore list before. If there is
- * another BSS available for the same ESS, we should try that
- * next. Otherwise, we may as well try this one once more
- * before allowing other, likely worse, ESSes to be considered.
- */
- freqs = get_bss_freqs_in_ess(wpa_s);
- if (freqs) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
- "has been seen; try it next");
- wpa_bssid_ignore_add(wpa_s, bssid);
- /*
- * On the next scan, go through only the known channels
- * used in this ESS based on previous scans to speed up
- * common load balancing use case.
- */
- os_free(wpa_s->next_scan_freqs);
- wpa_s->next_scan_freqs = freqs;
- }
- }
-
- wpa_s->consecutive_conn_failures++;
-
- if (wpa_s->consecutive_conn_failures > 3 && wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG, "Continuous association failures - "
- "consider temporary network disabling");
- wpas_auth_failed(wpa_s, "CONN_FAILED");
- }
- /*
- * Multiple consecutive connection failures mean that other APs are
- * either not available or have already been tried, so we can start
- * increasing the delay here to avoid constant scanning.
- */
- switch (wpa_s->consecutive_conn_failures) {
- case 1:
- timeout = 100;
- break;
- case 2:
- timeout = 500;
- break;
- case 3:
- timeout = 1000;
- break;
- case 4:
- timeout = 5000;
- break;
- default:
- timeout = 10000;
- break;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Consecutive connection failures: %d --> request scan in %d ms",
- wpa_s->consecutive_conn_failures, timeout);
-
- /*
- * TODO: if more than one possible AP is available in scan results,
- * could try the other ones before requesting a new scan.
- */
-
- /* speed up the connection attempt with normal scan */
- wpa_s->normal_scans = 0;
- wpa_supplicant_req_scan(wpa_s, timeout / 1000,
- 1000 * (timeout % 1000));
-}
-
-
-#ifdef CONFIG_FILS
-
-void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- const u8 *realm, *username, *rrk;
- size_t realm_len, username_len, rrk_len;
- u16 next_seq_num;
-
- /* Clear the PMKSA cache entry if FILS authentication was rejected.
- * Check for ERP keys existing to limit when this can be done since
- * the rejection response is not protected and such triggers should
- * really not allow internal state to be modified unless required to
- * avoid significant issues in functionality. In addition, drop
- * externally configure PMKSA entries even without ERP keys since it
- * is possible for an external component to add PMKSA entries for FILS
- * authentication without restoring previously generated ERP keys.
- *
- * In this case, this is needed to allow recovery from cases where the
- * AP or authentication server has dropped PMKSAs and ERP keys. */
- if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt))
- return;
-
- if (eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
- &username, &username_len,
- &realm, &realm_len, &next_seq_num,
- &rrk, &rrk_len) != 0 ||
- !realm) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "FILS: Drop external PMKSA cache entry");
- wpa_sm_aborted_external_cached(wpa_s->wpa);
- wpa_sm_external_pmksa_cache_flush(wpa_s->wpa, ssid);
- return;
- }
-
- wpa_dbg(wpa_s, MSG_DEBUG, "FILS: Drop PMKSA cache entry");
- wpa_sm_aborted_cached(wpa_s->wpa);
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
-}
-
-
-void fils_connection_failure(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- const u8 *realm, *username, *rrk;
- size_t realm_len, username_len, rrk_len;
- u16 next_seq_num;
-
- if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt) ||
- eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
- &username, &username_len,
- &realm, &realm_len, &next_seq_num,
- &rrk, &rrk_len) != 0 ||
- !realm)
- return;
-
- wpa_hexdump_ascii(MSG_DEBUG,
- "FILS: Store last connection failure realm",
- realm, realm_len);
- os_free(wpa_s->last_con_fail_realm);
- wpa_s->last_con_fail_realm = os_malloc(realm_len);
- if (wpa_s->last_con_fail_realm) {
- wpa_s->last_con_fail_realm_len = realm_len;
- os_memcpy(wpa_s->last_con_fail_realm, realm, realm_len);
- }
-}
-#endif /* CONFIG_FILS */
-
-
-int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
-{
- return wpa_s->conf->ap_scan == 2 ||
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
-}
-
-
-#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
-int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const char *field,
- const char *value)
-{
-#ifdef IEEE8021X_EAPOL
- struct eap_peer_config *eap = &ssid->eap;
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
- wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
- (const u8 *) value, os_strlen(value));
-
- switch (wpa_supplicant_ctrl_req_from_string(field)) {
- case WPA_CTRL_REQ_EAP_IDENTITY:
- os_free(eap->identity);
- eap->identity = (u8 *) os_strdup(value);
- eap->identity_len = os_strlen(value);
- eap->pending_req_identity = 0;
- if (ssid == wpa_s->current_ssid)
- wpa_s->reassociate = 1;
- break;
- case WPA_CTRL_REQ_EAP_PASSWORD:
- bin_clear_free(eap->password, eap->password_len);
- eap->password = (u8 *) os_strdup(value);
- eap->password_len = os_strlen(value);
- eap->pending_req_password = 0;
- if (ssid == wpa_s->current_ssid)
- wpa_s->reassociate = 1;
- break;
- case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
- bin_clear_free(eap->new_password, eap->new_password_len);
- eap->new_password = (u8 *) os_strdup(value);
- eap->new_password_len = os_strlen(value);
- eap->pending_req_new_password = 0;
- if (ssid == wpa_s->current_ssid)
- wpa_s->reassociate = 1;
- break;
- case WPA_CTRL_REQ_EAP_PIN:
- str_clear_free(eap->cert.pin);
- eap->cert.pin = os_strdup(value);
- eap->pending_req_pin = 0;
- if (ssid == wpa_s->current_ssid)
- wpa_s->reassociate = 1;
- break;
- case WPA_CTRL_REQ_EAP_OTP:
- bin_clear_free(eap->otp, eap->otp_len);
- eap->otp = (u8 *) os_strdup(value);
- eap->otp_len = os_strlen(value);
- os_free(eap->pending_req_otp);
- eap->pending_req_otp = NULL;
- eap->pending_req_otp_len = 0;
- break;
- case WPA_CTRL_REQ_EAP_PASSPHRASE:
- str_clear_free(eap->cert.private_key_passwd);
- eap->cert.private_key_passwd = os_strdup(value);
- eap->pending_req_passphrase = 0;
- if (ssid == wpa_s->current_ssid)
- wpa_s->reassociate = 1;
- break;
- case WPA_CTRL_REQ_SIM:
- str_clear_free(eap->external_sim_resp);
- eap->external_sim_resp = os_strdup(value);
- eap->pending_req_sim = 0;
- break;
- case WPA_CTRL_REQ_PSK_PASSPHRASE:
- if (wpa_config_set(ssid, "psk", value, 0) < 0)
- return -1;
- ssid->mem_only_psk = 1;
- if (ssid->passphrase)
- wpa_config_update_psk(ssid);
- if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- break;
- case WPA_CTRL_REQ_EXT_CERT_CHECK:
- if (eap->pending_ext_cert_check != PENDING_CHECK)
- return -1;
- if (os_strcmp(value, "good") == 0)
- eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
- else if (os_strcmp(value, "bad") == 0)
- eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
- else
- return -1;
- break;
- default:
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
- return -1;
- }
-
- return 0;
-#else /* IEEE8021X_EAPOL */
- wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
- return -1;
-#endif /* IEEE8021X_EAPOL */
-}
-#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
-
-
-int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-#ifdef CONFIG_WEP
- int i;
- unsigned int drv_enc;
-#endif /* CONFIG_WEP */
-
- if (wpa_s->p2p_mgmt)
- return 1; /* no normal network profiles on p2p_mgmt interface */
-
- if (ssid == NULL)
- return 1;
-
- if (ssid->disabled)
- return 1;
-
-#ifdef CONFIG_WEP
- if (wpa_s->drv_capa_known)
- drv_enc = wpa_s->drv_enc;
- else
- drv_enc = (unsigned int) -1;
-
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- size_t len = ssid->wep_key_len[i];
- if (len == 0)
- continue;
- if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
- continue;
- if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
- continue;
- if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
- continue;
- return 1; /* invalid WEP key */
- }
-#endif /* CONFIG_WEP */
-
- if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
- (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
- !(wpa_key_mgmt_sae(ssid->key_mgmt) && ssid->sae_password) &&
- !ssid->mem_only_psk)
- return 1;
-
- return 0;
-}
-
-
-int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
- if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
- !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
- /*
- * Driver does not support BIP -- ignore pmf=1 default
- * since the connection with PMF would fail and the
- * configuration does not require PMF to be enabled.
- */
- return NO_MGMT_FRAME_PROTECTION;
- }
-
- if (ssid &&
- (ssid->key_mgmt &
- ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
- WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
- /*
- * Do not use the default PMF value for non-RSN networks
- * since PMF is available only with RSN and pmf=2
- * configuration would otherwise prevent connections to
- * all open networks.
- */
- return NO_MGMT_FRAME_PROTECTION;
- }
-
- return wpa_s->conf->pmf;
- }
-
- return ssid->ieee80211w;
-}
-
-
-int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
- if (wpa_s->current_ssid == NULL ||
- wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
- os_memcmp(addr, wpa_s->bssid, ETH_ALEN) != 0)
- return 0;
- return wpa_sm_pmf_enabled(wpa_s->wpa);
-}
-
-
-int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
-{
- if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
- return 1;
- if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
- return 0;
- return -1;
-}
-
-
-void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
-{
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int dur;
- struct os_reltime now;
-
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "Authentication failure but no known "
- "SSID block");
- return;
- }
-
- if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
- return;
-
- ssid->auth_failures++;
-
-#ifdef CONFIG_P2P
- if (ssid->p2p_group &&
- (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
- /*
- * Skip the wait time since there is a short timeout on the
- * connection to a P2P group.
- */
- return;
- }
-#endif /* CONFIG_P2P */
-
- if (ssid->auth_failures > 50)
- dur = 300;
- else if (ssid->auth_failures > 10)
- dur = 120;
- else if (ssid->auth_failures > 5)
- dur = 90;
- else if (ssid->auth_failures > 3)
- dur = 60;
- else if (ssid->auth_failures > 2)
- dur = 30;
- else if (ssid->auth_failures > 1)
- dur = 20;
- else
- dur = 10;
-
- if (ssid->auth_failures > 1 &&
- wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
- dur += os_random() % (ssid->auth_failures * 10);
-
- os_get_reltime(&now);
- if (now.sec + dur <= ssid->disabled_until.sec)
- return;
-
- ssid->disabled_until.sec = now.sec + dur;
-
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
- "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
- ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
- ssid->auth_failures, dur, reason);
-}
-
-
-void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int clear_failures)
-{
- if (ssid == NULL)
- return;
-
- if (ssid->disabled_until.sec) {
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
- "id=%d ssid=\"%s\"",
- ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
- }
- ssid->disabled_until.sec = 0;
- ssid->disabled_until.usec = 0;
- if (clear_failures)
- ssid->auth_failures = 0;
-}
-
-
-int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- size_t i;
-
- if (wpa_s->disallow_aps_bssid == NULL)
- return 0;
-
- for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
- if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
- bssid, ETH_ALEN) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
- size_t ssid_len)
-{
- size_t i;
-
- if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
- return 0;
-
- for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
- struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
- if (ssid_len == s->ssid_len &&
- os_memcmp(ssid, s->ssid, ssid_len) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-/**
- * wpas_request_connection - Request a new connection
- * @wpa_s: Pointer to the network interface
- *
- * This function is used to request a new connection to be found. It will mark
- * the interface to allow reassociation and request a new scan to find a
- * suitable network to connect to.
- */
-void wpas_request_connection(struct wpa_supplicant *wpa_s)
-{
- wpa_s->normal_scans = 0;
- wpa_s->scan_req = NORMAL_SCAN_REQ;
- wpa_supplicant_reinit_autoscan(wpa_s);
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- wpa_s->last_owe_group = 0;
-
- if (wpa_supplicant_fast_associate(wpa_s) != 1)
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- else
- wpa_s->reattach = 0;
-}
-
-
-/**
- * wpas_request_disconnection - Request disconnection
- * @wpa_s: Pointer to the network interface
- *
- * This function is used to request disconnection from the currently connected
- * network. This will stop any ongoing scans and initiate deauthentication.
- */
-void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- wpa_s->reassociate = 0;
- wpa_s->disconnected = 1;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
- radio_remove_works(wpa_s, "connect", 0);
- radio_remove_works(wpa_s, "sme-connect", 0);
-}
-
-
-void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
- struct wpa_used_freq_data *freqs_data,
- unsigned int len)
-{
- unsigned int i;
-
- wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
- len, title);
- for (i = 0; i < len; i++) {
- struct wpa_used_freq_data *cur = &freqs_data[i];
- wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
- i, cur->freq, cur->flags);
- }
-}
-
-
-/*
- * Find the operating frequencies of any of the virtual interfaces that
- * are using the same radio as the current interface, and in addition, get
- * information about the interface types that are using the frequency.
- */
-int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs_data,
- unsigned int len)
-{
- struct wpa_supplicant *ifs;
- u8 bssid[ETH_ALEN];
- int freq;
- unsigned int idx = 0, i;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "Determining shared radio frequencies (max len %u)", len);
- os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
-
- dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
- radio_list) {
- if (idx == len)
- break;
-
- if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
- continue;
-
- if (ifs->current_ssid->mode == WPAS_MODE_AP ||
- ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
- ifs->current_ssid->mode == WPAS_MODE_MESH)
- freq = ifs->current_ssid->frequency;
- else if (wpa_drv_get_bssid(ifs, bssid) == 0)
- freq = ifs->assoc_freq;
- else
- continue;
-
- /* Hold only distinct freqs */
- for (i = 0; i < idx; i++)
- if (freqs_data[i].freq == freq)
- break;
-
- if (i == idx)
- freqs_data[idx++].freq = freq;
-
- if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
- freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
- WPA_FREQ_USED_BY_P2P_CLIENT :
- WPA_FREQ_USED_BY_INFRA_STATION;
- }
- }
-
- dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
- return idx;
-}
-
-
-/*
- * Find the operating frequencies of any of the virtual interfaces that
- * are using the same radio as the current interface.
- */
-int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
- int *freq_array, unsigned int len)
-{
- struct wpa_used_freq_data *freqs_data;
- int num, i;
-
- os_memset(freq_array, 0, sizeof(int) * len);
-
- freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
- if (!freqs_data)
- return -1;
-
- num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
- for (i = 0; i < num; i++)
- freq_array[i] = freqs_data[i].freq;
-
- os_free(freqs_data);
-
- return num;
-}
-
-
-struct wpa_supplicant *
-wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
-{
- switch (frame) {
-#ifdef CONFIG_P2P
- case VENDOR_ELEM_PROBE_REQ_P2P:
- case VENDOR_ELEM_PROBE_RESP_P2P:
- case VENDOR_ELEM_PROBE_RESP_P2P_GO:
- case VENDOR_ELEM_BEACON_P2P_GO:
- case VENDOR_ELEM_P2P_PD_REQ:
- case VENDOR_ELEM_P2P_PD_RESP:
- case VENDOR_ELEM_P2P_GO_NEG_REQ:
- case VENDOR_ELEM_P2P_GO_NEG_RESP:
- case VENDOR_ELEM_P2P_GO_NEG_CONF:
- case VENDOR_ELEM_P2P_INV_REQ:
- case VENDOR_ELEM_P2P_INV_RESP:
- case VENDOR_ELEM_P2P_ASSOC_REQ:
- case VENDOR_ELEM_P2P_ASSOC_RESP:
- return wpa_s->p2pdev;
-#endif /* CONFIG_P2P */
- default:
- return wpa_s;
- }
-}
-
-
-void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
-{
- unsigned int i;
- char buf[30];
-
- wpa_printf(MSG_DEBUG, "Update vendor elements");
-
- for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
- if (wpa_s->vendor_elem[i]) {
- int res;
-
- res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
- if (!os_snprintf_error(sizeof(buf), res)) {
- wpa_hexdump_buf(MSG_DEBUG, buf,
- wpa_s->vendor_elem[i]);
- }
- }
- }
-
-#ifdef CONFIG_P2P
- if (wpa_s->parent == wpa_s &&
- wpa_s->global->p2p &&
- !wpa_s->global->p2p_disabled)
- p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
-#endif /* CONFIG_P2P */
-}
-
-
-int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
- const u8 *elem, size_t len)
-{
- u8 *ie, *end;
-
- ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
- end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
-
- for (; ie + 1 < end; ie += 2 + ie[1]) {
- if (ie + len > end)
- break;
- if (os_memcmp(ie, elem, len) != 0)
- continue;
-
- if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
- wpabuf_free(wpa_s->vendor_elem[frame]);
- wpa_s->vendor_elem[frame] = NULL;
- } else {
- os_memmove(ie, ie + len, end - (ie + len));
- wpa_s->vendor_elem[frame]->used -= len;
- }
- wpas_vendor_elem_update(wpa_s);
- return 0;
- }
-
- return -1;
-}
-
-
-struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
- u16 num_modes, enum hostapd_hw_mode mode,
- bool is_6ghz)
-{
- u16 i;
-
- if (!modes)
- return NULL;
-
- for (i = 0; i < num_modes; i++) {
- if (modes[i].mode != mode ||
- !modes[i].num_channels || !modes[i].channels)
- continue;
- if ((!is_6ghz && !is_6ghz_freq(modes[i].channels[0].freq)) ||
- (is_6ghz && is_6ghz_freq(modes[i].channels[0].freq)))
- return &modes[i];
- }
-
- return NULL;
-}
-
-
-struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes,
- u16 num_modes, int freq)
-{
- int i, j;
-
- for (i = 0; i < num_modes; i++) {
- for (j = 0; j < modes[i].num_channels; j++) {
- if (freq == modes[i].channels[j].freq)
- return &modes[i];
- }
- }
-
- return NULL;
-}
-
-
-static struct
-wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- struct wpa_bss_tmp_disallowed *bss;
-
- dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
- struct wpa_bss_tmp_disallowed, list) {
- if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
- return bss;
- }
-
- return NULL;
-}
-
-
-static int wpa_set_driver_tmp_disallow_list(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss_tmp_disallowed *tmp;
- unsigned int num_bssid = 0;
- u8 *bssids;
- int ret;
-
- bssids = os_malloc(dl_list_len(&wpa_s->bss_tmp_disallowed) * ETH_ALEN);
- if (!bssids)
- return -1;
- dl_list_for_each(tmp, &wpa_s->bss_tmp_disallowed,
- struct wpa_bss_tmp_disallowed, list) {
- os_memcpy(&bssids[num_bssid * ETH_ALEN], tmp->bssid,
- ETH_ALEN);
- num_bssid++;
- }
- ret = wpa_drv_set_bssid_tmp_disallow(wpa_s, num_bssid, bssids);
- os_free(bssids);
- return ret;
-}
-
-
-static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- struct wpa_bss_tmp_disallowed *tmp, *bss = timeout_ctx;
-
- /* Make sure the bss is not already freed */
- dl_list_for_each(tmp, &wpa_s->bss_tmp_disallowed,
- struct wpa_bss_tmp_disallowed, list) {
- if (bss == tmp) {
- remove_bss_tmp_disallowed_entry(wpa_s, tmp);
- wpa_set_driver_tmp_disallow_list(wpa_s);
- break;
- }
- }
-}
-
-
-void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
- unsigned int sec, int rssi_threshold)
-{
- struct wpa_bss_tmp_disallowed *bss;
-
- bss = wpas_get_disallowed_bss(wpa_s, bssid);
- if (bss) {
- eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss);
- goto finish;
- }
-
- bss = os_malloc(sizeof(*bss));
- if (!bss) {
- wpa_printf(MSG_DEBUG,
- "Failed to allocate memory for temp disallow BSS");
- return;
- }
-
- os_memcpy(bss->bssid, bssid, ETH_ALEN);
- dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
- wpa_set_driver_tmp_disallow_list(wpa_s);
-
-finish:
- bss->rssi_threshold = rssi_threshold;
- eloop_register_timeout(sec, 0, wpa_bss_tmp_disallow_timeout,
- wpa_s, bss);
-}
-
-
-int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
-{
- struct wpa_bss_tmp_disallowed *disallowed = NULL, *tmp, *prev;
-
- dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
- struct wpa_bss_tmp_disallowed, list) {
- if (os_memcmp(bss->bssid, tmp->bssid, ETH_ALEN) == 0) {
- disallowed = tmp;
- break;
- }
- }
- if (!disallowed)
- return 0;
-
- if (disallowed->rssi_threshold != 0 &&
- bss->level > disallowed->rssi_threshold) {
- remove_bss_tmp_disallowed_entry(wpa_s, disallowed);
- wpa_set_driver_tmp_disallow_list(wpa_s);
- return 0;
- }
-
- return 1;
-}
-
-
-int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
- unsigned int type, const u8 *addr,
- const u8 *mask)
-{
- if ((addr && !mask) || (!addr && mask)) {
- wpa_printf(MSG_INFO,
- "MAC_ADDR_RAND_SCAN invalid addr/mask combination");
- return -1;
- }
-
- if (addr && mask && (!(mask[0] & 0x01) || (addr[0] & 0x01))) {
- wpa_printf(MSG_INFO,
- "MAC_ADDR_RAND_SCAN cannot allow multicast address");
- return -1;
- }
-
- if (type & MAC_ADDR_RAND_SCAN) {
- if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN,
- addr, mask))
- return -1;
- }
-
- if (type & MAC_ADDR_RAND_SCHED_SCAN) {
- if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN,
- addr, mask))
- return -1;
-
- if (wpa_s->sched_scanning && !wpa_s->pno)
- wpas_scan_restart_sched_scan(wpa_s);
- }
-
- if (type & MAC_ADDR_RAND_PNO) {
- if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO,
- addr, mask))
- return -1;
-
- if (wpa_s->pno) {
- wpas_stop_pno(wpa_s);
- wpas_start_pno(wpa_s);
- }
- }
-
- return 0;
-}
-
-
-int wpas_disable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
- unsigned int type)
-{
- wpas_mac_addr_rand_scan_clear(wpa_s, type);
- if (wpa_s->pno) {
- if (type & MAC_ADDR_RAND_PNO) {
- wpas_stop_pno(wpa_s);
- wpas_start_pno(wpa_s);
- }
- } else if (wpa_s->sched_scanning && (type & MAC_ADDR_RAND_SCHED_SCAN)) {
- wpas_scan_restart_sched_scan(wpa_s);
- }
-
- return 0;
-}
-
-
-int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
- struct wpa_signal_info *si)
-{
- int res;
-
- if (!wpa_s->driver->signal_poll)
- return -1;
-
- res = wpa_s->driver->signal_poll(wpa_s->drv_priv, si);
-
-#ifdef CONFIG_TESTING_OPTIONS
- if (res == 0) {
- struct driver_signal_override *dso;
-
- dl_list_for_each(dso, &wpa_s->drv_signal_override,
- struct driver_signal_override, list) {
- if (os_memcmp(wpa_s->bssid, dso->bssid,
- ETH_ALEN) != 0)
- continue;
- wpa_printf(MSG_DEBUG,
- "Override driver signal_poll information: current_signal: %d->%d avg_signal: %d->%d avg_beacon_signal: %d->%d current_noise: %d->%d",
- si->current_signal,
- dso->si_current_signal,
- si->avg_signal,
- dso->si_avg_signal,
- si->avg_beacon_signal,
- dso->si_avg_beacon_signal,
- si->current_noise,
- dso->si_current_noise);
- si->current_signal = dso->si_current_signal;
- si->avg_signal = dso->si_avg_signal;
- si->avg_beacon_signal = dso->si_avg_beacon_signal;
- si->current_noise = dso->si_current_noise;
- break;
- }
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- return res;
-}
-
-
-struct wpa_scan_results *
-wpa_drv_get_scan_results2(struct wpa_supplicant *wpa_s)
-{
- struct wpa_scan_results *scan_res;
-#ifdef CONFIG_TESTING_OPTIONS
- size_t idx;
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (!wpa_s->driver->get_scan_results2)
- return NULL;
-
- scan_res = wpa_s->driver->get_scan_results2(wpa_s->drv_priv);
-
-#ifdef CONFIG_TESTING_OPTIONS
- for (idx = 0; scan_res && idx < scan_res->num; idx++) {
- struct driver_signal_override *dso;
- struct wpa_scan_res *res = scan_res->res[idx];
-
- dl_list_for_each(dso, &wpa_s->drv_signal_override,
- struct driver_signal_override, list) {
- if (os_memcmp(res->bssid, dso->bssid, ETH_ALEN) != 0)
- continue;
- wpa_printf(MSG_DEBUG,
- "Override driver scan signal level %d->%d for "
- MACSTR,
- res->level, dso->scan_level,
- MAC2STR(res->bssid));
- res->flags |= WPA_SCAN_QUAL_INVALID;
- if (dso->scan_level < 0)
- res->flags |= WPA_SCAN_LEVEL_DBM;
- else
- res->flags &= ~WPA_SCAN_LEVEL_DBM;
- res->level = dso->scan_level;
- break;
- }
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- return scan_res;
-}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
deleted file mode 100644
index 6619d6ba7fb1..000000000000
--- a/wpa_supplicant/wpa_supplicant.conf
+++ /dev/null
@@ -1,2071 +0,0 @@
-##### Example wpa_supplicant configuration file ###############################
-#
-# This file describes configuration file format and lists all available option.
-# Please also take a look at simpler configuration examples in 'examples'
-# subdirectory.
-#
-# Empty lines and lines starting with # are ignored
-
-# NOTE! This file may contain password information and should probably be made
-# readable only by root user on multiuser systems.
-
-# Note: All file paths in this configuration file should use full (absolute,
-# not relative to working directory) path in order to allow working directory
-# to be changed. This can happen if wpa_supplicant is run in the background.
-
-# Whether to allow wpa_supplicant to update (overwrite) configuration
-#
-# This option can be used to allow wpa_supplicant to overwrite configuration
-# file whenever configuration is changed (e.g., new network block is added with
-# wpa_cli or wpa_gui, or a password is changed). This is required for
-# wpa_cli/wpa_gui to be able to store the configuration changes permanently.
-# Please note that overwriting configuration file will remove the comments from
-# it.
-#update_config=1
-
-# global configuration (shared by all network blocks)
-#
-# Parameters for the control interface. If this is specified, wpa_supplicant
-# will open a control interface that is available for external programs to
-# manage wpa_supplicant. The meaning of this string depends on which control
-# interface mechanism is used. For all cases, the existence of this parameter
-# in configuration is used to determine whether the control interface is
-# enabled.
-#
-# For UNIX domain sockets (default on Linux and BSD): This is a directory that
-# will be created for UNIX domain sockets for listening to requests from
-# external programs (CLI/GUI, etc.) for status information and configuration.
-# The socket file will be named based on the interface name, so multiple
-# wpa_supplicant processes can be run at the same time if more than one
-# interface is used.
-# /var/run/wpa_supplicant is the recommended directory for sockets and by
-# default, wpa_cli will use it when trying to connect with wpa_supplicant.
-#
-# Access control for the control interface can be configured by setting the
-# directory to allow only members of a group to use sockets. This way, it is
-# possible to run wpa_supplicant as root (since it needs to change network
-# configuration and open raw sockets) and still allow GUI/CLI components to be
-# run as non-root users. However, since the control interface can be used to
-# change the network configuration, this access needs to be protected in many
-# cases. By default, wpa_supplicant is configured to use gid 0 (root). If you
-# want to allow non-root users to use the control interface, add a new group
-# and change this value to match with that group. Add users that should have
-# control interface access to this group. If this variable is commented out or
-# not included in the configuration file, group will not be changed from the
-# value it got by default when the directory or socket was created.
-#
-# When configuring both the directory and group, use following format:
-# DIR=/var/run/wpa_supplicant GROUP=wheel
-# DIR=/var/run/wpa_supplicant GROUP=0
-# (group can be either group name or gid)
-#
-# For UDP connections (default on Windows): The value will be ignored. This
-# variable is just used to select that the control interface is to be created.
-# The value can be set to, e.g., udp (ctrl_interface=udp)
-#
-# For Windows Named Pipe: This value can be used to set the security descriptor
-# for controlling access to the control interface. Security descriptor can be
-# set using Security Descriptor String Format (see http://msdn.microsoft.com/
-# library/default.asp?url=/library/en-us/secauthz/security/
-# security_descriptor_string_format.asp). The descriptor string needs to be
-# prefixed with SDDL=. For example, ctrl_interface=SDDL=D: would set an empty
-# DACL (which will reject all connections). See README-Windows.txt for more
-# information about SDDL string format.
-#
-ctrl_interface=/var/run/wpa_supplicant
-
-# IEEE 802.1X/EAPOL version
-# wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which defines
-# EAPOL version 2. However, there are many APs that do not handle the new
-# version number correctly (they seem to drop the frames completely). In order
-# to make wpa_supplicant interoperate with these APs, the version number is set
-# to 1 by default. This configuration value can be used to set it to the new
-# version (2).
-# Note: When using MACsec, eapol_version shall be set to 3, which is
-# defined in IEEE Std 802.1X-2010.
-eapol_version=1
-
-# AP scanning/selection
-# By default, wpa_supplicant requests driver to perform AP scanning and then
-# uses the scan results to select a suitable AP. Another alternative is to
-# allow the driver to take care of AP scanning and selection and use
-# wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association
-# information from the driver.
-# 1: wpa_supplicant initiates scanning and AP selection; if no APs matching to
-# the currently enabled networks are found, a new network (IBSS or AP mode
-# operation) may be initialized (if configured) (default)
-# 0: This mode must only be used when using wired Ethernet drivers
-# (including MACsec).
-# 2: like 0, but associate with APs using security policy and SSID (but not
-# BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to
-# enable operation with hidden SSIDs and optimized roaming; in this mode,
-# the network blocks in the configuration file are tried one by one until
-# the driver reports successful association; each network block should have
-# explicit security policy (i.e., only one option in the lists) for
-# key_mgmt, pairwise, group, proto variables
-# Note: ap_scan=0/2 should not be used with the nl80211 driver interface (the
-# current Linux interface). ap_scan=1 is the only option working with nl80211.
-# For finding networks using hidden SSID, scan_ssid=1 in the network block can
-# be used with nl80211.
-# When using IBSS or AP mode, ap_scan=2 mode can force the new network to be
-# created immediately regardless of scan results. ap_scan=1 mode will first try
-# to scan for existing networks and only if no matches with the enabled
-# networks are found, a new IBSS or AP mode network is created.
-ap_scan=1
-
-# Whether to force passive scan for network connection
-#
-# By default, scans will send out Probe Request frames on channels that allow
-# active scanning. This advertise the local station to the world. Normally this
-# is fine, but users may wish to do passive scanning where the radio should only
-# listen quietly for Beacon frames and not send any Probe Request frames. Actual
-# functionality may be driver dependent.
-#
-# This parameter can be used to force only passive scanning to be used
-# for network connection cases. It should be noted that this will slow
-# down scan operations and reduce likelihood of finding the AP. In
-# addition, some use cases will override this due to functional
-# requirements, e.g., for finding an AP that uses hidden SSID
-# (scan_ssid=1) or P2P device discovery.
-#
-# 0: Do normal scans (allow active scans) (default)
-# 1: Do passive scans.
-#passive_scan=0
-
-# MPM residency
-# By default, wpa_supplicant implements the mesh peering manager (MPM) for an
-# open mesh. However, if the driver can implement the MPM, you may set this to
-# 0 to use the driver version. When AMPE is enabled, the wpa_supplicant MPM is
-# always used.
-# 0: MPM lives in the driver
-# 1: wpa_supplicant provides an MPM which handles peering (default)
-#user_mpm=1
-
-# Maximum number of peer links (0-255; default: 99)
-# Maximum number of mesh peering currently maintained by the STA.
-#max_peer_links=99
-
-# Timeout in seconds to detect STA inactivity (default: 300 seconds)
-#
-# This timeout value is used in mesh STA to clean up inactive stations.
-#mesh_max_inactivity=300
-
-# Enable 802.11s layer-2 routing and forwarding (dot11MeshForwarding)
-#mesh_fwding=1
-
-# cert_in_cb - Whether to include a peer certificate dump in events
-# This controls whether peer certificates for authentication server and
-# its certificate chain are included in EAP peer certificate events. This is
-# enabled by default.
-#cert_in_cb=1
-
-# EAP fast re-authentication
-# By default, fast re-authentication is enabled for all EAP methods that
-# support it. This variable can be used to disable fast re-authentication.
-# Normally, there is no need to disable this.
-fast_reauth=1
-
-# OpenSSL Engine support
-# These options can be used to load OpenSSL engines in special or legacy
-# modes.
-# The two engines that are supported currently are shown below:
-# They are both from the opensc project (http://www.opensc.org/)
-# By default the PKCS#11 engine is loaded if the client_cert or
-# private_key option appear to be a PKCS#11 URI, and these options
-# should not need to be used explicitly.
-# make the opensc engine available
-#opensc_engine_path=/usr/lib/opensc/engine_opensc.so
-# make the pkcs11 engine available
-#pkcs11_engine_path=/usr/lib/opensc/engine_pkcs11.so
-# configure the path to the pkcs11 module required by the pkcs11 engine
-#pkcs11_module_path=/usr/lib/pkcs11/opensc-pkcs11.so
-
-# OpenSSL cipher string
-#
-# This is an OpenSSL specific configuration option for configuring the default
-# ciphers. If not set, the value configured at build time ("DEFAULT:!EXP:!LOW"
-# by default) is used.
-# See https://www.openssl.org/docs/apps/ciphers.html for OpenSSL documentation
-# on cipher suite configuration. This is applicable only if wpa_supplicant is
-# built to use OpenSSL.
-#openssl_ciphers=DEFAULT:!EXP:!LOW
-
-# Dynamic EAP methods
-# If EAP methods were built dynamically as shared object files, they need to be
-# loaded here before being used in the network blocks. By default, EAP methods
-# are included statically in the build, so these lines are not needed
-#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_tls.so
-#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_md5.so
-
-# Driver interface parameters
-# This field can be used to configure arbitrary driver interface parameters. The
-# format is specific to the selected driver interface. This field is not used
-# in most cases.
-#driver_param="field=value"
-
-# Country code
-# The ISO/IEC alpha2 country code for the country in which this device is
-# currently operating.
-#country=US
-
-# Maximum lifetime for PMKSA in seconds; default 43200
-#dot11RSNAConfigPMKLifetime=43200
-# Threshold for reauthentication (percentage of PMK lifetime); default 70
-#dot11RSNAConfigPMKReauthThreshold=70
-# Timeout for security association negotiation in seconds; default 60
-#dot11RSNAConfigSATimeout=60
-
-# Wi-Fi Protected Setup (WPS) parameters
-
-# Universally Unique IDentifier (UUID; see RFC 4122) of the device
-# If not configured, UUID will be generated based on the mechanism selected with
-# the auto_uuid parameter.
-#uuid=12345678-9abc-def0-1234-56789abcdef0
-
-# Automatic UUID behavior
-# 0 = generate static value based on the local MAC address (default)
-# 1 = generate a random UUID every time wpa_supplicant starts
-#auto_uuid=0
-
-# Device Name
-# User-friendly description of device; up to 32 octets encoded in UTF-8
-#device_name=Wireless Client
-
-# Manufacturer
-# The manufacturer of the device (up to 64 ASCII characters)
-#manufacturer=Company
-
-# Model Name
-# Model of the device (up to 32 ASCII characters)
-#model_name=cmodel
-
-# Model Number
-# Additional device description (up to 32 ASCII characters)
-#model_number=123
-
-# Serial Number
-# Serial number of the device (up to 32 characters)
-#serial_number=12345
-
-# Primary Device Type
-# Used format: <categ>-<OUI>-<subcateg>
-# categ = Category as an integer value
-# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
-# default WPS OUI
-# subcateg = OUI-specific Sub Category as an integer value
-# Examples:
-# 1-0050F204-1 (Computer / PC)
-# 1-0050F204-2 (Computer / Server)
-# 5-0050F204-1 (Storage / NAS)
-# 6-0050F204-1 (Network Infrastructure / AP)
-#device_type=1-0050F204-1
-
-# OS Version
-# 4-octet operating system version number (hex string)
-#os_version=01020300
-
-# Config Methods
-# List of the supported configuration methods
-# Available methods: usba ethernet label display ext_nfc_token int_nfc_token
-# nfc_interface push_button keypad virtual_display physical_display
-# virtual_push_button physical_push_button
-# For WSC 1.0:
-#config_methods=label display push_button keypad
-# For WSC 2.0:
-#config_methods=label virtual_display virtual_push_button keypad
-
-# Credential processing
-# 0 = process received credentials internally (default)
-# 1 = do not process received credentials; just pass them over ctrl_iface to
-# external program(s)
-# 2 = process received credentials internally and pass them over ctrl_iface
-# to external program(s)
-#wps_cred_processing=0
-
-# Whether to enable SAE (WPA3-Personal transition mode) automatically for
-# WPA2-PSK credentials received using WPS.
-# 0 = only add the explicitly listed WPA2-PSK configuration (default)
-# 1 = add both the WPA2-PSK and SAE configuration and enable PMF so that the
-# station gets configured in WPA3-Personal transition mode (supports both
-# WPA2-Personal (PSK) and WPA3-Personal (SAE) APs).
-#wps_cred_add_sae=0
-
-# Vendor attribute in WPS M1, e.g., Windows 7 Vertical Pairing
-# The vendor attribute contents to be added in M1 (hex string)
-#wps_vendor_ext_m1=000137100100020001
-
-# NFC password token for WPS
-# These parameters can be used to configure a fixed NFC password token for the
-# station. This can be generated, e.g., with nfc_pw_token. When these
-# parameters are used, the station is assumed to be deployed with a NFC tag
-# that includes the matching NFC password token (e.g., written based on the
-# NDEF record from nfc_pw_token).
-#
-#wps_nfc_dev_pw_id: Device Password ID (16..65535)
-#wps_nfc_dh_pubkey: Hexdump of DH Public Key
-#wps_nfc_dh_privkey: Hexdump of DH Private Key
-#wps_nfc_dev_pw: Hexdump of Device Password
-
-# Priority for the networks added through WPS
-# This priority value will be set to each network profile that is added
-# by executing the WPS protocol.
-#wps_priority=0
-
-# Device Provisioning Protocol (DPP) parameters
-#
-# How to process DPP configuration
-# 0 = report received configuration to an external program for
-# processing; do not generate any network profile internally (default)
-# 1 = report received configuration to an external program and generate
-# a network profile internally, but do not automatically connect
-# to the created (disabled) profile; the network profile id is
-# reported to external programs
-# 2 = report received configuration to an external program, generate
-# a network profile internally, try to connect to the created
-# profile automatically
-#dpp_config_processing=0
-#
-# Name for Enrollee's DPP Configuration Request
-#dpp_name=Test
-#
-# MUD URL for Enrollee's DPP Configuration Request (optional)
-#dpp_mud_url=https://example.com/mud
-
-# Maximum number of BSS entries to keep in memory
-# Default: 200
-# This can be used to limit memory use on the BSS entries (cached scan
-# results). A larger value may be needed in environments that have huge number
-# of APs when using ap_scan=1 mode.
-#bss_max_count=200
-
-# BSS expiration age in seconds. A BSS will be removed from the local cache
-# if it is not in use and has not been seen for this time. Default is 180.
-#bss_expiration_age=180
-
-# BSS expiration after number of scans. A BSS will be removed from the local
-# cache if it is not seen in this number of scans.
-# Default is 2.
-#bss_expiration_scan_count=2
-
-# Automatic scan
-# This is an optional set of parameters for automatic scanning
-# within an interface in following format:
-#autoscan=<autoscan module name>:<module parameters>
-# autoscan is like bgscan but on disconnected or inactive state.
-# For instance, on exponential module parameters would be <base>:<limit>
-#autoscan=exponential:3:300
-# Which means a delay between scans on a base exponential of 3,
-# up to the limit of 300 seconds (3, 9, 27 ... 300)
-# For periodic module, parameters would be <fixed interval>
-#autoscan=periodic:30
-# So a delay of 30 seconds will be applied between each scan.
-# Note: If sched_scan_plans are configured and supported by the driver,
-# autoscan is ignored.
-
-# filter_ssids - SSID-based scan result filtering
-# 0 = do not filter scan results (default)
-# 1 = only include configured SSIDs in scan results/BSS table
-#filter_ssids=0
-
-# Password (and passphrase, etc.) backend for external storage
-# format: <backend name>[:<optional backend parameters>]
-# Test backend which stores passwords in memory. Should only be used for
-# development purposes.
-#ext_password_backend=test:pw1=password|pw2=testing
-# File-based backend which reads passwords from a file. The parameter
-# identifies the file to read passwords from. The password file follows the
-# format of wpa_supplicant.conf and accepts simple `key=passphrase` formatted
-# passwords.
-#ext_password_backend=file:/path/to/passwords.conf
-
-
-# Disable P2P functionality
-# p2p_disabled=1
-
-# Timeout in seconds to detect STA inactivity (default: 300 seconds)
-#
-# This timeout value is used in P2P GO mode to clean up
-# inactive stations.
-#p2p_go_max_inactivity=300
-
-# Passphrase length (8..63) for P2P GO
-#
-# This parameter controls the length of the random passphrase that is
-# generated at the GO. Default: 8.
-#p2p_passphrase_len=8
-
-# Extra delay between concurrent P2P search iterations
-#
-# This value adds extra delay in milliseconds between concurrent search
-# iterations to make p2p_find friendlier to concurrent operations by avoiding
-# it from taking 100% of radio resources. The default value is 500 ms.
-#p2p_search_delay=500
-
-# Opportunistic Key Caching (also known as Proactive Key Caching) default
-# This parameter can be used to set the default behavior for the
-# proactive_key_caching parameter. By default, OKC is disabled unless enabled
-# with the global okc=1 parameter or with the per-network
-# proactive_key_caching=1 parameter. With okc=1, OKC is enabled by default, but
-# can be disabled with per-network proactive_key_caching=0 parameter.
-#okc=0
-
-# Protected Management Frames default
-# This parameter can be used to set the default behavior for the ieee80211w
-# parameter for RSN networks. By default, PMF is disabled unless enabled with
-# the global pmf=1/2 parameter or with the per-network ieee80211w=1/2 parameter.
-# With pmf=1/2, PMF is enabled/required by default, but can be disabled with the
-# per-network ieee80211w parameter. This global default value does not apply
-# for non-RSN networks (key_mgmt=NONE) since PMF is available only when using
-# RSN.
-#pmf=0
-
-# Enabled SAE finite cyclic groups in preference order
-# By default (if this parameter is not set), the mandatory group 19 (ECC group
-# defined over a 256-bit prime order field, NIST P-256) is preferred and groups
-# 20 (NIST P-384) and 21 (NIST P-521) are also enabled. If this parameter is
-# set, the groups will be tried in the indicated order.
-# The group values are listed in the IANA registry:
-# http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-9
-# Note that groups 1, 2, 5, 22, 23, and 24 should not be used in production
-# purposes due limited security (see RFC 8247). Groups that are not as strong as
-# group 19 (ECC, NIST P-256) are unlikely to be useful for production use cases
-# since all implementations are required to support group 19.
-#sae_groups=19 20 21
-
-# SAE mechanism for PWE derivation
-# 0 = hunting-and-pecking loop only (default without password identifier)
-# 1 = hash-to-element only (default with password identifier)
-# 2 = both hunting-and-pecking loop and hash-to-element enabled
-# Note: The default value is likely to change from 0 to 2 once the new
-# hash-to-element mechanism has received more interoperability testing.
-# When using SAE password identifier, the hash-to-element mechanism is used
-# regardless of the sae_pwe parameter value.
-#sae_pwe=0
-
-# Default value for DTIM period (if not overridden in network block)
-#dtim_period=2
-
-# Default value for Beacon interval (if not overridden in network block)
-#beacon_int=100
-
-# Additional vendor specific elements for Beacon and Probe Response frames
-# This parameter can be used to add additional vendor specific element(s) into
-# the end of the Beacon and Probe Response frames. The format for these
-# element(s) is a hexdump of the raw information elements (id+len+payload for
-# one or more elements). This is used in AP and P2P GO modes.
-#ap_vendor_elements=dd0411223301
-
-# Ignore scan results older than request
-#
-# The driver may have a cache of scan results that makes it return
-# information that is older than our scan trigger. This parameter can
-# be used to configure such old information to be ignored instead of
-# allowing it to update the internal BSS table.
-#ignore_old_scan_res=0
-
-# scan_cur_freq: Whether to scan only the current frequency
-# 0: Scan all available frequencies. (Default)
-# 1: Scan current operating frequency if another VIF on the same radio
-# is already associated.
-
-# Seconds to consider old scan results valid for association (default: 5)
-#scan_res_valid_for_connect=5
-
-# MAC address policy default
-# 0 = use permanent MAC address
-# 1 = use random MAC address for each ESS connection
-# 2 = like 1, but maintain OUI (with local admin bit set)
-#
-# By default, permanent MAC address is used unless policy is changed by
-# the per-network mac_addr parameter. Global mac_addr=1 can be used to
-# change this default behavior.
-#mac_addr=0
-
-# Lifetime of random MAC address in seconds (default: 60)
-#rand_addr_lifetime=60
-
-# MAC address policy for pre-association operations (scanning, ANQP)
-# 0 = use permanent MAC address
-# 1 = use random MAC address
-# 2 = like 1, but maintain OUI (with local admin bit set)
-#preassoc_mac_addr=0
-
-# MAC address policy for GAS operations
-# 0 = use permanent MAC address
-# 1 = use random MAC address
-# 2 = like 1, but maintain OUI (with local admin bit set)
-# Note that this setting is ignored when a specific MAC address is needed for
-# a full protocol exchange that includes GAS, e.g., when going through a DPP
-# exchange that exposes the configured interface address as part of the DP
-# Public Action frame exchanges before using GAS. That same address is then used
-# during the GAS exchange as well to avoid breaking the protocol expectations.
-#gas_rand_mac_addr=0
-
-# Lifetime of GAS random MAC address in seconds (default: 60)
-#gas_rand_addr_lifetime=60
-
-# Interworking (IEEE 802.11u)
-
-# Enable Interworking
-# interworking=1
-
-# Enable P2P GO advertisement of Interworking
-# go_interworking=1
-
-# P2P GO Interworking: Access Network Type
-# 0 = Private network
-# 1 = Private network with guest access
-# 2 = Chargeable public network
-# 3 = Free public network
-# 4 = Personal device network
-# 5 = Emergency services only network
-# 14 = Test or experimental
-# 15 = Wildcard
-#go_access_network_type=0
-
-# P2P GO Interworking: Whether the network provides connectivity to the Internet
-# 0 = Unspecified
-# 1 = Network provides connectivity to the Internet
-#go_internet=1
-
-# P2P GO Interworking: Group Venue Info (optional)
-# The available values are defined in IEEE Std 802.11-2016, 9.4.1.35.
-# Example values (group,type):
-# 0,0 = Unspecified
-# 1,7 = Convention Center
-# 1,13 = Coffee Shop
-# 2,0 = Unspecified Business
-# 7,1 Private Residence
-#go_venue_group=7
-#go_venue_type=1
-
-# Homogeneous ESS identifier
-# If this is set, scans will be used to request response only from BSSes
-# belonging to the specified Homogeneous ESS. This is used only if interworking
-# is enabled.
-# hessid=00:11:22:33:44:55
-
-# Automatic network selection behavior
-# 0 = do not automatically go through Interworking network selection
-# (i.e., require explicit interworking_select command for this; default)
-# 1 = perform Interworking network selection if one or more
-# credentials have been configured and scan did not find a
-# matching network block
-#auto_interworking=0
-
-# GAS Address3 field behavior
-# 0 = P2P specification (Address3 = AP BSSID); default
-# 1 = IEEE 802.11 standard compliant (Address3 = Wildcard BSSID when
-# sent to not-associated AP; if associated, AP BSSID)
-#gas_address3=0
-
-# Publish fine timing measurement (FTM) responder functionality in
-# the Extended Capabilities element bit 70.
-# Controls whether FTM responder functionality will be published by AP/STA.
-# Note that actual FTM responder operation is managed outside wpa_supplicant.
-# 0 = Do not publish; default
-# 1 = Publish
-#ftm_responder=0
-
-# Publish fine timing measurement (FTM) initiator functionality in
-# the Extended Capabilities element bit 71.
-# Controls whether FTM initiator functionality will be published by AP/STA.
-# Note that actual FTM initiator operation is managed outside wpa_supplicant.
-# 0 = Do not publish; default
-# 1 = Publish
-#ftm_initiator=0
-
-# credential block
-#
-# Each credential used for automatic network selection is configured as a set
-# of parameters that are compared to the information advertised by the APs when
-# interworking_select and interworking_connect commands are used.
-#
-# credential fields:
-#
-# temporary: Whether this credential is temporary and not to be saved
-#
-# priority: Priority group
-# By default, all networks and credentials get the same priority group
-# (0). This field can be used to give higher priority for credentials
-# (and similarly in struct wpa_ssid for network blocks) to change the
-# Interworking automatic networking selection behavior. The matching
-# network (based on either an enabled network block or a credential)
-# with the highest priority value will be selected.
-#
-# pcsc: Use PC/SC and SIM/USIM card
-#
-# realm: Home Realm for Interworking
-#
-# username: Username for Interworking network selection
-#
-# password: Password for Interworking network selection
-#
-# ca_cert: CA certificate for Interworking network selection
-#
-# client_cert: File path to client certificate file (PEM/DER)
-# This field is used with Interworking networking selection for a case
-# where client certificate/private key is used for authentication
-# (EAP-TLS). Full path to the file should be used since working
-# directory may change when wpa_supplicant is run in the background.
-#
-# Certificates from PKCS#11 tokens can be referenced by a PKCS#11 URI.
-#
-# For example: private_key="pkcs11:manufacturer=piv_II;id=%01"
-#
-# Alternatively, a named configuration blob can be used by setting
-# this to blob://blob_name.
-#
-# private_key: File path to client private key file (PEM/DER/PFX)
-# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
-# commented out. Both the private key and certificate will be read
-# from the PKCS#12 file in this case. Full path to the file should be
-# used since working directory may change when wpa_supplicant is run
-# in the background.
-#
-# Keys in PKCS#11 tokens can be referenced by a PKCS#11 URI.
-# For example: private_key="pkcs11:manufacturer=piv_II;id=%01"
-#
-# Windows certificate store can be used by leaving client_cert out and
-# configuring private_key in one of the following formats:
-#
-# cert://substring_to_match
-#
-# hash://certificate_thumbprint_in_hex
-#
-# For example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
-#
-# Note that when running wpa_supplicant as an application, the user
-# certificate store (My user account) is used, whereas computer store
-# (Computer account) is used when running wpasvc as a service.
-#
-# Alternatively, a named configuration blob can be used by setting
-# this to blob://blob_name.
-#
-# private_key_passwd: Password for private key file
-#
-# imsi: IMSI in <MCC> | <MNC> | '-' | <MSIN> format
-#
-# milenage: Milenage parameters for SIM/USIM simulator in <Ki>:<OPc>:<SQN>
-# format
-#
-# domain: Home service provider FQDN(s)
-# This is used to compare against the Domain Name List to figure out
-# whether the AP is operated by the Home SP. Multiple domain entries can
-# be used to configure alternative FQDNs that will be considered home
-# networks.
-#
-# roaming_consortium: Roaming Consortium OI
-# If roaming_consortium_len is non-zero, this field contains the
-# Roaming Consortium OI that can be used to determine which access
-# points support authentication with this credential. This is an
-# alternative to the use of the realm parameter. When using Roaming
-# Consortium to match the network, the EAP parameters need to be
-# pre-configured with the credential since the NAI Realm information
-# may not be available or fetched.
-#
-# required_roaming_consortium: Required Roaming Consortium OI
-# If required_roaming_consortium_len is non-zero, this field contains the
-# Roaming Consortium OI that is required to be advertised by the AP for
-# the credential to be considered matching.
-#
-# roaming_consortiums: Roaming Consortium OI(s) memberships
-# This string field contains one or more comma delimited OIs (hexdump)
-# identifying the roaming consortiums of which the provider is a member.
-# The list is sorted from the most preferred one to the least preferred
-# one. A match between the Roaming Consortium OIs advertised by an AP and
-# the OIs in this list indicates that successful authentication is
-# possible.
-# (Hotspot 2.0 PerProviderSubscription/<X+>/HomeSP/RoamingConsortiumOI)
-#
-# eap: Pre-configured EAP method
-# This optional field can be used to specify which EAP method will be
-# used with this credential. If not set, the EAP method is selected
-# automatically based on ANQP information (e.g., NAI Realm).
-#
-# phase1: Pre-configure Phase 1 (outer authentication) parameters
-# This optional field is used with like the 'eap' parameter.
-#
-# phase2: Pre-configure Phase 2 (inner authentication) parameters
-# This optional field is used with like the 'eap' parameter.
-#
-# excluded_ssid: Excluded SSID
-# This optional field can be used to excluded specific SSID(s) from
-# matching with the network. Multiple entries can be used to specify more
-# than one SSID.
-#
-# roaming_partner: Roaming partner information
-# This optional field can be used to configure preferences between roaming
-# partners. The field is a string in following format:
-# <FQDN>,<0/1 exact match>,<priority>,<* or country code>
-# (non-exact match means any subdomain matches the entry; priority is in
-# 0..255 range with 0 being the highest priority)
-#
-# update_identifier: PPS MO ID
-# (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
-#
-# provisioning_sp: FQDN of the SP that provisioned the credential
-# This optional field can be used to keep track of the SP that provisioned
-# the credential to find the PPS MO (./Wi-Fi/<provisioning_sp>).
-#
-# Minimum backhaul threshold (PPS/<X+>/Policy/MinBackhauldThreshold/*)
-# These fields can be used to specify minimum download/upload backhaul
-# bandwidth that is preferred for the credential. This constraint is
-# ignored if the AP does not advertise WAN Metrics information or if the
-# limit would prevent any connection. Values are in kilobits per second.
-# min_dl_bandwidth_home
-# min_ul_bandwidth_home
-# min_dl_bandwidth_roaming
-# min_ul_bandwidth_roaming
-#
-# max_bss_load: Maximum BSS Load Channel Utilization (1..255)
-# (PPS/<X+>/Policy/MaximumBSSLoadValue)
-# This value is used as the maximum channel utilization for network
-# selection purposes for home networks. If the AP does not advertise
-# BSS Load or if the limit would prevent any connection, this constraint
-# will be ignored.
-#
-# req_conn_capab: Required connection capability
-# (PPS/<X+>/Policy/RequiredProtoPortTuple)
-# This value is used to configure set of required protocol/port pairs that
-# a roaming network shall support (include explicitly in Connection
-# Capability ANQP element). This constraint is ignored if the AP does not
-# advertise Connection Capability or if this constraint would prevent any
-# network connection. This policy is not used in home networks.
-# Format: <protocol>[:<comma-separated list of ports]
-# Multiple entries can be used to list multiple requirements.
-# For example, number of common TCP protocols:
-# req_conn_capab=6,22,80,443
-# For example, IPSec/IKE:
-# req_conn_capab=17:500
-# req_conn_capab=50
-#
-# ocsp: Whether to use/require OCSP to check server certificate
-# 0 = do not use OCSP stapling (TLS certificate status extension)
-# 1 = try to use OCSP stapling, but not require response
-# 2 = require valid OCSP stapling response
-# 3 = require valid OCSP stapling response for all not-trusted
-# certificates in the server certificate chain
-#
-# sim_num: Identifier for which SIM to use in multi-SIM devices
-#
-# for example:
-#
-#cred={
-# realm="example.com"
-# username="user@example.com"
-# password="password"
-# ca_cert="/etc/wpa_supplicant/ca.pem"
-# domain="example.com"
-#}
-#
-#cred={
-# imsi="310026-000000000"
-# milenage="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82"
-#}
-#
-#cred={
-# realm="example.com"
-# username="user"
-# password="password"
-# ca_cert="/etc/wpa_supplicant/ca.pem"
-# domain="example.com"
-# roaming_consortium=223344
-# eap=TTLS
-# phase2="auth=MSCHAPV2"
-#}
-
-# Hotspot 2.0
-# hs20=1
-
-# Scheduled scan plans
-#
-# A space delimited list of scan plans. Each scan plan specifies the scan
-# interval and number of iterations, delimited by a colon. The last scan plan
-# will run infinitely and thus must specify only the interval and not the number
-# of iterations.
-#
-# The driver advertises the maximum number of scan plans supported. If more scan
-# plans than supported are configured, only the first ones are set (up to the
-# maximum supported). The last scan plan that specifies only the interval is
-# always set as the last plan.
-#
-# If the scan interval or the number of iterations for a scan plan exceeds the
-# maximum supported, it will be set to the maximum supported value.
-#
-# Format:
-# sched_scan_plans=<interval:iterations> <interval:iterations> ... <interval>
-#
-# Example:
-# sched_scan_plans=10:100 20:200 30
-
-# Multi Band Operation (MBO) non-preferred channels
-# A space delimited list of non-preferred channels where each channel is a colon
-# delimited list of values.
-# Format:
-# non_pref_chan=<oper_class>:<chan>:<preference>:<reason>
-# Example:
-# non_pref_chan=81:5:10:2 81:1:0:2 81:9:0:2
-
-# MBO Cellular Data Capabilities
-# 1 = Cellular data connection available
-# 2 = Cellular data connection not available
-# 3 = Not cellular capable (default)
-#mbo_cell_capa=3
-
-# Optimized Connectivity Experience (OCE)
-# oce: Enable OCE features (bitmap)
-# Set BIT(0) to Enable OCE in non-AP STA mode (default; disabled if the driver
-# does not indicate support for OCE in STA mode)
-# Set BIT(1) to Enable OCE in STA-CFON mode
-#oce=1
-
-# Extended Key ID support for Individually Addressed frames
-# 0 = force off: Do not use Extended Key ID (default)
-# 1 = auto: Activate Extended Key ID support if the driver supports it
-#extended_key_id=0
-
-# network block
-#
-# Each network (usually AP's sharing the same SSID) is configured as a separate
-# block in this configuration file. The network blocks are in preference order
-# (the first match is used).
-#
-# network block fields:
-#
-# disabled:
-# 0 = this network can be used (default)
-# 1 = this network block is disabled (can be enabled through ctrl_iface,
-# e.g., with wpa_cli or wpa_gui)
-#
-# id_str: Network identifier string for external scripts. This value is passed
-# to external action script through wpa_cli as WPA_ID_STR environment
-# variable to make it easier to do network specific configuration.
-#
-# ssid: SSID (mandatory); network name in one of the optional formats:
-# - an ASCII string with double quotation
-# - a hex string (two characters per octet of SSID)
-# - a printf-escaped ASCII string P"<escaped string>"
-#
-# scan_ssid:
-# 0 = do not scan this SSID with specific Probe Request frames (default)
-# 1 = scan with SSID-specific Probe Request frames (this can be used to
-# find APs that do not accept broadcast SSID or use multiple SSIDs;
-# this will add latency to scanning, so enable this only when needed)
-#
-# bssid: BSSID (optional); if set, this network block is used only when
-# associating with the AP using the configured BSSID
-#
-# ignore_broadcast_ssid: SSID broadcast behavior
-# Send empty SSID in beacons and ignore probe request frames that do not
-# specify full SSID, i.e., require stations to know SSID.
-# default: disabled (0)
-# 1 = send empty (length=0) SSID in beacon and ignore probe request for
-# broadcast SSID
-# 2 = clear SSID (ASCII 0), but keep the original length (this may be required
-# with some clients that do not support empty SSID) and ignore probe
-# requests for broadcast SSID
-#
-# priority: priority group (integer)
-# By default, all networks will get same priority group (0). If some of the
-# networks are more desirable, this field can be used to change the order in
-# which wpa_supplicant goes through the networks when selecting a BSS. The
-# priority groups will be iterated in decreasing priority (i.e., the larger the
-# priority value, the sooner the network is matched against the scan results).
-# Within each priority group, networks will be selected based on security
-# policy, signal strength, etc.
-# Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are not
-# using this priority to select the order for scanning. Instead, they try the
-# networks in the order that used in the configuration file.
-#
-# mode: IEEE 802.11 operation mode
-# 0 = infrastructure (Managed) mode, i.e., associate with an AP (default)
-# 1 = IBSS (ad-hoc, peer-to-peer)
-# 2 = AP (access point)
-# Note: IBSS can only be used with key_mgmt NONE (plaintext and static WEP) and
-# WPA-PSK (with proto=RSN). In addition, key_mgmt=WPA-NONE (fixed group key
-# TKIP/CCMP) is available for backwards compatibility, but its use is
-# deprecated. WPA-None requires following network block options:
-# proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not
-# both), and psk must also be set.
-#
-# frequency: Channel frequency in megahertz (MHz) for IBSS, e.g.,
-# 2412 = IEEE 802.11b/g channel 1. This value is used to configure the initial
-# channel for IBSS (adhoc) networks. It is ignored in the infrastructure mode.
-# In addition, this value is only used by the station that creates the IBSS. If
-# an IBSS network with the configured SSID is already present, the frequency of
-# the network will be used instead of this configured value.
-#
-# pbss: Whether to use PBSS. Relevant to IEEE 802.11ad networks only.
-# 0 = do not use PBSS
-# 1 = use PBSS
-# 2 = don't care (not allowed in AP mode)
-# Used together with mode configuration. When mode is AP, it means to start a
-# PCP instead of a regular AP. When mode is infrastructure it means connect
-# to a PCP instead of AP. In this mode you can also specify 2 (don't care)
-# which means connect to either PCP or AP.
-# P2P_GO and P2P_GROUP_FORMATION modes must use PBSS in IEEE 802.11ad network.
-# For more details, see IEEE Std 802.11ad-2012.
-#
-# scan_freq: List of frequencies to scan
-# Space-separated list of frequencies in MHz to scan when searching for this
-# BSS. If the subset of channels used by the network is known, this option can
-# be used to optimize scanning to not occur on channels that the network does
-# not use. Example: scan_freq=2412 2437 2462
-#
-# freq_list: Array of allowed frequencies
-# Space-separated list of frequencies in MHz to allow for selecting the BSS. If
-# set, scan results that do not match any of the specified frequencies are not
-# considered when selecting a BSS.
-#
-# This can also be set on the outside of the network block. In this case,
-# it limits the frequencies that will be scanned.
-#
-# bgscan: Background scanning
-# wpa_supplicant behavior for background scanning can be specified by
-# configuring a bgscan module. These modules are responsible for requesting
-# background scans for the purpose of roaming within an ESS (i.e., within a
-# single network block with all the APs using the same SSID). The bgscan
-# parameter uses following format: "<bgscan module name>:<module parameters>"
-# Following bgscan modules are available:
-# simple - Periodic background scans based on signal strength
-# bgscan="simple:<short bgscan interval in seconds>:<signal strength threshold>:
-# <long interval>"
-# bgscan="simple:30:-45:300"
-# learn - Learn channels used by the network and try to avoid bgscans on other
-# channels (experimental)
-# bgscan="learn:<short bgscan interval in seconds>:<signal strength threshold>:
-# <long interval>[:<database file name>]"
-# bgscan="learn:30:-45:300:/etc/wpa_supplicant/network1.bgscan"
-# Explicitly disable bgscan by setting
-# bgscan=""
-#
-# This option can also be set outside of all network blocks for the bgscan
-# parameter to apply for all the networks that have no specific bgscan
-# parameter.
-#
-# proto: list of accepted protocols
-# WPA = WPA/IEEE 802.11i/D3.0
-# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
-# Note that RSN is used also for WPA3.
-# If not set, this defaults to: WPA RSN
-#
-# key_mgmt: list of accepted authenticated key management protocols
-# WPA-PSK = WPA pre-shared key (this requires 'psk' field)
-# WPA-EAP = WPA using EAP authentication
-# IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically
-# generated WEP keys
-# NONE = WPA is not used; plaintext or static WEP could be used
-# WPA-NONE = WPA-None for IBSS (deprecated; use proto=RSN key_mgmt=WPA-PSK
-# instead)
-# FT-PSK = Fast BSS Transition (IEEE 802.11r) with pre-shared key
-# FT-EAP = Fast BSS Transition (IEEE 802.11r) with EAP authentication
-# FT-EAP-SHA384 = Fast BSS Transition (IEEE 802.11r) with EAP authentication
-# and using SHA384
-# WPA-PSK-SHA256 = Like WPA-PSK but using stronger SHA256-based algorithms
-# WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms
-# SAE = Simultaneous authentication of equals; pre-shared key/password -based
-# authentication with stronger security than WPA-PSK especially when using
-# not that strong password; a.k.a. WPA3-Personal
-# FT-SAE = SAE with FT
-# WPA-EAP-SUITE-B = Suite B 128-bit level
-# WPA-EAP-SUITE-B-192 = Suite B 192-bit level
-# OSEN = Hotspot 2.0 Rel 2 online signup connection
-# FILS-SHA256 = Fast Initial Link Setup with SHA256
-# FILS-SHA384 = Fast Initial Link Setup with SHA384
-# FT-FILS-SHA256 = FT and Fast Initial Link Setup with SHA256
-# FT-FILS-SHA384 = FT and Fast Initial Link Setup with SHA384
-# OWE = Opportunistic Wireless Encryption (a.k.a. Enhanced Open)
-# DPP = Device Provisioning Protocol
-# If not set, this defaults to: WPA-PSK WPA-EAP
-#
-# ieee80211w: whether management frame protection is enabled
-# 0 = disabled (default unless changed with the global pmf parameter)
-# 1 = optional
-# 2 = required
-# The most common configuration options for this based on the PMF (protected
-# management frames) certification program are:
-# PMF enabled: ieee80211w=1 and key_mgmt=WPA-EAP WPA-EAP-SHA256
-# PMF required: ieee80211w=2 and key_mgmt=WPA-EAP-SHA256
-# (and similarly for WPA-PSK and WPA-PSK-SHA256 if WPA2-Personal is used)
-# WPA3-Personal-only mode: ieee80211w=2 and key_mgmt=SAE
-#
-# ocv: whether operating channel validation is enabled
-# This is a countermeasure against multi-channel on-path attacks.
-# Enabling this automatically also enables ieee80211w, if not yet enabled.
-# 0 = disabled (default)
-# 1 = enabled if wpa_supplicant's SME in use. Otherwise enabled only when the
-# driver indicates support for operating channel validation.
-#ocv=1
-#
-# auth_alg: list of allowed IEEE 802.11 authentication algorithms
-# OPEN = Open System authentication (required for WPA/WPA2)
-# SHARED = Shared Key authentication (requires static WEP keys)
-# LEAP = LEAP/Network EAP (only used with LEAP)
-# If not set, automatic selection is used (Open System with LEAP enabled if
-# LEAP is allowed as one of the EAP methods).
-#
-# pairwise: list of accepted pairwise (unicast) ciphers for WPA
-# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
-# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-# NONE = Use only Group Keys (deprecated, should not be included if APs support
-# pairwise keys)
-# If not set, this defaults to: CCMP TKIP
-#
-# group: list of accepted group (broadcast/multicast) ciphers for WPA
-# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
-# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-# WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
-# WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key [IEEE 802.11]
-# If not set, this defaults to: CCMP TKIP WEP104 WEP40
-#
-# group_mgmt: list of accepted group management ciphers for RSN (PMF)
-# AES-128-CMAC = BIP-CMAC-128
-# BIP-GMAC-128
-# BIP-GMAC-256
-# BIP-CMAC-256
-# If not set, no constraint on the cipher, i.e., accept whichever cipher the AP
-# indicates.
-#
-# psk: WPA preshared key; 256-bit pre-shared key
-# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e.,
-# 32 bytes or as an ASCII passphrase (in which case, the real PSK will be
-# generated using the passphrase and SSID). ASCII passphrase must be between
-# 8 and 63 characters (inclusive). ext:<name of external PSK field> format can
-# be used to indicate that the PSK/passphrase is stored in external storage.
-# This field is not needed, if WPA-EAP is used.
-# Note: Separate tool, wpa_passphrase, can be used to generate 256-bit keys
-# from ASCII passphrase. This process uses lot of CPU and wpa_supplicant
-# startup and reconfiguration time can be optimized by generating the PSK only
-# only when the passphrase or SSID has actually changed.
-#
-# mem_only_psk: Whether to keep PSK/passphrase only in memory
-# 0 = allow psk/passphrase to be stored to the configuration file
-# 1 = do not store psk/passphrase to the configuration file
-#mem_only_psk=0
-#
-# sae_password: SAE password
-# This parameter can be used to set a password for SAE. By default, the
-# passphrase from the psk parameter is used if this separate parameter is not
-# used, but psk follows the WPA-PSK constraints (8..63 characters) even though
-# SAE passwords do not have such constraints.
-#
-# sae_password_id: SAE password identifier
-# This parameter can be used to set an identifier for the SAE password. By
-# default, no such identifier is used. If set, the specified identifier value
-# is used by the other peer to select which password to use for authentication.
-#
-# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
-# Dynamic WEP key required for non-WPA mode
-# bit0 (1): require dynamically generated unicast WEP key
-# bit1 (2): require dynamically generated broadcast WEP key
-# (3 = require both keys; default)
-# Note: When using wired authentication (including MACsec drivers),
-# eapol_flags must be set to 0 for the authentication to be completed
-# successfully.
-#
-# macsec_policy: IEEE 802.1X/MACsec options
-# This determines how sessions are secured with MACsec (only for MACsec
-# drivers).
-# 0: MACsec not in use (default)
-# 1: MACsec enabled - Should secure, accept key server's advice to
-# determine whether to use a secure session or not.
-#
-# macsec_integ_only: IEEE 802.1X/MACsec transmit mode
-# This setting applies only when MACsec is in use, i.e.,
-# - macsec_policy is enabled
-# - the key server has decided to enable MACsec
-# 0: Encrypt traffic (default)
-# 1: Integrity only
-#
-# macsec_replay_protect: IEEE 802.1X/MACsec replay protection
-# This setting applies only when MACsec is in use, i.e.,
-# - macsec_policy is enabled
-# - the key server has decided to enable MACsec
-# 0: Replay protection disabled (default)
-# 1: Replay protection enabled
-#
-# macsec_replay_window: IEEE 802.1X/MACsec replay protection window
-# This determines a window in which replay is tolerated, to allow receipt
-# of frames that have been misordered by the network.
-# This setting applies only when MACsec replay protection active, i.e.,
-# - macsec_replay_protect is enabled
-# - the key server has decided to enable MACsec
-# 0: No replay window, strict check (default)
-# 1..2^32-1: number of packets that could be misordered
-#
-# macsec_port: IEEE 802.1X/MACsec port
-# Port component of the SCI
-# Range: 1-65534 (default: 1)
-#
-# mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode
-# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair.
-# In this mode, instances of wpa_supplicant can act as MACsec peers. The peer
-# with lower priority will become the key server and start distributing SAKs.
-# mka_cak (CAK = Secure Connectivity Association Key) takes a 16-byte (128-bit)
-# hex-string (32 hex-digits) or a 32-byte (256-bit) hex-string (64 hex-digits)
-# mka_ckn (CKN = CAK Name) takes a 1..32-bytes (8..256 bit) hex-string
-# (2..64 hex-digits)
-# mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being
-# default priority
-#
-# mixed_cell: This option can be used to configure whether so called mixed
-# cells, i.e., networks that use both plaintext and encryption in the same
-# SSID, are allowed when selecting a BSS from scan results.
-# 0 = disabled (default)
-# 1 = enabled
-#
-# proactive_key_caching:
-# Enable/disable opportunistic PMKSA caching for WPA2.
-# 0 = disabled (default unless changed with the global okc parameter)
-# 1 = enabled
-#
-# ft_eap_pmksa_caching:
-# Whether FT-EAP PMKSA caching is allowed
-# 0 = do not try to use PMKSA caching with FT-EAP (default)
-# 1 = try to use PMKSA caching with FT-EAP
-# This controls whether to try to use PMKSA caching with FT-EAP for the
-# FT initial mobility domain association.
-#ft_eap_pmksa_caching=0
-#
-# wep_key0..3: Static WEP key (ASCII in double quotation, e.g. "abcde" or
-# hex without quotation, e.g., 0102030405)
-# wep_tx_keyidx: Default WEP key index (TX) (0..3)
-#
-# wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to
-# enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies.
-#
-# wpa_deny_ptk0_rekey: Workaround for PTK rekey issues
-# PTK0 rekeys (using only one Key ID value for pairwise keys) can degrade the
-# security and stability with some cards.
-# To avoid the issues wpa_supplicant can replace those PTK rekeys (including
-# EAP reauthentications) with fast reconnects.
-#
-# Available options:
-# 0 = always rekey when configured/instructed (default)
-# 1 = only rekey when the local driver is explicitly indicating it can perform
-# this operation without issues
-# 2 = never allow problematic PTK0 rekeys
-#
-# group_rekey: Group rekeying time in seconds. This value, if non-zero, is used
-# as the dot11RSNAConfigGroupRekeyTime parameter when operating in
-# Authenticator role in IBSS, or in AP and mesh modes.
-#
-# Following fields are only used with internal EAP implementation.
-# eap: space-separated list of accepted EAP methods
-# MD5 = EAP-MD5 (insecure and does not generate keying material ->
-# cannot be used with WPA; to be used as a Phase 2 method
-# with EAP-PEAP or EAP-TTLS)
-# MSCHAPV2 = EAP-MSCHAPv2 (cannot be used separately with WPA; to be used
-# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
-# OTP = EAP-OTP (cannot be used separately with WPA; to be used
-# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
-# GTC = EAP-GTC (cannot be used separately with WPA; to be used
-# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
-# TLS = EAP-TLS (client and server certificate)
-# PEAP = EAP-PEAP (with tunnelled EAP authentication)
-# TTLS = EAP-TTLS (with tunnelled EAP or PAP/CHAP/MSCHAP/MSCHAPV2
-# authentication)
-# If not set, all compiled in methods are allowed.
-#
-# identity: Identity string for EAP
-# This field is also used to configure user NAI for
-# EAP-PSK/PAX/SAKE/GPSK.
-# anonymous_identity: Anonymous identity string for EAP (to be used as the
-# unencrypted identity with EAP types that support different tunnelled
-# identity, e.g., EAP-TTLS). This field can also be used with
-# EAP-SIM/AKA/AKA' to store the pseudonym identity.
-# password: Password string for EAP. This field can include either the
-# plaintext password (using ASCII or hex string) or a NtPasswordHash
-# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
-# NtPasswordHash can only be used when the password is for MSCHAPv2 or
-# MSCHAP (EAP-MSCHAPv2, EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
-# EAP-PSK (128-bit PSK), EAP-PAX (128-bit PSK), and EAP-SAKE (256-bit
-# PSK) is also configured using this field. For EAP-GPSK, this is a
-# variable length PSK. ext:<name of external password field> format can
-# be used to indicate that the password is stored in external storage.
-# ca_cert: File path to CA certificate file (PEM/DER). This file can have one
-# or more trusted CA certificates. If ca_cert and ca_path are not
-# included, server certificate will not be verified. This is insecure and
-# a trusted CA certificate should always be configured when using
-# EAP-TLS/TTLS/PEAP. Full path should be used since working directory may
-# change when wpa_supplicant is run in the background.
-#
-# Alternatively, this can be used to only perform matching of the server
-# certificate (SHA-256 hash of the DER encoded X.509 certificate). In
-# this case, the possible CA certificates in the server certificate chain
-# are ignored and only the server certificate is verified. This is
-# configured with the following format:
-# hash:://server/sha256/cert_hash_in_hex
-# For example: "hash://server/sha256/
-# 5a1bc1296205e6fdbe3979728efe3920798885c1c4590b5f90f43222d239ca6a"
-#
-# On Windows, trusted CA certificates can be loaded from the system
-# certificate store by setting this to cert_store://<name>, e.g.,
-# ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
-# Note that when running wpa_supplicant as an application, the user
-# certificate store (My user account) is used, whereas computer store
-# (Computer account) is used when running wpasvc as a service.
-# ca_path: Directory path for CA certificate files (PEM). This path may
-# contain multiple CA certificates in OpenSSL format. Common use for this
-# is to point to system trusted CA list which is often installed into
-# directory like /etc/ssl/certs. If configured, these certificates are
-# added to the list of trusted CAs. ca_cert may also be included in that
-# case, but it is not required.
-# client_cert: File path to client certificate file (PEM/DER)
-# Full path should be used since working directory may change when
-# wpa_supplicant is run in the background.
-# Alternatively, a named configuration blob can be used by setting this
-# to blob://<blob name>.
-# private_key: File path to client private key file (PEM/DER/PFX)
-# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
-# commented out. Both the private key and certificate will be read from
-# the PKCS#12 file in this case. Full path should be used since working
-# directory may change when wpa_supplicant is run in the background.
-# Windows certificate store can be used by leaving client_cert out and
-# configuring private_key in one of the following formats:
-# cert://substring_to_match
-# hash://certificate_thumbprint_in_hex
-# for example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
-# Note that when running wpa_supplicant as an application, the user
-# certificate store (My user account) is used, whereas computer store
-# (Computer account) is used when running wpasvc as a service.
-# Alternatively, a named configuration blob can be used by setting this
-# to blob://<blob name>.
-# private_key_passwd: Password for private key file (if left out, this will be
-# asked through control interface)
-# dh_file: File path to DH/DSA parameters file (in PEM format)
-# This is an optional configuration file for setting parameters for an
-# ephemeral DH key exchange. In most cases, the default RSA
-# authentication does not use this configuration. However, it is possible
-# setup RSA to use ephemeral DH key exchange. In addition, ciphers with
-# DSA keys always use ephemeral DH keys. This can be used to achieve
-# forward secrecy. If the file is in DSA parameters format, it will be
-# automatically converted into DH params.
-# subject_match: Substring to be matched against the subject of the
-# authentication server certificate. If this string is set, the server
-# certificate is only accepted if it contains this string in the subject.
-# The subject string is in following format:
-# /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com
-# Note: Since this is a substring match, this cannot be used securely to
-# do a suffix match against a possible domain name in the CN entry. For
-# such a use case, domain_suffix_match or domain_match should be used
-# instead.
-# altsubject_match: Semicolon separated string of entries to be matched against
-# the alternative subject name of the authentication server certificate.
-# If this string is set, the server certificate is only accepted if it
-# contains one of the entries in an alternative subject name extension.
-# altSubjectName string is in following format: TYPE:VALUE
-# Example: EMAIL:server@example.com
-# Example: DNS:server.example.com;DNS:server2.example.com
-# Following types are supported: EMAIL, DNS, URI
-# domain_suffix_match: Constraint for server domain name. If set, this FQDN is
-# used as a suffix match requirement for the AAA server certificate in
-# SubjectAltName dNSName element(s). If a matching dNSName is found, this
-# constraint is met. If no dNSName values are present, this constraint is
-# matched against SubjectName CN using same suffix match comparison.
-#
-# Suffix match here means that the host/domain name is compared one label
-# at a time starting from the top-level domain and all the labels in
-# domain_suffix_match shall be included in the certificate. The
-# certificate may include additional sub-level labels in addition to the
-# required labels.
-#
-# More than one match string can be provided by using semicolons to
-# separate the strings (e.g., example.org;example.com). When multiple
-# strings are specified, a match with any one of the values is considered
-# a sufficient match for the certificate, i.e., the conditions are ORed
-# together.
-#
-# For example, domain_suffix_match=example.com would match
-# test.example.com but would not match test-example.com.
-# domain_match: Constraint for server domain name
-# If set, this FQDN is used as a full match requirement for the
-# server certificate in SubjectAltName dNSName element(s). If a
-# matching dNSName is found, this constraint is met. If no dNSName
-# values are present, this constraint is matched against SubjectName CN
-# using same full match comparison. This behavior is similar to
-# domain_suffix_match, but has the requirement of a full match, i.e.,
-# no subdomains or wildcard matches are allowed. Case-insensitive
-# comparison is used, so "Example.com" matches "example.com", but would
-# not match "test.Example.com".
-#
-# More than one match string can be provided by using semicolons to
-# separate the strings (e.g., example.org;example.com). When multiple
-# strings are specified, a match with any one of the values is considered
-# a sufficient match for the certificate, i.e., the conditions are ORed
-# together.
-# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
-# (string with field-value pairs, e.g., "peapver=0" or
-# "peapver=1 peaplabel=1")
-# 'peapver' can be used to force which PEAP version (0 or 1) is used.
-# 'peaplabel=1' can be used to force new label, "client PEAP encryption",
-# to be used during key derivation when PEAPv1 or newer. Most existing
-# PEAPv1 implementation seem to be using the old label, "client EAP
-# encryption", and wpa_supplicant is now using that as the default value.
-# Some servers, e.g., Radiator, may require peaplabel=1 configuration to
-# interoperate with PEAPv1; see eap_testing.txt for more details.
-# 'peap_outer_success=0' can be used to terminate PEAP authentication on
-# tunneled EAP-Success. This is required with some RADIUS servers that
-# implement draft-josefsson-pppext-eap-tls-eap-05.txt (e.g.,
-# Lucent NavisRadius v4.4.0 with PEAP in "IETF Draft 5" mode)
-# include_tls_length=1 can be used to force wpa_supplicant to include
-# TLS Message Length field in all TLS messages even if they are not
-# fragmented.
-# sim_min_num_chal=3 can be used to configure EAP-SIM to require three
-# challenges (by default, it accepts 2 or 3)
-# result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
-# protected result indication.
-# 'crypto_binding' option can be used to control PEAPv0 cryptobinding
-# behavior:
-# * 0 = do not use cryptobinding (default)
-# * 1 = use cryptobinding if server supports it
-# * 2 = require cryptobinding
-# EAP-WSC (WPS) uses following options: pin=<Device Password> or
-# pbc=1.
-#
-# For wired IEEE 802.1X authentication, "allow_canned_success=1" can be
-# used to configure a mode that allows EAP-Success (and EAP-Failure)
-# without going through authentication step. Some switches use such
-# sequence when forcing the port to be authorized/unauthorized or as a
-# fallback option if the authentication server is unreachable. By default,
-# wpa_supplicant discards such frames to protect against potential attacks
-# by rogue devices, but this option can be used to disable that protection
-# for cases where the server/authenticator does not need to be
-# authenticated.
-# phase2: Phase2 (inner authentication with TLS tunnel) parameters
-# (string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
-# "autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS). "mschapv2_retry=0" can be
-# used to disable MSCHAPv2 password retry in authentication failure cases.
-#
-# TLS-based methods can use the following parameters to control TLS behavior
-# (these are normally in the phase1 parameter, but can be used also in the
-# phase2 parameter when EAP-TLS is used within the inner tunnel):
-# tls_allow_md5=1 - allow MD5-based certificate signatures (depending on the
-# TLS library, these may be disabled by default to enforce stronger
-# security)
-# tls_disable_time_checks=1 - ignore certificate validity time (this requests
-# the TLS library to accept certificates even if they are not currently
-# valid, i.e., have expired or have not yet become valid; this should be
-# used only for testing purposes)
-# tls_disable_session_ticket=1 - disable TLS Session Ticket extension
-# tls_disable_session_ticket=0 - allow TLS Session Ticket extension to be used
-# Note: If not set, this is automatically set to 1 for EAP-TLS/PEAP/TTLS
-# as a workaround for broken authentication server implementations unless
-# EAP workarounds are disabled with eap_workaround=0.
-# For EAP-FAST, this must be set to 0 (or left unconfigured for the
-# default value to be used automatically).
-# tls_disable_tlsv1_0=1 - disable use of TLSv1.0
-# tls_disable_tlsv1_0=0 - explicitly enable use of TLSv1.0 (this allows
-# systemwide TLS policies to be overridden)
-# tls_disable_tlsv1_1=1 - disable use of TLSv1.1 (a workaround for AAA servers
-# that have issues interoperating with updated TLS version)
-# tls_disable_tlsv1_1=0 - explicitly enable use of TLSv1.1 (this allows
-# systemwide TLS policies to be overridden)
-# tls_disable_tlsv1_2=1 - disable use of TLSv1.2 (a workaround for AAA servers
-# that have issues interoperating with updated TLS version)
-# tls_disable_tlsv1_2=0 - explicitly enable use of TLSv1.2 (this allows
-# systemwide TLS policies to be overridden)
-# tls_disable_tlsv1_3=1 - disable use of TLSv1.3 (a workaround for AAA servers
-# that have issues interoperating with updated TLS version)
-# tls_disable_tlsv1_3=0 - enable TLSv1.3 (experimental - disabled by default)
-# tls_ext_cert_check=0 - No external server certificate validation (default)
-# tls_ext_cert_check=1 - External server certificate validation enabled; this
-# requires an external program doing validation of server certificate
-# chain when receiving CTRL-RSP-EXT_CERT_CHECK event from the control
-# interface and report the result of the validation with
-# CTRL-RSP_EXT_CERT_CHECK.
-# tls_suiteb=0 - do not apply Suite B 192-bit constraints on TLS (default)
-# tls_suiteb=1 - apply Suite B 192-bit constraints on TLS; this is used in
-# particular when using Suite B with RSA keys of >= 3K (3072) bits
-#
-# Following certificate/private key fields are used in inner Phase2
-# authentication when using EAP-TTLS or EAP-PEAP.
-# ca_cert2: File path to CA certificate file. This file can have one or more
-# trusted CA certificates. If ca_cert2 and ca_path2 are not included,
-# server certificate will not be verified. This is insecure and a trusted
-# CA certificate should always be configured.
-# ca_path2: Directory path for CA certificate files (PEM)
-# client_cert2: File path to client certificate file
-# private_key2: File path to client private key file
-# private_key2_passwd: Password for private key file
-# dh_file2: File path to DH/DSA parameters file (in PEM format)
-# subject_match2: Substring to be matched against the subject of the
-# authentication server certificate. See subject_match for more details.
-# altsubject_match2: Semicolon separated string of entries to be matched
-# against the alternative subject name of the authentication server
-# certificate. See altsubject_match documentation for more details.
-# domain_suffix_match2: Constraint for server domain name. See
-# domain_suffix_match for more details.
-# ocsp2: See ocsp for more details.
-#
-# Separate machine credentials can be configured for EAP-TEAP Phase 2 with
-# "machine_" prefix (e.g., "machine_identity") in the configuration parameters.
-# See the parameters without that prefix for more details on the meaning and
-# format of each such parameter.
-#
-# fragment_size: Maximum EAP fragment size in bytes (default 1398).
-# This value limits the fragment size for EAP methods that support
-# fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set
-# small enough to make the EAP messages fit in MTU of the network
-# interface used for EAPOL. The default value is suitable for most
-# cases.
-#
-# ocsp: Whether to use/require OCSP to check server certificate
-# 0 = do not use OCSP stapling (TLS certificate status extension)
-# 1 = try to use OCSP stapling, but not require response
-# 2 = require valid OCSP stapling response
-# 3 = require valid OCSP stapling response for all not-trusted
-# certificates in the server certificate chain
-#
-# openssl_ciphers: OpenSSL specific cipher configuration
-# This can be used to override the global openssl_ciphers configuration
-# parameter (see above).
-#
-# erp: Whether EAP Re-authentication Protocol (ERP) is enabled
-#
-# EAP-FAST variables:
-# pac_file: File path for the PAC entries. wpa_supplicant will need to be able
-# to create this file and write updates to it when PAC is being
-# provisioned or refreshed. Full path to the file should be used since
-# working directory may change when wpa_supplicant is run in the
-# background. Alternatively, a named configuration blob can be used by
-# setting this to blob://<blob name>
-# phase1: fast_provisioning option can be used to enable in-line provisioning
-# of EAP-FAST credentials (PAC):
-# 0 = disabled,
-# 1 = allow unauthenticated provisioning,
-# 2 = allow authenticated provisioning,
-# 3 = allow both unauthenticated and authenticated provisioning
-# fast_max_pac_list_len=<num> option can be used to set the maximum
-# number of PAC entries to store in a PAC list (default: 10)
-# fast_pac_format=binary option can be used to select binary format for
-# storing PAC entries in order to save some space (the default
-# text format uses about 2.5 times the size of minimal binary
-# format)
-#
-# wpa_supplicant supports number of "EAP workarounds" to work around
-# interoperability issues with incorrectly behaving authentication servers.
-# These are enabled by default because some of the issues are present in large
-# number of authentication servers. Strict EAP conformance mode can be
-# configured by disabling workarounds with eap_workaround=0.
-
-# update_identifier: PPS MO ID
-# (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
-#
-# roaming_consortium_selection: Roaming Consortium Selection
-# The matching Roaming Consortium OI that was used to generate this
-# network profile.
-
-# Station inactivity limit
-#
-# If a station does not send anything in ap_max_inactivity seconds, an
-# empty data frame is sent to it in order to verify whether it is
-# still in range. If this frame is not ACKed, the station will be
-# disassociated and then deauthenticated. This feature is used to
-# clear station table of old entries when the STAs move out of the
-# range.
-#
-# The station can associate again with the AP if it is still in range;
-# this inactivity poll is just used as a nicer way of verifying
-# inactivity; i.e., client will not report broken connection because
-# disassociation frame is not sent immediately without first polling
-# the STA with a data frame.
-# default: 300 (i.e., 5 minutes)
-#ap_max_inactivity=300
-
-# DTIM period in Beacon intervals for AP mode (default: 2)
-#dtim_period=2
-
-# Beacon interval (default: 100 TU)
-#beacon_int=100
-
-# WPS in AP mode
-# 0 = WPS enabled and configured (default)
-# 1 = WPS disabled
-#wps_disabled=0
-
-# FILS DH Group
-# 0 = PFS disabled with FILS shared key authentication (default)
-# 1-65535 = DH Group to use for FILS PFS
-#fils_dh_group=0
-
-# DPP PFS
-# 0: allow PFS to be used or not used (default)
-# 1: require PFS to be used (note: not compatible with DPP R1)
-# 2: do not allow PFS to be used
-#dpp_pfs=0
-
-# Whether beacon protection is enabled
-# This depends on management frame protection (ieee80211w) being enabled and
-# beacon protection support indication from the driver.
-# 0 = disabled (default)
-# 1 = enabled
-#beacon_prot=0
-
-# OWE DH Group
-# 0: use default (19) first and then try all supported groups one by one if AP
-# rejects the selected group
-# 1-65535: DH Group to use for OWE
-# Groups 19 (NIST P-256), 20 (NIST P-384), and 21 (NIST P-521) are
-# currently supported.
-#owe_group=0
-
-# OWE-only mode (disable transition mode)
-# 0: enable transition mode (allow connection to either OWE or open BSS)
-# 1 = disable transition mode (allow connection only with OWE)
-#owe_only=0
-
-# OWE PTK derivation workaround
-# Initial OWE implementation used SHA256 when deriving the PTK for all
-# OWE groups. This was supposed to change to SHA384 for group 20 and
-# SHA512 for group 21. This parameter can be used to enable older
-# behavior mainly for testing purposes. There is no impact to group 19
-# behavior, but if enabled, this will make group 20 and 21 cases use
-# SHA256-based PTK derivation which will not work with the updated
-# OWE implementation on the AP side.
-#owe_ptk_workaround=0
-
-# Transition Disable indication
-# The AP can notify authenticated stations to disable transition mode
-# in their network profiles when the network has completed transition
-# steps, i.e., once sufficiently large number of APs in the ESS have
-# been updated to support the more secure alternative. When this
-# indication is used, the stations are expected to automatically
-# disable transition mode and less secure security options. This
-# includes use of WEP, TKIP (including use of TKIP as the group
-# cipher), and connections without PMF.
-# Bitmap bits:
-# bit 0 (0x01): WPA3-Personal (i.e., disable WPA2-Personal = WPA-PSK
-# and only allow SAE to be used)
-# bit 1 (0x02): SAE-PK (disable SAE without use of SAE-PK)
-# bit 2 (0x04): WPA3-Enterprise (move to requiring PMF)
-# bit 3 (0x08): Enhanced Open (disable use of open network; require
-# OWE)
-
-# SAE-PK mode
-# 0: automatic SAE/SAE-PK selection based on password; enable
-# transition mode (allow SAE authentication without SAE-PK)
-# 1: SAE-PK only (disable transition mode; allow SAE authentication
-# only with SAE-PK)
-# 2: disable SAE-PK (allow SAE authentication only without SAE-PK)
-#sae_pk=0
-
-# MAC address policy
-# 0 = use permanent MAC address
-# 1 = use random MAC address for each ESS connection
-# 2 = like 1, but maintain OUI (with local admin bit set)
-#mac_addr=0
-
-# disable_ht: Whether HT (802.11n) should be disabled.
-# 0 = HT enabled (if AP supports it)
-# 1 = HT disabled
-#
-# disable_ht40: Whether HT-40 (802.11n) should be disabled.
-# 0 = HT-40 enabled (if AP supports it)
-# 1 = HT-40 disabled
-#
-# disable_sgi: Whether SGI (short guard interval) should be disabled.
-# 0 = SGI enabled (if AP supports it)
-# 1 = SGI disabled
-#
-# disable_ldpc: Whether LDPC should be disabled.
-# 0 = LDPC enabled (if AP supports it)
-# 1 = LDPC disabled
-#
-# ht40_intolerant: Whether 40 MHz intolerant should be indicated.
-# 0 = 40 MHz tolerant (default)
-# 1 = 40 MHz intolerant
-#
-# ht_mcs: Configure allowed MCS rates.
-# Parsed as an array of bytes, in base-16 (ascii-hex)
-# ht_mcs="" // Use all available (default)
-# ht_mcs="0xff 00 00 00 00 00 00 00 00 00 " // Use MCS 0-7 only
-# ht_mcs="0xff ff 00 00 00 00 00 00 00 00 " // Use MCS 0-15 only
-#
-# disable_max_amsdu: Whether MAX_AMSDU should be disabled.
-# -1 = Do not make any changes.
-# 0 = Enable MAX-AMSDU if hardware supports it.
-# 1 = Disable AMSDU
-#
-# ampdu_factor: Maximum A-MPDU Length Exponent
-# Value: 0-3, see 7.3.2.56.3 in IEEE Std 802.11n-2009.
-#
-# ampdu_density: Allow overriding AMPDU density configuration.
-# Treated as hint by the kernel.
-# -1 = Do not make any changes.
-# 0-3 = Set AMPDU density (aka factor) to specified value.
-#
-# tx_stbc: Allow overriding STBC support for TX streams
-# Value: 0-1, see IEEE Std 802.11-2016, 9.4.2.56.2.
-# -1 = Do not make any changes (default)
-# 0 = Set if not supported
-# 1 = Set if supported
-#
-# rx_stbc: Allow overriding STBC support for RX streams
-# Value: 0-3, see IEEE Std 802.11-2016, 9.4.2.56.2.
-# -1 = Do not make any changes (default)
-# 0 = Set if not supported
-# 1 = Set for support of one spatial stream
-# 2 = Set for support of one and two spatial streams
-# 3 = Set for support of one, two and three spatial streams
-
-# disable_vht: Whether VHT should be disabled.
-# 0 = VHT enabled (if AP supports it)
-# 1 = VHT disabled
-#
-# vht_capa: VHT capabilities to set in the override
-# vht_capa_mask: mask of VHT capabilities
-#
-# vht_rx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for RX NSS 1-8
-# vht_tx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for TX NSS 1-8
-# 0: MCS 0-7
-# 1: MCS 0-8
-# 2: MCS 0-9
-# 3: not supported
-
-# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality
-# 0 = normal STA (default)
-# 1 = backhaul STA
-# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not
-# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
-# added to a bridge to allow forwarding frames over this backhaul link.
-
-##### Fast Session Transfer (FST) support #####################################
-#
-# The options in this section are only available when the build configuration
-# option CONFIG_FST is set while compiling wpa_supplicant. They allow this
-# interface to be a part of FST setup.
-#
-# FST is the transfer of a session from a channel to another channel, in the
-# same or different frequency bands.
-#
-# For details, see IEEE Std 802.11ad-2012.
-
-# Identifier of an FST Group the interface belongs to.
-#fst_group_id=bond0
-
-# Interface priority within the FST Group.
-# Announcing a higher priority for an interface means declaring it more
-# preferable for FST switch.
-# fst_priority is in 1..255 range with 1 being the lowest priority.
-#fst_priority=100
-
-# Default LLT value for this interface in milliseconds. The value used in case
-# no value provided during session setup. Default is 50 msec.
-# fst_llt is in 1..4294967 range (due to spec limitation, see 10.32.2.2
-# Transitioning between states).
-#fst_llt=100
-
-# BSS Transition Management
-# disable_btm - Disable BSS transition management in STA
-# Set to 0 to enable BSS transition management (default behavior)
-# Set to 1 to disable BSS transition management
-#disable_btm=0
-
-# Enable EDMG capability in STA/AP mode, default value is false
-#enable_edmg=1
-
-# This value is used to configure the channel bonding feature.
-# Default value is 0.
-# Relevant only if enable_edmg is true
-# In AP mode it defines the EDMG channel to use for AP operation.
-# In STA mode it defines the EDMG channel for connection (if supported by AP).
-#edmg_channel=9
-
-# Example blocks:
-
-# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
-network={
- ssid="simple"
- psk="very secret passphrase"
- priority=5
-}
-
-# Same as previous, but request SSID-specific scanning (for APs that reject
-# broadcast SSID)
-network={
- ssid="second ssid"
- scan_ssid=1
- psk="very secret passphrase"
- priority=2
-}
-
-# Only WPA-PSK is used. Any valid cipher combination is accepted.
-network={
- ssid="example"
- proto=WPA
- key_mgmt=WPA-PSK
- pairwise=CCMP TKIP
- group=CCMP TKIP WEP104 WEP40
- psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
- priority=2
-}
-
-# WPA-Personal(PSK) with TKIP and enforcement for frequent PTK rekeying
-network={
- ssid="example"
- proto=WPA
- key_mgmt=WPA-PSK
- pairwise=TKIP
- group=TKIP
- psk="not so secure passphrase"
- wpa_ptk_rekey=600
-}
-
-# Only WPA-EAP is used. Both CCMP and TKIP is accepted. An AP that used WEP104
-# or WEP40 as the group cipher will not be accepted.
-network={
- ssid="example"
- proto=RSN
- key_mgmt=WPA-EAP
- pairwise=CCMP TKIP
- group=CCMP TKIP
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- priority=1
-}
-
-# EAP-PEAP/MSCHAPv2 configuration for RADIUS servers that use the new peaplabel
-# (e.g., Radiator)
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=PEAP
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase1="peaplabel=1"
- phase2="auth=MSCHAPV2"
- priority=10
-}
-
-# EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the
-# unencrypted use. Real identity is sent only within an encrypted TLS tunnel.
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=TTLS
- identity="user@example.com"
- anonymous_identity="anonymous@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- priority=2
-}
-
-# EAP-TTLS/MSCHAPv2 configuration with anonymous identity for the unencrypted
-# use. Real identity is sent only within an encrypted TLS tunnel.
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=TTLS
- identity="user@example.com"
- anonymous_identity="anonymous@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- phase2="auth=MSCHAPV2"
-}
-
-# WPA-EAP, EAP-TTLS with different CA certificate used for outer and inner
-# authentication.
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=TTLS
- # Phase1 / outer authentication
- anonymous_identity="anonymous@example.com"
- ca_cert="/etc/cert/ca.pem"
- # Phase 2 / inner authentication
- phase2="autheap=TLS"
- ca_cert2="/etc/cert/ca2.pem"
- client_cert2="/etc/cer/user.pem"
- private_key2="/etc/cer/user.prv"
- private_key2_passwd="password"
- priority=2
-}
-
-# Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and
-# group cipher.
-network={
- ssid="example"
- bssid=00:11:22:33:44:55
- proto=WPA RSN
- key_mgmt=WPA-PSK WPA-EAP
- pairwise=CCMP
- group=CCMP
- psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
-}
-
-# Special characters in SSID, so use hex string. Default to WPA-PSK, WPA-EAP
-# and all valid ciphers.
-network={
- ssid=00010203
- psk=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
-}
-
-
-# EAP-SIM with a GSM SIM or USIM
-network={
- ssid="eap-sim-test"
- key_mgmt=WPA-EAP
- eap=SIM
- pin="1234"
- pcsc=""
-}
-
-
-# EAP-PSK
-network={
- ssid="eap-psk-test"
- key_mgmt=WPA-EAP
- eap=PSK
- anonymous_identity="eap_psk_user"
- password=06b4be19da289f475aa46a33cb793029
- identity="eap_psk_user@example.com"
-}
-
-
-# IEEE 802.1X/EAPOL with dynamically generated WEP keys (i.e., no WPA) using
-# EAP-TLS for authentication and key generation; require both unicast and
-# broadcast WEP keys.
-network={
- ssid="1x-test"
- key_mgmt=IEEE8021X
- eap=TLS
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- eapol_flags=3
-}
-
-
-# LEAP with dynamic WEP keys
-network={
- ssid="leap-example"
- key_mgmt=IEEE8021X
- eap=LEAP
- identity="user"
- password="foobar"
-}
-
-# EAP-IKEv2 using shared secrets for both server and peer authentication
-network={
- ssid="ikev2-example"
- key_mgmt=WPA-EAP
- eap=IKEV2
- identity="user"
- password="foobar"
-}
-
-# EAP-FAST with WPA (WPA or WPA2)
-network={
- ssid="eap-fast-test"
- key_mgmt=WPA-EAP
- eap=FAST
- anonymous_identity="FAST-000102030405"
- identity="username"
- password="password"
- phase1="fast_provisioning=1"
- pac_file="/etc/wpa_supplicant.eap-fast-pac"
-}
-
-network={
- ssid="eap-fast-test"
- key_mgmt=WPA-EAP
- eap=FAST
- anonymous_identity="FAST-000102030405"
- identity="username"
- password="password"
- phase1="fast_provisioning=1"
- pac_file="blob://eap-fast-pac"
-}
-
-# Plaintext connection (no WPA, no IEEE 802.1X)
-network={
- ssid="plaintext-test"
- key_mgmt=NONE
-}
-
-
-# Shared WEP key connection (no WPA, no IEEE 802.1X)
-network={
- ssid="static-wep-test"
- key_mgmt=NONE
- wep_key0="abcde"
- wep_key1=0102030405
- wep_key2="1234567890123"
- wep_tx_keyidx=0
- priority=5
-}
-
-
-# Shared WEP key connection (no WPA, no IEEE 802.1X) using Shared Key
-# IEEE 802.11 authentication
-network={
- ssid="static-wep-test2"
- key_mgmt=NONE
- wep_key0="abcde"
- wep_key1=0102030405
- wep_key2="1234567890123"
- wep_tx_keyidx=0
- priority=5
- auth_alg=SHARED
-}
-
-
-# IBSS/ad-hoc network with RSN
-network={
- ssid="ibss-rsn"
- key_mgmt=WPA-PSK
- proto=RSN
- psk="12345678"
- mode=1
- frequency=2412
- pairwise=CCMP
- group=CCMP
-}
-
-# IBSS/ad-hoc network with WPA-None/TKIP (deprecated)
-network={
- ssid="test adhoc"
- mode=1
- frequency=2412
- proto=WPA
- key_mgmt=WPA-NONE
- pairwise=NONE
- group=TKIP
- psk="secret passphrase"
-}
-
-# open mesh network
-network={
- ssid="test mesh"
- mode=5
- frequency=2437
- key_mgmt=NONE
-}
-
-# secure (SAE + AMPE) network
-network={
- ssid="secure mesh"
- mode=5
- frequency=2437
- key_mgmt=SAE
- psk="very secret passphrase"
-}
-
-
-# Catch all example that allows more or less all configuration modes
-network={
- ssid="example"
- scan_ssid=1
- key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
- pairwise=CCMP TKIP
- group=CCMP TKIP WEP104 WEP40
- psk="very secret passphrase"
- eap=TTLS PEAP TLS
- identity="user@example.com"
- password="foobar"
- ca_cert="/etc/cert/ca.pem"
- client_cert="/etc/cert/user.pem"
- private_key="/etc/cert/user.prv"
- private_key_passwd="password"
- phase1="peaplabel=0"
-}
-
-# Example of EAP-TLS with smartcard (openssl engine)
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=TLS
- proto=RSN
- pairwise=CCMP TKIP
- group=CCMP TKIP
- identity="user@example.com"
- ca_cert="/etc/cert/ca.pem"
-
- # Certificate and/or key identified by PKCS#11 URI (RFC7512)
- client_cert="pkcs11:manufacturer=piv_II;id=%01"
- private_key="pkcs11:manufacturer=piv_II;id=%01"
-
- # Optional PIN configuration; this can be left out and PIN will be
- # asked through the control interface
- pin="1234"
-}
-
-# Example configuration showing how to use an inlined blob as a CA certificate
-# data instead of using external file
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=TTLS
- identity="user@example.com"
- anonymous_identity="anonymous@example.com"
- password="foobar"
- ca_cert="blob://exampleblob"
- priority=20
-}
-
-blob-base64-exampleblob={
-SGVsbG8gV29ybGQhCg==
-}
-
-
-# Wildcard match for SSID (plaintext APs only). This example select any
-# open AP regardless of its SSID.
-network={
- key_mgmt=NONE
-}
-
-# Example configuration ignoring two APs - these will be ignored
-# for this network.
-network={
- ssid="example"
- psk="very secret passphrase"
- bssid_ignore=02:11:22:33:44:55 02:22:aa:44:55:66
-}
-
-# Example configuration limiting AP selection to a specific set of APs;
-# any other AP not matching the masked address will be ignored.
-network={
- ssid="example"
- psk="very secret passphrase"
- bssid_accept=02:55:ae:bc:00:00/ff:ff:ff:ff:00:00 00:00:77:66:55:44/00:00:ff:ff:ff:ff
-}
-
-# Example config file that will only scan on channel 36.
-freq_list=5180
-network={
- key_mgmt=NONE
-}
-
-
-# Example configuration using EAP-TTLS for authentication and key
-# generation for MACsec
-network={
- key_mgmt=IEEE8021X
- eap=TTLS
- phase2="auth=PAP"
- anonymous_identity="anonymous@example.com"
- identity="user@example.com"
- password="secretr"
- ca_cert="/etc/cert/ca.pem"
- eapol_flags=0
- macsec_policy=1
-}
-
-# Example configuration for MACsec with preshared key
-network={
- key_mgmt=NONE
- eapol_flags=0
- macsec_policy=1
- mka_cak=0123456789ABCDEF0123456789ABCDEF
- mka_ckn=6162636465666768696A6B6C6D6E6F707172737475767778797A303132333435
- mka_priority=128
-}
diff --git a/wpa_supplicant/wpa_supplicant_conf.mk b/wpa_supplicant/wpa_supplicant_conf.mk
deleted file mode 100644
index 74986ea6e628..000000000000
--- a/wpa_supplicant/wpa_supplicant_conf.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-#
-
-# Include this makefile to generate your hardware specific wpa_supplicant.conf
-# Requires: WIFI_DRIVER_SOCKET_IFACE
-
-LOCAL_PATH := $(call my-dir)
-
-########################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := wpa_supplicant.conf
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/wifi
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-WPA_SUPPLICANT_CONF_TEMPLATE := $(LOCAL_PATH)/wpa_supplicant_template.conf
-WPA_SUPPLICANT_CONF_SCRIPT := $(LOCAL_PATH)/wpa_supplicant_conf.sh
-$(LOCAL_BUILT_MODULE): PRIVATE_WIFI_DRIVER_SOCKET_IFACE := $(WIFI_DRIVER_SOCKET_IFACE)
-$(LOCAL_BUILT_MODULE): PRIVATE_WPA_SUPPLICANT_CONF_TEMPLATE := $(WPA_SUPPLICANT_CONF_TEMPLATE)
-$(LOCAL_BUILT_MODULE): PRIVATE_WPA_SUPPLICANT_CONF_SCRIPT := $(WPA_SUPPLICANT_CONF_SCRIPT)
-$(LOCAL_BUILT_MODULE) : $(WPA_SUPPLICANT_CONF_TEMPLATE) $(WPA_SUPPLICANT_CONF_SCRIPT)
- @echo Target wpa_supplicant.conf: $@
- @mkdir -p $(dir $@)
- $(hide) WIFI_DRIVER_SOCKET_IFACE="$(PRIVATE_WIFI_DRIVER_SOCKET_IFACE)" \
- bash $(PRIVATE_WPA_SUPPLICANT_CONF_SCRIPT) $(PRIVATE_WPA_SUPPLICANT_CONF_TEMPLATE) > $@
-
-########################
diff --git a/wpa_supplicant/wpa_supplicant_conf.sh b/wpa_supplicant/wpa_supplicant_conf.sh
deleted file mode 100755
index f36eef153c20..000000000000
--- a/wpa_supplicant/wpa_supplicant_conf.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# This software may be distributed under the terms of the BSD license.
-# See README for more details.
-#
-
-# Generate a wpa_supplicant.conf from the template.
-# $1: the template file name
-if [ -n "$WIFI_DRIVER_SOCKET_IFACE" ]
-then
- sed -e 's/#.*$//' -e 's/[ \t]*$//' -e '/^$/d' < $1 | sed -e "s/wlan0/$WIFI_DRIVER_SOCKET_IFACE/"
-else
- sed -e 's/#.*$//' -e 's/[ \t]*$//' -e '/^$/d' < $1
-fi
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
deleted file mode 100644
index 5fa765fda25c..000000000000
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ /dev/null
@@ -1,1889 +0,0 @@
-/*
- * wpa_supplicant - Internal definitions
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_I_H
-#define WPA_SUPPLICANT_I_H
-
-#include "utils/bitfield.h"
-#include "utils/list.h"
-#include "common/defs.h"
-#include "common/sae.h"
-#include "common/wpa_ctrl.h"
-#include "crypto/sha384.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "wps/wps_defs.h"
-#include "config_ssid.h"
-#include "wmm_ac.h"
-
-extern const char *const wpa_supplicant_version;
-extern const char *const wpa_supplicant_license;
-#ifndef CONFIG_NO_STDOUT_DEBUG
-extern const char *const wpa_supplicant_full_license1;
-extern const char *const wpa_supplicant_full_license2;
-extern const char *const wpa_supplicant_full_license3;
-extern const char *const wpa_supplicant_full_license4;
-extern const char *const wpa_supplicant_full_license5;
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
-struct wpa_sm;
-struct wpa_supplicant;
-struct ibss_rsn;
-struct scan_info;
-struct wpa_bss;
-struct wpa_scan_results;
-struct hostapd_hw_modes;
-struct wpa_driver_associate_params;
-struct wpa_cred;
-
-/*
- * Forward declarations of private structures used within the ctrl_iface
- * backends. Other parts of wpa_supplicant do not have access to data stored in
- * these structures.
- */
-struct ctrl_iface_priv;
-struct ctrl_iface_global_priv;
-struct wpas_dbus_priv;
-struct wpas_binder_priv;
-
-/**
- * struct wpa_interface - Parameters for wpa_supplicant_add_iface()
- */
-struct wpa_interface {
- /**
- * confname - Configuration name (file or profile) name
- *
- * This can also be %NULL when a configuration file is not used. In
- * that case, ctrl_interface must be set to allow the interface to be
- * configured.
- */
- const char *confname;
-
- /**
- * confanother - Additional configuration name (file or profile) name
- *
- * This can also be %NULL when the additional configuration file is not
- * used.
- */
- const char *confanother;
-
- /**
- * ctrl_interface - Control interface parameter
- *
- * If a configuration file is not used, this variable can be used to
- * set the ctrl_interface parameter that would have otherwise been read
- * from the configuration file. If both confname and ctrl_interface are
- * set, ctrl_interface is used to override the value from configuration
- * file.
- */
- const char *ctrl_interface;
-
- /**
- * driver - Driver interface name, or %NULL to use the default driver
- */
- const char *driver;
-
- /**
- * driver_param - Driver interface parameters
- *
- * If a configuration file is not used, this variable can be used to
- * set the driver_param parameters that would have otherwise been read
- * from the configuration file. If both confname and driver_param are
- * set, driver_param is used to override the value from configuration
- * file.
- */
- const char *driver_param;
-
- /**
- * ifname - Interface name
- */
- const char *ifname;
-
- /**
- * bridge_ifname - Optional bridge interface name
- *
- * If the driver interface (ifname) is included in a Linux bridge
- * device, the bridge interface may need to be used for receiving EAPOL
- * frames. This can be enabled by setting this variable to enable
- * receiving of EAPOL frames from an additional interface.
- */
- const char *bridge_ifname;
-
- /**
- * p2p_mgmt - Interface used for P2P management (P2P Device operations)
- *
- * Indicates whether wpas_p2p_init() must be called for this interface.
- * This is used only when the driver supports a dedicated P2P Device
- * interface that is not a network interface.
- */
- int p2p_mgmt;
-
-#ifdef CONFIG_MATCH_IFACE
- /**
- * matched - Interface was matched rather than specified
- *
- */
- enum {
- WPA_IFACE_NOT_MATCHED,
- WPA_IFACE_MATCHED_NULL,
- WPA_IFACE_MATCHED
- } matched;
-#endif /* CONFIG_MATCH_IFACE */
-};
-
-/**
- * struct wpa_params - Parameters for wpa_supplicant_init()
- */
-struct wpa_params {
- /**
- * daemonize - Run %wpa_supplicant in the background
- */
- int daemonize;
-
- /**
- * wait_for_monitor - Wait for a monitor program before starting
- */
- int wait_for_monitor;
-
- /**
- * pid_file - Path to a PID (process ID) file
- *
- * If this and daemonize are set, process ID of the background process
- * will be written to the specified file.
- */
- char *pid_file;
-
- /**
- * wpa_debug_level - Debugging verbosity level (e.g., MSG_INFO)
- */
- int wpa_debug_level;
-
- /**
- * wpa_debug_show_keys - Whether keying material is included in debug
- *
- * This parameter can be used to allow keying material to be included
- * in debug messages. This is a security risk and this option should
- * not be enabled in normal configuration. If needed during
- * development or while troubleshooting, this option can provide more
- * details for figuring out what is happening.
- */
- int wpa_debug_show_keys;
-
- /**
- * wpa_debug_timestamp - Whether to include timestamp in debug messages
- */
- int wpa_debug_timestamp;
-
- /**
- * ctrl_interface - Global ctrl_iface path/parameter
- */
- char *ctrl_interface;
-
- /**
- * ctrl_interface_group - Global ctrl_iface group
- */
- char *ctrl_interface_group;
-
- /**
- * dbus_ctrl_interface - Enable the DBus control interface
- */
- int dbus_ctrl_interface;
-
- /**
- * wpa_debug_file_path - Path of debug file or %NULL to use stdout
- */
- const char *wpa_debug_file_path;
-
- /**
- * wpa_debug_syslog - Enable log output through syslog
- */
- int wpa_debug_syslog;
-
- /**
- * wpa_debug_tracing - Enable log output through Linux tracing
- */
- int wpa_debug_tracing;
-
- /**
- * override_driver - Optional driver parameter override
- *
- * This parameter can be used to override the driver parameter in
- * dynamic interface addition to force a specific driver wrapper to be
- * used instead.
- */
- char *override_driver;
-
- /**
- * override_ctrl_interface - Optional ctrl_interface override
- *
- * This parameter can be used to override the ctrl_interface parameter
- * in dynamic interface addition to force a control interface to be
- * created.
- */
- char *override_ctrl_interface;
-
- /**
- * entropy_file - Optional entropy file
- *
- * This parameter can be used to configure wpa_supplicant to maintain
- * its internal entropy store over restarts.
- */
- char *entropy_file;
-
-#ifdef CONFIG_P2P
- /**
- * conf_p2p_dev - Configuration file used to hold the
- * P2P Device configuration parameters.
- *
- * This can also be %NULL. In such a case, if a P2P Device dedicated
- * interfaces is created, the main configuration file will be used.
- */
- char *conf_p2p_dev;
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_MATCH_IFACE
- /**
- * match_ifaces - Interface descriptions to match
- */
- struct wpa_interface *match_ifaces;
-
- /**
- * match_iface_count - Number of defined matching interfaces
- */
- int match_iface_count;
-#endif /* CONFIG_MATCH_IFACE */
-};
-
-struct p2p_srv_bonjour {
- struct dl_list list;
- struct wpabuf *query;
- struct wpabuf *resp;
-};
-
-struct p2p_srv_upnp {
- struct dl_list list;
- u8 version;
- char *service;
-};
-
-/**
- * struct wpa_global - Internal, global data for all %wpa_supplicant interfaces
- *
- * This structure is initialized by calling wpa_supplicant_init() when starting
- * %wpa_supplicant.
- */
-struct wpa_global {
- struct wpa_supplicant *ifaces;
- struct wpa_params params;
- struct ctrl_iface_global_priv *ctrl_iface;
- struct wpas_dbus_priv *dbus;
- struct wpas_binder_priv *binder;
- void **drv_priv;
- size_t drv_count;
- struct os_time suspend_time;
- struct p2p_data *p2p;
- struct wpa_supplicant *p2p_init_wpa_s;
- struct wpa_supplicant *p2p_group_formation;
- struct wpa_supplicant *p2p_invite_group;
- u8 p2p_dev_addr[ETH_ALEN];
- struct os_reltime p2p_go_wait_client;
- struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */
- struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
- int p2p_disabled;
- int cross_connection;
- int p2p_long_listen; /* remaining time in long Listen state in ms */
- struct wpa_freq_range_list p2p_disallow_freq;
- struct wpa_freq_range_list p2p_go_avoid_freq;
- enum wpa_conc_pref {
- WPA_CONC_PREF_NOT_SET,
- WPA_CONC_PREF_STA,
- WPA_CONC_PREF_P2P
- } conc_pref;
- unsigned int p2p_per_sta_psk:1;
- unsigned int p2p_fail_on_wps_complete:1;
- unsigned int p2p_24ghz_social_channels:1;
- unsigned int pending_p2ps_group:1;
- unsigned int pending_group_iface_for_p2ps:1;
- unsigned int pending_p2ps_group_freq;
-
-#ifdef CONFIG_WIFI_DISPLAY
- int wifi_display;
-#define MAX_WFD_SUBELEMS 12
- struct wpabuf *wfd_subelem[MAX_WFD_SUBELEMS];
-#endif /* CONFIG_WIFI_DISPLAY */
-
- struct psk_list_entry *add_psk; /* From group formation */
-};
-
-
-/**
- * struct wpa_radio - Internal data for per-radio information
- *
- * This structure is used to share data about configured interfaces
- * (struct wpa_supplicant) that share the same physical radio, e.g., to allow
- * better coordination of offchannel operations.
- */
-struct wpa_radio {
- char name[16]; /* from driver_ops get_radio_name() or empty if not
- * available */
- /** NULL if no external scan running. */
- struct wpa_supplicant *external_scan_req_interface;
- unsigned int num_active_works;
- struct dl_list ifaces; /* struct wpa_supplicant::radio_list entries */
- struct dl_list work; /* struct wpa_radio_work::list entries */
-};
-
-/**
- * Checks whether an external scan is running on a given radio.
- * @radio: Pointer to radio struct
- * Returns: true if an external scan is running, false otherwise.
- */
-static inline bool external_scan_running(struct wpa_radio *radio)
-{
- return radio && radio->external_scan_req_interface;
-}
-
-#define MAX_ACTIVE_WORKS 2
-
-
-/**
- * struct wpa_radio_work - Radio work item
- */
-struct wpa_radio_work {
- struct dl_list list;
- unsigned int freq; /* known frequency (MHz) or 0 for multiple/unknown */
- const char *type;
- struct wpa_supplicant *wpa_s;
- void (*cb)(struct wpa_radio_work *work, int deinit);
- void *ctx;
- unsigned int started:1;
- struct os_reltime time;
- unsigned int bands;
-};
-
-int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
- const char *type, int next,
- void (*cb)(struct wpa_radio_work *work, int deinit),
- void *ctx);
-void radio_work_done(struct wpa_radio_work *work);
-void radio_remove_works(struct wpa_supplicant *wpa_s,
- const char *type, int remove_all);
-void radio_remove_pending_work(struct wpa_supplicant *wpa_s, void *ctx);
-void radio_work_check_next(struct wpa_supplicant *wpa_s);
-struct wpa_radio_work *
-radio_work_pending(struct wpa_supplicant *wpa_s, const char *type);
-
-struct wpa_connect_work {
- unsigned int sme:1;
- unsigned int bss_removed:1;
- struct wpa_bss *bss;
- struct wpa_ssid *ssid;
-};
-
-int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
- struct wpa_ssid *test_ssid);
-void wpas_connect_work_free(struct wpa_connect_work *cwork);
-void wpas_connect_work_done(struct wpa_supplicant *wpa_s);
-
-struct wpa_external_work {
- unsigned int id;
- char type[100];
- unsigned int timeout;
-};
-
-enum wpa_radio_work_band wpas_freq_to_band(int freq);
-unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs);
-
-/**
- * offchannel_send_action_result - Result of offchannel send Action frame
- */
-enum offchannel_send_action_result {
- OFFCHANNEL_SEND_ACTION_SUCCESS /**< Frame was send and acknowledged */,
- OFFCHANNEL_SEND_ACTION_NO_ACK /**< Frame was sent, but not acknowledged
- */,
- OFFCHANNEL_SEND_ACTION_FAILED /**< Frame was not sent due to a failure
- */
-};
-
-struct wps_ap_info {
- u8 bssid[ETH_ALEN];
- enum wps_ap_info_type {
- WPS_AP_NOT_SEL_REG,
- WPS_AP_SEL_REG,
- WPS_AP_SEL_REG_OUR
- } type;
- unsigned int tries;
- struct os_reltime last_attempt;
- unsigned int pbc_active;
- u8 uuid[WPS_UUID_LEN];
-};
-
-#define WPA_FREQ_USED_BY_INFRA_STATION BIT(0)
-#define WPA_FREQ_USED_BY_P2P_CLIENT BIT(1)
-
-struct wpa_used_freq_data {
- int freq;
- unsigned int flags;
-};
-
-#define RRM_NEIGHBOR_REPORT_TIMEOUT 1 /* 1 second for AP to send a report */
-
-/*
- * struct rrm_data - Data used for managing RRM features
- */
-struct rrm_data {
- /* rrm_used - indication regarding the current connection */
- unsigned int rrm_used:1;
-
- /*
- * notify_neighbor_rep - Callback for notifying report requester
- */
- void (*notify_neighbor_rep)(void *ctx, struct wpabuf *neighbor_rep);
-
- /*
- * neighbor_rep_cb_ctx - Callback context
- * Received in the callback registration, and sent to the callback
- * function as a parameter.
- */
- void *neighbor_rep_cb_ctx;
-
- /* next_neighbor_rep_token - Next request's dialog token */
- u8 next_neighbor_rep_token;
-
- /* token - Dialog token of the current radio measurement */
- u8 token;
-
- /* destination address of the current radio measurement request */
- u8 dst_addr[ETH_ALEN];
-};
-
-enum wpa_supplicant_test_failure {
- WPAS_TEST_FAILURE_NONE,
- WPAS_TEST_FAILURE_SCAN_TRIGGER,
-};
-
-struct icon_entry {
- struct dl_list list;
- u8 bssid[ETH_ALEN];
- u8 dialog_token;
- char *file_name;
- u8 *image;
- size_t image_len;
-};
-
-struct wpa_bss_tmp_disallowed {
- struct dl_list list;
- u8 bssid[ETH_ALEN];
- int rssi_threshold;
-};
-
-struct beacon_rep_data {
- u8 token;
- u8 last_indication;
- struct wpa_driver_scan_params scan_params;
- u8 ssid[SSID_MAX_LEN];
- size_t ssid_len;
- u8 bssid[ETH_ALEN];
- enum beacon_report_detail report_detail;
- struct bitfield *eids;
-};
-
-
-struct external_pmksa_cache {
- struct dl_list list;
- void *pmksa_cache;
-};
-
-struct fils_hlp_req {
- struct dl_list list;
- u8 dst[ETH_ALEN];
- struct wpabuf *pkt;
-};
-
-struct driver_signal_override {
- struct dl_list list;
- u8 bssid[ETH_ALEN];
- int si_current_signal;
- int si_avg_signal;
- int si_avg_beacon_signal;
- int si_current_noise;
- int scan_level;
-};
-
-struct robust_av_data {
- u8 dialog_token;
- enum scs_request_type request_type;
- u8 up_bitmap;
- u8 up_limit;
- u32 stream_timeout;
- u8 frame_classifier[48];
- size_t frame_classifier_len;
- bool valid_config;
-};
-
-struct dscp_policy_status {
- u8 id;
- u8 status;
-};
-
-struct dscp_resp_data {
- bool more;
- bool reset;
- bool solicited;
- struct dscp_policy_status *policy;
- int num_policies;
-};
-
-#ifdef CONFIG_PASN
-
-struct pasn_fils {
- u8 nonce[FILS_NONCE_LEN];
- u8 anonce[FILS_NONCE_LEN];
- u8 session[FILS_SESSION_LEN];
- u8 erp_pmkid[PMKID_LEN];
- bool completed;
-};
-
-struct wpas_pasn {
- int akmp;
- int cipher;
- u16 group;
- int freq;
- size_t kdk_len;
-
- u8 trans_seq;
- u8 status;
-
- u8 bssid[ETH_ALEN];
- size_t pmk_len;
- u8 pmk[PMK_LEN_MAX];
- bool using_pmksa;
-
- u8 hash[SHA384_MAC_LEN];
-
- struct wpabuf *beacon_rsne_rsnxe;
- struct wpa_ptk ptk;
- struct crypto_ecdh *ecdh;
-
- struct wpabuf *comeback;
- u16 comeback_after;
-
-#ifdef CONFIG_SAE
- struct sae_data sae;
-#endif /* CONFIG_SAE */
-
- struct wpa_ssid *ssid;
-
-#ifdef CONFIG_FILS
- struct pasn_fils fils;
-#endif /* CONFIG_FILS */
-
-#ifdef CONFIG_IEEE80211R
- u8 pmk_r1[PMK_LEN_MAX];
- size_t pmk_r1_len;
- u8 pmk_r1_name[WPA_PMK_NAME_LEN];
-#endif /* CONFIG_IEEE80211R */
-};
-#endif /* CONFIG_PASN */
-
-
-enum ip_version {
- IPV4 = 4,
- IPV6 = 6,
-};
-
-
-struct ipv4_params {
- struct in_addr src_ip;
- struct in_addr dst_ip;
- u16 src_port;
- u16 dst_port;
- u8 dscp;
- u8 protocol;
- u8 param_mask;
-};
-
-
-struct ipv6_params {
- struct in6_addr src_ip;
- struct in6_addr dst_ip;
- u16 src_port;
- u16 dst_port;
- u8 dscp;
- u8 next_header;
- u8 flow_label[3];
- u8 param_mask;
-};
-
-
-struct type4_params {
- u8 classifier_mask;
- enum ip_version ip_version;
- union {
- struct ipv4_params v4;
- struct ipv6_params v6;
- } ip_params;
-};
-
-
-struct type10_params {
- u8 prot_instance;
- u8 prot_number;
- u8 *filter_value;
- u8 *filter_mask;
- size_t filter_len;
-};
-
-
-struct tclas_element {
- u8 user_priority;
- u8 classifier_type;
- union {
- struct type4_params type4_param;
- struct type10_params type10_param;
- } frame_classifier;
-};
-
-
-struct scs_desc_elem {
- u8 scs_id;
- enum scs_request_type request_type;
- u8 intra_access_priority;
- bool scs_up_avail;
- struct tclas_element *tclas_elems;
- unsigned int num_tclas_elem;
- u8 tclas_processing;
-};
-
-
-struct scs_robust_av_data {
- struct scs_desc_elem *scs_desc_elems;
- unsigned int num_scs_desc;
-};
-
-
-enum scs_response_status {
- SCS_DESC_SENT = 0,
- SCS_DESC_SUCCESS = 1,
-};
-
-
-struct active_scs_elem {
- struct dl_list list;
- u8 scs_id;
- enum scs_response_status status;
-};
-
-
-/**
- * struct wpa_supplicant - Internal data for wpa_supplicant interface
- *
- * This structure contains the internal data for core wpa_supplicant code. This
- * should be only used directly from the core code. However, a pointer to this
- * data is used from other files as an arbitrary context pointer in calls to
- * core functions.
- */
-struct wpa_supplicant {
- struct wpa_global *global;
- struct wpa_radio *radio; /* shared radio context */
- struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */
- struct wpa_supplicant *parent;
- struct wpa_supplicant *p2pdev;
- struct wpa_supplicant *next;
- struct l2_packet_data *l2;
- struct l2_packet_data *l2_br;
- struct os_reltime roam_start;
- struct os_reltime roam_time;
- struct os_reltime session_start;
- struct os_reltime session_length;
- unsigned char own_addr[ETH_ALEN];
- unsigned char perm_addr[ETH_ALEN];
- char ifname[100];
-#ifdef CONFIG_MATCH_IFACE
- int matched;
-#endif /* CONFIG_MATCH_IFACE */
-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
- char *dbus_new_path;
- char *dbus_groupobj_path;
-#ifdef CONFIG_AP
- char *preq_notify_peer;
-#endif /* CONFIG_AP */
-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_BINDER
- const void *binder_object_key;
-#endif /* CONFIG_CTRL_IFACE_BINDER */
- char bridge_ifname[16];
-
- char *confname;
- char *confanother;
-
- struct wpa_config *conf;
- int countermeasures;
- struct os_reltime last_michael_mic_error;
- u8 bssid[ETH_ALEN];
- u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
- * field contains the target BSSID. */
- int reassociate; /* reassociation requested */
- bool roam_in_progress; /* roam in progress */
- unsigned int reassoc_same_bss:1; /* reassociating to the same BSS */
- unsigned int reassoc_same_ess:1; /* reassociating to the same ESS */
- int disconnected; /* all connections disabled; i.e., do no reassociate
- * before this has been cleared */
- struct wpa_ssid *current_ssid;
- struct wpa_ssid *last_ssid;
- struct wpa_bss *current_bss;
- int ap_ies_from_associnfo;
- unsigned int assoc_freq;
- u8 *last_con_fail_realm;
- size_t last_con_fail_realm_len;
-
- /* Selected configuration (based on Beacon/ProbeResp WPA IE) */
- int pairwise_cipher;
- int deny_ptk0_rekey;
- int group_cipher;
- int key_mgmt;
- int wpa_proto;
- int mgmt_group_cipher;
-
- void *drv_priv; /* private data used by driver_ops */
- void *global_drv_priv;
-
- u8 *bssid_filter;
- size_t bssid_filter_count;
-
- u8 *disallow_aps_bssid;
- size_t disallow_aps_bssid_count;
- struct wpa_ssid_value *disallow_aps_ssid;
- size_t disallow_aps_ssid_count;
-
- u32 setband_mask;
-
- /* Preferred network for the next connection attempt */
- struct wpa_ssid *next_ssid;
-
- /* previous scan was wildcard when interleaving between
- * wildcard scans and specific SSID scan when max_ssids=1 */
- int prev_scan_wildcard;
- struct wpa_ssid *prev_scan_ssid; /* previously scanned SSID;
- * NULL = not yet initialized (start
- * with wildcard SSID)
- * WILDCARD_SSID_SCAN = wildcard
- * SSID was used in the previous scan
- */
-#define WILDCARD_SSID_SCAN ((struct wpa_ssid *) 1)
-
- struct wpa_ssid *prev_sched_ssid; /* last SSID used in sched scan */
- int sched_scan_timeout;
- int first_sched_scan;
- int sched_scan_timed_out;
- struct sched_scan_plan *sched_scan_plans;
- size_t sched_scan_plans_num;
-
- void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
- void (*scan_res_fail_handler)(struct wpa_supplicant *wpa_s);
- struct dl_list bss; /* struct wpa_bss::list */
- struct dl_list bss_id; /* struct wpa_bss::list_id */
- size_t num_bss;
- unsigned int bss_update_idx;
- unsigned int bss_next_id;
-
- /*
- * Pointers to BSS entries in the order they were in the last scan
- * results.
- */
- struct wpa_bss **last_scan_res;
- size_t last_scan_res_used;
- size_t last_scan_res_size;
- struct os_reltime last_scan;
-
- const struct wpa_driver_ops *driver;
- int interface_removed; /* whether the network interface has been
- * removed */
- struct wpa_sm *wpa;
- struct ptksa_cache *ptksa;
-
- struct eapol_sm *eapol;
-
- struct ctrl_iface_priv *ctrl_iface;
-
- enum wpa_states wpa_state;
- struct wpa_radio_work *scan_work;
- int scanning;
- int sched_scanning;
- unsigned int sched_scan_stop_req:1;
- int new_connection;
-
- int eapol_received; /* number of EAPOL packets received after the
- * previous association event */
-
- u8 rsnxe[20];
- size_t rsnxe_len;
-
- struct scard_data *scard;
- char imsi[20];
- int mnc_len;
-
- unsigned char last_eapol_src[ETH_ALEN];
-
- unsigned int keys_cleared; /* bitfield of key indexes that the driver is
- * known not to be configured with a key */
-
- struct wpa_bssid_ignore *bssid_ignore;
-
- /* Number of connection failures since last successful connection */
- unsigned int consecutive_conn_failures;
-
- /**
- * scan_req - Type of the scan request
- */
- enum scan_req_type {
- /**
- * NORMAL_SCAN_REQ - Normal scan request
- *
- * This is used for scans initiated by wpa_supplicant to find an
- * AP for a connection.
- */
- NORMAL_SCAN_REQ,
-
- /**
- * INITIAL_SCAN_REQ - Initial scan request
- *
- * This is used for the first scan on an interface to force at
- * least one scan to be run even if the configuration does not
- * include any enabled networks.
- */
- INITIAL_SCAN_REQ,
-
- /**
- * MANUAL_SCAN_REQ - Manual scan request
- *
- * This is used for scans where the user request a scan or
- * a specific wpa_supplicant operation (e.g., WPS) requires scan
- * to be run.
- */
- MANUAL_SCAN_REQ
- } scan_req, last_scan_req;
- enum wpa_states scan_prev_wpa_state;
- struct os_reltime scan_trigger_time, scan_start_time;
- /* Minimum freshness requirement for connection purposes */
- struct os_reltime scan_min_time;
- int scan_runs; /* number of scan runs since WPS was started */
- int *next_scan_freqs;
- int *select_network_scan_freqs;
- int *manual_scan_freqs;
- int *manual_sched_scan_freqs;
- unsigned int manual_scan_passive:1;
- unsigned int manual_scan_use_id:1;
- unsigned int manual_scan_only_new:1;
- unsigned int own_scan_requested:1;
- unsigned int own_scan_running:1;
- unsigned int clear_driver_scan_cache:1;
- unsigned int manual_scan_id;
- int scan_interval; /* time in sec between scans to find suitable AP */
- int normal_scans; /* normal scans run before sched_scan */
- int scan_for_connection; /* whether the scan request was triggered for
- * finding a connection */
- /*
- * A unique cookie representing the vendor scan request. This cookie is
- * returned from the driver interface. 0 indicates that there is no
- * pending vendor scan request.
- */
- u64 curr_scan_cookie;
-#define MAX_SCAN_ID 16
- int scan_id[MAX_SCAN_ID];
- unsigned int scan_id_count;
- u8 next_scan_bssid[ETH_ALEN];
- unsigned int next_scan_bssid_wildcard_ssid:1;
-
- struct wpa_ssid_value *ssids_from_scan_req;
- unsigned int num_ssids_from_scan_req;
- int *last_scan_freqs;
- unsigned int num_last_scan_freqs;
- unsigned int suitable_network;
- unsigned int no_suitable_network;
-
- u64 drv_flags;
- u64 drv_flags2;
- unsigned int drv_enc;
- unsigned int drv_rrm_flags;
-
- /*
- * A bitmap of supported protocols for probe response offload. See
- * struct wpa_driver_capa in driver.h
- */
- unsigned int probe_resp_offloads;
-
- /* extended capabilities supported by the driver */
- const u8 *extended_capa, *extended_capa_mask;
- unsigned int extended_capa_len;
-
- int max_scan_ssids;
- int max_sched_scan_ssids;
- unsigned int max_sched_scan_plans;
- unsigned int max_sched_scan_plan_interval;
- unsigned int max_sched_scan_plan_iterations;
- int sched_scan_supported;
- unsigned int max_match_sets;
- unsigned int max_remain_on_chan;
- unsigned int max_stations;
-
- int pending_mic_error_report;
- int pending_mic_error_pairwise;
- int mic_errors_seen; /* Michael MIC errors with the current PTK */
-
- struct wps_context *wps;
- int wps_success; /* WPS success event received */
- struct wps_er *wps_er;
- unsigned int wps_run;
- struct os_reltime wps_pin_start_time;
- bool bssid_ignore_cleared;
-
- struct wpabuf *pending_eapol_rx;
- struct os_reltime pending_eapol_rx_time;
- u8 pending_eapol_rx_src[ETH_ALEN];
- unsigned int last_eapol_matches_bssid:1;
- unsigned int eap_expected_failure:1;
- unsigned int reattach:1; /* reassociation to the same BSS requested */
- unsigned int mac_addr_changed:1;
- unsigned int added_vif:1;
- unsigned int wnmsleep_used:1;
- unsigned int owe_transition_select:1;
- unsigned int owe_transition_search:1;
- unsigned int connection_set:1;
- unsigned int connection_ht:1;
- unsigned int connection_vht:1;
- unsigned int connection_he:1;
- unsigned int disable_mbo_oce:1;
-
- struct os_reltime last_mac_addr_change;
- int last_mac_addr_style;
-
- struct ibss_rsn *ibss_rsn;
-
- int set_sta_uapsd;
- int sta_uapsd;
- int set_ap_uapsd;
- int ap_uapsd;
- int auth_alg;
- u16 last_owe_group;
-
-#ifdef CONFIG_SME
- struct {
- u8 ssid[SSID_MAX_LEN];
- size_t ssid_len;
- int freq;
- u8 assoc_req_ie[1500];
- size_t assoc_req_ie_len;
- int mfp;
- int ft_used;
- u8 mobility_domain[2];
- u8 *ft_ies;
- size_t ft_ies_len;
- u8 prev_bssid[ETH_ALEN];
- int prev_bssid_set;
- int auth_alg;
- int proto;
-
- int sa_query_count; /* number of pending SA Query requests;
- * 0 = no SA Query in progress */
- int sa_query_timed_out;
- u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN *
- * sa_query_count octets of pending
- * SA Query transaction identifiers */
- struct os_reltime sa_query_start;
- struct os_reltime last_unprot_disconnect;
- enum { HT_SEC_CHAN_UNKNOWN,
- HT_SEC_CHAN_ABOVE,
- HT_SEC_CHAN_BELOW } ht_sec_chan;
- u8 sched_obss_scan;
- u16 obss_scan_int;
- u16 bss_max_idle_period;
-#ifdef CONFIG_SAE
- struct sae_data sae;
- struct wpabuf *sae_token;
- int sae_group_index;
- unsigned int sae_pmksa_caching:1;
- u16 seq_num;
- u8 ext_auth_bssid[ETH_ALEN];
- u8 ext_auth_ssid[SSID_MAX_LEN];
- size_t ext_auth_ssid_len;
- int *sae_rejected_groups;
-#endif /* CONFIG_SAE */
- } sme;
-#endif /* CONFIG_SME */
-
-#ifdef CONFIG_AP
- struct hostapd_iface *ap_iface;
- void (*ap_configured_cb)(void *ctx, void *data);
- void *ap_configured_cb_ctx;
- void *ap_configured_cb_data;
-#endif /* CONFIG_AP */
-
- struct hostapd_iface *ifmsh;
-#ifdef CONFIG_MESH
- struct mesh_rsn *mesh_rsn;
- int mesh_if_idx;
- unsigned int mesh_if_created:1;
- unsigned int mesh_ht_enabled:1;
- unsigned int mesh_vht_enabled:1;
- unsigned int mesh_he_enabled:1;
- struct wpa_driver_mesh_join_params *mesh_params;
-#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- /* struct external_pmksa_cache::list */
- struct dl_list mesh_external_pmksa_cache;
-#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
-#endif /* CONFIG_MESH */
-
- unsigned int off_channel_freq;
- struct wpabuf *pending_action_tx;
- u8 pending_action_src[ETH_ALEN];
- u8 pending_action_dst[ETH_ALEN];
- u8 pending_action_bssid[ETH_ALEN];
- unsigned int pending_action_freq;
- int pending_action_no_cck;
- int pending_action_without_roc;
- unsigned int pending_action_tx_done:1;
- void (*pending_action_tx_status_cb)(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result
- result);
- unsigned int roc_waiting_drv_freq;
- int action_tx_wait_time;
- int action_tx_wait_time_used;
-
- int p2p_mgmt;
-
-#ifdef CONFIG_P2P
- struct p2p_go_neg_results *go_params;
- int create_p2p_iface;
- u8 pending_interface_addr[ETH_ALEN];
- char pending_interface_name[100];
- int pending_interface_type;
- int p2p_group_idx;
- unsigned int pending_listen_freq;
- unsigned int pending_listen_duration;
- enum {
- NOT_P2P_GROUP_INTERFACE,
- P2P_GROUP_INTERFACE_PENDING,
- P2P_GROUP_INTERFACE_GO,
- P2P_GROUP_INTERFACE_CLIENT
- } p2p_group_interface;
- struct p2p_group *p2p_group;
- char p2p_pin[10];
- int p2p_wps_method;
- u8 p2p_auth_invite[ETH_ALEN];
- int p2p_sd_over_ctrl_iface;
- int p2p_in_provisioning;
- int p2p_in_invitation;
- int p2p_invite_go_freq;
- int pending_invite_ssid_id;
- int show_group_started;
- u8 go_dev_addr[ETH_ALEN];
- int pending_pd_before_join;
- u8 pending_join_iface_addr[ETH_ALEN];
- u8 pending_join_dev_addr[ETH_ALEN];
- int pending_join_wps_method;
- u8 p2p_join_ssid[SSID_MAX_LEN];
- size_t p2p_join_ssid_len;
- int p2p_join_scan_count;
- int auto_pd_scan_retry;
- int force_long_sd;
- u16 pending_pd_config_methods;
- enum {
- NORMAL_PD, AUTO_PD_GO_NEG, AUTO_PD_JOIN, AUTO_PD_ASP
- } pending_pd_use;
-
- /*
- * Whether cross connection is disallowed by the AP to which this
- * interface is associated (only valid if there is an association).
- */
- int cross_connect_disallowed;
-
- /*
- * Whether this P2P group is configured to use cross connection (only
- * valid if this is P2P GO interface). The actual cross connect packet
- * forwarding may not be configured depending on the uplink status.
- */
- int cross_connect_enabled;
-
- /* Whether cross connection forwarding is in use at the moment. */
- int cross_connect_in_use;
-
- /*
- * Uplink interface name for cross connection
- */
- char cross_connect_uplink[100];
-
- unsigned int p2p_auto_join:1;
- unsigned int p2p_auto_pd:1;
- unsigned int p2p_go_do_acs:1;
- unsigned int p2p_persistent_group:1;
- unsigned int p2p_fallback_to_go_neg:1;
- unsigned int p2p_pd_before_go_neg:1;
- unsigned int p2p_go_ht40:1;
- unsigned int p2p_go_vht:1;
- unsigned int p2p_go_edmg:1;
- unsigned int p2p_go_he:1;
- unsigned int user_initiated_pd:1;
- unsigned int p2p_go_group_formation_completed:1;
- unsigned int group_formation_reported:1;
- unsigned int waiting_presence_resp;
- int p2p_first_connection_timeout;
- unsigned int p2p_nfc_tag_enabled:1;
- unsigned int p2p_peer_oob_pk_hash_known:1;
- unsigned int p2p_disable_ip_addr_req:1;
- unsigned int p2ps_method_config_any:1;
- unsigned int p2p_cli_probe:1;
- unsigned int p2p_go_allow_dfs:1;
- enum hostapd_hw_mode p2p_go_acs_band;
- int p2p_persistent_go_freq;
- int p2p_persistent_id;
- int p2p_go_intent;
- int p2p_connect_freq;
- struct os_reltime p2p_auto_started;
- struct wpa_ssid *p2p_last_4way_hs_fail;
- struct wpa_radio_work *p2p_scan_work;
- struct wpa_radio_work *p2p_listen_work;
- struct wpa_radio_work *p2p_send_action_work;
-
- u16 p2p_oob_dev_pw_id; /* OOB Device Password Id for group formation */
- struct wpabuf *p2p_oob_dev_pw; /* OOB Device Password for group
- * formation */
- u8 p2p_peer_oob_pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
- u8 p2p_ip_addr_info[3 * 4];
-
- /* group common frequencies */
- int *p2p_group_common_freqs;
- unsigned int p2p_group_common_freqs_num;
- u8 p2ps_join_addr[ETH_ALEN];
-
- unsigned int p2p_go_max_oper_chwidth;
- unsigned int p2p_go_vht_center_freq2;
- int p2p_lo_started;
-#endif /* CONFIG_P2P */
-
- struct wpa_ssid *bgscan_ssid;
- const struct bgscan_ops *bgscan;
- void *bgscan_priv;
-
- const struct autoscan_ops *autoscan;
- struct wpa_driver_scan_params *autoscan_params;
- void *autoscan_priv;
-
- struct wpa_ssid *connect_without_scan;
-
- struct wps_ap_info *wps_ap;
- size_t num_wps_ap;
- int wps_ap_iter;
-
- int after_wps;
- int known_wps_freq;
- unsigned int wps_freq;
- int wps_fragment_size;
- int auto_reconnect_disabled;
-
- /* Channel preferences for AP/P2P GO use */
- int best_24_freq;
- int best_5_freq;
- int best_overall_freq;
-
- struct gas_query *gas;
- struct gas_server *gas_server;
-
-#ifdef CONFIG_INTERWORKING
- unsigned int fetch_anqp_in_progress:1;
- unsigned int network_select:1;
- unsigned int auto_select:1;
- unsigned int auto_network_select:1;
- unsigned int interworking_fast_assoc_tried:1;
- unsigned int fetch_all_anqp:1;
- unsigned int fetch_osu_info:1;
- unsigned int fetch_osu_waiting_scan:1;
- unsigned int fetch_osu_icon_in_progress:1;
- struct wpa_bss *interworking_gas_bss;
- unsigned int osu_icon_id;
- struct dl_list icon_head; /* struct icon_entry */
- struct osu_provider *osu_prov;
- size_t osu_prov_count;
- struct os_reltime osu_icon_fetch_start;
- unsigned int num_osu_scans;
- unsigned int num_prov_found;
-#endif /* CONFIG_INTERWORKING */
- unsigned int drv_capa_known;
-
- struct {
- struct hostapd_hw_modes *modes;
- u16 num_modes;
- u16 flags;
- } hw;
- enum local_hw_capab {
- CAPAB_NO_HT_VHT,
- CAPAB_HT,
- CAPAB_HT40,
- CAPAB_VHT,
- } hw_capab;
-#ifdef CONFIG_MACSEC
- struct ieee802_1x_kay *kay;
-#endif /* CONFIG_MACSEC */
-
- int pno;
- int pno_sched_pending;
-
- /* WLAN_REASON_* reason codes. Negative if locally generated. */
- int disconnect_reason;
-
- /* WLAN_STATUS_* status codes from last received Authentication frame
- * from the AP. */
- u16 auth_status_code;
-
- /* WLAN_STATUS_* status codes from (Re)Association Response frame. */
- u16 assoc_status_code;
-
- struct ext_password_data *ext_pw;
-
- struct wpabuf *last_gas_resp, *prev_gas_resp;
- u8 last_gas_addr[ETH_ALEN], prev_gas_addr[ETH_ALEN];
- u8 last_gas_dialog_token, prev_gas_dialog_token;
-
- unsigned int no_keep_alive:1;
- unsigned int ext_mgmt_frame_handling:1;
- unsigned int ext_eapol_frame_io:1;
- unsigned int wmm_ac_supported:1;
- unsigned int ext_work_in_progress:1;
- unsigned int own_disconnect_req:1;
- unsigned int own_reconnect_req:1;
- unsigned int ignore_post_flush_scan_res:1;
-
-#define MAC_ADDR_RAND_SCAN BIT(0)
-#define MAC_ADDR_RAND_SCHED_SCAN BIT(1)
-#define MAC_ADDR_RAND_PNO BIT(2)
-#define MAC_ADDR_RAND_ALL (MAC_ADDR_RAND_SCAN | \
- MAC_ADDR_RAND_SCHED_SCAN | \
- MAC_ADDR_RAND_PNO)
- unsigned int mac_addr_rand_supported;
- unsigned int mac_addr_rand_enable;
-
- /* MAC Address followed by mask (2 * ETH_ALEN) */
- u8 *mac_addr_scan;
- u8 *mac_addr_sched_scan;
- u8 *mac_addr_pno;
-
-#ifdef CONFIG_WNM
- u8 wnm_dialog_token;
- u8 wnm_reply;
- u8 wnm_num_neighbor_report;
- u8 wnm_mode;
- u16 wnm_dissoc_timer;
- u8 wnm_bss_termination_duration[12];
- struct neighbor_report *wnm_neighbor_report_elements;
- struct os_reltime wnm_cand_valid_until;
- u8 wnm_cand_from_bss[ETH_ALEN];
- enum bss_trans_mgmt_status_code bss_tm_status;
- struct wpabuf *coloc_intf_elems;
- u8 coloc_intf_dialog_token;
- u8 coloc_intf_auto_report;
- u8 coloc_intf_timeout;
-#ifdef CONFIG_MBO
- unsigned int wnm_mbo_trans_reason_present:1;
- u8 wnm_mbo_transition_reason;
-#endif /* CONFIG_MBO */
-#endif /* CONFIG_WNM */
-
-#ifdef CONFIG_TESTING_GET_GTK
- u8 last_gtk[32];
- size_t last_gtk_len;
-#endif /* CONFIG_TESTING_GET_GTK */
-
- unsigned int num_multichan_concurrent;
- struct wpa_radio_work *connect_work;
-
- unsigned int ext_work_id;
-
- struct wpabuf *vendor_elem[NUM_VENDOR_ELEM_FRAMES];
-
-#ifdef CONFIG_TESTING_OPTIONS
- struct l2_packet_data *l2_test;
- unsigned int extra_roc_dur;
- enum wpa_supplicant_test_failure test_failure;
- char *get_pref_freq_list_override;
- unsigned int reject_btm_req_reason;
- unsigned int p2p_go_csa_on_inv:1;
- unsigned int ignore_auth_resp:1;
- unsigned int ignore_assoc_disallow:1;
- unsigned int disable_sa_query:1;
- unsigned int testing_resend_assoc:1;
- unsigned int ignore_sae_h2e_only:1;
- int ft_rsnxe_used;
- struct wpabuf *sae_commit_override;
- enum wpa_alg last_tk_alg;
- u8 last_tk_addr[ETH_ALEN];
- int last_tk_key_idx;
- u8 last_tk[WPA_TK_MAX_LEN];
- size_t last_tk_len;
- struct wpabuf *last_assoc_req_wpa_ie;
- int *extra_sae_rejected_groups;
- struct wpabuf *rsne_override_eapol;
- struct wpabuf *rsnxe_override_assoc;
- struct wpabuf *rsnxe_override_eapol;
- struct dl_list drv_signal_override;
- unsigned int oci_freq_override_eapol;
- unsigned int oci_freq_override_saquery_req;
- unsigned int oci_freq_override_saquery_resp;
- unsigned int oci_freq_override_eapol_g2;
- unsigned int oci_freq_override_ft_assoc;
- unsigned int oci_freq_override_fils_assoc;
- unsigned int oci_freq_override_wnm_sleep;
-#endif /* CONFIG_TESTING_OPTIONS */
-
- struct wmm_ac_assoc_data *wmm_ac_assoc_info;
- struct wmm_tspec_element *tspecs[WMM_AC_NUM][TS_DIR_IDX_COUNT];
- struct wmm_ac_addts_request *addts_request;
- u8 wmm_ac_last_dialog_token;
- struct wmm_tspec_element *last_tspecs;
- u8 last_tspecs_count;
-
- struct rrm_data rrm;
- struct beacon_rep_data beacon_rep_data;
-
-#ifdef CONFIG_FST
- struct fst_iface *fst;
- const struct wpabuf *fst_ies;
- struct wpabuf *received_mb_ies;
-#endif /* CONFIG_FST */
-
-#ifdef CONFIG_MBO
- /* Multiband operation non-preferred channel */
- struct wpa_mbo_non_pref_channel {
- enum mbo_non_pref_chan_reason reason;
- u8 oper_class;
- u8 chan;
- u8 preference;
- } *non_pref_chan;
- size_t non_pref_chan_num;
- u8 mbo_wnm_token;
- /**
- * enable_oce - Enable OCE if it is enabled by user and device also
- * supports OCE.
- * User can enable OCE with wpa_config's 'oce' parameter as follows -
- * - Set BIT(0) to enable OCE in non-AP STA mode.
- * - Set BIT(1) to enable OCE in STA-CFON mode.
- */
- u8 enable_oce;
-#endif /* CONFIG_MBO */
-
- /*
- * This should be under CONFIG_MBO, but it is left out to allow using
- * the bss_temp_disallowed list for other purposes as well.
- */
- struct dl_list bss_tmp_disallowed;
-
- /*
- * Content of a measurement report element with type 8 (LCI),
- * own location.
- */
- struct wpabuf *lci;
- struct os_reltime lci_time;
-
- struct os_reltime beacon_rep_scan;
-
- /* FILS HLP requests (struct fils_hlp_req) */
- struct dl_list fils_hlp_req;
-
- struct sched_scan_relative_params {
- /**
- * relative_rssi_set - Enable relatively preferred BSS reporting
- *
- * 0 = Disable reporting relatively preferred BSSs
- * 1 = Enable reporting relatively preferred BSSs
- */
- int relative_rssi_set;
-
- /**
- * relative_rssi - Relative RSSI for reporting better BSSs
- *
- * Amount of RSSI by which a BSS should be better than the
- * current connected BSS so that the new BSS can be reported
- * to user space. This applies to sched_scan operations.
- */
- int relative_rssi;
-
- /**
- * relative_adjust_band - Band in which RSSI is to be adjusted
- */
- enum set_band relative_adjust_band;
-
- /**
- * relative_adjust_rssi - RSSI adjustment
- *
- * An amount of relative_adjust_rssi should be added to the
- * BSSs that belong to the relative_adjust_band while comparing
- * with other bands for BSS reporting.
- */
- int relative_adjust_rssi;
- } srp;
-
- /* RIC elements for FT protocol */
- struct wpabuf *ric_ies;
-
- int last_auth_timeout_sec;
-
-#ifdef CONFIG_DPP
- struct dpp_global *dpp;
- struct dpp_authentication *dpp_auth;
- struct wpa_radio_work *dpp_listen_work;
- unsigned int dpp_pending_listen_freq;
- unsigned int dpp_listen_freq;
- struct os_reltime dpp_listen_end;
- u8 dpp_allowed_roles;
- int dpp_qr_mutual;
- int dpp_netrole;
- int dpp_auth_ok_on_ack;
- int dpp_in_response_listen;
- int dpp_gas_client;
- int dpp_gas_dialog_token;
- u8 dpp_intro_bssid[ETH_ALEN];
- void *dpp_intro_network;
- struct dpp_pkex *dpp_pkex;
- struct dpp_bootstrap_info *dpp_pkex_bi;
- char *dpp_pkex_code;
- char *dpp_pkex_identifier;
- char *dpp_pkex_auth_cmd;
- char *dpp_configurator_params;
- struct os_reltime dpp_last_init;
- struct os_reltime dpp_init_iter_start;
- unsigned int dpp_init_max_tries;
- unsigned int dpp_init_retry_time;
- unsigned int dpp_resp_wait_time;
- unsigned int dpp_resp_max_tries;
- unsigned int dpp_resp_retry_time;
- u8 dpp_last_ssid[SSID_MAX_LEN];
- size_t dpp_last_ssid_len;
- bool dpp_conf_backup_received;
-#ifdef CONFIG_DPP2
- struct dpp_pfs *dpp_pfs;
- int dpp_pfs_fallback;
- struct wpabuf *dpp_presence_announcement;
- struct dpp_bootstrap_info *dpp_chirp_bi;
- int dpp_chirp_freq;
- int *dpp_chirp_freqs;
- int dpp_chirp_iter;
- int dpp_chirp_round;
- int dpp_chirp_scan_done;
- int dpp_chirp_listen;
- struct wpa_ssid *dpp_reconfig_ssid;
- int dpp_reconfig_ssid_id;
- struct dpp_reconfig_id *dpp_reconfig_id;
-#endif /* CONFIG_DPP2 */
-#ifdef CONFIG_TESTING_OPTIONS
- char *dpp_config_obj_override;
- char *dpp_discovery_override;
- char *dpp_groups_override;
- unsigned int dpp_ignore_netaccesskey_mismatch:1;
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_DPP */
-
-#ifdef CONFIG_FILS
- unsigned int disable_fils:1;
-#endif /* CONFIG_FILS */
- unsigned int ieee80211ac:1;
- unsigned int enabled_4addr_mode:1;
- unsigned int multi_bss_support:1;
- unsigned int drv_authorized_port:1;
- unsigned int multi_ap_ie:1;
- unsigned int multi_ap_backhaul:1;
- unsigned int multi_ap_fronthaul:1;
- struct robust_av_data robust_av;
- bool mscs_setup_done;
-
-#ifdef CONFIG_PASN
- struct wpas_pasn pasn;
- struct wpa_radio_work *pasn_auth_work;
-#endif /* CONFIG_PASN */
- struct scs_robust_av_data scs_robust_av_req;
- u8 scs_dialog_token;
-#ifdef CONFIG_TESTING_OPTIONS
- unsigned int disable_scs_support:1;
- unsigned int disable_mscs_support:1;
-#endif /* CONFIG_TESTING_OPTIONS */
- struct dl_list active_scs_ids;
- bool ongoing_scs_req;
- u8 dscp_req_dialog_token;
- u8 dscp_query_dialog_token;
- unsigned int enable_dscp_policy_capa:1;
- unsigned int connection_dscp:1;
- unsigned int wait_for_dscp_req:1;
-};
-
-
-/* wpa_supplicant.c */
-void wpa_supplicant_apply_ht_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params);
-void wpa_supplicant_apply_vht_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params);
-void wpa_supplicant_apply_he_overrides(
- struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- struct wpa_driver_associate_params *params);
-
-int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
-
-const char * wpa_supplicant_state_txt(enum wpa_states state);
-int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_update_bridge_ifname(struct wpa_supplicant *wpa_s,
- const char *bridge_ifname);
-void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct wpa_ie_data *ie);
-int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, struct wpa_ssid *ssid,
- u8 *wpa_ie, size_t *wpa_ie_len);
-int wpas_restore_permanent_mac_addr(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss,
- struct wpa_ssid *ssid);
-void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s);
-void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr);
-void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
- int sec, int usec);
-void wpas_auth_timeout_restart(struct wpa_supplicant *wpa_s, int sec_diff);
-void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
- enum wpa_states state);
-struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s);
-const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
- u16 reason_code);
-void wpa_supplicant_reconnect(struct wpa_supplicant *wpa_s);
-
-struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id);
-int wpa_supplicant_remove_all_networks(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpas_remove_cred(struct wpa_supplicant *wpa_s, struct wpa_cred *cred);
-int wpas_remove_all_creds(struct wpa_supplicant *wpa_s);
-int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
- const char *pkcs11_engine_path,
- const char *pkcs11_module_path);
-int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s,
- int ap_scan);
-int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
- unsigned int expire_age);
-int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
- unsigned int expire_count);
-int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
- int scan_interval);
-int wpa_supplicant_set_debug_params(struct wpa_global *global,
- int debug_level, int debug_timestamp,
- int debug_show_keys);
-void free_hw_features(struct wpa_supplicant *wpa_s);
-
-void wpa_show_license(void);
-
-struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
- const char *ifname);
-struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
- struct wpa_interface *iface,
- struct wpa_supplicant *parent);
-int wpa_supplicant_remove_iface(struct wpa_global *global,
- struct wpa_supplicant *wpa_s,
- int terminate);
-struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
- const char *ifname);
-struct wpa_global * wpa_supplicant_init(struct wpa_params *params);
-int wpa_supplicant_run(struct wpa_global *global);
-void wpa_supplicant_deinit(struct wpa_global *global);
-
-int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void wpa_supplicant_terminate_proc(struct wpa_global *global);
-void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len);
-void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
-void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
-void fils_connection_failure(struct wpa_supplicant *wpa_s);
-void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
-int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
-int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
-void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);
-void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, int clear_failures);
-int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid);
-int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
- size_t ssid_len);
-void wpas_request_connection(struct wpa_supplicant *wpa_s);
-void wpas_request_disconnection(struct wpa_supplicant *wpa_s);
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
-int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
-int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
-void add_freq(int *freqs, int *num_freqs, int freq);
-
-int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
- u8 *op_class, u8 *chan, u8 *phy_type);
-
-int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
- int mantissa, u8 min_twt, int setup_cmd, u64 twt,
- bool requestor, bool trigger, bool implicit,
- bool flow_type, u8 flow_id, bool protection,
- u8 twt_channel, u8 control);
-int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags);
-
-void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
-void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
- const u8 *report, size_t report_len);
-int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid_value *ssid,
- int lci, int civic,
- void (*cb)(void *ctx,
- struct wpabuf *neighbor_rep),
- void *cb_ctx);
-void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *dst,
- const u8 *frame, size_t len);
-void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
- const u8 *src,
- const u8 *frame, size_t len,
- int rssi);
-void wpas_rrm_refuse_request(struct wpa_supplicant *wpa_s);
-int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res,
- struct scan_info *info);
-void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s);
-void wpas_flush_fils_hlp_req(struct wpa_supplicant *wpa_s);
-void wpas_clear_disabled_interface(void *eloop_ctx, void *timeout_ctx);
-void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s);
-
-
-/* MBO functions */
-int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len,
- int add_oce_capa);
-const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr);
-const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr);
-void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- struct wpa_ssid *ssid);
-const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len,
- enum mbo_attr_id attr);
-int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s,
- const char *non_pref_chan);
-void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie);
-void wpas_mbo_ie_trans_req(struct wpa_supplicant *wpa_s, const u8 *ie,
- size_t len);
-size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos,
- size_t len,
- enum mbo_transition_reject_reason reason);
-void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa);
-struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, u32 mbo_subtypes);
-void mbo_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss, const u8 *sa,
- const u8 *data, size_t slen);
-void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s);
-
-/* op_classes.c */
-enum chan_allowed {
- NOT_ALLOWED, NO_IR, RADAR, ALLOWED
-};
-
-enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
- u8 channel, u8 bw);
-size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss, u8 *pos, size_t len);
-int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s);
-
-int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
- unsigned int type, const u8 *addr,
- const u8 *mask);
-int wpas_disable_mac_addr_randomization(struct wpa_supplicant *wpa_s,
- unsigned int type);
-
-/**
- * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response
- * @wpa_s: Pointer to wpa_supplicant data
- * @ssid: Pointer to the network block the reply is for
- * @field: field the response is a reply for
- * @value: value (ie, password, etc) for @field
- * Returns: 0 on success, non-zero on error
- *
- * Helper function to handle replies to control interface requests.
- */
-int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const char *field,
- const char *value);
-
-void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- struct hostapd_freq_params *freq);
-
-/* events.c */
-void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected,
- struct wpa_ssid *ssid);
-void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx);
-void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx);
-void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s);
-struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid **selected_ssid);
-int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
- struct channel_list_changed *info);
-int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
- struct wpa_bss *current_bss,
- struct wpa_bss *seleceted);
-
-/* eap_register.c */
-int eap_register_methods(void);
-
-/**
- * Utility method to tell if a given network is for persistent group storage
- * @ssid: Network object
- * Returns: 1 if network is a persistent group, 0 otherwise
- */
-static inline int network_is_persistent_group(struct wpa_ssid *ssid)
-{
- return ssid->disabled == 2 && ssid->p2p_persistent_group;
-}
-
-
-static inline int wpas_mode_to_ieee80211_mode(enum wpas_mode mode)
-{
- switch (mode) {
- default:
- case WPAS_MODE_INFRA:
- return IEEE80211_MODE_INFRA;
- case WPAS_MODE_IBSS:
- return IEEE80211_MODE_IBSS;
- case WPAS_MODE_AP:
- case WPAS_MODE_P2P_GO:
- case WPAS_MODE_P2P_GROUP_FORMATION:
- return IEEE80211_MODE_AP;
- case WPAS_MODE_MESH:
- return IEEE80211_MODE_MESH;
- }
-}
-
-
-int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
-
-int wpas_init_ext_pw(struct wpa_supplicant *wpa_s);
-
-void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
- struct wpa_used_freq_data *freqs_data,
- unsigned int len);
-
-int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
- struct wpa_used_freq_data *freqs_data,
- unsigned int len);
-int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
- int *freq_array, unsigned int len);
-
-void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
-
-void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s);
-struct wpa_supplicant * wpas_vendor_elem(struct wpa_supplicant *wpa_s,
- enum wpa_vendor_elem_frame frame);
-int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
- const u8 *elem, size_t len);
-
-#ifdef CONFIG_FST
-
-struct fst_wpa_obj;
-
-void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
- struct fst_wpa_obj *iface_obj);
-
-#endif /* CONFIG_FST */
-
-int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd);
-
-struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
- u16 num_modes, enum hostapd_hw_mode mode,
- bool is_6ghz);
-struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes,
- u16 num_modes, int freq);
-
-void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
- unsigned int sec, int rssi_threshold);
-int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss);
-void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s);
-
-struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
- int i, struct wpa_bss *bss,
- struct wpa_ssid *group,
- int only_first_ssid, int debug_print);
-
-int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
- enum wpa_driver_if_type if_type,
- unsigned int *num,
- unsigned int *freq_list);
-
-int wpa_is_fils_supported(struct wpa_supplicant *wpa_s);
-int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s);
-
-void wpas_clear_driver_signal_override(struct wpa_supplicant *wpa_s);
-
-int wpas_send_mscs_req(struct wpa_supplicant *wpa_s);
-void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
- struct wpabuf *buf);
-void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *buf,
- size_t len);
-void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ies, size_t ies_len);
-int wpas_send_scs_req(struct wpa_supplicant *wpa_s);
-void free_up_tclas_elem(struct scs_desc_elem *elem);
-void free_up_scs_desc(struct scs_robust_av_data *data);
-void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src, const u8 *buf,
- size_t len);
-void wpas_scs_deinit(struct wpa_supplicant *wpa_s);
-void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
- const u8 *src,
- const u8 *buf, size_t len);
-void wpas_dscp_deinit(struct wpa_supplicant *wpa_s);
-int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
- struct dscp_resp_data *resp_data);
-void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
- const u8 *ies, size_t ies_len);
-int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
- size_t domain_name_length);
-
-int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
- const u8 *bssid, int akmp, int cipher,
- u16 group, int network_id,
- const u8 *comeback, size_t comeback_len);
-void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s);
-int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
- const u8 *data, size_t data_len, u8 acked);
-int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt, size_t len);
-
-int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid);
-
-#endif /* WPA_SUPPLICANT_I_H */
diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf
deleted file mode 100644
index f55227f82685..000000000000
--- a/wpa_supplicant/wpa_supplicant_template.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-##### wpa_supplicant configuration file template #####
-update_config=1
-eapol_version=1
-ap_scan=1
-fast_reauth=1
-pmf=1
-p2p_add_cli_chan=1
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
deleted file mode 100644
index 17fc05bcbdab..000000000000
--- a/wpa_supplicant/wpas_glue.c
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * WPA Supplicant - Glue code to setup EAPOL and RSN modules
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "eap_peer/eap.h"
-#include "rsn_supp/wpa.h"
-#include "eloop.h"
-#include "config.h"
-#include "l2_packet/l2_packet.h"
-#include "common/wpa_common.h"
-#include "common/ptksa_cache.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "sme.h"
-#include "common/ieee802_11_defs.h"
-#include "common/wpa_ctrl.h"
-#include "wpas_glue.h"
-#include "wps_supplicant.h"
-#include "bss.h"
-#include "scan.h"
-#include "notify.h"
-#include "wpas_kay.h"
-
-
-#ifndef CONFIG_NO_CONFIG_BLOBS
-#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
-static void wpa_supplicant_set_config_blob(void *ctx,
- struct wpa_config_blob *blob)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_config_set_blob(wpa_s->conf, blob);
- if (wpa_s->conf->update_config) {
- int ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
- if (ret) {
- wpa_printf(MSG_DEBUG, "Failed to update config after "
- "blob set");
- }
- }
-}
-
-
-static const struct wpa_config_blob *
-wpa_supplicant_get_config_blob(void *ctx, const char *name)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_config_get_blob(wpa_s->conf, name);
-}
-#endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
-#endif /* CONFIG_NO_CONFIG_BLOBS */
-
-
-#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
-static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
- const void *data, u16 data_len,
- size_t *msg_len, void **data_pos)
-{
- struct ieee802_1x_hdr *hdr;
-
- *msg_len = sizeof(*hdr) + data_len;
- hdr = os_malloc(*msg_len);
- if (hdr == NULL)
- return NULL;
-
- hdr->version = wpa_s->conf->eapol_version;
- hdr->type = type;
- hdr->length = host_to_be16(data_len);
-
- if (data)
- os_memcpy(hdr + 1, data, data_len);
- else
- os_memset(hdr + 1, 0, data_len);
-
- if (data_pos)
- *data_pos = hdr + 1;
-
- return (u8 *) hdr;
-}
-
-
-/**
- * wpa_ether_send - Send Ethernet frame
- * @wpa_s: Pointer to wpa_supplicant data
- * @dest: Destination MAC address
- * @proto: Ethertype in host byte order
- * @buf: Frame payload starting from IEEE 802.1X header
- * @len: Frame payload length
- * Returns: >=0 on success, <0 on failure
- */
-int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
- u16 proto, const u8 *buf, size_t len)
-{
-#ifdef CONFIG_TESTING_OPTIONS
- if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
- size_t hex_len = 2 * len + 1;
- char *hex = os_malloc(hex_len);
-
- if (hex == NULL)
- return -1;
- wpa_snprintf_hex(hex, hex_len, buf, len);
- wpa_msg(wpa_s, MSG_INFO, "EAPOL-TX " MACSTR " %s",
- MAC2STR(dest), hex);
- os_free(hex);
- return 0;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_CONTROL_PORT) {
- int encrypt = wpa_s->wpa &&
- wpa_sm_has_ptk_installed(wpa_s->wpa);
-
- return wpa_drv_tx_control_port(wpa_s, dest, proto, buf, len,
- !encrypt);
- }
-
- if (wpa_s->l2) {
- return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
- }
-
- return -1;
-}
-#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
-
-
-#ifdef IEEE8021X_EAPOL
-
-/**
- * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
- * @ctx: Pointer to wpa_supplicant data (wpa_s)
- * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
- * @buf: EAPOL payload (after IEEE 802.1X header)
- * @len: EAPOL payload length
- * Returns: >=0 on success, <0 on failure
- *
- * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
- * to the current Authenticator.
- */
-static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
- size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- u8 *msg, *dst, bssid[ETH_ALEN];
- size_t msglen;
- int res;
-
- /* TODO: could add l2_packet_sendmsg that allows fragments to avoid
- * extra copy here */
-
- if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_DPP ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
- /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
- * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
- * machines. */
- wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
- "mode (type=%d len=%lu)", type,
- (unsigned long) len);
- return -1;
- }
-
- if (pmksa_cache_get_current(wpa_s->wpa) &&
- type == IEEE802_1X_TYPE_EAPOL_START) {
- /*
- * We were trying to use PMKSA caching and sending EAPOL-Start
- * would abort that and trigger full EAPOL authentication.
- * However, we've already waited for the AP/Authenticator to
- * start 4-way handshake or EAP authentication, and apparently
- * it has not done so since the startWhen timer has reached zero
- * to get the state machine sending EAPOL-Start. This is not
- * really supposed to happen, but an interoperability issue with
- * a deployed AP has been identified where the connection fails
- * due to that AP failing to operate correctly if PMKID is
- * included in the Association Request frame. To work around
- * this, assume PMKSA caching failed and try to initiate full
- * EAP authentication.
- */
- if (!wpa_s->current_ssid ||
- wpa_s->current_ssid->eap_workaround) {
- wpa_printf(MSG_DEBUG,
- "RSN: Timeout on waiting for the AP to initiate 4-way handshake for PMKSA caching or EAP authentication - try to force it to start EAP authentication");
- } else {
- wpa_printf(MSG_DEBUG,
- "RSN: PMKSA caching - do not send EAPOL-Start");
- return -1;
- }
- }
-
- if (is_zero_ether_addr(wpa_s->bssid)) {
- wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
- "EAPOL frame");
- if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
- !is_zero_ether_addr(bssid)) {
- dst = bssid;
- wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
- " from the driver as the EAPOL destination",
- MAC2STR(dst));
- } else {
- dst = wpa_s->last_eapol_src;
- wpa_printf(MSG_DEBUG, "Using the source address of the"
- " last received EAPOL frame " MACSTR " as "
- "the EAPOL destination",
- MAC2STR(dst));
- }
- } else {
- /* BSSID was already set (from (Re)Assoc event, so use it as
- * the EAPOL destination. */
- dst = wpa_s->bssid;
- }
-
- msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
- if (msg == NULL)
- return -1;
-
- wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
- wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
- res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
- os_free(msg);
- return res;
-}
-
-
-#ifdef CONFIG_WEP
-/**
- * wpa_eapol_set_wep_key - set WEP key for the driver
- * @ctx: Pointer to wpa_supplicant data (wpa_s)
- * @unicast: 1 = individual unicast key, 0 = broadcast key
- * @keyidx: WEP key index (0..3)
- * @key: Pointer to key data
- * @keylen: Key length in bytes
- * Returns: 0 on success or < 0 on error.
- */
-static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
- const u8 *key, size_t keylen)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
- WPA_CIPHER_WEP104;
- if (unicast)
- wpa_s->pairwise_cipher = cipher;
- else
- wpa_s->group_cipher = cipher;
- }
- return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
- unicast ? wpa_s->bssid : NULL,
- keyidx, unicast, NULL, 0, key, keylen,
- unicast ? KEY_FLAG_PAIRWISE_RX_TX :
- KEY_FLAG_GROUP_RX_TX_DEFAULT);
-}
-#endif /* CONFIG_WEP */
-
-
-static void wpa_supplicant_aborted_cached(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_sm_aborted_cached(wpa_s->wpa);
-}
-
-
-static const char * result_str(enum eapol_supp_result result)
-{
- switch (result) {
- case EAPOL_SUPP_RESULT_FAILURE:
- return "FAILURE";
- case EAPOL_SUPP_RESULT_SUCCESS:
- return "SUCCESS";
- case EAPOL_SUPP_RESULT_EXPECTED_FAILURE:
- return "EXPECTED_FAILURE";
- }
- return "?";
-}
-
-
-static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
- enum eapol_supp_result result,
- void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- int res, pmk_len;
- u8 pmk[PMK_LEN];
-
- wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s",
- result_str(result));
-
- if (wpas_wps_eapol_cb(wpa_s) > 0)
- return;
-
- wpa_s->eap_expected_failure = result ==
- EAPOL_SUPP_RESULT_EXPECTED_FAILURE;
-
- if (result != EAPOL_SUPP_RESULT_SUCCESS) {
- /*
- * Make sure we do not get stuck here waiting for long EAPOL
- * timeout if the AP does not disconnect in case of
- * authentication failure.
- */
- wpa_supplicant_req_auth_timeout(wpa_s, 2, 0);
- } else {
- ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src);
- }
-
- if (result != EAPOL_SUPP_RESULT_SUCCESS ||
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
- return;
-
- if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
- return;
-
- wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
- "handshake");
-
- pmk_len = PMK_LEN;
- if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
-#ifdef CONFIG_IEEE80211R
- u8 buf[2 * PMK_LEN];
- wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for "
- "driver-based 4-way hs and FT");
- res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN);
- if (res == 0) {
- os_memcpy(pmk, buf + PMK_LEN, PMK_LEN);
- os_memset(buf, 0, sizeof(buf));
- }
-#else /* CONFIG_IEEE80211R */
- res = -1;
-#endif /* CONFIG_IEEE80211R */
- } else {
- res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
- if (res) {
- /*
- * EAP-LEAP is an exception from other EAP methods: it
- * uses only 16-byte PMK.
- */
- res = eapol_sm_get_key(eapol, pmk, 16);
- pmk_len = 16;
- }
- }
-
- if (res) {
- wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
- "machines");
- return;
- }
-
- wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way "
- "handshake", pmk, pmk_len);
-
- if (wpa_drv_set_key(wpa_s, 0, NULL, 0, 0, NULL, 0, pmk,
- pmk_len, KEY_FLAG_PMK)) {
- wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
- }
-
- wpa_supplicant_cancel_scan(wpa_s);
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-
-}
-
-
-static void wpa_supplicant_notify_eapol_done(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
- if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
- wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
- } else {
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- }
-}
-
-#endif /* IEEE8021X_EAPOL */
-
-
-#ifndef CONFIG_NO_WPA
-
-static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
-{
- int ret = 0;
- struct wpa_bss *curr = NULL, *bss;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- const u8 *ie;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0)
- continue;
- if (ssid == NULL ||
- ((bss->ssid_len == ssid->ssid_len &&
- os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) ||
- ssid->ssid_len == 0)) {
- curr = bss;
- break;
- }
-#ifdef CONFIG_OWE
- if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- (bss->flags & WPA_BSS_OWE_TRANSITION)) {
- curr = bss;
- break;
- }
-#endif /* CONFIG_OWE */
- }
-
- if (curr) {
- ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE);
- if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
- ret = -1;
-
- ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
- if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
- ret = -1;
-
- ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
- if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
- ret = -1;
- } else {
- ret = -1;
- }
-
- return ret;
-}
-
-
-static int wpa_supplicant_get_beacon_ie(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_get_beacon_ie(wpa_s) == 0) {
- return 0;
- }
-
- /* No WPA/RSN IE found in the cached scan results. Try to get updated
- * scan results from the driver. */
- if (wpa_supplicant_update_scan_results(wpa_s) < 0)
- return -1;
-
- return wpa_get_beacon_ie(wpa_s);
-}
-
-
-static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
- const void *data, u16 data_len,
- size_t *msg_len, void **data_pos)
-{
- return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
-}
-
-
-static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
- const u8 *buf, size_t len)
-{
- return wpa_ether_send(wpa_s, dest, proto, buf, len);
-}
-
-
-static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
-{
- wpa_supplicant_cancel_auth_timeout(wpa_s);
-}
-
-
-static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state)
-{
- wpa_supplicant_set_state(wpa_s, state);
-}
-
-
-/**
- * wpa_supplicant_get_state - Get the connection state
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: The current connection state (WPA_*)
- */
-static enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
-{
- return wpa_s->wpa_state;
-}
-
-
-static enum wpa_states _wpa_supplicant_get_state(void *wpa_s)
-{
- return wpa_supplicant_get_state(wpa_s);
-}
-
-
-static void _wpa_supplicant_deauthenticate(void *wpa_s, u16 reason_code)
-{
- wpa_supplicant_deauthenticate(wpa_s, reason_code);
- /* Schedule a scan to make sure we continue looking for networks */
- wpa_supplicant_req_scan(wpa_s, 5, 0);
-}
-
-
-static void _wpa_supplicant_reconnect(void *wpa_s)
-{
- wpa_supplicant_reconnect(wpa_s);
-}
-
-
-static void * wpa_supplicant_get_network_ctx(void *wpa_s)
-{
- return wpa_supplicant_get_ssid(wpa_s);
-}
-
-
-static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_drv_get_bssid(wpa_s, bssid);
-}
-
-
-static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg,
- const u8 *addr, int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len,
- enum key_flag key_flag)
-{
- struct wpa_supplicant *wpa_s = _wpa_s;
- if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
- /* Clear the MIC error counter when setting a new PTK. */
- wpa_s->mic_errors_seen = 0;
- }
-#ifdef CONFIG_TESTING_GET_GTK
- if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) &&
- alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) {
- os_memcpy(wpa_s->last_gtk, key, key_len);
- wpa_s->last_gtk_len = key_len;
- }
-#endif /* CONFIG_TESTING_GET_GTK */
-#ifdef CONFIG_TESTING_OPTIONS
- if (addr && !is_broadcast_ether_addr(addr) &&
- !(key_flag & KEY_FLAG_MODIFY)) {
- wpa_s->last_tk_alg = alg;
- os_memcpy(wpa_s->last_tk_addr, addr, ETH_ALEN);
- wpa_s->last_tk_key_idx = key_idx;
- if (key)
- os_memcpy(wpa_s->last_tk, key, key_len);
- wpa_s->last_tk_len = key_len;
- }
-#endif /* CONFIG_TESTING_OPTIONS */
- return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
- key, key_len, key_flag);
-}
-
-
-static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
- int protection_type,
- int key_type)
-{
- return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
- key_type);
-}
-
-
-static struct wpa_ssid * wpas_get_network_ctx(struct wpa_supplicant *wpa_s,
- void *network_ctx)
-{
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (network_ctx == ssid)
- return ssid;
- }
-
- return NULL;
-}
-
-
-static int wpa_supplicant_add_pmkid(void *_wpa_s, void *network_ctx,
- const u8 *bssid, const u8 *pmkid,
- const u8 *fils_cache_id,
- const u8 *pmk, size_t pmk_len,
- u32 pmk_lifetime, u8 pmk_reauth_threshold,
- int akmp)
-{
- struct wpa_supplicant *wpa_s = _wpa_s;
- struct wpa_ssid *ssid;
- struct wpa_pmkid_params params;
-
- os_memset(&params, 0, sizeof(params));
- ssid = wpas_get_network_ctx(wpa_s, network_ctx);
- if (ssid) {
- wpa_msg(wpa_s, MSG_INFO, PMKSA_CACHE_ADDED MACSTR " %d",
- MAC2STR(bssid), ssid->id);
- if ((akmp == WPA_KEY_MGMT_FT_IEEE8021X ||
- akmp == WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
- !ssid->ft_eap_pmksa_caching) {
- /* Since we will not be using PMKSA caching for FT-EAP
- * within wpa_supplicant to avoid known interop issues
- * with APs, do not add this PMKID to the driver either
- * so that we won't be hitting those interop issues
- * with driver-based RSNE generation. */
- wpa_printf(MSG_DEBUG,
- "FT: Do not add PMKID entry to the driver since FT-EAP PMKSA caching is not enabled in configuration");
- return 0;
- }
- }
- if (ssid && fils_cache_id) {
- params.ssid = ssid->ssid;
- params.ssid_len = ssid->ssid_len;
- params.fils_cache_id = fils_cache_id;
- } else {
- params.bssid = bssid;
- }
-
- params.pmkid = pmkid;
- params.pmk = pmk;
- params.pmk_len = pmk_len;
- params.pmk_lifetime = pmk_lifetime;
- params.pmk_reauth_threshold = pmk_reauth_threshold;
-
- return wpa_drv_add_pmkid(wpa_s, &params);
-}
-
-
-static int wpa_supplicant_remove_pmkid(void *_wpa_s, void *network_ctx,
- const u8 *bssid, const u8 *pmkid,
- const u8 *fils_cache_id)
-{
- struct wpa_supplicant *wpa_s = _wpa_s;
- struct wpa_ssid *ssid;
- struct wpa_pmkid_params params;
-
- os_memset(&params, 0, sizeof(params));
- ssid = wpas_get_network_ctx(wpa_s, network_ctx);
- if (ssid)
- wpa_msg(wpa_s, MSG_INFO, PMKSA_CACHE_REMOVED MACSTR " %d",
- MAC2STR(bssid), ssid->id);
- if (ssid && fils_cache_id) {
- params.ssid = ssid->ssid;
- params.ssid_len = ssid->ssid_len;
- params.fils_cache_id = fils_cache_id;
- } else {
- params.bssid = bssid;
- }
-
- params.pmkid = pmkid;
-
- return wpa_drv_remove_pmkid(wpa_s, &params);
-}
-
-
-#ifdef CONFIG_IEEE80211R
-static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
- const u8 *ies, size_t ies_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
- return sme_update_ft_ies(wpa_s, md, ies, ies_len);
- return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
-}
-
-
-static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
- const u8 *target_ap,
- const u8 *ies, size_t ies_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- int ret;
- u8 *data, *pos;
- size_t data_len;
-
- if (action != 1) {
- wpa_printf(MSG_ERROR, "Unsupported send_ft_action action %d",
- action);
- return -1;
- }
-
- /*
- * Action frame payload:
- * Category[1] = 6 (Fast BSS Transition)
- * Action[1] = 1 (Fast BSS Transition Request)
- * STA Address
- * Target AP Address
- * FT IEs
- */
-
- data_len = 2 + 2 * ETH_ALEN + ies_len;
- data = os_malloc(data_len);
- if (data == NULL)
- return -1;
- pos = data;
- *pos++ = 0x06; /* FT Action category */
- *pos++ = action;
- os_memcpy(pos, wpa_s->own_addr, ETH_ALEN);
- pos += ETH_ALEN;
- os_memcpy(pos, target_ap, ETH_ALEN);
- pos += ETH_ALEN;
- os_memcpy(pos, ies, ies_len);
-
- ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
- wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid,
- data, data_len, 0);
- os_free(data);
-
- return ret;
-}
-
-
-static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_driver_auth_params params;
- struct wpa_bss *bss;
-
- bss = wpa_bss_get_bssid(wpa_s, target_ap);
- if (bss == NULL)
- return -1;
-
- os_memset(&params, 0, sizeof(params));
- params.bssid = target_ap;
- params.freq = bss->freq;
- params.ssid = bss->ssid;
- params.ssid_len = bss->ssid_len;
- params.auth_alg = WPA_AUTH_ALG_FT;
- params.local_state_change = 1;
- return wpa_drv_authenticate(wpa_s, &params);
-}
-#endif /* CONFIG_IEEE80211R */
-
-
-#ifdef CONFIG_TDLS
-
-static int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported,
- int *tdls_ext_setup,
- int *tdls_chan_switch)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- *tdls_supported = 0;
- *tdls_ext_setup = 0;
- *tdls_chan_switch = 0;
-
- if (!wpa_s->drv_capa_known)
- return -1;
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)
- *tdls_supported = 1;
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP)
- *tdls_ext_setup = 1;
-
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH)
- *tdls_chan_switch = 1;
-
- return 0;
-}
-
-
-static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
- u8 action_code, u8 dialog_token,
- u16 status_code, u32 peer_capab,
- int initiator, const u8 *buf,
- size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
- status_code, peer_capab, initiator, buf,
- len);
-}
-
-
-static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
-{
- struct wpa_supplicant *wpa_s = ctx;
- return wpa_drv_tdls_oper(wpa_s, oper, peer);
-}
-
-
-static int wpa_supplicant_tdls_peer_addset(
- void *ctx, const u8 *peer, int add, u16 aid, u16 capability,
- const u8 *supp_rates, size_t supp_rates_len,
- const struct ieee80211_ht_capabilities *ht_capab,
- const struct ieee80211_vht_capabilities *vht_capab,
- const struct ieee80211_he_capabilities *he_capab,
- size_t he_capab_len,
- const struct ieee80211_he_6ghz_band_cap *he_6ghz_he_capab,
- u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
- const u8 *supp_channels, size_t supp_channels_len,
- const u8 *supp_oper_classes, size_t supp_oper_classes_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct hostapd_sta_add_params params;
-
- os_memset(&params, 0, sizeof(params));
-
- params.addr = peer;
- params.aid = aid;
- params.capability = capability;
- params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
-
- /*
- * Don't rely only on qosinfo for WMM capability. It may be 0 even when
- * present. Allow the WMM IE to also indicate QoS support.
- */
- if (wmm || qosinfo)
- params.flags |= WPA_STA_WMM;
-
- params.ht_capabilities = ht_capab;
- params.vht_capabilities = vht_capab;
- params.he_capab = he_capab;
- params.he_capab_len = he_capab_len;
- params.he_6ghz_capab = he_6ghz_he_capab;
- params.qosinfo = qosinfo;
- params.listen_interval = 0;
- params.supp_rates = supp_rates;
- params.supp_rates_len = supp_rates_len;
- params.set = !add;
- params.ext_capab = ext_capab;
- params.ext_capab_len = ext_capab_len;
- params.supp_channels = supp_channels;
- params.supp_channels_len = supp_channels_len;
- params.supp_oper_classes = supp_oper_classes;
- params.supp_oper_classes_len = supp_oper_classes_len;
-
- return wpa_drv_sta_add(wpa_s, &params);
-}
-
-
-static int wpa_supplicant_tdls_enable_channel_switch(
- void *ctx, const u8 *addr, u8 oper_class,
- const struct hostapd_freq_params *params)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- return wpa_drv_tdls_enable_channel_switch(wpa_s, addr, oper_class,
- params);
-}
-
-
-static int wpa_supplicant_tdls_disable_channel_switch(void *ctx, const u8 *addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- return wpa_drv_tdls_disable_channel_switch(wpa_s, addr);
-}
-
-#endif /* CONFIG_TDLS */
-
-#endif /* CONFIG_NO_WPA */
-
-
-enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
-{
- if (os_strcmp(field, "IDENTITY") == 0)
- return WPA_CTRL_REQ_EAP_IDENTITY;
- else if (os_strcmp(field, "PASSWORD") == 0)
- return WPA_CTRL_REQ_EAP_PASSWORD;
- else if (os_strcmp(field, "NEW_PASSWORD") == 0)
- return WPA_CTRL_REQ_EAP_NEW_PASSWORD;
- else if (os_strcmp(field, "PIN") == 0)
- return WPA_CTRL_REQ_EAP_PIN;
- else if (os_strcmp(field, "OTP") == 0)
- return WPA_CTRL_REQ_EAP_OTP;
- else if (os_strcmp(field, "PASSPHRASE") == 0)
- return WPA_CTRL_REQ_EAP_PASSPHRASE;
- else if (os_strcmp(field, "SIM") == 0)
- return WPA_CTRL_REQ_SIM;
- else if (os_strcmp(field, "PSK_PASSPHRASE") == 0)
- return WPA_CTRL_REQ_PSK_PASSPHRASE;
- else if (os_strcmp(field, "EXT_CERT_CHECK") == 0)
- return WPA_CTRL_REQ_EXT_CERT_CHECK;
- return WPA_CTRL_REQ_UNKNOWN;
-}
-
-
-const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
- const char *default_txt,
- const char **txt)
-{
- const char *ret = NULL;
-
- *txt = default_txt;
-
- switch (field) {
- case WPA_CTRL_REQ_EAP_IDENTITY:
- *txt = "Identity";
- ret = "IDENTITY";
- break;
- case WPA_CTRL_REQ_EAP_PASSWORD:
- *txt = "Password";
- ret = "PASSWORD";
- break;
- case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
- *txt = "New Password";
- ret = "NEW_PASSWORD";
- break;
- case WPA_CTRL_REQ_EAP_PIN:
- *txt = "PIN";
- ret = "PIN";
- break;
- case WPA_CTRL_REQ_EAP_OTP:
- ret = "OTP";
- break;
- case WPA_CTRL_REQ_EAP_PASSPHRASE:
- *txt = "Private key passphrase";
- ret = "PASSPHRASE";
- break;
- case WPA_CTRL_REQ_SIM:
- ret = "SIM";
- break;
- case WPA_CTRL_REQ_PSK_PASSPHRASE:
- *txt = "PSK or passphrase";
- ret = "PSK_PASSPHRASE";
- break;
- case WPA_CTRL_REQ_EXT_CERT_CHECK:
- *txt = "External server certificate validation";
- ret = "EXT_CERT_CHECK";
- break;
- default:
- break;
- }
-
- /* txt needs to be something */
- if (*txt == NULL) {
- wpa_printf(MSG_WARNING, "No message for request %d", field);
- ret = NULL;
- }
-
- return ret;
-}
-
-
-void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const char *field_name, const char *txt)
-{
- char *buf;
- size_t buflen;
- int len;
-
- buflen = 100 + os_strlen(txt) + ssid->ssid_len;
- buf = os_malloc(buflen);
- if (buf == NULL)
- return;
- len = os_snprintf(buf, buflen, "%s-%d:%s needed for SSID ",
- field_name, ssid->id, txt);
- if (os_snprintf_error(buflen, len)) {
- os_free(buf);
- return;
- }
- if (ssid->ssid && buflen > len + ssid->ssid_len) {
- os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
- len += ssid->ssid_len;
- buf[len] = '\0';
- }
- buf[buflen - 1] = '\0';
- wpa_msg(wpa_s, MSG_INFO, WPA_CTRL_REQ "%s", buf);
- os_free(buf);
-}
-
-
-#ifdef IEEE8021X_EAPOL
-#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
-static void wpa_supplicant_eap_param_needed(void *ctx,
- enum wpa_ctrl_req_type field,
- const char *default_txt)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- const char *field_name, *txt = NULL;
-
- if (ssid == NULL)
- return;
-
- if (field == WPA_CTRL_REQ_EXT_CERT_CHECK)
- ssid->eap.pending_ext_cert_check = PENDING_CHECK;
- wpas_notify_network_request(wpa_s, ssid, field, default_txt);
-
- field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
- &txt);
- if (field_name == NULL) {
- wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
- field);
- return;
- }
-
- wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name);
-
- wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
-}
-#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
-#define wpa_supplicant_eap_param_needed NULL
-#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
-
-
-#ifdef CONFIG_EAP_PROXY
-
-static void wpa_supplicant_eap_proxy_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
- size_t len;
-
- wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, -1,
- wpa_s->imsi, &len);
- if (wpa_s->mnc_len > 0) {
- wpa_s->imsi[len] = '\0';
- wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
- wpa_s->imsi, wpa_s->mnc_len);
- } else {
- wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
- }
-}
-
-
-static void wpa_sm_sim_state_error_handler(struct wpa_supplicant *wpa_s)
-{
- int i;
- struct wpa_ssid *ssid;
- const struct eap_method_type *eap_methods;
-
- if (!wpa_s->conf)
- return;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- eap_methods = ssid->eap.eap_methods;
- if (!eap_methods)
- continue;
-
- for (i = 0; eap_methods[i].method != EAP_TYPE_NONE; i++) {
- if (eap_methods[i].vendor == EAP_VENDOR_IETF &&
- (eap_methods[i].method == EAP_TYPE_SIM ||
- eap_methods[i].method == EAP_TYPE_AKA ||
- eap_methods[i].method == EAP_TYPE_AKA_PRIME)) {
- wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
- break;
- }
- }
- }
-}
-
-
-static void
-wpa_supplicant_eap_proxy_notify_sim_status(void *ctx,
- enum eap_proxy_sim_state sim_state)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_printf(MSG_DEBUG, "eap_proxy: SIM card status %u", sim_state);
- switch (sim_state) {
- case SIM_STATE_ERROR:
- wpa_sm_sim_state_error_handler(wpa_s);
- break;
- default:
- wpa_printf(MSG_DEBUG, "eap_proxy: SIM card status unknown");
- break;
- }
-}
-
-#endif /* CONFIG_EAP_PROXY */
-
-
-static void wpa_supplicant_port_cb(void *ctx, int authorized)
-{
- struct wpa_supplicant *wpa_s = ctx;
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_printf(MSG_DEBUG, "AP mode active - skip EAPOL Supplicant "
- "port status: %s",
- authorized ? "Authorized" : "Unauthorized");
- return;
- }
-#endif /* CONFIG_AP */
- wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s",
- authorized ? "Authorized" : "Unauthorized");
- wpa_drv_set_supp_port(wpa_s, authorized);
-}
-
-
-static void wpa_supplicant_cert_cb(void *ctx, struct tls_cert_data *cert,
- const char *cert_hash)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_certification(wpa_s, cert, cert_hash);
-}
-
-
-static void wpa_supplicant_status_cb(void *ctx, const char *status,
- const char *parameter)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_eap_status(wpa_s, status, parameter);
-}
-
-
-static void wpa_supplicant_eap_error_cb(void *ctx, int error_code)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_eap_error(wpa_s, error_code);
-}
-
-
-static int wpa_supplicant_eap_auth_start_cb(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (!wpa_s->new_connection && wpa_s->deny_ptk0_rekey &&
- !wpa_sm_ext_key_id_active(wpa_s->wpa)) {
- wpa_msg(wpa_s, MSG_INFO,
- "WPA: PTK0 rekey not allowed, reconnecting");
- wpa_supplicant_reconnect(wpa_s);
- return -1;
- }
- return 0;
-}
-
-
-static void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- char *str;
- int res;
-
- wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity",
- id, len);
-
- if (wpa_s->current_ssid == NULL)
- return;
-
- if (id == NULL) {
- if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
- "NULL", 0) < 0)
- return;
- } else {
- str = os_malloc(len * 2 + 1);
- if (str == NULL)
- return;
- wpa_snprintf_hex(str, len * 2 + 1, id, len);
- res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
- str, 0);
- os_free(str);
- if (res < 0)
- return;
- }
-
- if (wpa_s->conf->update_config) {
- res = wpa_config_write(wpa_s->confname, wpa_s->conf);
- if (res) {
- wpa_printf(MSG_DEBUG, "Failed to update config after "
- "anonymous_id update");
- }
- }
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
-{
-#ifdef IEEE8021X_EAPOL
- struct eapol_ctx *ctx;
- ctx = os_zalloc(sizeof(*ctx));
- if (ctx == NULL) {
- wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
- return -1;
- }
-
- ctx->ctx = wpa_s;
- ctx->msg_ctx = wpa_s;
- ctx->eapol_send_ctx = wpa_s;
- ctx->preauth = 0;
- ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
- ctx->eapol_send = wpa_supplicant_eapol_send;
-#ifdef CONFIG_WEP
- ctx->set_wep_key = wpa_eapol_set_wep_key;
-#endif /* CONFIG_WEP */
-#ifndef CONFIG_NO_CONFIG_BLOBS
- ctx->set_config_blob = wpa_supplicant_set_config_blob;
- ctx->get_config_blob = wpa_supplicant_get_config_blob;
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- ctx->aborted_cached = wpa_supplicant_aborted_cached;
- ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
- ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
- ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
- ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers;
- ctx->wps = wpa_s->wps;
- ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
-#ifdef CONFIG_EAP_PROXY
- ctx->eap_proxy_cb = wpa_supplicant_eap_proxy_cb;
- ctx->eap_proxy_notify_sim_status =
- wpa_supplicant_eap_proxy_notify_sim_status;
-#endif /* CONFIG_EAP_PROXY */
- ctx->port_cb = wpa_supplicant_port_cb;
- ctx->cb = wpa_supplicant_eapol_cb;
- ctx->cert_cb = wpa_supplicant_cert_cb;
- ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
- ctx->status_cb = wpa_supplicant_status_cb;
- ctx->eap_error_cb = wpa_supplicant_eap_error_cb;
- ctx->confirm_auth_cb = wpa_supplicant_eap_auth_start_cb;
- ctx->set_anon_id = wpa_supplicant_set_anon_id;
- ctx->cb_ctx = wpa_s;
- wpa_s->eapol = eapol_sm_init(ctx);
- if (wpa_s->eapol == NULL) {
- os_free(ctx);
- wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
- "machines.");
- return -1;
- }
-#endif /* IEEE8021X_EAPOL */
-
- return 0;
-}
-
-
-#ifndef CONFIG_NO_WPA
-
-static void wpa_supplicant_set_rekey_offload(void *ctx,
- const u8 *kek, size_t kek_len,
- const u8 *kck, size_t kck_len,
- const u8 *replay_ctr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpa_drv_set_rekey_info(wpa_s, kek, kek_len, kck, kck_len, replay_ctr);
-}
-
-
-static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk,
- size_t pmk_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->conf->key_mgmt_offload &&
- (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
- return wpa_drv_set_key(wpa_s, 0, NULL, 0, 0,
- NULL, 0, pmk, pmk_len, KEY_FLAG_PMK);
- else
- return 0;
-}
-
-
-static void wpa_supplicant_fils_hlp_rx(void *ctx, const u8 *dst, const u8 *src,
- const u8 *pkt, size_t pkt_len)
-{
- struct wpa_supplicant *wpa_s = ctx;
- char *hex;
- size_t hexlen;
-
- hexlen = pkt_len * 2 + 1;
- hex = os_malloc(hexlen);
- if (!hex)
- return;
- wpa_snprintf_hex(hex, hexlen, pkt, pkt_len);
- wpa_msg(wpa_s, MSG_INFO, FILS_HLP_RX "dst=" MACSTR " src=" MACSTR
- " frame=%s", MAC2STR(dst), MAC2STR(src), hex);
- os_free(hex);
-}
-
-
-static int wpa_supplicant_channel_info(void *_wpa_s,
- struct wpa_channel_info *ci)
-{
- struct wpa_supplicant *wpa_s = _wpa_s;
-
- return wpa_drv_channel_info(wpa_s, ci);
-}
-
-
-static void disable_wpa_wpa2(struct wpa_ssid *ssid)
-{
- ssid->proto &= ~WPA_PROTO_WPA;
- ssid->proto |= WPA_PROTO_RSN;
- ssid->key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_PSK_SHA256);
- ssid->group_cipher &= ~WPA_CIPHER_TKIP;
- if (!(ssid->group_cipher & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
- WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256)))
- ssid->group_cipher |= WPA_CIPHER_CCMP;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
-}
-
-
-static void wpa_supplicant_transition_disable(void *_wpa_s, u8 bitmap)
-{
- struct wpa_supplicant *wpa_s = _wpa_s;
- struct wpa_ssid *ssid;
- int changed = 0;
-
- wpa_msg(wpa_s, MSG_INFO, TRANSITION_DISABLE "%02x", bitmap);
-
- ssid = wpa_s->current_ssid;
- if (!ssid)
- return;
-
-#ifdef CONFIG_SAE
- if ((bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) &&
- wpa_key_mgmt_sae(wpa_s->key_mgmt) &&
- (ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)) &&
- (ssid->ieee80211w != MGMT_FRAME_PROTECTION_REQUIRED ||
- (ssid->group_cipher & WPA_CIPHER_TKIP))) {
- wpa_printf(MSG_DEBUG,
- "WPA3-Personal transition mode disabled based on AP notification");
- disable_wpa_wpa2(ssid);
- changed = 1;
- }
-
- if ((bitmap & TRANSITION_DISABLE_SAE_PK) &&
- wpa_key_mgmt_sae(wpa_s->key_mgmt) &&
-#ifdef CONFIG_SME
- wpa_s->sme.sae.state == SAE_ACCEPTED &&
- wpa_s->sme.sae.pk &&
-#endif /* CONFIG_SME */
- (ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)) &&
- (ssid->sae_pk != SAE_PK_MODE_ONLY ||
- ssid->ieee80211w != MGMT_FRAME_PROTECTION_REQUIRED ||
- (ssid->group_cipher & WPA_CIPHER_TKIP))) {
- wpa_printf(MSG_DEBUG,
- "SAE-PK: SAE authentication without PK disabled based on AP notification");
- disable_wpa_wpa2(ssid);
- ssid->sae_pk = SAE_PK_MODE_ONLY;
- changed = 1;
- }
-#endif /* CONFIG_SAE */
-
- if ((bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) &&
- wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
- (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X |
- WPA_KEY_MGMT_FT_IEEE8021X |
- WPA_KEY_MGMT_IEEE8021X_SHA256)) &&
- (ssid->ieee80211w != MGMT_FRAME_PROTECTION_REQUIRED ||
- (ssid->group_cipher & WPA_CIPHER_TKIP))) {
- disable_wpa_wpa2(ssid);
- changed = 1;
- }
-
- if ((bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) &&
- wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
- (ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
- !ssid->owe_only) {
- ssid->owe_only = 1;
- changed = 1;
- }
-
- if (!changed)
- return;
-
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf))
- wpa_printf(MSG_DEBUG, "Failed to update configuration");
-#endif /* CONFIG_NO_CONFIG_WRITE */
-}
-
-
-static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher,
- u32 life_time, const struct wpa_ptk *ptk)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- ptksa_cache_add(wpa_s->ptksa, addr, cipher, life_time, ptk);
-}
-
-#endif /* CONFIG_NO_WPA */
-
-
-int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
-{
-#ifndef CONFIG_NO_WPA
- struct wpa_sm_ctx *ctx;
-
- wpa_s->ptksa = ptksa_cache_init();
- if (!wpa_s->ptksa) {
- wpa_printf(MSG_ERROR, "Failed to allocate PTKSA");
- return -1;
- }
-
- ctx = os_zalloc(sizeof(*ctx));
- if (ctx == NULL) {
- wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
-
- ptksa_cache_deinit(wpa_s->ptksa);
- wpa_s->ptksa = NULL;
-
- return -1;
- }
-
- ctx->ctx = wpa_s;
- ctx->msg_ctx = wpa_s;
- ctx->set_state = _wpa_supplicant_set_state;
- ctx->get_state = _wpa_supplicant_get_state;
- ctx->deauthenticate = _wpa_supplicant_deauthenticate;
- ctx->reconnect = _wpa_supplicant_reconnect;
- ctx->set_key = wpa_supplicant_set_key;
- ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
- ctx->get_bssid = wpa_supplicant_get_bssid;
- ctx->ether_send = _wpa_ether_send;
- ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
- ctx->alloc_eapol = _wpa_alloc_eapol;
- ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
- ctx->add_pmkid = wpa_supplicant_add_pmkid;
- ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
-#ifndef CONFIG_NO_CONFIG_BLOBS
- ctx->set_config_blob = wpa_supplicant_set_config_blob;
- ctx->get_config_blob = wpa_supplicant_get_config_blob;
-#endif /* CONFIG_NO_CONFIG_BLOBS */
- ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
-#ifdef CONFIG_IEEE80211R
- ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
- ctx->send_ft_action = wpa_supplicant_send_ft_action;
- ctx->mark_authenticated = wpa_supplicant_mark_authenticated;
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_TDLS
- ctx->tdls_get_capa = wpa_supplicant_tdls_get_capa;
- ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt;
- ctx->tdls_oper = wpa_supplicant_tdls_oper;
- ctx->tdls_peer_addset = wpa_supplicant_tdls_peer_addset;
- ctx->tdls_enable_channel_switch =
- wpa_supplicant_tdls_enable_channel_switch;
- ctx->tdls_disable_channel_switch =
- wpa_supplicant_tdls_disable_channel_switch;
-#endif /* CONFIG_TDLS */
- ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
- ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk;
- ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
- ctx->channel_info = wpa_supplicant_channel_info;
- ctx->transition_disable = wpa_supplicant_transition_disable;
- ctx->store_ptk = wpa_supplicant_store_ptk;
-
- wpa_s->wpa = wpa_sm_init(ctx);
- if (wpa_s->wpa == NULL) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize WPA state machine");
- os_free(ctx);
- ptksa_cache_deinit(wpa_s->ptksa);
- wpa_s->ptksa = NULL;
- return -1;
- }
-#endif /* CONFIG_NO_WPA */
-
- return 0;
-}
-
-
-void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct rsn_supp_config conf;
- if (ssid) {
- os_memset(&conf, 0, sizeof(conf));
- conf.network_ctx = ssid;
- conf.allowed_pairwise_cipher = ssid->pairwise_cipher;
-#ifdef IEEE8021X_EAPOL
- conf.proactive_key_caching = ssid->proactive_key_caching < 0 ?
- wpa_s->conf->okc : ssid->proactive_key_caching;
- conf.eap_workaround = ssid->eap_workaround;
- conf.eap_conf_ctx = &ssid->eap;
-#endif /* IEEE8021X_EAPOL */
- conf.ssid = ssid->ssid;
- conf.ssid_len = ssid->ssid_len;
- conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey;
- conf.wpa_deny_ptk0_rekey = ssid->wpa_deny_ptk0_rekey;
- conf.owe_ptk_workaround = ssid->owe_ptk_workaround;
-#ifdef CONFIG_P2P
- if (ssid->p2p_group && wpa_s->current_bss &&
- !wpa_s->p2p_disable_ip_addr_req) {
- struct wpabuf *p2p;
- p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
- P2P_IE_VENDOR_TYPE);
- if (p2p) {
- u8 group_capab;
- group_capab = p2p_get_group_capab(p2p);
- if (group_capab &
- P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION)
- conf.p2p = 1;
- wpabuf_free(p2p);
- }
- }
-#endif /* CONFIG_P2P */
- conf.wpa_rsc_relaxation = wpa_s->conf->wpa_rsc_relaxation;
-#ifdef CONFIG_FILS
- if (wpa_key_mgmt_fils(wpa_s->key_mgmt))
- conf.fils_cache_id =
- wpa_bss_get_fils_cache_id(wpa_s->current_bss);
-#endif /* CONFIG_FILS */
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION) ||
- (wpa_s->drv_flags2 &
- WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT))
- conf.beacon_prot = ssid->beacon_prot;
-
-#ifdef CONFIG_PASN
-#ifdef CONFIG_TESTING_OPTIONS
- conf.force_kdk_derivation = wpa_s->conf->force_kdk_derivation;
-#endif /* CONFIG_TESTING_OPTIONS */
-#endif /* CONFIG_PASN */
- }
- wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
-}
diff --git a/wpa_supplicant/wpas_glue.h b/wpa_supplicant/wpas_glue.h
deleted file mode 100644
index 338af4e650a7..000000000000
--- a/wpa_supplicant/wpas_glue.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * WPA Supplicant - Glue code to setup EAPOL and RSN modules
- * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPAS_GLUE_H
-#define WPAS_GLUE_H
-
-enum wpa_ctrl_req_type;
-
-int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
-int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
-void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
- u16 proto, const u8 *buf, size_t len);
-
-const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
- const char *default_txt,
- const char **txt);
-
-enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field);
-
-void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
- const char *field_name, const char *txt);
-
-#endif /* WPAS_GLUE_H */
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c
deleted file mode 100644
index defd0f2f7e81..000000000000
--- a/wpa_supplicant/wpas_kay.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * IEEE 802.1X-2010 KaY Interface
- * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "eap_peer/eap.h"
-#include "eap_peer/eap_i.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "pae/ieee802_1x_key.h"
-#include "pae/ieee802_1x_kay.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "config_ssid.h"
-#include "driver_i.h"
-#include "wpas_kay.h"
-
-
-#define DEFAULT_KEY_LEN 16
-/* secure Connectivity Association Key Name (CKN) */
-#define DEFAULT_CKN_LEN 16
-
-
-static int wpas_macsec_init(void *priv, struct macsec_init_params *params)
-{
- return wpa_drv_macsec_init(priv, params);
-}
-
-
-static int wpas_macsec_deinit(void *priv)
-{
- return wpa_drv_macsec_deinit(priv);
-}
-
-
-static int wpas_macsec_get_capability(void *priv, enum macsec_cap *cap)
-{
- return wpa_drv_macsec_get_capability(priv, cap);
-}
-
-
-static int wpas_enable_protect_frames(void *wpa_s, bool enabled)
-{
- return wpa_drv_enable_protect_frames(wpa_s, enabled);
-}
-
-
-static int wpas_enable_encrypt(void *wpa_s, bool enabled)
-{
- return wpa_drv_enable_encrypt(wpa_s, enabled);
-}
-
-
-static int wpas_set_replay_protect(void *wpa_s, bool enabled, u32 window)
-{
- return wpa_drv_set_replay_protect(wpa_s, enabled, window);
-}
-
-
-static int wpas_set_current_cipher_suite(void *wpa_s, u64 cs)
-{
- return wpa_drv_set_current_cipher_suite(wpa_s, cs);
-}
-
-
-static int wpas_enable_controlled_port(void *wpa_s, bool enabled)
-{
- return wpa_drv_enable_controlled_port(wpa_s, enabled);
-}
-
-
-static int wpas_get_receive_lowest_pn(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_get_receive_lowest_pn(wpa_s, sa);
-}
-
-
-static int wpas_get_transmit_next_pn(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_get_transmit_next_pn(wpa_s, sa);
-}
-
-
-static int wpas_set_transmit_next_pn(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_set_transmit_next_pn(wpa_s, sa);
-}
-
-
-static int wpas_set_receive_lowest_pn(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_set_receive_lowest_pn(wpa_s, sa);
-}
-
-
-static unsigned int conf_offset_val(enum confidentiality_offset co)
-{
- switch (co) {
- case CONFIDENTIALITY_OFFSET_30:
- return 30;
- break;
- case CONFIDENTIALITY_OFFSET_50:
- return 50;
- default:
- return 0;
- }
-}
-
-
-static int wpas_create_receive_sc(void *wpa_s, struct receive_sc *sc,
- enum validate_frames vf,
- enum confidentiality_offset co)
-{
- return wpa_drv_create_receive_sc(wpa_s, sc, conf_offset_val(co), vf);
-}
-
-
-static int wpas_delete_receive_sc(void *wpa_s, struct receive_sc *sc)
-{
- return wpa_drv_delete_receive_sc(wpa_s, sc);
-}
-
-
-static int wpas_create_receive_sa(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_create_receive_sa(wpa_s, sa);
-}
-
-
-static int wpas_delete_receive_sa(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_delete_receive_sa(wpa_s, sa);
-}
-
-
-static int wpas_enable_receive_sa(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_enable_receive_sa(wpa_s, sa);
-}
-
-
-static int wpas_disable_receive_sa(void *wpa_s, struct receive_sa *sa)
-{
- return wpa_drv_disable_receive_sa(wpa_s, sa);
-}
-
-
-static int
-wpas_create_transmit_sc(void *wpa_s, struct transmit_sc *sc,
- enum confidentiality_offset co)
-{
- return wpa_drv_create_transmit_sc(wpa_s, sc, conf_offset_val(co));
-}
-
-
-static int wpas_delete_transmit_sc(void *wpa_s, struct transmit_sc *sc)
-{
- return wpa_drv_delete_transmit_sc(wpa_s, sc);
-}
-
-
-static int wpas_create_transmit_sa(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_create_transmit_sa(wpa_s, sa);
-}
-
-
-static int wpas_delete_transmit_sa(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_delete_transmit_sa(wpa_s, sa);
-}
-
-
-static int wpas_enable_transmit_sa(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_enable_transmit_sa(wpa_s, sa);
-}
-
-
-static int wpas_disable_transmit_sa(void *wpa_s, struct transmit_sa *sa)
-{
- return wpa_drv_disable_transmit_sa(wpa_s, sa);
-}
-
-
-int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
- struct ieee802_1x_kay_ctx *kay_ctx;
- struct ieee802_1x_kay *res = NULL;
- enum macsec_policy policy;
-
- ieee802_1x_dealloc_kay_sm(wpa_s);
-
- if (!ssid || ssid->macsec_policy == 0)
- return 0;
-
- if (ssid->macsec_policy == 1) {
- if (ssid->macsec_integ_only == 1)
- policy = SHOULD_SECURE;
- else
- policy = SHOULD_ENCRYPT;
- } else {
- policy = DO_NOT_SECURE;
- }
-
- kay_ctx = os_zalloc(sizeof(*kay_ctx));
- if (!kay_ctx)
- return -1;
-
- kay_ctx->ctx = wpa_s;
-
- kay_ctx->macsec_init = wpas_macsec_init;
- kay_ctx->macsec_deinit = wpas_macsec_deinit;
- kay_ctx->macsec_get_capability = wpas_macsec_get_capability;
- kay_ctx->enable_protect_frames = wpas_enable_protect_frames;
- kay_ctx->enable_encrypt = wpas_enable_encrypt;
- kay_ctx->set_replay_protect = wpas_set_replay_protect;
- kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite;
- kay_ctx->enable_controlled_port = wpas_enable_controlled_port;
- kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn;
- kay_ctx->get_transmit_next_pn = wpas_get_transmit_next_pn;
- kay_ctx->set_transmit_next_pn = wpas_set_transmit_next_pn;
- kay_ctx->set_receive_lowest_pn = wpas_set_receive_lowest_pn;
- kay_ctx->create_receive_sc = wpas_create_receive_sc;
- kay_ctx->delete_receive_sc = wpas_delete_receive_sc;
- kay_ctx->create_receive_sa = wpas_create_receive_sa;
- kay_ctx->delete_receive_sa = wpas_delete_receive_sa;
- kay_ctx->enable_receive_sa = wpas_enable_receive_sa;
- kay_ctx->disable_receive_sa = wpas_disable_receive_sa;
- kay_ctx->create_transmit_sc = wpas_create_transmit_sc;
- kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc;
- kay_ctx->create_transmit_sa = wpas_create_transmit_sa;
- kay_ctx->delete_transmit_sa = wpas_delete_transmit_sa;
- kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa;
- kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa;
-
- res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect,
- ssid->macsec_replay_window, ssid->macsec_port,
- ssid->mka_priority, wpa_s->ifname,
- wpa_s->own_addr);
- /* ieee802_1x_kay_init() frees kay_ctx on failure */
- if (res == NULL)
- return -1;
-
- wpa_s->kay = res;
-
- return 0;
-}
-
-
-void ieee802_1x_dealloc_kay_sm(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->kay)
- return;
-
- ieee802_1x_kay_deinit(wpa_s->kay);
- wpa_s->kay = NULL;
-}
-
-
-static int ieee802_1x_auth_get_session_id(struct wpa_supplicant *wpa_s,
- const u8 *addr, u8 *sid, size_t *len)
-{
- const u8 *session_id;
- size_t id_len, need_len;
-
- session_id = eapol_sm_get_session_id(wpa_s->eapol, &id_len);
- if (session_id == NULL) {
- wpa_printf(MSG_DEBUG,
- "Failed to get SessionID from EAPOL state machines");
- return -1;
- }
-
- need_len = 1 + 2 * 32 /* random size */;
- if (need_len > id_len) {
- wpa_printf(MSG_DEBUG, "EAP Session-Id not long enough");
- return -1;
- }
-
- os_memcpy(sid, session_id, need_len);
- *len = need_len;
-
- return 0;
-}
-
-
-static int ieee802_1x_auth_get_msk(struct wpa_supplicant *wpa_s, const u8 *addr,
- u8 *msk, size_t *len)
-{
- u8 key[EAP_MSK_LEN];
- size_t keylen;
- struct eapol_sm *sm;
- int res;
-
- sm = wpa_s->eapol;
- if (sm == NULL)
- return -1;
-
- keylen = EAP_MSK_LEN;
- res = eapol_sm_get_key(sm, key, keylen);
- if (res) {
- wpa_printf(MSG_DEBUG,
- "Failed to get MSK from EAPOL state machines");
- return -1;
- }
-
- if (keylen > *len)
- keylen = *len;
- os_memcpy(msk, key, keylen);
- *len = keylen;
-
- return 0;
-}
-
-
-void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- u8 *sid;
- size_t sid_len = 128;
- struct mka_key_name *ckn;
- struct mka_key *cak;
- struct mka_key *msk;
- void *res = NULL;
-
- if (!wpa_s->kay || wpa_s->kay->policy == DO_NOT_SECURE)
- return NULL;
-
- wpa_printf(MSG_DEBUG,
- "IEEE 802.1X: External notification - Create MKA for "
- MACSTR, MAC2STR(peer_addr));
-
- msk = os_zalloc(sizeof(*msk));
- sid = os_zalloc(sid_len);
- ckn = os_zalloc(sizeof(*ckn));
- cak = os_zalloc(sizeof(*cak));
- if (!msk || !sid || !ckn || !cak)
- goto fail;
-
- msk->len = DEFAULT_KEY_LEN;
- if (ieee802_1x_auth_get_msk(wpa_s, wpa_s->bssid, msk->key, &msk->len)) {
- wpa_printf(MSG_ERROR, "IEEE 802.1X: Could not get MSK");
- goto fail;
- }
-
- if (ieee802_1x_auth_get_session_id(wpa_s, wpa_s->bssid, sid, &sid_len))
- {
- wpa_printf(MSG_ERROR,
- "IEEE 802.1X: Could not get EAP Session Id");
- goto fail;
- }
-
- /* Derive CAK from MSK */
- cak->len = DEFAULT_KEY_LEN;
- if (ieee802_1x_cak_aes_cmac(msk->key, msk->len, wpa_s->own_addr,
- peer_addr, cak->key, cak->len)) {
- wpa_printf(MSG_ERROR,
- "IEEE 802.1X: Deriving CAK failed");
- goto fail;
- }
- wpa_hexdump_key(MSG_DEBUG, "Derived CAK", cak->key, cak->len);
-
- /* Derive CKN from MSK */
- ckn->len = DEFAULT_CKN_LEN;
- if (ieee802_1x_ckn_aes_cmac(msk->key, msk->len, wpa_s->own_addr,
- peer_addr, sid, sid_len, ckn->name)) {
- wpa_printf(MSG_ERROR,
- "IEEE 802.1X: Deriving CKN failed");
- goto fail;
- }
- wpa_hexdump(MSG_DEBUG, "Derived CKN", ckn->name, ckn->len);
-
- res = ieee802_1x_kay_create_mka(wpa_s->kay, ckn, cak, 0,
- EAP_EXCHANGE, false);
-
-fail:
- if (msk) {
- os_memset(msk, 0, sizeof(*msk));
- os_free(msk);
- }
- os_free(sid);
- os_free(ckn);
- if (cak) {
- os_memset(cak, 0, sizeof(*cak));
- os_free(cak);
- }
-
- return res;
-}
-
-
-void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- struct mka_key *cak;
- struct mka_key_name *ckn;
- void *res = NULL;
-
- if ((ssid->mka_psk_set & MKA_PSK_SET) != MKA_PSK_SET)
- goto end;
-
- ckn = os_zalloc(sizeof(*ckn));
- if (!ckn)
- goto end;
-
- cak = os_zalloc(sizeof(*cak));
- if (!cak)
- goto free_ckn;
-
- if (ieee802_1x_alloc_kay_sm(wpa_s, ssid) < 0 || !wpa_s->kay)
- goto free_cak;
-
- if (wpa_s->kay->policy == DO_NOT_SECURE)
- goto dealloc;
-
- cak->len = ssid->mka_cak_len;
- os_memcpy(cak->key, ssid->mka_cak, cak->len);
-
- ckn->len = ssid->mka_ckn_len;
- os_memcpy(ckn->name, ssid->mka_ckn, ckn->len);
-
- res = ieee802_1x_kay_create_mka(wpa_s->kay, ckn, cak, 0, PSK, false);
- if (res)
- goto free_cak;
-
-dealloc:
- /* Failed to create MKA */
- ieee802_1x_dealloc_kay_sm(wpa_s);
-free_cak:
- os_free(cak);
-free_ckn:
- os_free(ckn);
-end:
- return res;
-}
diff --git a/wpa_supplicant/wpas_kay.h b/wpa_supplicant/wpas_kay.h
deleted file mode 100644
index 81f8e0ce329e..000000000000
--- a/wpa_supplicant/wpas_kay.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * IEEE 802.1X-2010 KaY Interface
- * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPAS_KAY_H
-#define WPAS_KAY_H
-
-#ifdef CONFIG_MACSEC
-
-int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr);
-void ieee802_1x_dealloc_kay_sm(struct wpa_supplicant *wpa_s);
-
-void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
-
-#else /* CONFIG_MACSEC */
-
-static inline int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-static inline void *
-ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s,
- const u8 *peer_addr)
-{
- return NULL;
-}
-
-static inline void ieee802_1x_dealloc_kay_sm(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline void *
-ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-#endif /* CONFIG_MACSEC */
-
-#endif /* WPAS_KAY_H */
diff --git a/wpa_supplicant/wpas_module_tests.c b/wpa_supplicant/wpas_module_tests.c
deleted file mode 100644
index ce5398cb851a..000000000000
--- a/wpa_supplicant/wpas_module_tests.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * wpa_supplicant module tests
- * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/module_tests.h"
-#include "wpa_supplicant_i.h"
-#include "bssid_ignore.h"
-
-
-static int wpas_bssid_ignore_module_tests(void)
-{
- struct wpa_supplicant wpa_s;
- int ret = -1;
-
- os_memset(&wpa_s, 0, sizeof(wpa_s));
-
- wpa_bssid_ignore_clear(&wpa_s);
-
- if (wpa_bssid_ignore_get(NULL, NULL) != NULL ||
- wpa_bssid_ignore_get(NULL, (u8 *) "123456") != NULL ||
- wpa_bssid_ignore_get(&wpa_s, NULL) != NULL ||
- wpa_bssid_ignore_get(&wpa_s, (u8 *) "123456") != NULL)
- goto fail;
-
- if (wpa_bssid_ignore_add(NULL, NULL) == 0 ||
- wpa_bssid_ignore_add(NULL, (u8 *) "123456") == 0 ||
- wpa_bssid_ignore_add(&wpa_s, NULL) == 0)
- goto fail;
-
- if (wpa_bssid_ignore_del(NULL, NULL) == 0 ||
- wpa_bssid_ignore_del(NULL, (u8 *) "123456") == 0 ||
- wpa_bssid_ignore_del(&wpa_s, NULL) == 0 ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "123456") == 0)
- goto fail;
-
- if (wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "444444") < 0 ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "333333") < 0 ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "xxxxxx") == 0 ||
- wpa_bssid_ignore_get(&wpa_s, (u8 *) "xxxxxx") != NULL ||
- wpa_bssid_ignore_get(&wpa_s, (u8 *) "111111") == NULL ||
- wpa_bssid_ignore_get(&wpa_s, (u8 *) "222222") == NULL ||
- wpa_bssid_ignore_get(&wpa_s, (u8 *) "444444") == NULL ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "222222") < 0 ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "444444") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0)
- goto fail;
-
- wpa_bssid_ignore_clear(&wpa_s);
-
- if (wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0 ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "444444") < 0 ||
- !wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111") ||
- wpa_bssid_ignore_del(&wpa_s, (u8 *) "111111") < 0 ||
- wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111") ||
- wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0)
- goto fail;
-
- wpa_bssid_ignore_update(&wpa_s);
-
- if (!wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111"))
- goto fail;
-
- ret = 0;
-fail:
- wpa_bssid_ignore_clear(&wpa_s);
-
- if (ret)
- wpa_printf(MSG_ERROR, "bssid_ignore module test failure");
-
- return ret;
-}
-
-
-int wpas_module_tests(void)
-{
- int ret = 0;
-
- wpa_printf(MSG_INFO, "wpa_supplicant module tests");
-
- if (wpas_bssid_ignore_module_tests() < 0)
- ret = -1;
-
-#ifdef CONFIG_WPS
- if (wps_module_tests() < 0)
- ret = -1;
-#endif /* CONFIG_WPS */
-
- if (utils_module_tests() < 0)
- ret = -1;
-
- if (common_module_tests() < 0)
- ret = -1;
-
- if (crypto_module_tests() < 0)
- ret = -1;
-
- return ret;
-}
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
deleted file mode 100644
index 5633f3d1ecaf..000000000000
--- a/wpa_supplicant/wps_supplicant.c
+++ /dev/null
@@ -1,3013 +0,0 @@
-/*
- * wpa_supplicant / WPS integration
- * Copyright (c) 2008-2014, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "uuid.h"
-#include "crypto/random.h"
-#include "crypto/dh_group5.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "common/wpa_common.h"
-#include "common/wpa_ctrl.h"
-#include "eap_common/eap_wsc_common.h"
-#include "eap_peer/eap.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "rsn_supp/wpa.h"
-#include "wps/wps_attr_parse.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-#include "notify.h"
-#include "bssid_ignore.h"
-#include "bss.h"
-#include "scan.h"
-#include "ap.h"
-#include "p2p/p2p.h"
-#include "p2p_supplicant.h"
-#include "wps_supplicant.h"
-
-
-#ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
-#define WPS_PIN_SCAN_IGNORE_SEL_REG 3
-#endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
-
-/*
- * The minimum time in seconds before trying to associate to a WPS PIN AP that
- * does not have Selected Registrar TRUE.
- */
-#ifndef WPS_PIN_TIME_IGNORE_SEL_REG
-#define WPS_PIN_TIME_IGNORE_SEL_REG 5
-#endif /* WPS_PIN_TIME_IGNORE_SEL_REG */
-
-static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
-static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
-
-
-static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
-{
- os_free(wpa_s->wps_ap);
- wpa_s->wps_ap = NULL;
- wpa_s->num_wps_ap = 0;
- wpa_s->wps_ap_iter = 0;
-}
-
-
-static void wpas_wps_assoc_with_cred(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- int use_fast_assoc = timeout_ctx != NULL;
-
- wpa_printf(MSG_DEBUG, "WPS: Continuing association after eapol_cb");
- if (!use_fast_assoc ||
- wpa_supplicant_fast_associate(wpa_s) != 1)
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
-{
- eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 0);
- eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 1);
-}
-
-
-int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
-{
- if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
- return 1;
-
- if (!wpa_s->wps_success &&
- wpa_s->current_ssid &&
- eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
- const u8 *bssid = wpa_s->bssid;
- if (is_zero_ether_addr(bssid))
- bssid = wpa_s->pending_bssid;
-
- wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
- " did not succeed - continue trying to find "
- "suitable AP", MAC2STR(bssid));
- wpa_bssid_ignore_add(wpa_s, bssid);
-
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- wpa_s->reassociate = 1;
- wpa_supplicant_req_scan(wpa_s,
- wpa_s->bssid_ignore_cleared ? 5 : 0, 0);
- wpa_s->bssid_ignore_cleared = false;
- return 1;
- }
-
- wpas_wps_clear_ap_info(wpa_s);
- eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success)
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL);
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
- !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
- int disabled = wpa_s->current_ssid->disabled;
- unsigned int freq = wpa_s->assoc_freq;
- struct wpa_bss *bss;
- struct wpa_ssid *ssid = NULL;
- int use_fast_assoc = 0;
-
- wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
- "try to associate with the received credential "
- "(freq=%u)", freq);
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- if (disabled) {
- wpa_printf(MSG_DEBUG, "WPS: Current network is "
- "disabled - wait for user to enable");
- return 1;
- }
- wpa_s->after_wps = 5;
- wpa_s->wps_freq = freq;
- wpa_s->normal_scans = 0;
- wpa_s->reassociate = 1;
-
- wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
- "without a new scan can be used");
- bss = wpa_supplicant_pick_network(wpa_s, &ssid);
- if (bss) {
- struct wpabuf *wps;
- struct wps_parse_attr attr;
-
- wps = wpa_bss_get_vendor_ie_multi(bss,
- WPS_IE_VENDOR_TYPE);
- if (wps && wps_parse_msg(wps, &attr) == 0 &&
- attr.wps_state &&
- *attr.wps_state == WPS_STATE_CONFIGURED)
- use_fast_assoc = 1;
- wpabuf_free(wps);
- }
-
- /*
- * Complete the next step from an eloop timeout to allow pending
- * driver events related to the disconnection to be processed
- * first. This makes it less likely for disconnection event to
- * cause problems with the following connection.
- */
- wpa_printf(MSG_DEBUG, "WPS: Continue association from timeout");
- wpas_wps_assoc_with_cred_cancel(wpa_s);
- eloop_register_timeout(0, 10000,
- wpas_wps_assoc_with_cred, wpa_s,
- use_fast_assoc ? (void *) 1 :
- (void *) 0);
- return 1;
- }
-
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
- wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
- "for external credential processing");
- wpas_clear_wps(wpa_s);
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- return 1;
- }
-
- return 0;
-}
-
-
-static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- const struct wps_credential *cred)
-{
- struct wpa_driver_capa capa;
- struct wpa_bss *bss;
- const u8 *ie;
- struct wpa_ie_data adv;
- int wpa2 = 0, ccmp = 0;
- enum wpa_driver_if_type iftype;
-
- /*
- * Many existing WPS APs do not know how to negotiate WPA2 or CCMP in
- * case they are configured for mixed mode operation (WPA+WPA2 and
- * TKIP+CCMP). Try to use scan results to figure out whether the AP
- * actually supports stronger security and select that if the client
- * has support for it, too.
- */
-
- if (wpa_drv_get_capa(wpa_s, &capa))
- return; /* Unknown what driver supports */
-
- if (ssid->ssid == NULL)
- return;
- bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
- if (!bss)
- bss = wpa_bss_get(wpa_s, wpa_s->bssid,
- ssid->ssid, ssid->ssid_len);
- if (bss == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
- "table - use credential as-is");
- return;
- }
-
- wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
-
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
- wpa2 = 1;
- if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
- ccmp = 1;
- } else {
- ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 &&
- adv.pairwise_cipher & WPA_CIPHER_CCMP)
- ccmp = 1;
- }
-
- if (ie == NULL && (ssid->proto & WPA_PROTO_WPA) &&
- (ssid->pairwise_cipher & WPA_CIPHER_TKIP)) {
- /*
- * TODO: This could be the initial AP configuration and the
- * Beacon contents could change shortly. Should request a new
- * scan and delay addition of the network until the updated
- * scan results are available.
- */
- wpa_printf(MSG_DEBUG, "WPS: The AP did not yet advertise WPA "
- "support - use credential as-is");
- return;
- }
-
- iftype = ssid->p2p_group ? WPA_IF_P2P_CLIENT : WPA_IF_STATION;
-
- if (ccmp && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
- (ssid->pairwise_cipher & WPA_CIPHER_TKIP) &&
- (capa.key_mgmt_iftype[iftype] &
- WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
- wpa_printf(MSG_DEBUG, "WPS: Add CCMP into the credential "
- "based on scan results");
- if (wpa_s->conf->ap_scan == 1)
- ssid->pairwise_cipher |= WPA_CIPHER_CCMP;
- else
- ssid->pairwise_cipher = WPA_CIPHER_CCMP;
- }
-
- if (wpa2 && !(ssid->proto & WPA_PROTO_RSN) &&
- (ssid->proto & WPA_PROTO_WPA) &&
- (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
- wpa_printf(MSG_DEBUG, "WPS: Add WPA2 into the credential "
- "based on scan results");
- if (wpa_s->conf->ap_scan == 1)
- ssid->proto |= WPA_PROTO_RSN;
- else
- ssid->proto = WPA_PROTO_RSN;
- }
-}
-
-
-static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *new_ssid)
-{
- struct wpa_ssid *ssid, *next;
-
- for (ssid = wpa_s->conf->ssid, next = ssid ? ssid->next : NULL; ssid;
- ssid = next, next = ssid ? ssid->next : NULL) {
- /*
- * new_ssid has already been added to the list in
- * wpas_wps_add_network(), so skip it.
- */
- if (ssid == new_ssid)
- continue;
-
- if (ssid->bssid_set || new_ssid->bssid_set) {
- if (ssid->bssid_set != new_ssid->bssid_set)
- continue;
- if (os_memcmp(ssid->bssid, new_ssid->bssid, ETH_ALEN) !=
- 0)
- continue;
- }
-
- /* compare SSID */
- if (ssid->ssid_len == 0 || ssid->ssid_len != new_ssid->ssid_len)
- continue;
-
- if (ssid->ssid && new_ssid->ssid) {
- if (os_memcmp(ssid->ssid, new_ssid->ssid,
- ssid->ssid_len) != 0)
- continue;
- } else if (ssid->ssid || new_ssid->ssid)
- continue;
-
- /* compare security parameters */
- if (ssid->auth_alg != new_ssid->auth_alg ||
- ssid->key_mgmt != new_ssid->key_mgmt ||
- (ssid->group_cipher != new_ssid->group_cipher &&
- !(ssid->group_cipher & new_ssid->group_cipher &
- WPA_CIPHER_CCMP)))
- continue;
-
- /*
- * Some existing WPS APs will send two creds in case they are
- * configured for mixed mode operation (WPA+WPA2 and TKIP+CCMP).
- * Try to merge these two creds if they are received in the same
- * M8 message.
- */
- if (ssid->wps_run && ssid->wps_run == new_ssid->wps_run &&
- wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
- if (new_ssid->passphrase && ssid->passphrase &&
- os_strcmp(new_ssid->passphrase, ssid->passphrase) !=
- 0) {
- wpa_printf(MSG_DEBUG,
- "WPS: M8 Creds with different passphrase - do not merge");
- continue;
- }
-
- if (new_ssid->psk_set &&
- (!ssid->psk_set ||
- os_memcmp(new_ssid->psk, ssid->psk, 32) != 0)) {
- wpa_printf(MSG_DEBUG,
- "WPS: M8 Creds with different PSK - do not merge");
- continue;
- }
-
- if ((new_ssid->passphrase && !ssid->passphrase) ||
- (!new_ssid->passphrase && ssid->passphrase)) {
- wpa_printf(MSG_DEBUG,
- "WPS: M8 Creds with different passphrase/PSK type - do not merge");
- continue;
- }
-
- wpa_printf(MSG_DEBUG,
- "WPS: Workaround - merge likely WPA/WPA2-mixed mode creds in same M8 message");
- new_ssid->proto |= ssid->proto;
- new_ssid->pairwise_cipher |= ssid->pairwise_cipher;
- } else {
- /*
- * proto and pairwise_cipher difference matter for
- * non-mixed-mode creds.
- */
- if (ssid->proto != new_ssid->proto ||
- ssid->pairwise_cipher != new_ssid->pairwise_cipher)
- continue;
- }
-
- /* Remove the duplicated older network entry. */
- wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id);
- wpas_notify_network_removed(wpa_s, ssid);
- if (wpa_s->current_ssid == ssid)
- wpa_s->current_ssid = NULL;
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- }
-}
-
-
-static int wpa_supplicant_wps_cred(void *ctx,
- const struct wps_credential *cred)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- u16 auth_type;
-#ifdef CONFIG_WPS_REG_DISABLE_OPEN
- int registrar = 0;
-#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
- bool add_sae;
-
- if ((wpa_s->conf->wps_cred_processing == 1 ||
- wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
- size_t blen = cred->cred_attr_len * 2 + 1;
- char *buf = os_malloc(blen);
- if (buf) {
- wpa_snprintf_hex(buf, blen,
- cred->cred_attr, cred->cred_attr_len);
- wpa_msg(wpa_s, MSG_INFO, "%s%s",
- WPS_EVENT_CRED_RECEIVED, buf);
- os_free(buf);
- }
-
- wpas_notify_wps_credential(wpa_s, cred);
- } else
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
-
- wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
- cred->cred_attr, cred->cred_attr_len);
-
- if (wpa_s->conf->wps_cred_processing == 1)
- return 0;
-
- wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
- wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
- cred->auth_type);
- wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
- wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
- wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
- cred->key, cred->key_len);
- wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
- MAC2STR(cred->mac_addr));
-
- auth_type = cred->auth_type;
- if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
- wpa_printf(MSG_DEBUG, "WPS: Workaround - convert mixed-mode "
- "auth_type into WPA2PSK");
- auth_type = WPS_AUTH_WPA2PSK;
- }
-
- if (auth_type != WPS_AUTH_OPEN &&
- auth_type != WPS_AUTH_WPAPSK &&
- auth_type != WPS_AUTH_WPA2PSK) {
- wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for "
- "unsupported authentication type 0x%x",
- auth_type);
- return 0;
- }
-
- if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) {
- if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) {
- wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with "
- "invalid Network Key length %lu",
- (unsigned long) cred->key_len);
- return -1;
- }
- }
-
- if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
- wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
- "on the received credential");
-#ifdef CONFIG_WPS_REG_DISABLE_OPEN
- if (ssid->eap.identity &&
- ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
- os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
- WSC_ID_REGISTRAR_LEN) == 0)
- registrar = 1;
-#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
- os_free(ssid->eap.identity);
- ssid->eap.identity = NULL;
- ssid->eap.identity_len = 0;
- os_free(ssid->eap.phase1);
- ssid->eap.phase1 = NULL;
- os_free(ssid->eap.eap_methods);
- ssid->eap.eap_methods = NULL;
- if (!ssid->p2p_group) {
- ssid->temporary = 0;
- ssid->bssid_set = 0;
- }
- ssid->disabled_until.sec = 0;
- ssid->disabled_until.usec = 0;
- ssid->auth_failures = 0;
- } else {
- wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
- "received credential");
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL)
- return -1;
- if (wpa_s->current_ssid) {
- /*
- * Should the GO issue multiple credentials for some
- * reason, each credential should be marked as a
- * temporary P2P group similarly to the one that gets
- * marked as such based on the pre-configured values
- * used for the WPS network block.
- */
- ssid->p2p_group = wpa_s->current_ssid->p2p_group;
- ssid->temporary = wpa_s->current_ssid->temporary;
- }
- wpas_notify_network_added(wpa_s, ssid);
- }
-
- wpa_config_set_network_defaults(ssid);
- ssid->wps_run = wpa_s->wps_run;
-
- os_free(ssid->ssid);
- ssid->ssid = os_malloc(cred->ssid_len);
- if (ssid->ssid) {
- os_memcpy(ssid->ssid, cred->ssid, cred->ssid_len);
- ssid->ssid_len = cred->ssid_len;
- }
-
- switch (cred->encr_type) {
- case WPS_ENCR_NONE:
- break;
- case WPS_ENCR_TKIP:
- ssid->pairwise_cipher = WPA_CIPHER_TKIP | WPA_CIPHER_CCMP;
- break;
- case WPS_ENCR_AES:
- ssid->pairwise_cipher = WPA_CIPHER_CCMP;
- if (wpa_s->drv_capa_known &&
- (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP)) {
- ssid->pairwise_cipher |= WPA_CIPHER_GCMP;
- ssid->group_cipher |= WPA_CIPHER_GCMP;
- }
- if (wpa_s->drv_capa_known &&
- (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)) {
- ssid->pairwise_cipher |= WPA_CIPHER_GCMP_256;
- ssid->group_cipher |= WPA_CIPHER_GCMP_256;
- }
- if (wpa_s->drv_capa_known &&
- (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256)) {
- ssid->pairwise_cipher |= WPA_CIPHER_CCMP_256;
- ssid->group_cipher |= WPA_CIPHER_CCMP_256;
- }
- break;
- }
-
- switch (auth_type) {
- case WPS_AUTH_OPEN:
- ssid->auth_alg = WPA_AUTH_ALG_OPEN;
- ssid->key_mgmt = WPA_KEY_MGMT_NONE;
- ssid->proto = 0;
-#ifdef CONFIG_WPS_REG_DISABLE_OPEN
- if (registrar) {
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OPEN_NETWORK
- "id=%d - Credentials for an open "
- "network disabled by default - use "
- "'select_network %d' to enable",
- ssid->id, ssid->id);
- ssid->disabled = 1;
- }
-#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
- break;
- case WPS_AUTH_WPAPSK:
- ssid->auth_alg = WPA_AUTH_ALG_OPEN;
- ssid->key_mgmt = WPA_KEY_MGMT_PSK;
- ssid->proto = WPA_PROTO_WPA | WPA_PROTO_RSN;
- break;
- case WPS_AUTH_WPA2PSK:
- ssid->auth_alg = WPA_AUTH_ALG_OPEN;
- ssid->key_mgmt = WPA_KEY_MGMT_PSK;
- add_sae = wpa_s->conf->wps_cred_add_sae;
-#ifdef CONFIG_P2P
- if (ssid->p2p_group && is_p2p_6ghz_capable(wpa_s->global->p2p))
- add_sae = true;
-#endif /* CONFIG_P2P */
- if (add_sae && cred->key_len != 2 * PMK_LEN) {
- ssid->auth_alg = 0;
- ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
- ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
- }
- ssid->proto = WPA_PROTO_RSN;
- break;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
- if (cred->key_len == 2 * PMK_LEN) {
- if (hexstr2bin((const char *) cred->key, ssid->psk,
- PMK_LEN)) {
- wpa_printf(MSG_ERROR, "WPS: Invalid Network "
- "Key");
- return -1;
- }
- ssid->psk_set = 1;
- ssid->export_keys = 1;
- } else if (cred->key_len >= 8 && cred->key_len < 2 * PMK_LEN) {
- os_free(ssid->passphrase);
- ssid->passphrase = os_malloc(cred->key_len + 1);
- if (ssid->passphrase == NULL)
- return -1;
- os_memcpy(ssid->passphrase, cred->key, cred->key_len);
- ssid->passphrase[cred->key_len] = '\0';
- wpa_config_update_psk(ssid);
- ssid->export_keys = 1;
- } else {
- wpa_printf(MSG_ERROR, "WPS: Invalid Network Key "
- "length %lu",
- (unsigned long) cred->key_len);
- return -1;
- }
- }
- ssid->priority = wpa_s->conf->wps_priority;
-
- wpas_wps_security_workaround(wpa_s, ssid, cred);
-
- wpas_wps_remove_dup_network(wpa_s, ssid);
-
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf)) {
- wpa_printf(MSG_DEBUG, "WPS: Failed to update configuration");
- return -1;
- }
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
- if (ssid->priority)
- wpa_config_update_prio_list(wpa_s->conf);
-
- /*
- * Optimize the post-WPS scan based on the channel used during
- * the provisioning in case EAP-Failure is not received.
- */
- wpa_s->after_wps = 5;
- wpa_s->wps_freq = wpa_s->assoc_freq;
-
- return 0;
-}
-
-
-static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
- struct wps_event_m2d *m2d)
-{
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
- "dev_password_id=%d config_error=%d",
- m2d->dev_password_id, m2d->config_error);
- wpas_notify_wps_event_m2d(wpa_s, m2d);
-#ifdef CONFIG_P2P
- if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s) {
- wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_M2D
- "dev_password_id=%d config_error=%d",
- m2d->dev_password_id, m2d->config_error);
- }
- if (m2d->config_error == WPS_CFG_MULTIPLE_PBC_DETECTED) {
- /*
- * Notify P2P from eloop timeout to avoid issues with the
- * interface getting removed while processing a message.
- */
- eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, wpa_s,
- NULL);
- }
-#endif /* CONFIG_P2P */
-}
-
-
-static void wpas_wps_clear_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- wpa_printf(MSG_DEBUG, "WPS: Clear WPS network from timeout");
- wpas_clear_wps(wpa_s);
-}
-
-
-static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
- struct wps_event_fail *fail)
-{
- if (fail->error_indication > 0 &&
- fail->error_indication < NUM_WPS_EI_VALUES) {
- wpa_msg(wpa_s, MSG_INFO,
- WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
- fail->msg, fail->config_error, fail->error_indication,
- wps_ei_str(fail->error_indication));
- if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
- wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
- "msg=%d config_error=%d reason=%d (%s)",
- fail->msg, fail->config_error,
- fail->error_indication,
- wps_ei_str(fail->error_indication));
- } else {
- wpa_msg(wpa_s, MSG_INFO,
- WPS_EVENT_FAIL "msg=%d config_error=%d",
- fail->msg, fail->config_error);
- if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
- wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
- "msg=%d config_error=%d",
- fail->msg, fail->config_error);
- }
-
- /*
- * Need to allow WPS processing to complete, e.g., by sending WSC_NACK.
- */
- wpa_printf(MSG_DEBUG, "WPS: Register timeout to clear WPS network");
- eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
- eloop_register_timeout(0, 100000, wpas_wps_clear_timeout, wpa_s, NULL);
-
- wpas_notify_wps_event_fail(wpa_s, fail);
- wpas_p2p_wps_failed(wpa_s, fail);
-}
-
-
-static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx);
-
-static void wpas_wps_reenable_networks(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
- int changed = 0;
-
- eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if (ssid->disabled_for_connect && ssid->disabled) {
- ssid->disabled_for_connect = 0;
- ssid->disabled = 0;
- wpas_notify_network_enabled_changed(wpa_s, ssid);
- changed++;
- }
- }
-
- if (changed) {
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (wpa_s->conf->update_config &&
- wpa_config_write(wpa_s->confname, wpa_s->conf)) {
- wpa_printf(MSG_DEBUG, "WPS: Failed to update "
- "configuration");
- }
-#endif /* CONFIG_NO_CONFIG_WRITE */
- }
-}
-
-
-static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- /* Enable the networks disabled during wpas_wps_reassoc */
- wpas_wps_reenable_networks(wpa_s);
-}
-
-
-int wpas_wps_reenable_networks_pending(struct wpa_supplicant *wpa_s)
-{
- return eloop_is_timeout_registered(wpas_wps_reenable_networks_cb,
- wpa_s, NULL);
-}
-
-
-static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
-{
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
- wpa_s->wps_success = 1;
- wpas_notify_wps_event_success(wpa_s);
- if (wpa_s->current_ssid)
- wpas_clear_temp_disabled(wpa_s, wpa_s->current_ssid, 1);
- wpa_s->consecutive_conn_failures = 0;
-
- /*
- * Enable the networks disabled during wpas_wps_reassoc after 10
- * seconds. The 10 seconds timer is to allow the data connection to be
- * formed before allowing other networks to be selected.
- */
- eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
- NULL);
-
- wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
-}
-
-
-static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
- struct wps_event_er_ap *ap)
-{
- char uuid_str[100];
- char dev_type[WPS_DEV_TYPE_BUFSIZE];
-
- uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
- if (ap->pri_dev_type)
- wps_dev_type_bin2str(ap->pri_dev_type, dev_type,
- sizeof(dev_type));
- else
- dev_type[0] = '\0';
-
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR
- " pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|",
- uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state,
- ap->friendly_name ? ap->friendly_name : "",
- ap->manufacturer ? ap->manufacturer : "",
- ap->model_description ? ap->model_description : "",
- ap->model_name ? ap->model_name : "",
- ap->manufacturer_url ? ap->manufacturer_url : "",
- ap->model_url ? ap->model_url : "");
-}
-
-
-static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
- struct wps_event_er_ap *ap)
-{
- char uuid_str[100];
- uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
-}
-
-
-static void wpa_supplicant_wps_event_er_enrollee_add(
- struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
-{
- char uuid_str[100];
- char dev_type[WPS_DEV_TYPE_BUFSIZE];
-
- uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
- if (enrollee->pri_dev_type)
- wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type,
- sizeof(dev_type));
- else
- dev_type[0] = '\0';
-
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
- " M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
- "|%s|%s|%s|%s|%s|",
- uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
- enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
- enrollee->dev_name ? enrollee->dev_name : "",
- enrollee->manufacturer ? enrollee->manufacturer : "",
- enrollee->model_name ? enrollee->model_name : "",
- enrollee->model_number ? enrollee->model_number : "",
- enrollee->serial_number ? enrollee->serial_number : "");
-}
-
-
-static void wpa_supplicant_wps_event_er_enrollee_remove(
- struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
-{
- char uuid_str[100];
- uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
- uuid_str, MAC2STR(enrollee->mac_addr));
-}
-
-
-static void wpa_supplicant_wps_event_er_ap_settings(
- struct wpa_supplicant *wpa_s,
- struct wps_event_er_ap_settings *ap_settings)
-{
- char uuid_str[100];
- char key_str[65];
- const struct wps_credential *cred = ap_settings->cred;
-
- key_str[0] = '\0';
- if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
- if (cred->key_len >= 8 && cred->key_len <= 64) {
- os_memcpy(key_str, cred->key, cred->key_len);
- key_str[cred->key_len] = '\0';
- }
- }
-
- uuid_bin2str(ap_settings->uuid, uuid_str, sizeof(uuid_str));
- /* Use wpa_msg_ctrl to avoid showing the key in debug log */
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_SETTINGS
- "uuid=%s ssid=%s auth_type=0x%04x encr_type=0x%04x "
- "key=%s",
- uuid_str, wpa_ssid_txt(cred->ssid, cred->ssid_len),
- cred->auth_type, cred->encr_type, key_str);
-}
-
-
-static void wpa_supplicant_wps_event_er_set_sel_reg(
- struct wpa_supplicant *wpa_s,
- struct wps_event_er_set_selected_registrar *ev)
-{
- char uuid_str[100];
-
- uuid_bin2str(ev->uuid, uuid_str, sizeof(uuid_str));
- switch (ev->state) {
- case WPS_ER_SET_SEL_REG_START:
- wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
- "uuid=%s state=START sel_reg=%d dev_passwd_id=%u "
- "sel_reg_config_methods=0x%x",
- uuid_str, ev->sel_reg, ev->dev_passwd_id,
- ev->sel_reg_config_methods);
- break;
- case WPS_ER_SET_SEL_REG_DONE:
- wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
- "uuid=%s state=DONE", uuid_str);
- break;
- case WPS_ER_SET_SEL_REG_FAILED:
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_SET_SEL_REG
- "uuid=%s state=FAILED", uuid_str);
- break;
- }
-}
-
-
-static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
- union wps_event_data *data)
-{
- struct wpa_supplicant *wpa_s = ctx;
- switch (event) {
- case WPS_EV_M2D:
- wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
- break;
- case WPS_EV_FAIL:
- wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
- break;
- case WPS_EV_SUCCESS:
- wpa_supplicant_wps_event_success(wpa_s);
- break;
- case WPS_EV_PWD_AUTH_FAIL:
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface && data->pwd_auth_fail.enrollee)
- wpa_supplicant_ap_pwd_auth_fail(wpa_s);
-#endif /* CONFIG_AP */
- break;
- case WPS_EV_PBC_OVERLAP:
- break;
- case WPS_EV_PBC_TIMEOUT:
- break;
- case WPS_EV_PBC_ACTIVE:
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ACTIVE);
- break;
- case WPS_EV_PBC_DISABLE:
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_DISABLE);
- break;
- case WPS_EV_ER_AP_ADD:
- wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
- break;
- case WPS_EV_ER_AP_REMOVE:
- wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
- break;
- case WPS_EV_ER_ENROLLEE_ADD:
- wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
- &data->enrollee);
- break;
- case WPS_EV_ER_ENROLLEE_REMOVE:
- wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
- &data->enrollee);
- break;
- case WPS_EV_ER_AP_SETTINGS:
- wpa_supplicant_wps_event_er_ap_settings(wpa_s,
- &data->ap_settings);
- break;
- case WPS_EV_ER_SET_SELECTED_REGISTRAR:
- wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
- &data->set_sel_reg);
- break;
- case WPS_EV_AP_PIN_SUCCESS:
- break;
- }
-}
-
-
-static int wpa_supplicant_wps_rf_band(void *ctx)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (!wpa_s->current_ssid || !wpa_s->assoc_freq)
- return 0;
-
- return (wpa_s->assoc_freq > 50000) ? WPS_RF_60GHZ :
- (wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ;
-}
-
-
-enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
-{
- if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
- eap_is_wps_pin_enrollee(&ssid->eap))
- return WPS_REQ_ENROLLEE;
- else
- return WPS_REQ_REGISTRAR;
-}
-
-
-static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
-{
- int id;
- struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
-
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
-
- prev_current = wpa_s->current_ssid;
-
- /* Enable the networks disabled during wpas_wps_reassoc */
- wpas_wps_reenable_networks(wpa_s);
-
- eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
-
- /* Remove any existing WPS network from configuration */
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- if (ssid == wpa_s->current_ssid) {
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
- id = ssid->id;
- remove_ssid = ssid;
- } else
- id = -1;
- ssid = ssid->next;
- if (id >= 0) {
- if (prev_current == remove_ssid) {
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL,
- NULL);
- }
- wpas_notify_network_removed(wpa_s, remove_ssid);
- wpa_config_remove_network(wpa_s->conf, id);
- }
- }
-
- wpas_wps_clear_ap_info(wpa_s);
-}
-
-
-static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_supplicant *wpa_s = eloop_ctx;
- union wps_event_data data;
-
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
- "out");
- os_memset(&data, 0, sizeof(data));
- data.fail.config_error = WPS_CFG_MSG_TIMEOUT;
- data.fail.error_indication = WPS_EI_NO_ERROR;
- /*
- * Call wpas_notify_wps_event_fail() directly instead of through
- * wpa_supplicant_wps_event() which would end up registering unnecessary
- * timeouts (those are only for the case where the failure happens
- * during an EAP-WSC exchange).
- */
- wpas_notify_wps_event_fail(wpa_s, &data.fail);
- wpas_clear_wps(wpa_s);
-}
-
-
-static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
- int registrar, const u8 *dev_addr,
- const u8 *bssid)
-{
- struct wpa_ssid *ssid;
-
- ssid = wpa_config_add_network(wpa_s->conf);
- if (ssid == NULL)
- return NULL;
- wpas_notify_network_added(wpa_s, ssid);
- wpa_config_set_network_defaults(ssid);
- ssid->temporary = 1;
- if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
- wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
- wpa_config_set(ssid, "identity", registrar ?
- "\"" WSC_ID_REGISTRAR "\"" :
- "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
- wpas_notify_network_removed(wpa_s, ssid);
- wpa_config_remove_network(wpa_s->conf, ssid->id);
- return NULL;
- }
-
-#ifdef CONFIG_P2P
- if (dev_addr)
- os_memcpy(ssid->go_p2p_dev_addr, dev_addr, ETH_ALEN);
-#endif /* CONFIG_P2P */
-
- if (bssid) {
-#ifndef CONFIG_P2P
- struct wpa_bss *bss;
- int count = 0;
-#endif /* CONFIG_P2P */
-
- os_memcpy(ssid->bssid, bssid, ETH_ALEN);
- ssid->bssid_set = 1;
-
- /*
- * Note: With P2P, the SSID may change at the time the WPS
- * provisioning is started, so better not filter the AP based
- * on the current SSID in the scan results.
- */
-#ifndef CONFIG_P2P
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
- continue;
-
- os_free(ssid->ssid);
- ssid->ssid = os_memdup(bss->ssid, bss->ssid_len);
- if (ssid->ssid == NULL)
- break;
- ssid->ssid_len = bss->ssid_len;
- wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
- "scan results",
- ssid->ssid, ssid->ssid_len);
- count++;
- }
-
- if (count > 1) {
- wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
- "for the AP; use wildcard");
- os_free(ssid->ssid);
- ssid->ssid = NULL;
- ssid->ssid_len = 0;
- }
-#endif /* CONFIG_P2P */
- }
-
- return ssid;
-}
-
-
-static void wpas_wps_temp_disable(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *selected)
-{
- struct wpa_ssid *ssid;
-
- if (wpa_s->current_ssid) {
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_DEAUTH_LEAVING);
- }
-
- /* Mark all other networks disabled and trigger reassociation */
- ssid = wpa_s->conf->ssid;
- while (ssid) {
- int was_disabled = ssid->disabled;
- ssid->disabled_for_connect = 0;
- /*
- * In case the network object corresponds to a persistent group
- * then do not send out network disabled signal. In addition,
- * do not change disabled status of persistent network objects
- * from 2 to 1 should we connect to another network.
- */
- if (was_disabled != 2) {
- ssid->disabled = ssid != selected;
- if (was_disabled != ssid->disabled) {
- if (ssid->disabled)
- ssid->disabled_for_connect = 1;
- wpas_notify_network_enabled_changed(wpa_s,
- ssid);
- }
- }
- ssid = ssid->next;
- }
-}
-
-
-static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *selected, const u8 *bssid,
- int freq)
-{
- struct wpa_bss *bss;
-
- wpa_s->wps_run++;
- if (wpa_s->wps_run == 0)
- wpa_s->wps_run++;
- wpa_s->after_wps = 0;
- wpa_s->known_wps_freq = 0;
- if (freq) {
- wpa_s->after_wps = 5;
- wpa_s->wps_freq = freq;
- } else if (bssid) {
- bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
- if (bss && bss->freq > 0) {
- wpa_s->known_wps_freq = 1;
- wpa_s->wps_freq = bss->freq;
- }
- }
-
- wpas_wps_temp_disable(wpa_s, selected);
-
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
- wpa_s->scan_runs = 0;
- wpa_s->normal_scans = 0;
- wpa_s->wps_success = 0;
- wpa_s->bssid_ignore_cleared = false;
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-}
-
-
-int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group, int multi_ap_backhaul_sta)
-{
- struct wpa_ssid *ssid;
- char phase1[32];
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_printf(MSG_DEBUG,
- "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
- return -1;
- }
-#endif /* CONFIG_AP */
- wpas_clear_wps(wpa_s);
- ssid = wpas_wps_add_network(wpa_s, 0, NULL, bssid);
- if (ssid == NULL)
- return -1;
- ssid->temporary = 1;
- ssid->p2p_group = p2p_group;
- /*
- * When starting a regular WPS process (not P2P group formation)
- * the registrar/final station can be either AP or PCP
- * so use a "don't care" value for the pbss flag.
- */
- if (!p2p_group)
- ssid->pbss = 2;
-#ifdef CONFIG_P2P
- if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
- ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
- if (ssid->ssid) {
- ssid->ssid_len = wpa_s->go_params->ssid_len;
- os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
- ssid->ssid_len);
- if (wpa_s->go_params->freq > 56160) {
- /* P2P in 60 GHz uses PBSS */
- ssid->pbss = 1;
- }
- if (wpa_s->go_params->edmg &&
- wpas_p2p_try_edmg_channel(wpa_s,
- wpa_s->go_params) == 0)
- ssid->enable_edmg = 1;
-
- wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
- "SSID", ssid->ssid, ssid->ssid_len);
- }
- }
-#endif /* CONFIG_P2P */
- os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
- multi_ap_backhaul_sta ? " multi_ap=1" : "");
- if (wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
- return -1;
- if (wpa_s->wps_fragment_size)
- ssid->eap.fragment_size = wpa_s->wps_fragment_size;
- if (multi_ap_backhaul_sta)
- ssid->multi_ap_backhaul_sta = 1;
- wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
- eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
- wpa_s, NULL);
- wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
- return 0;
-}
-
-
-static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
- const u8 *dev_addr, const u8 *bssid,
- const char *pin, int p2p_group, u16 dev_pw_id,
- const u8 *peer_pubkey_hash,
- const u8 *ssid_val, size_t ssid_len, int freq)
-{
- struct wpa_ssid *ssid;
- char val[128 + 2 * WPS_OOB_PUBKEY_HASH_LEN];
- unsigned int rpin = 0;
- char hash[2 * WPS_OOB_PUBKEY_HASH_LEN + 10];
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_printf(MSG_DEBUG,
- "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
- return -1;
- }
-#endif /* CONFIG_AP */
- wpas_clear_wps(wpa_s);
- if (bssid && is_zero_ether_addr(bssid))
- bssid = NULL;
- ssid = wpas_wps_add_network(wpa_s, 0, dev_addr, bssid);
- if (ssid == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: Could not add network");
- return -1;
- }
- ssid->temporary = 1;
- ssid->p2p_group = p2p_group;
- /*
- * When starting a regular WPS process (not P2P group formation)
- * the registrar/final station can be either AP or PCP
- * so use a "don't care" value for the pbss flag.
- */
- if (!p2p_group)
- ssid->pbss = 2;
- if (ssid_val) {
- ssid->ssid = os_malloc(ssid_len);
- if (ssid->ssid) {
- os_memcpy(ssid->ssid, ssid_val, ssid_len);
- ssid->ssid_len = ssid_len;
- }
- }
- if (peer_pubkey_hash) {
- os_memcpy(hash, " pkhash=", 8);
- wpa_snprintf_hex_uppercase(hash + 8, sizeof(hash) - 8,
- peer_pubkey_hash,
- WPS_OOB_PUBKEY_HASH_LEN);
- } else {
- hash[0] = '\0';
- }
-#ifdef CONFIG_P2P
- if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
- os_free(ssid->ssid);
- ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
- if (ssid->ssid) {
- ssid->ssid_len = wpa_s->go_params->ssid_len;
- os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
- ssid->ssid_len);
- if (wpa_s->go_params->freq > 56160) {
- /* P2P in 60 GHz uses PBSS */
- ssid->pbss = 1;
- }
- if (wpa_s->go_params->edmg &&
- wpas_p2p_try_edmg_channel(wpa_s,
- wpa_s->go_params) == 0)
- ssid->enable_edmg = 1;
-
- wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
- "SSID", ssid->ssid, ssid->ssid_len);
- }
- }
-#endif /* CONFIG_P2P */
- if (pin)
- os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u%s\"",
- pin, dev_pw_id, hash);
- else if (pin == NULL && dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
- os_snprintf(val, sizeof(val), "\"dev_pw_id=%u%s\"",
- dev_pw_id, hash);
- } else {
- if (wps_generate_pin(&rpin) < 0) {
- wpa_printf(MSG_DEBUG, "WPS: Could not generate PIN");
- return -1;
- }
- os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u%s\"",
- rpin, dev_pw_id, hash);
- }
- if (wpa_config_set(ssid, "phase1", val, 0) < 0) {
- wpa_printf(MSG_DEBUG, "WPS: Failed to set phase1 '%s'", val);
- return -1;
- }
-
- if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER)
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_PIN_ACTIVE);
-
- if (wpa_s->wps_fragment_size)
- ssid->eap.fragment_size = wpa_s->wps_fragment_size;
- eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
- wpa_s, NULL);
- wpa_s->wps_ap_iter = 1;
- wpas_wps_reassoc(wpa_s, ssid, bssid, freq);
- return rpin;
-}
-
-
-int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, int p2p_group, u16 dev_pw_id)
-{
- os_get_reltime(&wpa_s->wps_pin_start_time);
- return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
- dev_pw_id, NULL, NULL, 0, 0);
-}
-
-
-void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
- union wps_event_data data;
-
- os_memset(&data, 0, sizeof(data));
- data.fail.config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
- data.fail.error_indication = WPS_EI_NO_ERROR;
- /*
- * Call wpas_notify_wps_event_fail() directly instead of through
- * wpa_supplicant_wps_event() which would end up registering unnecessary
- * timeouts (those are only for the case where the failure happens
- * during an EAP-WSC exchange).
- */
- wpas_notify_wps_event_fail(wpa_s, &data.fail);
-}
-
-/* Cancel the wps pbc/pin requests */
-int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
- return wpa_supplicant_ap_wps_cancel(wpa_s);
- }
-#endif /* CONFIG_AP */
-
- if (wpa_s->wpa_state == WPA_SCANNING ||
- wpa_s->wpa_state == WPA_DISCONNECTED) {
- wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
- wpa_supplicant_cancel_scan(wpa_s);
- wpas_clear_wps(wpa_s);
- } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
- wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
- "deauthenticate");
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- wpas_clear_wps(wpa_s);
- } else {
- wpas_wps_reenable_networks(wpa_s);
- wpas_wps_clear_ap_info(wpa_s);
- if (eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL) >
- 0)
- wpas_clear_wps(wpa_s);
- }
-
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CANCEL);
- wpa_s->after_wps = 0;
-
- return 0;
-}
-
-
-int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, struct wps_new_ap_settings *settings)
-{
- struct wpa_ssid *ssid;
- char val[200];
- char *pos, *end;
- int res;
-
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
- wpa_printf(MSG_DEBUG,
- "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
- return -1;
- }
-#endif /* CONFIG_AP */
- if (!pin)
- return -1;
- wpas_clear_wps(wpa_s);
- ssid = wpas_wps_add_network(wpa_s, 1, NULL, bssid);
- if (ssid == NULL)
- return -1;
- ssid->temporary = 1;
- pos = val;
- end = pos + sizeof(val);
- res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
- if (os_snprintf_error(end - pos, res))
- return -1;
- pos += res;
- if (settings) {
- res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s "
- "new_encr=%s new_key=%s",
- settings->ssid_hex, settings->auth,
- settings->encr, settings->key_hex);
- if (os_snprintf_error(end - pos, res))
- return -1;
- pos += res;
- }
- res = os_snprintf(pos, end - pos, "\"");
- if (os_snprintf_error(end - pos, res))
- return -1;
- if (wpa_config_set(ssid, "phase1", val, 0) < 0)
- return -1;
- if (wpa_s->wps_fragment_size)
- ssid->eap.fragment_size = wpa_s->wps_fragment_size;
- eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
- wpa_s, NULL);
- wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
- return 0;
-}
-
-
-static int wpas_wps_new_psk_cb(void *ctx, const u8 *mac_addr,
- const u8 *p2p_dev_addr, const u8 *psk,
- size_t psk_len)
-{
- if (is_zero_ether_addr(p2p_dev_addr)) {
- wpa_printf(MSG_DEBUG,
- "Received new WPA/WPA2-PSK from WPS for STA " MACSTR,
- MAC2STR(mac_addr));
- } else {
- wpa_printf(MSG_DEBUG,
- "Received new WPA/WPA2-PSK from WPS for STA " MACSTR
- " P2P Device Addr " MACSTR,
- MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
- }
- wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
-
- /* TODO */
-
- return 0;
-}
-
-
-static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
- const struct wps_device_data *dev)
-{
- char uuid[40], txt[400];
- int len;
- char devtype[WPS_DEV_TYPE_BUFSIZE];
- if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
- return;
- wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
- len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
- " [%s|%s|%s|%s|%s|%s]",
- uuid, MAC2STR(dev->mac_addr), dev->device_name,
- dev->manufacturer, dev->model_name,
- dev->model_number, dev->serial_number,
- wps_dev_type_bin2str(dev->pri_dev_type, devtype,
- sizeof(devtype)));
- if (!os_snprintf_error(sizeof(txt), len))
- wpa_printf(MSG_INFO, "%s", txt);
-}
-
-
-static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
- u16 sel_reg_config_methods)
-{
-#ifdef CONFIG_WPS_ER
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->wps_er == NULL)
- return;
- wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
- "dev_password_id=%u sel_reg_config_methods=0x%x",
- sel_reg, dev_passwd_id, sel_reg_config_methods);
- wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
- sel_reg_config_methods);
-#endif /* CONFIG_WPS_ER */
-}
-
-
-static u16 wps_fix_config_methods(u16 config_methods)
-{
- if ((config_methods &
- (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
- WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
- wpa_printf(MSG_INFO, "WPS: Converting display to "
- "virtual_display for WPS 2.0 compliance");
- config_methods |= WPS_CONFIG_VIRT_DISPLAY;
- }
- if ((config_methods &
- (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
- WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
- wpa_printf(MSG_INFO, "WPS: Converting push_button to "
- "virtual_push_button for WPS 2.0 compliance");
- config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
- }
-
- return config_methods;
-}
-
-
-static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
- struct wps_context *wps)
-{
- char buf[50];
- const char *src;
-
- if (is_nil_uuid(wpa_s->conf->uuid)) {
- struct wpa_supplicant *first;
- first = wpa_s->global->ifaces;
- while (first && first->next)
- first = first->next;
- if (first && first != wpa_s) {
- if (wps != wpa_s->global->ifaces->wps)
- os_memcpy(wps->uuid,
- wpa_s->global->ifaces->wps->uuid,
- WPS_UUID_LEN);
- src = "from the first interface";
- } else if (wpa_s->conf->auto_uuid == 1) {
- uuid_random(wps->uuid);
- src = "based on random data";
- } else {
- uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
- src = "based on MAC address";
- }
- } else {
- os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
- src = "based on configuration";
- }
-
- uuid_bin2str(wps->uuid, buf, sizeof(buf));
- wpa_dbg(wpa_s, MSG_DEBUG, "WPS: UUID %s: %s", src, buf);
-}
-
-
-static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
- struct wps_context *wps)
-{
- wpabuf_free(wps->dev.vendor_ext_m1);
- wps->dev.vendor_ext_m1 = NULL;
-
- if (wpa_s->conf->wps_vendor_ext_m1) {
- wps->dev.vendor_ext_m1 =
- wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
- if (!wps->dev.vendor_ext_m1) {
- wpa_printf(MSG_ERROR, "WPS: Cannot "
- "allocate memory for vendor_ext_m1");
- }
- }
-}
-
-
-int wpas_wps_init(struct wpa_supplicant *wpa_s)
-{
- struct wps_context *wps;
- struct wps_registrar_config rcfg;
- struct hostapd_hw_modes *modes;
- u16 m;
-
- wps = os_zalloc(sizeof(*wps));
- if (wps == NULL)
- return -1;
-
- wps->cred_cb = wpa_supplicant_wps_cred;
- wps->event_cb = wpa_supplicant_wps_event;
- wps->rf_band_cb = wpa_supplicant_wps_rf_band;
- wps->cb_ctx = wpa_s;
-
- wps->dev.device_name = wpa_s->conf->device_name;
- wps->dev.manufacturer = wpa_s->conf->manufacturer;
- wps->dev.model_name = wpa_s->conf->model_name;
- wps->dev.model_number = wpa_s->conf->model_number;
- wps->dev.serial_number = wpa_s->conf->serial_number;
- wps->config_methods =
- wps_config_methods_str2bin(wpa_s->conf->config_methods);
- if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
- (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
- wpa_printf(MSG_ERROR, "WPS: Both Label and Display config "
- "methods are not allowed at the same time");
- os_free(wps);
- return -1;
- }
- wps->config_methods = wps_fix_config_methods(wps->config_methods);
- wps->dev.config_methods = wps->config_methods;
- os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN);
-
- wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
- os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
- WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
-
- wpas_wps_set_vendor_ext_m1(wpa_s, wps);
-
- wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
- modes = wpa_s->hw.modes;
- if (modes) {
- for (m = 0; m < wpa_s->hw.num_modes; m++) {
- if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
- modes[m].mode == HOSTAPD_MODE_IEEE80211G)
- wps->dev.rf_bands |= WPS_RF_24GHZ;
- else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
- wps->dev.rf_bands |= WPS_RF_50GHZ;
- else if (modes[m].mode == HOSTAPD_MODE_IEEE80211AD)
- wps->dev.rf_bands |= WPS_RF_60GHZ;
- }
- }
- if (wps->dev.rf_bands == 0) {
- /*
- * Default to claiming support for both bands if the driver
- * does not provide support for fetching supported bands.
- */
- wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
- }
- os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
- wpas_wps_set_uuid(wpa_s, wps);
-
-#ifdef CONFIG_NO_TKIP
- wps->auth_types = WPS_AUTH_WPA2PSK;
- wps->encr_types = WPS_ENCR_AES;
-#else /* CONFIG_NO_TKIP */
- wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
- wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
-#endif /* CONFIG_NO_TKIP */
-
- os_memset(&rcfg, 0, sizeof(rcfg));
- rcfg.new_psk_cb = wpas_wps_new_psk_cb;
- rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
- rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
- rcfg.cb_ctx = wpa_s;
-
- wps->registrar = wps_registrar_init(wps, &rcfg);
- if (wps->registrar == NULL) {
- wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
- os_free(wps);
- return -1;
- }
-
- wpa_s->wps = wps;
-
- return 0;
-}
-
-
-#ifdef CONFIG_WPS_ER
-static void wpas_wps_nfc_clear(struct wps_context *wps)
-{
- wps->ap_nfc_dev_pw_id = 0;
- wpabuf_free(wps->ap_nfc_dh_pubkey);
- wps->ap_nfc_dh_pubkey = NULL;
- wpabuf_free(wps->ap_nfc_dh_privkey);
- wps->ap_nfc_dh_privkey = NULL;
- wpabuf_free(wps->ap_nfc_dev_pw);
- wps->ap_nfc_dev_pw = NULL;
-}
-#endif /* CONFIG_WPS_ER */
-
-
-void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
-{
- wpas_wps_assoc_with_cred_cancel(wpa_s);
- eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
- eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
- wpas_wps_clear_ap_info(wpa_s);
-
-#ifdef CONFIG_P2P
- eloop_cancel_timeout(wpas_p2p_pbc_overlap_cb, wpa_s, NULL);
-#endif /* CONFIG_P2P */
-
- if (wpa_s->wps == NULL)
- return;
-
-#ifdef CONFIG_WPS_ER
- wps_er_deinit(wpa_s->wps_er, NULL, NULL);
- wpa_s->wps_er = NULL;
- wpas_wps_nfc_clear(wpa_s->wps);
-#endif /* CONFIG_WPS_ER */
-
- wps_registrar_deinit(wpa_s->wps->registrar);
- wpabuf_free(wpa_s->wps->dh_pubkey);
- wpabuf_free(wpa_s->wps->dh_privkey);
- wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
- os_free(wpa_s->wps->network_key);
- os_free(wpa_s->wps);
- wpa_s->wps = NULL;
-}
-
-
-int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct wpa_bss *bss)
-{
- struct wpabuf *wps_ie;
-
- if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
- return -1;
-
- wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
- if (!wps_ie) {
- wpa_printf(MSG_DEBUG, " skip - non-WPS AP");
- return 0;
- }
-
- if (!wps_is_selected_pbc_registrar(wps_ie)) {
- wpa_printf(MSG_DEBUG, " skip - WPS AP "
- "without active PBC Registrar");
- wpabuf_free(wps_ie);
- return 0;
- }
-
- /* TODO: overlap detection */
- wpa_printf(MSG_DEBUG, " selected based on WPS IE "
- "(Active PBC)");
- wpabuf_free(wps_ie);
- return 1;
- }
-
- if (eap_is_wps_pin_enrollee(&ssid->eap)) {
- if (!wps_ie) {
- wpa_printf(MSG_DEBUG, " skip - non-WPS AP");
- return 0;
- }
-
- /*
- * Start with WPS APs that advertise our address as an
- * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
- * allow any WPS AP after couple of scans since some APs do not
- * set Selected Registrar attribute properly when using
- * external Registrar.
- */
- if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
- struct os_reltime age;
-
- os_reltime_age(&wpa_s->wps_pin_start_time, &age);
-
- if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG ||
- age.sec < WPS_PIN_TIME_IGNORE_SEL_REG) {
- wpa_printf(MSG_DEBUG,
- " skip - WPS AP without active PIN Registrar (scan_runs=%d age=%d)",
- wpa_s->scan_runs, (int) age.sec);
- wpabuf_free(wps_ie);
- return 0;
- }
- wpa_printf(MSG_DEBUG, " selected based on WPS IE");
- } else {
- wpa_printf(MSG_DEBUG, " selected based on WPS IE "
- "(Authorized MAC or Active PIN)");
- }
- wpabuf_free(wps_ie);
- return 1;
- }
-
- if (wps_ie) {
- wpa_printf(MSG_DEBUG, " selected based on WPS IE");
- wpabuf_free(wps_ie);
- return 1;
- }
-
- return -1;
-}
-
-
-int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss)
-{
- struct wpabuf *wps_ie = NULL;
- int ret = 0;
-
- if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
- wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
- /* allow wildcard SSID for WPS PBC */
- ret = 1;
- }
- } else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
- wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- if (wps_ie &&
- (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
- wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
- /* allow wildcard SSID for WPS PIN */
- ret = 1;
- }
- }
-
- if (!ret && ssid->bssid_set &&
- os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
- /* allow wildcard SSID due to hardcoded BSSID match */
- ret = 1;
- }
-
-#ifdef CONFIG_WPS_STRICT
- if (wps_ie) {
- if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
- 0, bss->bssid) < 0)
- ret = 0;
- if (bss->beacon_ie_len) {
- struct wpabuf *bcn_wps;
- bcn_wps = wpa_bss_get_vendor_ie_multi_beacon(
- bss, WPS_IE_VENDOR_TYPE);
- if (bcn_wps == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
- "missing from AP Beacon");
- ret = 0;
- } else {
- if (wps_validate_beacon(wps_ie) < 0)
- ret = 0;
- wpabuf_free(bcn_wps);
- }
- }
- }
-#endif /* CONFIG_WPS_STRICT */
-
- wpabuf_free(wps_ie);
-
- return ret;
-}
-
-
-int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected, struct wpa_ssid *ssid)
-{
- const u8 *sel_uuid;
- struct wpabuf *wps_ie;
- int ret = 0;
- size_t i;
-
- if (!eap_is_wps_pbc_enrollee(&ssid->eap))
- return 0;
-
- wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
- "present in scan results; selected BSSID " MACSTR,
- MAC2STR(selected->bssid));
- if (!is_zero_ether_addr(ssid->bssid))
- wpa_printf(MSG_DEBUG,
- "WPS: Network profile limited to accept only a single BSSID " MACSTR,
- MAC2STR(ssid->bssid));
-
- /* Make sure that only one AP is in active PBC mode */
- wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
- if (wps_ie) {
- sel_uuid = wps_get_uuid_e(wps_ie);
- wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
- sel_uuid, UUID_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
- "WPS IE?!");
- sel_uuid = NULL;
- }
-
- for (i = 0; i < wpa_s->num_wps_ap; i++) {
- struct wps_ap_info *ap = &wpa_s->wps_ap[i];
-
- if (!ap->pbc_active ||
- os_memcmp(selected->bssid, ap->bssid, ETH_ALEN) == 0)
- continue;
-
- if (!is_zero_ether_addr(ssid->bssid) &&
- os_memcmp(ap->bssid, ssid->bssid, ETH_ALEN) != 0) {
- wpa_printf(MSG_DEBUG, "WPS: Ignore another BSS " MACSTR
- " in active PBC mode due to local BSSID limitation",
- MAC2STR(ap->bssid));
- continue;
- }
-
- wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
- MACSTR, MAC2STR(ap->bssid));
- wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
- ap->uuid, UUID_LEN);
- if (sel_uuid == NULL ||
- os_memcmp(sel_uuid, ap->uuid, UUID_LEN) != 0) {
- ret = 1; /* PBC overlap */
- wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
- MACSTR " and " MACSTR,
- MAC2STR(selected->bssid),
- MAC2STR(ap->bssid));
- break;
- }
-
- /* TODO: verify that this is reasonable dual-band situation */
- }
-
- wpabuf_free(wps_ie);
-
- return ret;
-}
-
-
-void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
- struct wpa_bss *bss;
- unsigned int pbc = 0, auth = 0, pin = 0, wps = 0;
-
- if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
- return;
-
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- struct wpabuf *ie;
- ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- if (!ie)
- continue;
- if (wps_is_selected_pbc_registrar(ie))
- pbc++;
- else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
- auth++;
- else if (wps_is_selected_pin_registrar(ie))
- pin++;
- else
- wps++;
- wpabuf_free(ie);
- }
-
- if (pbc)
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
- else if (auth)
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH);
- else if (pin)
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
- else if (wps)
- wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
-}
-
-
-int wpas_wps_searching(struct wpa_supplicant *wpa_s)
-{
- struct wpa_ssid *ssid;
-
- for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
- if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
- return 1;
- }
-
- return 0;
-}
-
-
-int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
- char *end)
-{
- struct wpabuf *wps_ie;
- int ret;
-
- wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA);
- if (wps_ie == NULL)
- return 0;
-
- ret = wps_attr_text(wps_ie, buf, end);
- wpabuf_free(wps_ie);
- return ret;
-}
-
-
-int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
-{
-#ifdef CONFIG_WPS_ER
- if (wpa_s->wps_er) {
- wps_er_refresh(wpa_s->wps_er);
- return 0;
- }
- wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
- if (wpa_s->wps_er == NULL)
- return -1;
- return 0;
-#else /* CONFIG_WPS_ER */
- return 0;
-#endif /* CONFIG_WPS_ER */
-}
-
-
-void wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WPS_ER
- wps_er_deinit(wpa_s->wps_er, NULL, NULL);
- wpa_s->wps_er = NULL;
-#endif /* CONFIG_WPS_ER */
-}
-
-
-#ifdef CONFIG_WPS_ER
-int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
- const char *uuid, const char *pin)
-{
- u8 u[UUID_LEN];
- const u8 *use_uuid = NULL;
- u8 addr_buf[ETH_ALEN];
-
- if (os_strcmp(uuid, "any") == 0) {
- } else if (uuid_str2bin(uuid, u) == 0) {
- use_uuid = u;
- } else if (hwaddr_aton(uuid, addr_buf) == 0) {
- use_uuid = wps_er_get_sta_uuid(wpa_s->wps_er, addr_buf);
- if (use_uuid == NULL)
- return -1;
- } else
- return -1;
- return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
- use_uuid,
- (const u8 *) pin, os_strlen(pin), 300);
-}
-
-
-int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
-{
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
-
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return -1;
- return wps_er_pbc(wpa_s->wps_er, use_uuid, use_addr);
-}
-
-
-int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin)
-{
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
-
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return -1;
-
- return wps_er_learn(wpa_s->wps_er, use_uuid, use_addr, (const u8 *) pin,
- os_strlen(pin));
-}
-
-
-static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
- struct wps_credential *cred)
-{
- os_memset(cred, 0, sizeof(*cred));
- if (ssid->ssid_len > SSID_MAX_LEN)
- return -1;
- os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
- cred->ssid_len = ssid->ssid_len;
- if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
- cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
- WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
- if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
- cred->encr_type = WPS_ENCR_AES;
- else
- cred->encr_type = WPS_ENCR_TKIP;
- if (ssid->passphrase) {
- cred->key_len = os_strlen(ssid->passphrase);
- if (cred->key_len >= 64)
- return -1;
- os_memcpy(cred->key, ssid->passphrase, cred->key_len);
- } else if (ssid->psk_set) {
- cred->key_len = 32;
- os_memcpy(cred->key, ssid->psk, 32);
- } else
- return -1;
- } else {
- cred->auth_type = WPS_AUTH_OPEN;
- cred->encr_type = WPS_ENCR_NONE;
- }
-
- return 0;
-}
-
-
-int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
- int id)
-{
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
- struct wpa_ssid *ssid;
- struct wps_credential cred;
- int ret;
-
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return -1;
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL || ssid->ssid == NULL)
- return -1;
-
- if (wpas_wps_network_to_cred(ssid, &cred) < 0)
- return -1;
- ret = wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
- os_memset(&cred, 0, sizeof(cred));
- return ret;
-}
-
-
-int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin, struct wps_new_ap_settings *settings)
-{
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
- struct wps_credential cred;
- size_t len;
-
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return -1;
- if (settings->ssid_hex == NULL || settings->auth == NULL ||
- settings->encr == NULL || settings->key_hex == NULL)
- return -1;
-
- os_memset(&cred, 0, sizeof(cred));
- len = os_strlen(settings->ssid_hex);
- if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
- hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
- return -1;
- cred.ssid_len = len / 2;
-
- len = os_strlen(settings->key_hex);
- if ((len & 1) || len > 2 * sizeof(cred.key) ||
- hexstr2bin(settings->key_hex, cred.key, len / 2))
- return -1;
- cred.key_len = len / 2;
-
- if (os_strcmp(settings->auth, "OPEN") == 0)
- cred.auth_type = WPS_AUTH_OPEN;
- else if (os_strcmp(settings->auth, "WPAPSK") == 0)
- cred.auth_type = WPS_AUTH_WPAPSK;
- else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
- cred.auth_type = WPS_AUTH_WPA2PSK;
- else
- return -1;
-
- if (os_strcmp(settings->encr, "NONE") == 0)
- cred.encr_type = WPS_ENCR_NONE;
-#ifdef CONFIG_TESTING_OPTIONS
- else if (os_strcmp(settings->encr, "WEP") == 0)
- cred.encr_type = WPS_ENCR_WEP;
-#endif /* CONFIG_TESTING_OPTIONS */
- else if (os_strcmp(settings->encr, "TKIP") == 0)
- cred.encr_type = WPS_ENCR_TKIP;
- else if (os_strcmp(settings->encr, "CCMP") == 0)
- cred.encr_type = WPS_ENCR_AES;
- else
- return -1;
-
- return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
- (const u8 *) pin, os_strlen(pin), &cred);
-}
-
-
-#ifdef CONFIG_WPS_NFC
-struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef, const char *uuid)
-{
- struct wpabuf *ret;
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
-
- if (!wpa_s->wps_er)
- return NULL;
-
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return NULL;
-
- ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
- if (ndef && ret) {
- struct wpabuf *tmp;
- tmp = ndef_build_wifi(ret);
- wpabuf_free(ret);
- if (tmp == NULL)
- return NULL;
- ret = tmp;
- }
-
- return ret;
-}
-#endif /* CONFIG_WPS_NFC */
-
-
-static int callbacks_pending = 0;
-
-static void wpas_wps_terminate_cb(void *ctx)
-{
- wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
- if (--callbacks_pending <= 0)
- eloop_terminate();
-}
-#endif /* CONFIG_WPS_ER */
-
-
-int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WPS_ER
- if (wpa_s->wps_er) {
- callbacks_pending++;
- wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
- wpa_s->wps_er = NULL;
- return 1;
- }
-#endif /* CONFIG_WPS_ER */
- return 0;
-}
-
-
-void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
-{
- struct wps_context *wps = wpa_s->wps;
-
- if (wps == NULL)
- return;
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
- wps->config_methods = wps_config_methods_str2bin(
- wpa_s->conf->config_methods);
- if ((wps->config_methods &
- (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
- (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
- wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
- "config methods are not allowed at the "
- "same time");
- wps->config_methods &= ~WPS_CONFIG_LABEL;
- }
- }
- wps->config_methods = wps_fix_config_methods(wps->config_methods);
- wps->dev.config_methods = wps->config_methods;
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
- os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
- WPS_DEV_TYPE_LEN);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
- wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
- os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
- wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
- }
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
- wpas_wps_set_vendor_ext_m1(wpa_s, wps);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
- wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
-
- if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
- wpas_wps_set_uuid(wpa_s, wps);
-
- if (wpa_s->conf->changed_parameters &
- (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
- /* Update pointers to make sure they refer current values */
- wps->dev.device_name = wpa_s->conf->device_name;
- wps->dev.manufacturer = wpa_s->conf->manufacturer;
- wps->dev.model_name = wpa_s->conf->model_name;
- wps->dev.model_number = wpa_s->conf->model_number;
- wps->dev.serial_number = wpa_s->conf->serial_number;
- }
-}
-
-
-void wpas_wps_update_mac_addr(struct wpa_supplicant *wpa_s)
-{
- struct wps_context *wps;
-
- wps = wpa_s->wps;
- if (wps)
- os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-#ifdef CONFIG_WPS_ER
-static struct wpabuf *
-wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
- struct wpa_ssid *ssid)
-{
- struct wpabuf *ret;
- struct wps_credential cred;
-
- if (wpas_wps_network_to_cred(ssid, &cred) < 0)
- return NULL;
-
- ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
-
- if (ndef && ret) {
- struct wpabuf *tmp;
- tmp = ndef_build_wifi(ret);
- wpabuf_free(ret);
- if (tmp == NULL)
- return NULL;
- ret = tmp;
- }
-
- return ret;
-}
-#endif /* CONFIG_WPS_ER */
-
-
-struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef, const char *id_str)
-{
-#ifdef CONFIG_WPS_ER
- if (id_str) {
- int id;
- char *end = NULL;
- struct wpa_ssid *ssid;
-
- id = strtol(id_str, &end, 10);
- if (end && *end)
- return NULL;
-
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL)
- return NULL;
- return wpas_wps_network_config_token(wpa_s, ndef, ssid);
- }
-#endif /* CONFIG_WPS_ER */
-#ifdef CONFIG_AP
- if (wpa_s->ap_iface)
- return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
-#endif /* CONFIG_AP */
- return NULL;
-}
-
-
-struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
-{
- if (wpa_s->conf->wps_nfc_pw_from_config) {
- return wps_nfc_token_build(ndef,
- wpa_s->conf->wps_nfc_dev_pw_id,
- wpa_s->conf->wps_nfc_dh_pubkey,
- wpa_s->conf->wps_nfc_dev_pw);
- }
-
- return wps_nfc_token_gen(ndef, &wpa_s->conf->wps_nfc_dev_pw_id,
- &wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey,
- &wpa_s->conf->wps_nfc_dev_pw);
-}
-
-
-int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *go_dev_addr,
- const u8 *bssid,
- const struct wpabuf *dev_pw, u16 dev_pw_id,
- int p2p_group, const u8 *peer_pubkey_hash,
- const u8 *ssid, size_t ssid_len, int freq)
-{
- struct wps_context *wps = wpa_s->wps;
- char pw[32 * 2 + 1];
-
- if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
- dev_pw = wpa_s->conf->wps_nfc_dev_pw;
- dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
- }
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
- wpa_s->conf->wps_nfc_dh_privkey == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: Missing DH params - "
- "cannot start NFC-triggered connection");
- return -1;
- }
-
- if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: Missing Device Password (id=%u) - "
- "cannot start NFC-triggered connection", dev_pw_id);
- return -1;
- }
-
- dh5_free(wps->dh_ctx);
- wpabuf_free(wps->dh_pubkey);
- wpabuf_free(wps->dh_privkey);
- wps->dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
- wps->dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
- if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
- wps->dh_ctx = NULL;
- wpabuf_free(wps->dh_pubkey);
- wps->dh_pubkey = NULL;
- wpabuf_free(wps->dh_privkey);
- wps->dh_privkey = NULL;
- wpa_printf(MSG_DEBUG, "WPS: Failed to get DH priv/pub key");
- return -1;
- }
- wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
- if (wps->dh_ctx == NULL) {
- wpabuf_free(wps->dh_pubkey);
- wps->dh_pubkey = NULL;
- wpabuf_free(wps->dh_privkey);
- wps->dh_privkey = NULL;
- wpa_printf(MSG_DEBUG, "WPS: Failed to initialize DH context");
- return -1;
- }
-
- if (dev_pw) {
- wpa_snprintf_hex_uppercase(pw, sizeof(pw),
- wpabuf_head(dev_pw),
- wpabuf_len(dev_pw));
- }
- return wpas_wps_start_dev_pw(wpa_s, go_dev_addr, bssid,
- dev_pw ? pw : NULL,
- p2p_group, dev_pw_id, peer_pubkey_hash,
- ssid, ssid_len, freq);
-}
-
-
-static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
- struct wps_parse_attr *attr)
-{
- /*
- * Disable existing networks temporarily to allow the newly learned
- * credential to be preferred. Enable the temporarily disabled networks
- * after 10 seconds.
- */
- wpas_wps_temp_disable(wpa_s, NULL);
- eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
- NULL);
-
- if (wps_oob_use_cred(wpa_s->wps, attr) < 0)
- return -1;
-
- if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
- return 0;
-
- if (attr->ap_channel) {
- u16 chan = WPA_GET_BE16(attr->ap_channel);
- int freq = 0;
-
- if (chan >= 1 && chan <= 13)
- freq = 2407 + 5 * chan;
- else if (chan == 14)
- freq = 2484;
- else if (chan >= 30)
- freq = 5000 + 5 * chan;
-
- if (freq) {
- wpa_printf(MSG_DEBUG, "WPS: Credential container indicated AP channel %u -> %u MHz",
- chan, freq);
- wpa_s->after_wps = 5;
- wpa_s->wps_freq = freq;
- }
- }
-
- wpa_printf(MSG_DEBUG, "WPS: Request reconnection with new network "
- "based on the received credential added");
- wpa_s->normal_scans = 0;
- wpa_supplicant_reinit_autoscan(wpa_s);
- wpa_s->disconnected = 0;
- wpa_s->reassociate = 1;
-
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
-
- return 0;
-}
-
-
-#ifdef CONFIG_WPS_ER
-static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s,
- struct wps_parse_attr *attr)
-{
- return wps_registrar_add_nfc_password_token(
- wpa_s->wps->registrar, attr->oob_dev_password,
- attr->oob_dev_password_len);
-}
-#endif /* CONFIG_WPS_ER */
-
-
-static int wpas_wps_nfc_tag_process(struct wpa_supplicant *wpa_s,
- const struct wpabuf *wps)
-{
- struct wps_parse_attr attr;
-
- wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
-
- if (wps_parse_msg(wps, &attr)) {
- wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
- return -1;
- }
-
- if (attr.num_cred)
- return wpas_wps_use_cred(wpa_s, &attr);
-
-#ifdef CONFIG_WPS_ER
- if (attr.oob_dev_password)
- return wpas_wps_add_nfc_password_token(wpa_s, &attr);
-#endif /* CONFIG_WPS_ER */
-
- wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
- return -1;
-}
-
-
-int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data, int forced_freq)
-{
- const struct wpabuf *wps = data;
- struct wpabuf *tmp = NULL;
- int ret;
-
- if (wpabuf_len(data) < 4)
- return -1;
-
- if (*wpabuf_head_u8(data) != 0x10) {
- /* Assume this contains full NDEF record */
- tmp = ndef_parse_wifi(data);
- if (tmp == NULL) {
-#ifdef CONFIG_P2P
- tmp = ndef_parse_p2p(data);
- if (tmp) {
- ret = wpas_p2p_nfc_tag_process(wpa_s, tmp,
- forced_freq);
- wpabuf_free(tmp);
- return ret;
- }
-#endif /* CONFIG_P2P */
- wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
- return -1;
- }
- wps = tmp;
- }
-
- ret = wpas_wps_nfc_tag_process(wpa_s, wps);
- wpabuf_free(tmp);
- return ret;
-}
-
-
-struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
- int ndef)
-{
- struct wpabuf *ret;
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
- wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey) < 0)
- return NULL;
-
- ret = wps_build_nfc_handover_req(wpa_s->wps,
- wpa_s->conf->wps_nfc_dh_pubkey);
-
- if (ndef && ret) {
- struct wpabuf *tmp;
- tmp = ndef_build_wifi(ret);
- wpabuf_free(ret);
- if (tmp == NULL)
- return NULL;
- ret = tmp;
- }
-
- return ret;
-}
-
-
-#ifdef CONFIG_WPS_NFC
-
-static struct wpabuf *
-wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s, int ndef,
- const char *uuid)
-{
-#ifdef CONFIG_WPS_ER
- struct wpabuf *ret;
- u8 u[UUID_LEN], *use_uuid = NULL;
- u8 addr[ETH_ALEN], *use_addr = NULL;
- struct wps_context *wps = wpa_s->wps;
-
- if (wps == NULL)
- return NULL;
-
- if (uuid == NULL)
- return NULL;
- if (uuid_str2bin(uuid, u) == 0)
- use_uuid = u;
- else if (hwaddr_aton(uuid, addr) == 0)
- use_addr = addr;
- else
- return NULL;
-
- if (wpa_s->conf->wps_nfc_dh_pubkey == NULL) {
- if (wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
- &wpa_s->conf->wps_nfc_dh_privkey) < 0)
- return NULL;
- }
-
- wpas_wps_nfc_clear(wps);
- wps->ap_nfc_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
- wps->ap_nfc_dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
- wps->ap_nfc_dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
- if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey) {
- wpas_wps_nfc_clear(wps);
- return NULL;
- }
-
- ret = wps_er_nfc_handover_sel(wpa_s->wps_er, wpa_s->wps, use_uuid,
- use_addr, wpa_s->conf->wps_nfc_dh_pubkey);
- if (ndef && ret) {
- struct wpabuf *tmp;
- tmp = ndef_build_wifi(ret);
- wpabuf_free(ret);
- if (tmp == NULL)
- return NULL;
- ret = tmp;
- }
-
- return ret;
-#else /* CONFIG_WPS_ER */
- return NULL;
-#endif /* CONFIG_WPS_ER */
-}
-#endif /* CONFIG_WPS_NFC */
-
-
-struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef, int cr, const char *uuid)
-{
- struct wpabuf *ret;
- if (!cr)
- return NULL;
- ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
- if (ret)
- return ret;
- return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
-}
-
-
-static int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data)
-{
- struct wpabuf *wps;
- int ret = -1;
- u16 wsc_len;
- const u8 *pos;
- struct wpabuf msg;
- struct wps_parse_attr attr;
- u16 dev_pw_id;
- const u8 *bssid = NULL;
- int freq = 0;
-
- wps = ndef_parse_wifi(data);
- if (wps == NULL)
- return -1;
- wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
- "payload from NFC connection handover");
- wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
- if (wpabuf_len(wps) < 2) {
- wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Select "
- "Message");
- goto out;
- }
- pos = wpabuf_head(wps);
- wsc_len = WPA_GET_BE16(pos);
- if (wsc_len > wpabuf_len(wps) - 2) {
- wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
- "in Wi-Fi Handover Select Message", wsc_len);
- goto out;
- }
- pos += 2;
-
- wpa_hexdump(MSG_DEBUG,
- "WPS: WSC attributes in Wi-Fi Handover Select Message",
- pos, wsc_len);
- if (wsc_len < wpabuf_len(wps) - 2) {
- wpa_hexdump(MSG_DEBUG,
- "WPS: Ignore extra data after WSC attributes",
- pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
- }
-
- wpabuf_set(&msg, pos, wsc_len);
- ret = wps_parse_msg(&msg, &attr);
- if (ret < 0) {
- wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
- "Wi-Fi Handover Select Message");
- goto out;
- }
-
- if (attr.oob_dev_password == NULL ||
- attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
- wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
- "included in Wi-Fi Handover Select Message");
- ret = -1;
- goto out;
- }
-
- if (attr.ssid == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: No SSID included in Wi-Fi Handover "
- "Select Message");
- ret = -1;
- goto out;
- }
-
- wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", attr.ssid, attr.ssid_len);
-
- if (attr.mac_addr) {
- bssid = attr.mac_addr;
- wpa_printf(MSG_DEBUG, "WPS: MAC Address (BSSID): " MACSTR,
- MAC2STR(bssid));
- }
-
- if (attr.rf_bands)
- wpa_printf(MSG_DEBUG, "WPS: RF Bands: %d", *attr.rf_bands);
-
- if (attr.ap_channel) {
- u16 chan = WPA_GET_BE16(attr.ap_channel);
-
- wpa_printf(MSG_DEBUG, "WPS: AP Channel: %d", chan);
-
- if (chan >= 1 && chan <= 13 &&
- (attr.rf_bands == NULL || *attr.rf_bands & WPS_RF_24GHZ))
- freq = 2407 + 5 * chan;
- else if (chan == 14 &&
- (attr.rf_bands == NULL ||
- *attr.rf_bands & WPS_RF_24GHZ))
- freq = 2484;
- else if (chan >= 30 &&
- (attr.rf_bands == NULL ||
- *attr.rf_bands & WPS_RF_50GHZ))
- freq = 5000 + 5 * chan;
- else if (chan >= 1 && chan <= 6 &&
- (attr.rf_bands == NULL ||
- *attr.rf_bands & WPS_RF_60GHZ))
- freq = 56160 + 2160 * chan;
-
- if (freq) {
- wpa_printf(MSG_DEBUG,
- "WPS: AP indicated channel %u -> %u MHz",
- chan, freq);
- }
- }
-
- wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
- attr.oob_dev_password, attr.oob_dev_password_len);
- dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
- WPS_OOB_PUBKEY_HASH_LEN);
- if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
- wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
- "%u in Wi-Fi Handover Select Message", dev_pw_id);
- ret = -1;
- goto out;
- }
- wpa_hexdump(MSG_DEBUG, "WPS: AP Public Key hash",
- attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
-
- ret = wpas_wps_start_nfc(wpa_s, NULL, bssid, NULL, dev_pw_id, 0,
- attr.oob_dev_password,
- attr.ssid, attr.ssid_len, freq);
-
-out:
- wpabuf_free(wps);
- return ret;
-}
-
-
-int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel)
-{
- wpa_printf(MSG_DEBUG, "NFC: WPS connection handover reported");
- wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in request", req);
- wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in select", sel);
- return wpas_wps_nfc_rx_handover_sel(wpa_s, sel);
-}
-
-
-int wpas_er_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel)
-{
- struct wpabuf *wps;
- int ret = -1;
- u16 wsc_len;
- const u8 *pos;
- struct wpabuf msg;
- struct wps_parse_attr attr;
- u16 dev_pw_id;
-
- /*
- * Enrollee/station is always initiator of the NFC connection handover,
- * so use the request message here to find Enrollee public key hash.
- */
- wps = ndef_parse_wifi(req);
- if (wps == NULL)
- return -1;
- wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
- "payload from NFC connection handover");
- wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
- if (wpabuf_len(wps) < 2) {
- wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Request "
- "Message");
- goto out;
- }
- pos = wpabuf_head(wps);
- wsc_len = WPA_GET_BE16(pos);
- if (wsc_len > wpabuf_len(wps) - 2) {
- wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
- "in rt Wi-Fi Handover Request Message", wsc_len);
- goto out;
- }
- pos += 2;
-
- wpa_hexdump(MSG_DEBUG,
- "WPS: WSC attributes in Wi-Fi Handover Request Message",
- pos, wsc_len);
- if (wsc_len < wpabuf_len(wps) - 2) {
- wpa_hexdump(MSG_DEBUG,
- "WPS: Ignore extra data after WSC attributes",
- pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
- }
-
- wpabuf_set(&msg, pos, wsc_len);
- ret = wps_parse_msg(&msg, &attr);
- if (ret < 0) {
- wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
- "Wi-Fi Handover Request Message");
- goto out;
- }
-
- if (attr.oob_dev_password == NULL ||
- attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
- wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
- "included in Wi-Fi Handover Request Message");
- ret = -1;
- goto out;
- }
-
- if (attr.uuid_e == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: No UUID-E included in Wi-Fi "
- "Handover Request Message");
- ret = -1;
- goto out;
- }
-
- wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", attr.uuid_e, WPS_UUID_LEN);
-
- wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
- attr.oob_dev_password, attr.oob_dev_password_len);
- dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
- WPS_OOB_PUBKEY_HASH_LEN);
- if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
- wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
- "%u in Wi-Fi Handover Request Message", dev_pw_id);
- ret = -1;
- goto out;
- }
- wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Public Key hash",
- attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
-
- ret = wps_registrar_add_nfc_pw_token(wpa_s->wps->registrar,
- attr.oob_dev_password,
- DEV_PW_NFC_CONNECTION_HANDOVER,
- NULL, 0, 1);
-
-out:
- wpabuf_free(wps);
- return ret;
-}
-
-#endif /* CONFIG_WPS_NFC */
-
-
-static void wpas_wps_dump_ap_info(struct wpa_supplicant *wpa_s)
-{
- size_t i;
- struct os_reltime now;
-
- if (wpa_debug_level > MSG_DEBUG)
- return;
-
- if (wpa_s->wps_ap == NULL)
- return;
-
- os_get_reltime(&now);
-
- for (i = 0; i < wpa_s->num_wps_ap; i++) {
- struct wps_ap_info *ap = &wpa_s->wps_ap[i];
- struct wpa_bssid_ignore *e = wpa_bssid_ignore_get(wpa_s,
- ap->bssid);
-
- wpa_printf(MSG_DEBUG, "WPS: AP[%d] " MACSTR " type=%d "
- "tries=%d last_attempt=%d sec ago bssid_ignore=%d",
- (int) i, MAC2STR(ap->bssid), ap->type, ap->tries,
- ap->last_attempt.sec > 0 ?
- (int) now.sec - (int) ap->last_attempt.sec : -1,
- e ? e->count : 0);
- }
-}
-
-
-static struct wps_ap_info * wpas_wps_get_ap_info(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
- size_t i;
-
- if (wpa_s->wps_ap == NULL)
- return NULL;
-
- for (i = 0; i < wpa_s->num_wps_ap; i++) {
- struct wps_ap_info *ap = &wpa_s->wps_ap[i];
- if (os_memcmp(ap->bssid, bssid, ETH_ALEN) == 0)
- return ap;
- }
-
- return NULL;
-}
-
-
-static void wpas_wps_update_ap_info_bss(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res)
-{
- struct wpabuf *wps;
- enum wps_ap_info_type type;
- struct wps_ap_info *ap;
- int r, pbc_active;
- const u8 *uuid;
-
- if (wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE) == NULL)
- return;
-
- wps = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
- if (wps == NULL)
- return;
-
- r = wps_is_addr_authorized(wps, wpa_s->own_addr, 1);
- if (r == 2)
- type = WPS_AP_SEL_REG_OUR;
- else if (r == 1)
- type = WPS_AP_SEL_REG;
- else
- type = WPS_AP_NOT_SEL_REG;
-
- uuid = wps_get_uuid_e(wps);
- pbc_active = wps_is_selected_pbc_registrar(wps);
-
- ap = wpas_wps_get_ap_info(wpa_s, res->bssid);
- if (ap) {
- if (ap->type != type) {
- wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR
- " changed type %d -> %d",
- MAC2STR(res->bssid), ap->type, type);
- ap->type = type;
- if (type != WPS_AP_NOT_SEL_REG)
- wpa_bssid_ignore_del(wpa_s, ap->bssid);
- }
- ap->pbc_active = pbc_active;
- if (uuid)
- os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
- goto out;
- }
-
- ap = os_realloc_array(wpa_s->wps_ap, wpa_s->num_wps_ap + 1,
- sizeof(struct wps_ap_info));
- if (ap == NULL)
- goto out;
-
- wpa_s->wps_ap = ap;
- ap = &wpa_s->wps_ap[wpa_s->num_wps_ap];
- wpa_s->num_wps_ap++;
-
- os_memset(ap, 0, sizeof(*ap));
- os_memcpy(ap->bssid, res->bssid, ETH_ALEN);
- ap->type = type;
- ap->pbc_active = pbc_active;
- if (uuid)
- os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
- wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR " type %d added",
- MAC2STR(ap->bssid), ap->type);
-
-out:
- wpabuf_free(wps);
-}
-
-
-void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
- size_t i;
-
- for (i = 0; i < scan_res->num; i++)
- wpas_wps_update_ap_info_bss(wpa_s, scan_res->res[i]);
-
- wpas_wps_dump_ap_info(wpa_s);
-}
-
-
-void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
- struct wps_ap_info *ap;
-
- wpa_s->after_wps = 0;
-
- if (!wpa_s->wps_ap_iter)
- return;
- ap = wpas_wps_get_ap_info(wpa_s, bssid);
- if (ap == NULL)
- return;
- ap->tries++;
- os_get_reltime(&ap->last_attempt);
-}
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
deleted file mode 100644
index c55936ceeaaf..000000000000
--- a/wpa_supplicant/wps_supplicant.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * wpa_supplicant / WPS integration
- * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPS_SUPPLICANT_H
-#define WPS_SUPPLICANT_H
-
-struct wpa_scan_results;
-
-#ifdef CONFIG_WPS
-
-#include "wps/wps.h"
-#include "wps/wps_defs.h"
-
-struct wpa_bss;
-
-struct wps_new_ap_settings {
- const char *ssid_hex;
- const char *auth;
- const char *encr;
- const char *key_hex;
-};
-
-int wpas_wps_init(struct wpa_supplicant *wpa_s);
-void wpas_wps_deinit(struct wpa_supplicant *wpa_s);
-int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
-enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
-int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
- int p2p_group, int multi_ap_backhaul_sta);
-int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, int p2p_group, u16 dev_pw_id);
-void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);
-int wpas_wps_cancel(struct wpa_supplicant *wpa_s);
-int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, struct wps_new_ap_settings *settings);
-int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct wpa_bss *bss);
-int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct wpa_bss *bss);
-int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected, struct wpa_ssid *ssid);
-void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s);
-int wpas_wps_searching(struct wpa_supplicant *wpa_s);
-int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *pos,
- char *end);
-int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter);
-void wpas_wps_er_stop(struct wpa_supplicant *wpa_s);
-int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
- const char *uuid, const char *pin);
-int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid);
-int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin);
-int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
- int id);
-int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin, struct wps_new_ap_settings *settings);
-struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef, const char *uuid);
-int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
-void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
-void wpas_wps_update_mac_addr(struct wpa_supplicant *wpa_s);
-struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef, const char *id_str);
-struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
-int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *dev_addr,
- const u8 *bssid,
- const struct wpabuf *dev_pw, u16 dev_pw_id,
- int p2p_group, const u8 *peer_pubkey_hash,
- const u8 *ssid, size_t ssid_len, int freq);
-int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
- const struct wpabuf *data, int forced_freq);
-struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
- int ndef);
-struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
- int ndef, int cr, const char *uuid);
-int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel);
-int wpas_er_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
- const struct wpabuf *req,
- const struct wpabuf *sel);
-void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res);
-void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid);
-int wpas_wps_reenable_networks_pending(struct wpa_supplicant *wpa_s);
-
-#else /* CONFIG_WPS */
-
-static inline int wpas_wps_init(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline u8 wpas_wps_get_req_type(struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-static inline int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss)
-{
- return -1;
-}
-
-static inline int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct wpa_bss *bss)
-{
- return 0;
-}
-
-static inline int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
- struct wpa_bss *selected,
- struct wpa_ssid *ssid)
-{
- return 0;
-}
-
-static inline void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
-{
-}
-
-static inline int wpas_wps_searching(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
- struct wpa_scan_results *scan_res)
-{
-}
-
-static inline void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s,
- const u8 *bssid)
-{
-}
-
-static inline int
-wpas_wps_reenable_networks_pending(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
-static inline void wpas_wps_update_mac_addr(struct wpa_supplicant *wpa_s)
-{
-}
-
-#endif /* CONFIG_WPS */
-
-#endif /* WPS_SUPPLICANT_H */