diff --git a/src/api/action.c b/src/api/action.c index 6900203b..6dcfa6eb 100644 --- a/src/api/action.c +++ b/src/api/action.c @@ -17,9 +17,10 @@ // reboot() #include #include - // exit_code #include "signals.h" +// flush_network_table() +#include "database/network-table.h" static int run_and_stream_command(struct ftl_conn *api, const char *path, const char *const args[]) { @@ -172,3 +173,17 @@ int api_action_flush_logs(struct ftl_conn *api) "Cannot flush the logs", NULL); } + +int api_action_flush_arp(struct ftl_conn *api) +{ + log_info("Received API request to flush the ARP cache"); + + // Flush the ARP cache + if(flush_network_table()) + return send_json_success(api); + else + return send_json_error(api, 500, + "server_error", + "Cannot flush the ARP cache", + NULL); +} diff --git a/src/api/api.c b/src/api/api.c index ed4c7f1d..ef922a1f 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -90,6 +90,7 @@ static struct { { "/api/action/poweroff", "", api_action_poweroff, { false, true, 0 }, true, HTTP_POST }, { "/api/action/restartdns", "", api_action_restartDNS, { false, true, 0 }, true, HTTP_POST }, { "/api/action/flush/logs", "", api_action_flush_logs, { false, true, 0 }, true, HTTP_POST }, + { "/api/action/flush/arp", "", api_action_flush_arp, { false, true, 0 }, true, HTTP_POST }, { "/api/docs", "", api_docs, { false, true, 0 }, false, HTTP_GET }, }; diff --git a/src/api/api.h b/src/api/api.h index 7082d268..2527f29e 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -100,6 +100,7 @@ int api_action_poweroff(struct ftl_conn *api); int api_action_reboot(struct ftl_conn *api); int api_action_restartDNS(struct ftl_conn *api); int api_action_flush_logs(struct ftl_conn *api); +int api_action_flush_arp(struct ftl_conn *api); // Search methods int api_search(struct ftl_conn *api); diff --git a/src/api/docs/content/specs/action.yaml b/src/api/docs/content/specs/action.yaml index 4a44f45e..be98daeb 100644 --- a/src/api/docs/content/specs/action.yaml +++ b/src/api/docs/content/specs/action.yaml @@ -163,3 +163,28 @@ components: allOf: - $ref: 'common.yaml#/components/errors/unauthorized' - $ref: 'common.yaml#/components/schemas/took' + flush_arp: + post: + summary: Flush the network table + tags: + - Actions + operationId: "action_flusharp" + description: | + Flushes the network table. This includes emptying the ARP table and removing both all known devices and their associated addresses. + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: 'common.yaml#/components/schemas/success' + - $ref: 'common.yaml#/components/schemas/took' + '401': + description: Unauthorized + content: + application/json: + schema: + allOf: + - $ref: 'common.yaml#/components/errors/unauthorized' + - $ref: 'common.yaml#/components/schemas/took' diff --git a/src/api/docs/content/specs/main.yaml b/src/api/docs/content/specs/main.yaml index 8bcdf096..8f020961 100644 --- a/src/api/docs/content/specs/main.yaml +++ b/src/api/docs/content/specs/main.yaml @@ -233,6 +233,9 @@ paths: /action/flush/logs: $ref: 'action.yaml#/components/paths/flush_logs' + /action/flush/arp: + $ref: 'action.yaml#/components/paths/flush_arp' + /action/reboot: $ref: 'action.yaml#/components/paths/reboot' diff --git a/src/database/network-table.c b/src/database/network-table.c index fbed6a1a..d6f58463 100644 --- a/src/database/network-table.c +++ b/src/database/network-table.c @@ -1218,6 +1218,26 @@ static bool clean_network_table(sqlite3* db) return true; } +bool flush_network_table(void) +{ + sqlite3 *db = dbopen(false, false); + if(db == NULL) + return false; + + // Remove all IP addresses + if(dbquery(db, "DELETE FROM network_addresses;") != SQLITE_OK) + return false; + + // Remove all devices + if(dbquery(db, "DELETE FROM network;") != SQLITE_OK) + return false; + + // Close database + dbclose(&db); + + return true; +} + // Parse kernel's neighbor cache void parse_neighbor_cache(sqlite3* db) { diff --git a/src/database/network-table.h b/src/database/network-table.h index 81f6f318..b85697cf 100644 --- a/src/database/network-table.h +++ b/src/database/network-table.h @@ -24,6 +24,7 @@ int getAliasclientIDfromIP(sqlite3 *db, const char *ipaddr); char* __attribute__((malloc)) getNameFromIP(sqlite3 *db, const char* ipaddr); char* __attribute__((malloc)) getIfaceFromIP(sqlite3 *db, const char* ipaddr); void resolveNetworkTableNames(void); +bool flush_network_table(void); typedef struct { unsigned int id;