diff options
Diffstat (limited to 'main/firewall.c')
| -rw-r--r-- | main/firewall.c | 93 |
1 files changed, 83 insertions, 10 deletions
diff --git a/main/firewall.c b/main/firewall.c index 8087b54..f349ab1 100644 --- a/main/firewall.c +++ b/main/firewall.c | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | #include "firewall.h" | 1 | #include "firewall.h" |
| 2 | #include "dns_server.h" | 2 | #include "dns_server.h" |
| 3 | #include "esp_log.h" | 3 | #include "esp_log.h" |
| 4 | #include "esp_wifi.h" | ||
| 5 | #include "esp_wifi_ap_get_sta_list.h" | ||
| 4 | #include "lwip/lwip_napt.h" | 6 | #include "lwip/lwip_napt.h" |
| 7 | #include "lwip/etharp.h" | ||
| 8 | #include "lwip/netif.h" | ||
| 5 | #include <string.h> | 9 | #include <string.h> |
| 6 | 10 | ||
| 7 | #define MAX_CLIENTS 10 | 11 | #define MAX_CLIENTS 10 |
| @@ -12,11 +16,51 @@ static bool s_nat_enabled = false; | |||
| 12 | 16 | ||
| 13 | typedef struct { | 17 | typedef struct { |
| 14 | uint32_t ip; | 18 | uint32_t ip; |
| 19 | char mac[FW_MAX_MAC_LEN]; | ||
| 15 | } fw_client_t; | 20 | } fw_client_t; |
| 16 | 21 | ||
| 17 | static fw_client_t s_clients[MAX_CLIENTS]; | 22 | static fw_client_t s_clients[MAX_CLIENTS]; |
| 18 | static int s_client_count = 0; | 23 | static int s_client_count = 0; |
| 19 | 24 | ||
| 25 | static struct netif *get_ap_netif(void) | ||
| 26 | { | ||
| 27 | return netif_get_by_index(NETIF_NO_INDEX); | ||
| 28 | } | ||
| 29 | |||
| 30 | esp_err_t firewall_get_mac_for_ip(uint32_t client_ip, char *mac_out, size_t mac_out_size) | ||
| 31 | { | ||
| 32 | wifi_sta_list_t sta_list; | ||
| 33 | if (esp_wifi_ap_get_sta_list(&sta_list) == ESP_OK) { | ||
| 34 | wifi_sta_mac_ip_list_t ip_mac_list; | ||
| 35 | if (esp_wifi_ap_get_sta_list_with_ip(&sta_list, &ip_mac_list) == ESP_OK) { | ||
| 36 | for (int i = 0; i < ip_mac_list.num; i++) { | ||
| 37 | if (ip_mac_list.sta[i].ip.addr == client_ip) { | ||
| 38 | snprintf(mac_out, mac_out_size, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
| 39 | ip_mac_list.sta[i].mac[0], ip_mac_list.sta[i].mac[1], | ||
| 40 | ip_mac_list.sta[i].mac[2], ip_mac_list.sta[i].mac[3], | ||
| 41 | ip_mac_list.sta[i].mac[4], ip_mac_list.sta[i].mac[5]); | ||
| 42 | return ESP_OK; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | ip4_addr_t *entry_ip = NULL; | ||
| 49 | struct netif *entry_netif = NULL; | ||
| 50 | struct eth_addr *entry_eth = NULL; | ||
| 51 | ssize_t i = 0; | ||
| 52 | while (etharp_get_entry(i, &entry_ip, &entry_netif, &entry_eth) == ERR_OK) { | ||
| 53 | if (entry_ip && entry_ip->addr == client_ip && entry_eth) { | ||
| 54 | snprintf(mac_out, mac_out_size, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
| 55 | entry_eth->addr[0], entry_eth->addr[1], entry_eth->addr[2], | ||
| 56 | entry_eth->addr[3], entry_eth->addr[4], entry_eth->addr[5]); | ||
| 57 | return ESP_OK; | ||
| 58 | } | ||
| 59 | i++; | ||
| 60 | } | ||
| 61 | return ESP_FAIL; | ||
| 62 | } | ||
| 63 | |||
| 20 | esp_err_t firewall_init(esp_ip4_addr_t ap_ip) | 64 | esp_err_t firewall_init(esp_ip4_addr_t ap_ip) |
| 21 | { | 65 | { |
| 22 | s_ap_ip = ap_ip; | 66 | s_ap_ip = ap_ip; |
| @@ -56,34 +100,61 @@ void firewall_disable_nat(void) | |||
| 56 | ESP_LOGI(TAG, "NAT disabled"); | 100 | ESP_LOGI(TAG, "NAT disabled"); |
| 57 | } | 101 | } |
| 58 | 102 | ||
| 59 | void firewall_grant_access(uint32_t client_ip) | 103 | static fw_client_t *find_client_by_ip(uint32_t client_ip) |
| 60 | { | 104 | { |
| 61 | for (int i = 0; i < s_client_count; i++) { | 105 | for (int i = 0; i < s_client_count; i++) { |
| 62 | if (s_clients[i].ip == client_ip) return; | 106 | if (s_clients[i].ip == client_ip) return &s_clients[i]; |
| 107 | } | ||
| 108 | return NULL; | ||
| 109 | } | ||
| 110 | |||
| 111 | static fw_client_t *find_client_by_mac(const char *mac) | ||
| 112 | { | ||
| 113 | for (int i = 0; i < s_client_count; i++) { | ||
| 114 | if (s_clients[i].mac[0] != '\0' && strcmp(s_clients[i].mac, mac) == 0) { | ||
| 115 | return &s_clients[i]; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | return NULL; | ||
| 119 | } | ||
| 120 | |||
| 121 | void firewall_grant_access(uint32_t client_ip) | ||
| 122 | { | ||
| 123 | fw_client_t *existing = find_client_by_ip(client_ip); | ||
| 124 | if (existing) { | ||
| 125 | existing->ip = client_ip; | ||
| 126 | return; | ||
| 63 | } | 127 | } |
| 64 | if (s_client_count >= MAX_CLIENTS) { | 128 | if (s_client_count >= MAX_CLIENTS) { |
| 65 | ESP_LOGW(TAG, "Max clients reached, cannot grant access"); | 129 | ESP_LOGW(TAG, "Max clients reached, cannot grant access"); |
| 66 | return; | 130 | return; |
| 67 | } | 131 | } |
| 68 | s_clients[s_client_count].ip = client_ip; | 132 | |
| 133 | fw_client_t *client = &s_clients[s_client_count]; | ||
| 134 | client->ip = client_ip; | ||
| 135 | client->mac[0] = '\0'; | ||
| 136 | firewall_get_mac_for_ip(client_ip, client->mac, sizeof(client->mac)); | ||
| 69 | s_client_count++; | 137 | s_client_count++; |
| 138 | |||
| 70 | dns_server_set_client_authenticated(client_ip, true); | 139 | dns_server_set_client_authenticated(client_ip, true); |
| 71 | update_nat(); | 140 | update_nat(); |
| 72 | 141 | ||
| 73 | esp_ip4_addr_t ip_addr = { .addr = client_ip }; | 142 | esp_ip4_addr_t ip_addr = { .addr = client_ip }; |
| 74 | ESP_LOGI(TAG, "Access granted to " IPSTR, IP2STR(&ip_addr)); | 143 | ESP_LOGI(TAG, "Access granted to " IPSTR " mac=%s", IP2STR(&ip_addr), |
| 144 | client->mac[0] ? client->mac : "unknown"); | ||
| 75 | } | 145 | } |
| 76 | 146 | ||
| 77 | void firewall_revoke_access(uint32_t client_ip) | 147 | void firewall_revoke_access(uint32_t client_ip) |
| 78 | { | 148 | { |
| 79 | for (int i = 0; i < s_client_count; i++) { | 149 | for (int i = 0; i < s_client_count; i++) { |
| 80 | if (s_clients[i].ip == client_ip) { | 150 | if (s_clients[i].ip == client_ip) { |
| 151 | esp_ip4_addr_t ip_addr = { .addr = client_ip }; | ||
| 152 | ESP_LOGI(TAG, "Access revoked for " IPSTR " mac=%s", IP2STR(&ip_addr), | ||
| 153 | s_clients[i].mac[0] ? s_clients[i].mac : "unknown"); | ||
| 81 | s_clients[i] = s_clients[s_client_count - 1]; | 154 | s_clients[i] = s_clients[s_client_count - 1]; |
| 82 | s_client_count--; | 155 | s_client_count--; |
| 83 | dns_server_set_client_authenticated(client_ip, false); | 156 | dns_server_set_client_authenticated(client_ip, false); |
| 84 | update_nat(); | 157 | update_nat(); |
| 85 | esp_ip4_addr_t ip_addr = { .addr = client_ip }; | ||
| 86 | ESP_LOGI(TAG, "Access revoked for " IPSTR, IP2STR(&ip_addr)); | ||
| 87 | return; | 158 | return; |
| 88 | } | 159 | } |
| 89 | } | 160 | } |
| @@ -101,10 +172,12 @@ void firewall_revoke_all(void) | |||
| 101 | 172 | ||
| 102 | bool firewall_is_client_allowed(uint32_t client_ip) | 173 | bool firewall_is_client_allowed(uint32_t client_ip) |
| 103 | { | 174 | { |
| 104 | for (int i = 0; i < s_client_count; i++) { | 175 | return find_client_by_ip(client_ip) != NULL; |
| 105 | if (s_clients[i].ip == client_ip) return true; | 176 | } |
| 106 | } | 177 | |
| 107 | return false; | 178 | bool firewall_is_mac_allowed(const char *mac) |
| 179 | { | ||
| 180 | return find_client_by_mac(mac) != NULL; | ||
| 108 | } | 181 | } |
| 109 | 182 | ||
| 110 | int firewall_client_count(void) | 183 | int firewall_client_count(void) |