Move command registry from components/command/ into components/core/. New modules: mod_canbus, mod_honeypot, mod_fallback, mod_redteam, mod_ota. Replace mod_proxy with tun_core (multiplexed SOCKS5 tunnel). Kconfig extended with per-module settings and async worker config.
198 lines
5.4 KiB
C
198 lines
5.4 KiB
C
/*
|
|
* Eun0us - ICMP Ping Module
|
|
* Clean & stream-based implementation
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "lwip/inet.h"
|
|
#include "lwip/netdb.h"
|
|
#include "esp_log.h"
|
|
#include "ping/ping_sock.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#define TAG "PING"
|
|
|
|
/* Context passed to ping callbacks via cb_args */
|
|
typedef struct {
|
|
char req[64]; /* request_id copy (empty string if none) */
|
|
} ping_ctx_t;
|
|
|
|
/* ============================================================
|
|
* Ping callbacks
|
|
* ============================================================ */
|
|
|
|
static void ping_on_success(esp_ping_handle_t hdl, void *args)
|
|
{
|
|
ping_ctx_t *ctx = (ping_ctx_t *)args;
|
|
const char *req = (ctx && ctx->req[0]) ? ctx->req : NULL;
|
|
char line[256];
|
|
|
|
uint8_t ttl;
|
|
uint16_t seq;
|
|
uint32_t time_ms, size;
|
|
ip_addr_t addr;
|
|
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seq, sizeof(seq));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &time_ms, sizeof(time_ms));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &size, sizeof(size));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &addr, sizeof(addr));
|
|
|
|
int len = snprintf(line, sizeof(line),
|
|
"%lu bytes from %s: icmp_seq=%u ttl=%u time=%lums",
|
|
(unsigned long)size,
|
|
ipaddr_ntoa(&addr),
|
|
seq,
|
|
ttl,
|
|
(unsigned long)time_ms
|
|
);
|
|
|
|
if (len > 0) {
|
|
msg_data(TAG, line, len, false, req);
|
|
}
|
|
}
|
|
|
|
static void ping_on_timeout(esp_ping_handle_t hdl, void *args)
|
|
{
|
|
ping_ctx_t *ctx = (ping_ctx_t *)args;
|
|
const char *req = (ctx && ctx->req[0]) ? ctx->req : NULL;
|
|
char line[256];
|
|
|
|
uint16_t seq;
|
|
ip_addr_t addr;
|
|
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seq, sizeof(seq));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &addr, sizeof(addr));
|
|
|
|
int len = snprintf(line, sizeof(line),
|
|
"From %s: icmp_seq=%u timeout",
|
|
ipaddr_ntoa(&addr),
|
|
seq
|
|
);
|
|
|
|
if (len > 0) {
|
|
msg_data(TAG, line, len, false, req);
|
|
}
|
|
}
|
|
|
|
static void ping_on_end(esp_ping_handle_t hdl, void *args)
|
|
{
|
|
ping_ctx_t *ctx = (ping_ctx_t *)args;
|
|
const char *req = (ctx && ctx->req[0]) ? ctx->req : NULL;
|
|
|
|
uint32_t sent, recv, duration;
|
|
ip_addr_t addr;
|
|
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &sent, sizeof(sent));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &recv, sizeof(recv));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &duration, sizeof(duration));
|
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &addr, sizeof(addr));
|
|
|
|
int loss = sent ? (100 - (recv * 100 / sent)) : 0;
|
|
|
|
char line[256];
|
|
int len = snprintf(line, sizeof(line),
|
|
"--- %s ping statistics ---\n"
|
|
"%lu packets transmitted, %lu received, %d%% packet loss, time %lums",
|
|
ipaddr_ntoa(&addr),
|
|
(unsigned long)sent,
|
|
(unsigned long)recv,
|
|
loss,
|
|
(unsigned long)duration
|
|
);
|
|
|
|
if (len > 0) {
|
|
msg_data(TAG, line, len, true, req);
|
|
}
|
|
|
|
esp_ping_delete_session(hdl);
|
|
free(ctx);
|
|
}
|
|
|
|
/* ============================================================
|
|
* Command entry point
|
|
* ============================================================ */
|
|
|
|
int do_ping_cmd(int argc, char **argv, const char *req)
|
|
{
|
|
if (argc < 1) {
|
|
msg_error(TAG,
|
|
"usage: ping <host> [timeout interval size count ttl iface]",
|
|
req);
|
|
return -1;
|
|
}
|
|
|
|
esp_ping_config_t cfg = ESP_PING_DEFAULT_CONFIG();
|
|
cfg.count = 4;
|
|
cfg.timeout_ms = 1000;
|
|
cfg.task_stack_size = 8192; /* default 2048 too small for msg_data→protobuf stack */
|
|
|
|
const char *host = argv[0];
|
|
|
|
/* Optional arguments */
|
|
if (argc > 1) cfg.timeout_ms = atoi(argv[1]) * 1000;
|
|
if (argc > 2) cfg.interval_ms = (uint32_t)(atof(argv[2]) * 1000);
|
|
if (argc > 3) cfg.data_size = atoi(argv[3]);
|
|
if (argc > 4) cfg.count = atoi(argv[4]);
|
|
if (argc > 5) cfg.tos = atoi(argv[5]);
|
|
if (argc > 6) cfg.ttl = atoi(argv[6]);
|
|
|
|
/* Resolve host */
|
|
ip_addr_t target;
|
|
memset(&target, 0, sizeof(target));
|
|
|
|
if (!ipaddr_aton(host, &target)) {
|
|
struct addrinfo *res = NULL;
|
|
|
|
if (getaddrinfo(host, NULL, NULL, &res) != 0 || !res) {
|
|
msg_error(TAG, "unknown host", req);
|
|
return -1;
|
|
}
|
|
|
|
#ifdef CONFIG_LWIP_IPV4
|
|
if (res->ai_family == AF_INET) {
|
|
inet_addr_to_ip4addr(
|
|
ip_2_ip4(&target),
|
|
&((struct sockaddr_in *)res->ai_addr)->sin_addr
|
|
);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_LWIP_IPV6
|
|
if (res->ai_family == AF_INET6) {
|
|
inet6_addr_to_ip6addr(
|
|
ip_2_ip6(&target),
|
|
&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr
|
|
);
|
|
}
|
|
#endif
|
|
|
|
freeaddrinfo(res);
|
|
}
|
|
|
|
cfg.target_addr = target;
|
|
|
|
/* Heap-allocate context for callbacks (freed in ping_on_end) */
|
|
ping_ctx_t *ctx = calloc(1, sizeof(ping_ctx_t));
|
|
if (ctx && req) {
|
|
snprintf(ctx->req, sizeof(ctx->req), "%s", req);
|
|
}
|
|
|
|
esp_ping_callbacks_t cbs = {
|
|
.on_ping_success = ping_on_success,
|
|
.on_ping_timeout = ping_on_timeout,
|
|
.on_ping_end = ping_on_end,
|
|
.cb_args = ctx
|
|
};
|
|
|
|
esp_ping_handle_t ping;
|
|
esp_ping_new_session(&cfg, &cbs, &ping);
|
|
esp_ping_start(ping);
|
|
|
|
return 0;
|
|
}
|