161 lines
5.2 KiB
C
Executable File
161 lines
5.2 KiB
C
Executable File
/*
|
|
* scalpel.c -- USB Virtual Network Tap (Nettap) module
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*
|
|
* USB virtual network tap. Captures IP packets from usb0 via raw
|
|
* AF_PACKET socket, parses src/dst IPv4 addresses, displays them
|
|
* on an LVGL console, and coalesces writes to disk via the
|
|
* flash-safe timed logger.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <net/if.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/input.h>
|
|
#include "h2_ui.h"
|
|
#include "log_manager.h"
|
|
|
|
#define NUM_WINDOWS 5
|
|
#define CONSOLE_MAX_LINES 20
|
|
|
|
const log_window_t window_durations[NUM_WINDOWS] = {
|
|
WINDOW_30S, WINDOW_1M, WINDOW_2M, WINDOW_5M, WINDOW_10M
|
|
};
|
|
const char *window_labels[NUM_WINDOWS] = {
|
|
"30 SECONDS", "1 MINUTE", "2 MINUTES", "5 MINUTES", "10 MINUTES"
|
|
};
|
|
|
|
static lv_obj_t *console;
|
|
static timed_logger_t *logger;
|
|
|
|
static void process_ip_packet(const uint8_t *pkt, ssize_t pkt_len) {
|
|
uint16_t ethertype = ((uint16_t)pkt[12] << 8) | pkt[13];
|
|
if (ethertype != 0x0800) return;
|
|
if (pkt_len < 34) return;
|
|
|
|
char display_row[64];
|
|
snprintf(display_row, sizeof(display_row),
|
|
"IP: %d.%d.%d.%d -> %d.%d.%d.%d",
|
|
pkt[26], pkt[27], pkt[28], pkt[29],
|
|
pkt[30], pkt[31], pkt[32], pkt[33]);
|
|
|
|
char log_row[128];
|
|
snprintf(log_row, sizeof(log_row),
|
|
"[%ld] SIZE:%ld %d.%d.%d.%d->%d.%d.%d.%d\n",
|
|
(long)time(NULL), (long)pkt_len,
|
|
pkt[26], pkt[27], pkt[28], pkt[29],
|
|
pkt[30], pkt[31], pkt[32], pkt[33]);
|
|
|
|
if (logger) timed_log_write(logger, log_row);
|
|
|
|
lv_list_add_text(console, display_row);
|
|
static int line_count;
|
|
line_count++;
|
|
if (line_count > CONSOLE_MAX_LINES) {
|
|
lv_obj_clean(console);
|
|
line_count = 0;
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
init_h2_graphics_runtime("USB TAP MANAGER NODE");
|
|
LOG_INF("nettap module started");
|
|
|
|
lv_obj_t *scr = lv_scr_act();
|
|
|
|
lv_obj_t *title = lv_label_create(scr);
|
|
lv_label_set_text(title, "USB VIRTUAL NETTAP");
|
|
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
|
|
lv_obj_set_style_text_color(title, COLOR_PRIMARY, LV_PART_MAIN);
|
|
|
|
lv_obj_t *config_card = lv_obj_create(scr);
|
|
lv_obj_set_size(config_card, 290, 160);
|
|
lv_obj_align(config_card, LV_ALIGN_CENTER, 0, 15);
|
|
lv_obj_set_style_bg_color(config_card, lv_color_make(22, 28, 38), LV_PART_MAIN);
|
|
|
|
lv_obj_t *cfg_lbl = lv_label_create(config_card);
|
|
lv_label_set_text(cfg_lbl, "SET DATA FLUSH TIME WINDOW:");
|
|
lv_obj_align(cfg_lbl, LV_ALIGN_TOP_MID, 0, 10);
|
|
|
|
lv_obj_t *window_lbl = lv_label_create(config_card);
|
|
lv_obj_align(window_lbl, LV_ALIGN_CENTER, 0, -5);
|
|
lv_obj_set_style_text_color(window_lbl, COLOR_ACCENT, LV_PART_MAIN);
|
|
|
|
int input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
|
|
struct input_event ev;
|
|
int sel = 1;
|
|
|
|
while (1) {
|
|
lv_label_set_text(window_lbl, window_labels[sel]);
|
|
lv_timer_handler();
|
|
if (input_fd < 0) { usleep(15000); continue; }
|
|
if (read(input_fd, &ev, sizeof(struct input_event)) <= 0) { usleep(15000); continue; }
|
|
|
|
if (ev.type == EV_REL && ev.code == 0) {
|
|
if (ev.value > 0 && sel < NUM_WINDOWS - 1) sel++;
|
|
if (ev.value < 0 && sel > 0) sel--;
|
|
}
|
|
if (ev.type == EV_KEY && ev.value == 1 && ev.code == H2_KEY_PLAY) break;
|
|
usleep(15000);
|
|
}
|
|
|
|
logger = timed_log_init("/data/loot_drop/tether_stream.log", window_durations[sel]);
|
|
lv_obj_del(config_card);
|
|
|
|
console = lv_list_create(scr);
|
|
lv_obj_set_size(console, 300, 160);
|
|
lv_obj_align(console, LV_ALIGN_CENTER, 0, 15);
|
|
|
|
int sysfd = open("/sys/class/net/usb0/operstate", O_WRONLY);
|
|
if (sysfd >= 0) {
|
|
(void)write(sysfd, "up", 2);
|
|
close(sysfd);
|
|
}
|
|
|
|
int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
|
if (sock_raw >= 0) {
|
|
struct ifreq ifr;
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
strncpy(ifr.ifr_name, "usb0", IFNAMSIZ - 1);
|
|
if (ioctl(sock_raw, SIOCGIFINDEX, &ifr) >= 0) {
|
|
fcntl(sock_raw, F_SETFL, O_NONBLOCK);
|
|
lv_obj_t *l = lv_list_add_text(console, "NETTAP ACTIVE: Listening on usb0...");
|
|
lv_obj_set_style_text_color(l, COLOR_ACCENT, LV_PART_MAIN);
|
|
LOG_INF("nettap listening on usb0, flush window: %s", window_labels[sel]);
|
|
}
|
|
}
|
|
|
|
uint8_t pkt_buf[2048];
|
|
|
|
while (1) {
|
|
lv_timer_handler();
|
|
|
|
if (sock_raw >= 0) {
|
|
ssize_t pkt_len = recvfrom(sock_raw, pkt_buf, sizeof(pkt_buf), 0, NULL, NULL);
|
|
if (pkt_len > 0) process_ip_packet(pkt_buf, pkt_len);
|
|
}
|
|
|
|
if (logger && (time(NULL) - logger->window_start >= logger->window_duration))
|
|
timed_log_flush_to_media(logger);
|
|
|
|
if (input_fd >= 0 && read(input_fd, &ev, sizeof(struct input_event)) > 0) {
|
|
if (ev.type == EV_KEY && ev.code == H2_KEY_BACK && ev.value == 1) break;
|
|
}
|
|
usleep(5000);
|
|
}
|
|
|
|
if (logger) timed_log_close(logger);
|
|
if (sock_raw >= 0) close(sock_raw);
|
|
if (input_fd >= 0) close(input_fd);
|
|
LOG_INF("nettap module exited");
|
|
return 0;
|
|
} |