ESP8266/ESP32 中查看,修改AP的IP信息,并剔除指定的STA
ESP系列的芯片支持WiFi功能的STA+AP工作模式,今天我们来聊一聊当ESP系列的芯片工作在AP模式(即作为一个WiFi热点)时,如何查看其IP、修改其IP,并剔除不想让其连接到AP的指定STA。
1.查看并修改AP的IP
实验环境是一块ESP8266作为AP,一块ESP32作为STA,代码模板使用的是ESP8266 RTOS SDK/ESP-IDF上的WiFi_Start代码。不多说,上代码:(代码在ESP8266/ESP32下的实现基本一致,并全部通过了测试,注释给出了相关说明)
[code]/* WiFi softAP Example This example code is in the Public Domain (or CC0 licensed, at your option.) Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #include "lwip/err.h" #include "lwip/sys.h" /* The examples use WiFi configuration that you can set via project configuration menu. If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD #define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN static const char *TAG = "wifi softAP"; /* define some temporary variable to show the result*/ tcpip_adapter_ip_info_t local_ip; esp_err_t res_ap_get; esp_err_t res_ap_set; static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if (event_id == WIFI_EVENT_AP_STACONNECTED) { wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid); /*printf self mac and IP*/ res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip); if(res_ap_get == ESP_OK){ ESP_LOGI(TAG,"get is success\n"); ESP_LOGI(TAG, "now_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip)); ESP_LOGI(TAG, "now_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask)); ESP_LOGI(TAG, "now_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); } } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid); } } void wifi_init_softap() { tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_create_default()); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL)); wifi_config_t wifi_config = { .ap = { .ssid = EXAMPLE_ESP_WIFI_SSID, .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID), .password = EXAMPLE_ESP_WIFI_PASS, .max_connection = EXAMPLE_MAX_STA_CONN, .authmode = WIFI_AUTH_WPA_WPA2_PSK }, }; if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config)); /*you must call esp_wifi_start() before set your new IP, because the WiFi system's start always load the original IP information from the tcpip_adapter_init(),if you want change the original IP , please change the IP in tcpip_adapter_init(),otherwise,please allow the system load the original IP firstly when call esp_wifi_start(), and then you can set your new IP*/ ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); /*print old IP information*/ res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip); if(res_ap_get == ESP_OK){ ESP_LOGI(TAG,"get is success\n"); } ESP_LOGI(TAG, "old_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip)); ESP_LOGI(TAG, "old_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask)); ESP_LOGI(TAG, "old_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); /*stop dhcps*/ tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP); /*write */ IP4_ADDR(&local_ip.ip, 192, 168 , 47, 110); IP4_ADDR(&local_ip.gw, 192, 168 , 47, 120); IP4_ADDR(&local_ip.netmask, 255, 255 , 255, 0); /*print set IP information*/ ESP_LOGI(TAG,"set ip:"IPSTR"\n",IP2STR(&local_ip.ip)); ESP_LOGI(TAG,"set:netmask"IPSTR"\n",IP2STR(&local_ip.netmask)); ESP_LOGI(TAG,"set gw:"IPSTR"\n",IP2STR(&local_ip.gw)); /*set new IP*/ res_ap_set = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip); if(res_ap_set == ESP_OK){ ESP_LOGI(TAG,"set is success\n"); } else { ESP_LOGI(TAG,"set is failed\n"); } /*restart adapter dhcps*/ tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP); /*print new IP information*/ res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip); if(res_ap_get == ESP_OK){ ESP_LOGI(TAG,"get is success\n"); } ESP_LOGI(TAG, "new_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip)); ESP_LOGI(TAG, "new_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask)); ESP_LOGI(TAG, "new_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); } void app_main() { ESP_ERROR_CHECK(nvs_flash_init()); ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); wifi_init_softap(); }
测试结果如下:
结果分析:
获取原IP:192.168.4.1
要设置的IP:192.168.47.110
设置成功后再次获取当前IP为:192.168.47.110,证明设置IP成功。
作为补充,我在 WIFI_EVENT_AP_STACONNECTED事件下添加了每当有STA连接该AP,就打印一次AP当前IP的代码,从图中可以看到,now_self_ip为192.168.47.110,这正是我们设置的IP值,因此,再一次证明了我们已经成功修改该AP的IP。
上述提供了一种再运行时修改AP的IP的方法,如果想在开发板上电运行就使用指定的IP,可以在
模式AP模式获取自身IP、修改自己的IP,剔除指定id的STA。如果不想在运行时修改IP,可以在始化代码tcpip_adapter_init()的实现中直接修改结构体中的IP和掩码,就可以在初始化时加载指定的IP。
2.剔除指定的STA
有时候我们希望将一些”蹭网“的STA拉入黑名单,防止其连接到我们的AP上。
下面的代码给出了一种剔除连接到AP的指定STA的方法:(替换掉上面代码的同名函数即可,就增加了小部分代码)
[code]static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if (event_id == WIFI_EVENT_AP_STACONNECTED) { wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid); /*printf self mac and IP*/ res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip); if(res_ap_get == ESP_OK){ ESP_LOGI(TAG,"get is success\n"); ESP_LOGI(TAG, "now_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip)); ESP_LOGI(TAG, "now_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask)); ESP_LOGI(TAG, "now_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); } esp_err_t res_deauth_sta; res_deauth_sta = esp_wifi_deauth_sta(event->aid);/* deauth the sta*/ if(res_deauth_sta == ESP_OK){ ESP_LOGI(TAG,"deauth OK"); } else{ ESP_LOGI(TAG,"deauth failed"); } } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid); } }
通过esp_wifi_deauth_sta()函数就可以将指定的STA剔除,从而断开其对AP的连接。
实验结果如下:
结果分析:每当station 在join(即加入)该AP时,就会触发对应的WIFI_EVENT_AP_STACONNECTED事件,而在该事件下,我们调用了对应的剔除函数esp_wifi_deauth_sta(),因此每当该STA接入,就会剔除它(提示deauth OK)。所以,上述代码会提示该STA不停的join、leave.
下图还给出了STA被不停剔除的串口输出:
该串口输出提示,该STA在连接的auth -> assoc阶段未成功,因此,提示STA_DISCONNECTED,即STA连接不到AP。
3.参考资料与WLAN的基础扫盲链接:
1.esp8266 AP模式下剔除station https://blog.csdn.net/u013550000/article/details/89407724
2.[填坑]ESP32修改softap IP地址后WiFi信号丢失问题 https://blog.csdn.net/qq_20515461/article/details/102816663
3.非常好的WLAN、WiFi基础知识讲解资源:https://forum.huawei.com/enterprise/zh/forum.php?mod=collection&action=view&ctid=61
- Linux查看并修改主机名称、IP等信息
- 获取并修改本机的ip,网关,dns,子网掩码等信息
- 查看指定IP的名称
- oracle查看/修改最大连接数和当前连接数/用户等信息
- 【视频】配置信息管理 的 使用方法(三):查看和修改元数据、查看数据库的表视图存储过程等信息
- Java 通过Socket监听指定服务器(IP)的指定端口,及向指定服务器的指定端口发送信息
- shell脚本自动修改IP信息
- RHEL5下tcp最大连接信息查看及修改方法
- 树莓派集群实践2——修改树莓派3 指定IP,DNS要修改dhcpcd.conf
- 在Linux的系统下如何才能修改IP信息
- CentOS 查看IP,端口 修改IP,打开端口生效
- Android 怎么通过adb 查看ip信息
- Android 通过iptables修改到指定主机的路由信息
- 【视频】配置信息管理 的 使用方法(三):查看和修改元数据、查看数据库的表视图存储过程等信息
- 做web开发和测试,修改hosts指定某个域名访问某个特定的IP后,如何使hosts立即生效的方法
- stat 查看一个文件的修改时间,创建时间等信息的命令
- 闪回表+查看和修改撤销表空间的信息+闪回表操作语法+闪回表的案例
- [系统安全] 最新神器,可修改指定串号,手机号,Mac,机型等信息
- CentOS 查看IP,端口 修改IP,打开端口生效
- linux下修改IP信息