#include "Firewall.h" ESPFirewall::ESPFirewall(int port) { this->amount_of_rules = 0; this->head = NULL; log_i("Starting Firewall-API on %i", port); this->firewall_api = new WebServer(port); this->setup_routing(); this->add_rule_to_firewall("192.168.0.1", "192.168.0.10", "TCP", "DROP"); this->add_rule_to_firewall("192.168.0.2", "192.168.0.15", "UDP", "REJECT"); } void ESPFirewall::setup_routing() { this->firewall_api->on("/api/v1/firewall", HTTP_GET, std::bind(&ESPFirewall::get_firewall_handler, this)); this->firewall_api->on("/api/v1/firewall", HTTP_POST, std::bind(&ESPFirewall::post_firewall_handler, this)); this->firewall_api->begin(); } void ESPFirewall::custom_message_response(const char *message, int response_code) { cJSON *json_response = cJSON_CreateObject(); cJSON_AddBoolToObject(json_response, "ok", true); cJSON_AddStringToObject(json_response, "message", message); this->firewall_api->send(response_code, "application/json", cJSON_Print(json_response)); cJSON_Delete(json_response); } void ESPFirewall::prepare_firewall_json(cJSON *jsonResponse, firewall_rule_t *link) { cJSON_AddBoolToObject(jsonResponse, "ok", true); cJSON_AddNumberToObject(jsonResponse, "number", link->key); cJSON_AddStringToObject(jsonResponse, "source", link->source); cJSON_AddStringToObject(jsonResponse, "destination", link->destination); cJSON_AddStringToObject(jsonResponse, "protocol", link->protocol); cJSON_AddStringToObject(jsonResponse, "target", link->target); } firewall_rule_t *ESPFirewall::add_rule_to_firewall(const char *source, const char *destination, const char *protocol, const char *target) { firewall_rule_t *temp; firewall_rule_t *link = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); link->key = ++amount_of_rules; strcpy(link->source, source); strcpy(link->destination, destination); strcpy(link->protocol, protocol); strcpy(link->target, target); if (head == NULL) { head = link; link->next = NULL; return link; } temp = head; while (temp->next != NULL) { temp = temp->next; } temp->next = link; link->next = NULL; return link; } void ESPFirewall::post_firewall_handler() { if ((firewall_api->hasArg("source") || firewall_api->hasArg("destination") || firewall_api->hasArg("protocol") || firewall_api->hasArg("target")) == false) { this->custom_message_response("not enough erguments provided", 400); } else { const char *source = firewall_api->arg("source").c_str(); const char *destination = firewall_api->arg("destination").c_str(); const char *protocol = firewall_api->arg("protocol").c_str(); const char *target = firewall_api->arg("target").c_str(); firewall_rule_t *ptr = this->add_rule_to_firewall(source, destination, protocol, target); cJSON *json_response = cJSON_CreateObject(); prepare_firewall_json(json_response, ptr); this->firewall_api->send(200, "application/json", cJSON_Print(json_response)); } } void ESPFirewall::get_firewall_handler() { firewall_rule_t *ptr = head; cJSON *json_response = cJSON_CreateArray(); while (ptr != NULL) { cJSON *json_firewall_rule = cJSON_CreateObject(); prepare_firewall_json(json_firewall_rule, ptr); cJSON_AddItemToArray(json_response, json_firewall_rule); ptr = ptr->next; } this->firewall_api->send(200, "application/json", cJSON_Print(json_response)); } void ESPFirewall::handle_clients() { this->firewall_api->handleClient(); }