#include "Firewall.h" ESPFirewall::ESPFirewall(int port) { log_i("Starting Firewall-API on %i", port); this->firewall_api = new AsyncWebServer(port); this->setup_routing(); } void ESPFirewall::add_rule_to_firewall(firewall_rule_t *rule) { firewall_rule_t *temp; if (head == NULL) { head = rule; rule->next = NULL; return; } temp = head; while (temp->next != NULL) { temp = temp->next; } temp->next = rule; rule->next = NULL; return; } void ESPFirewall::get_firewall_rules_handler(AsyncWebServerRequest *request) { firewall_rule_t *ptr = this->head; DynamicJsonDocument json(1024); String response; json["amount"] = amount_of_rules; JsonArray rules = json.createNestedArray("rules"); while (ptr != NULL) { JsonObject rule = rules.createNestedObject(); rule["key"] = ptr->key; rule["source"] = ptr->source; rule["destination"] = ptr->destination; rule["protocol"] = ptr->protocol; rule["target"] = ptr->target; ptr = ptr->next; } serializeJson(json, response); request->send(200, "application/json", response); } void ESPFirewall::get_firewall_rule_handler(AsyncWebServerRequest *request) { int rule_number = request->pathArg(0).toInt(); DynamicJsonDocument json(1024); String response; json["message"] = "get firewall rule"; json["key"] = rule_number; serializeJson(json, response); request->send(404, "application/json", response); } void ESPFirewall::post_firewall_handler(AsyncWebServerRequest *request) { DynamicJsonDocument json(1024); String response; int response_code; if (request_has_firewall_parameter(request)) { firewall_rule_t *rule = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); rule->key = ++amount_of_rules; const char *source = request->arg("source").c_str(); strcpy(rule->source, strlen(source) <= IP4ADDR_STRLEN_MAX ? source : "-"); const char *destination = request->arg("destination").c_str(); strcpy(rule->destination, strlen(destination) <= IP4ADDR_STRLEN_MAX ? destination : "-"); const char *protocol = request->arg("protocol").c_str(); strcpy(rule->protocol, strlen(protocol) <= PROTOCOL_LENGTH ? protocol : "-"); const char *target = request->arg("target").c_str(); strcpy(rule->target, strlen(target) <= TARGET_LENGTH ? target : "-"); add_rule_to_firewall(rule); json["key"] = rule->key; json["source"] = rule->source; json["destination"] = rule->destination; json["protocol"] = rule->protocol; json["target"] = rule->target; response_code = 200; } else { json["message"] = "not enough parameter provided"; response_code = 400; } serializeJson(json, response); request->send(response_code, "application/json", response); } void ESPFirewall::not_found(AsyncWebServerRequest *request) { DynamicJsonDocument json(1024); String response; json["message"] = "not found"; serializeJson(json, response); request->send(404, "application/json", response); } bool ESPFirewall::request_has_firewall_parameter(AsyncWebServerRequest *request) { return request->hasArg("source") || request->hasArg("destination") || request->hasArg("protocol") || request->hasArg("target"); } void ESPFirewall::setup_routing() { firewall_api->on("^\\/api/v1/firewall\\/([0-9]+)$", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rule_handler, this, std::placeholders::_1)); firewall_api->on("/api/v1/firewall", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rules_handler, this, std::placeholders::_1)); firewall_api->on("/api/v1/firewall", HTTP_POST, std::bind(&ESPFirewall::post_firewall_handler, this, std::placeholders::_1)); firewall_api->onNotFound(std::bind(&ESPFirewall::not_found, this, std::placeholders::_1)); this->firewall_api->begin(); }