941 lines
30 KiB
C
941 lines
30 KiB
C
/**
|
||
* Phantom Router Firmware - Специализированная прошивка роутера
|
||
*
|
||
* Эта прошивка превращает обычный роутер в Phantom Gateway,
|
||
* обеспечивая прозрачный доступ к Phantom сети для всех
|
||
* подключенных устройств без дополнительной настройки.
|
||
*
|
||
* Совместимость: OpenWrt, DD-WRT, LEDE
|
||
* Автор: Phantom Protocol Team 2025
|
||
* Версия: 1.0.0
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <signal.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
#include <arpa/inet.h>
|
||
#include <pthread.h>
|
||
#include <json-c/json.h>
|
||
#include <curl/curl.h>
|
||
#include <iwinfo.h>
|
||
#include <uci.h>
|
||
|
||
// Включение Phantom DNS Gateway
|
||
#include "../src/phantom_dns_gateway.h"
|
||
|
||
#define PHANTOM_ROUTER_VERSION "1.0.0"
|
||
#define MAX_CONNECTED_DEVICES 254
|
||
#define MAX_SSID_LENGTH 32
|
||
#define MAX_PASSWORD_LENGTH 64
|
||
#define CONFIG_FILE "/etc/phantom/router.conf"
|
||
#define STATUS_FILE "/tmp/phantom_status.json"
|
||
#define LOG_FILE "/var/log/phantom_router.log"
|
||
|
||
// Структура информации об устройстве
|
||
typedef struct {
|
||
char mac_address[18];
|
||
char ip_address[16];
|
||
char hostname[64];
|
||
bool is_phantom_enabled;
|
||
time_t first_seen;
|
||
time_t last_seen;
|
||
uint64_t bytes_sent;
|
||
uint64_t bytes_received;
|
||
} connected_device_t;
|
||
|
||
// Структура конфигурации роутера
|
||
typedef struct {
|
||
// Сетевые настройки
|
||
char wan_interface[16];
|
||
char lan_interface[16];
|
||
char wifi_interface[16];
|
||
|
||
// WiFi настройки
|
||
char ssid[MAX_SSID_LENGTH];
|
||
char password[MAX_PASSWORD_LENGTH];
|
||
char phantom_ssid[MAX_SSID_LENGTH];
|
||
char phantom_password[MAX_PASSWORD_LENGTH];
|
||
bool enable_phantom_wifi;
|
||
|
||
// Phantom настройки
|
||
bool enable_phantom_dns;
|
||
bool auto_discover_nodes;
|
||
char phantom_nodes[10][64];
|
||
int phantom_node_count;
|
||
|
||
// Безопасность
|
||
bool enable_firewall;
|
||
bool block_malicious_domains;
|
||
bool enable_parental_control;
|
||
|
||
// Мониторинг
|
||
bool enable_monitoring;
|
||
uint16_t web_interface_port;
|
||
char admin_password[64];
|
||
} phantom_router_config_t;
|
||
|
||
// Структура состояния роутера
|
||
typedef struct {
|
||
phantom_router_config_t config;
|
||
phantom_dns_gateway_t *dns_gateway;
|
||
connected_device_t devices[MAX_CONNECTED_DEVICES];
|
||
int device_count;
|
||
bool is_running;
|
||
pthread_mutex_t lock;
|
||
|
||
// Статистика
|
||
uint64_t total_dns_queries;
|
||
uint64_t phantom_dns_queries;
|
||
uint64_t blocked_queries;
|
||
time_t start_time;
|
||
} phantom_router_t;
|
||
|
||
// Глобальная переменная роутера
|
||
static phantom_router_t *g_router = NULL;
|
||
|
||
/**
|
||
* Инициализация роутера Phantom
|
||
*/
|
||
phantom_router_t* phantom_router_create(void) {
|
||
phantom_router_t *router = calloc(1, sizeof(phantom_router_t));
|
||
if (!router) {
|
||
fprintf(stderr, "Не удалось выделить память для роутера\n");
|
||
return NULL;
|
||
}
|
||
|
||
// Инициализация мутекса
|
||
pthread_mutex_init(&router->lock, NULL);
|
||
|
||
// Загрузка конфигурации по умолчанию
|
||
phantom_router_load_default_config(&router->config);
|
||
|
||
// Загрузка конфигурации из файла
|
||
phantom_router_load_config(&router->config, CONFIG_FILE);
|
||
|
||
router->start_time = time(NULL);
|
||
router->is_running = false;
|
||
|
||
printf("Phantom Router создан успешно\n");
|
||
return router;
|
||
}
|
||
|
||
/**
|
||
* Загрузка конфигурации по умолчанию
|
||
*/
|
||
void phantom_router_load_default_config(phantom_router_config_t *config) {
|
||
if (!config) return;
|
||
|
||
// Сетевые интерфейсы
|
||
strcpy(config->wan_interface, "eth0");
|
||
strcpy(config->lan_interface, "br-lan");
|
||
strcpy(config->wifi_interface, "wlan0");
|
||
|
||
// WiFi настройки
|
||
strcpy(config->ssid, "Phantom-Router");
|
||
strcpy(config->password, "phantom123");
|
||
strcpy(config->phantom_ssid, "Phantom-Network");
|
||
strcpy(config->phantom_password, "phantom456");
|
||
config->enable_phantom_wifi = true;
|
||
|
||
// Phantom настройки
|
||
config->enable_phantom_dns = true;
|
||
config->auto_discover_nodes = true;
|
||
config->phantom_node_count = 0;
|
||
|
||
// Безопасность
|
||
config->enable_firewall = true;
|
||
config->block_malicious_domains = true;
|
||
config->enable_parental_control = false;
|
||
|
||
// Мониторинг
|
||
config->enable_monitoring = true;
|
||
config->web_interface_port = 8080;
|
||
strcpy(config->admin_password, "admin123");
|
||
}
|
||
|
||
/**
|
||
* Загрузка конфигурации из файла
|
||
*/
|
||
int phantom_router_load_config(phantom_router_config_t *config, const char *config_file) {
|
||
if (!config || !config_file) {
|
||
return -1;
|
||
}
|
||
|
||
FILE *file = fopen(config_file, "r");
|
||
if (!file) {
|
||
printf("Файл конфигурации не найден, используется конфигурация по умолчанию\n");
|
||
return 0;
|
||
}
|
||
|
||
char line[256];
|
||
while (fgets(line, sizeof(line), file)) {
|
||
// Удаление символа новой строки
|
||
line[strcspn(line, "\n")] = 0;
|
||
|
||
// Пропуск комментариев и пустых строк
|
||
if (line[0] == '#' || line[0] == '\0') {
|
||
continue;
|
||
}
|
||
|
||
// Парсинг параметров
|
||
char *key = strtok(line, "=");
|
||
char *value = strtok(NULL, "=");
|
||
|
||
if (!key || !value) {
|
||
continue;
|
||
}
|
||
|
||
// Обработка параметров
|
||
if (strcmp(key, "ssid") == 0) {
|
||
strncpy(config->ssid, value, MAX_SSID_LENGTH - 1);
|
||
} else if (strcmp(key, "password") == 0) {
|
||
strncpy(config->password, value, MAX_PASSWORD_LENGTH - 1);
|
||
} else if (strcmp(key, "phantom_ssid") == 0) {
|
||
strncpy(config->phantom_ssid, value, MAX_SSID_LENGTH - 1);
|
||
} else if (strcmp(key, "phantom_password") == 0) {
|
||
strncpy(config->phantom_password, value, MAX_PASSWORD_LENGTH - 1);
|
||
} else if (strcmp(key, "enable_phantom_dns") == 0) {
|
||
config->enable_phantom_dns = (strcmp(value, "true") == 0);
|
||
} else if (strcmp(key, "web_interface_port") == 0) {
|
||
config->web_interface_port = atoi(value);
|
||
}
|
||
}
|
||
|
||
fclose(file);
|
||
printf("Конфигурация загружена из %s\n", config_file);
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Запуск роутера Phantom
|
||
*/
|
||
int phantom_router_start(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
pthread_mutex_lock(&router->lock);
|
||
|
||
if (router->is_running) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
return 0;
|
||
}
|
||
|
||
printf("Запуск Phantom Router...\n");
|
||
|
||
// Настройка сетевых интерфейсов
|
||
if (phantom_router_setup_network(router) != 0) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
fprintf(stderr, "Не удалось настроить сетевые интерфейсы\n");
|
||
return -1;
|
||
}
|
||
|
||
// Настройка WiFi
|
||
if (phantom_router_setup_wifi(router) != 0) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
fprintf(stderr, "Не удалось настроить WiFi\n");
|
||
return -1;
|
||
}
|
||
|
||
// Запуск Phantom DNS Gateway
|
||
if (router->config.enable_phantom_dns) {
|
||
if (phantom_router_start_dns_gateway(router) != 0) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
fprintf(stderr, "Не удалось запустить Phantom DNS Gateway\n");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
// Запуск веб-интерфейса
|
||
if (router->config.enable_monitoring) {
|
||
if (phantom_router_start_web_interface(router) != 0) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
fprintf(stderr, "Не удалось запустить веб-интерфейс\n");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
// Запуск мониторинга устройств
|
||
if (phantom_router_start_device_monitoring(router) != 0) {
|
||
pthread_mutex_unlock(&router->lock);
|
||
fprintf(stderr, "Не удалось запустить мониторинг устройств\n");
|
||
return -1;
|
||
}
|
||
|
||
router->is_running = true;
|
||
pthread_mutex_unlock(&router->lock);
|
||
|
||
printf("Phantom Router запущен успешно\n");
|
||
printf("WiFi SSID: %s\n", router->config.ssid);
|
||
printf("Phantom SSID: %s\n", router->config.phantom_ssid);
|
||
printf("Веб-интерфейс: http://192.168.1.1:%d\n", router->config.web_interface_port);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Настройка сетевых интерфейсов
|
||
*/
|
||
int phantom_router_setup_network(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Настройка сетевых интерфейсов...\n");
|
||
|
||
// Настройка LAN интерфейса
|
||
char cmd[256];
|
||
snprintf(cmd, sizeof(cmd),
|
||
"ip addr add 192.168.1.1/24 dev %s",
|
||
router->config.lan_interface);
|
||
|
||
if (system(cmd) != 0) {
|
||
fprintf(stderr, "Не удалось настроить LAN интерфейс\n");
|
||
return -1;
|
||
}
|
||
|
||
// Включение IP forwarding
|
||
system("echo 1 > /proc/sys/net/ipv4/ip_forward");
|
||
|
||
// Настройка NAT
|
||
system("iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE");
|
||
system("iptables -A FORWARD -i br-lan -o eth0 -j ACCEPT");
|
||
system("iptables -A FORWARD -i eth0 -o br-lan -m state --state RELATED,ESTABLISHED -j ACCEPT");
|
||
|
||
// Настройка DHCP сервера
|
||
phantom_router_setup_dhcp(router);
|
||
|
||
printf("Сетевые интерфейсы настроены\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Настройка DHCP сервера
|
||
*/
|
||
int phantom_router_setup_dhcp(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Настройка DHCP сервера...\n");
|
||
|
||
// Создание конфигурации dnsmasq
|
||
FILE *dhcp_conf = fopen("/tmp/dnsmasq.conf", "w");
|
||
if (!dhcp_conf) {
|
||
return -1;
|
||
}
|
||
|
||
fprintf(dhcp_conf, "# Phantom Router DHCP Configuration\n");
|
||
fprintf(dhcp_conf, "interface=%s\n", router->config.lan_interface);
|
||
fprintf(dhcp_conf, "dhcp-range=192.168.1.100,192.168.1.200,12h\n");
|
||
fprintf(dhcp_conf, "dhcp-option=3,192.168.1.1\n"); // Gateway
|
||
|
||
// Настройка DNS серверов
|
||
if (router->config.enable_phantom_dns) {
|
||
fprintf(dhcp_conf, "dhcp-option=6,192.168.1.1\n"); // Phantom DNS
|
||
} else {
|
||
fprintf(dhcp_conf, "dhcp-option=6,8.8.8.8,8.8.4.4\n"); // Google DNS
|
||
}
|
||
|
||
fprintf(dhcp_conf, "dhcp-authoritative\n");
|
||
fprintf(dhcp_conf, "log-queries\n");
|
||
|
||
fclose(dhcp_conf);
|
||
|
||
// Запуск dnsmasq
|
||
system("killall dnsmasq 2>/dev/null");
|
||
system("dnsmasq -C /tmp/dnsmasq.conf");
|
||
|
||
printf("DHCP сервер настроен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Настройка WiFi
|
||
*/
|
||
int phantom_router_setup_wifi(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Настройка WiFi...\n");
|
||
|
||
// Создание основной WiFi сети
|
||
if (phantom_router_create_wifi_network(router,
|
||
router->config.ssid,
|
||
router->config.password,
|
||
false) != 0) {
|
||
return -1;
|
||
}
|
||
|
||
// Создание Phantom WiFi сети (если включена)
|
||
if (router->config.enable_phantom_wifi) {
|
||
if (phantom_router_create_wifi_network(router,
|
||
router->config.phantom_ssid,
|
||
router->config.phantom_password,
|
||
true) != 0) {
|
||
fprintf(stderr, "Не удалось создать Phantom WiFi сеть\n");
|
||
// Не критичная ошибка, продолжаем
|
||
}
|
||
}
|
||
|
||
printf("WiFi настроен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Создание WiFi сети
|
||
*/
|
||
int phantom_router_create_wifi_network(phantom_router_t *router,
|
||
const char *ssid,
|
||
const char *password,
|
||
bool is_phantom) {
|
||
if (!router || !ssid || !password) {
|
||
return -1;
|
||
}
|
||
|
||
// Создание конфигурации hostapd
|
||
char conf_file[64];
|
||
snprintf(conf_file, sizeof(conf_file), "/tmp/hostapd_%s.conf",
|
||
is_phantom ? "phantom" : "main");
|
||
|
||
FILE *hostapd_conf = fopen(conf_file, "w");
|
||
if (!hostapd_conf) {
|
||
return -1;
|
||
}
|
||
|
||
fprintf(hostapd_conf, "# %s WiFi Configuration\n", is_phantom ? "Phantom" : "Main");
|
||
fprintf(hostapd_conf, "interface=%s\n", router->config.wifi_interface);
|
||
fprintf(hostapd_conf, "driver=nl80211\n");
|
||
fprintf(hostapd_conf, "ssid=%s\n", ssid);
|
||
fprintf(hostapd_conf, "hw_mode=g\n");
|
||
fprintf(hostapd_conf, "channel=6\n");
|
||
fprintf(hostapd_conf, "wmm_enabled=0\n");
|
||
fprintf(hostapd_conf, "macaddr_acl=0\n");
|
||
fprintf(hostapd_conf, "auth_algs=1\n");
|
||
fprintf(hostapd_conf, "ignore_broadcast_ssid=0\n");
|
||
fprintf(hostapd_conf, "wpa=2\n");
|
||
fprintf(hostapd_conf, "wpa_passphrase=%s\n", password);
|
||
fprintf(hostapd_conf, "wpa_key_mgmt=WPA-PSK\n");
|
||
fprintf(hostapd_conf, "wpa_pairwise=TKIP\n");
|
||
fprintf(hostapd_conf, "rsn_pairwise=CCMP\n");
|
||
|
||
if (is_phantom) {
|
||
// Дополнительные настройки для Phantom сети
|
||
fprintf(hostapd_conf, "# Phantom Network Settings\n");
|
||
fprintf(hostapd_conf, "max_num_sta=50\n");
|
||
fprintf(hostapd_conf, "beacon_int=100\n");
|
||
}
|
||
|
||
fclose(hostapd_conf);
|
||
|
||
// Запуск hostapd
|
||
char cmd[128];
|
||
snprintf(cmd, sizeof(cmd), "hostapd %s -B", conf_file);
|
||
|
||
if (system(cmd) != 0) {
|
||
fprintf(stderr, "Не удалось запустить hostapd для %s\n", ssid);
|
||
return -1;
|
||
}
|
||
|
||
printf("WiFi сеть '%s' создана\n", ssid);
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Запуск Phantom DNS Gateway
|
||
*/
|
||
int phantom_router_start_dns_gateway(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Запуск Phantom DNS Gateway...\n");
|
||
|
||
// Создание конфигурации DNS Gateway
|
||
gateway_config_t dns_config = {0};
|
||
strcpy(dns_config.bind_address, "0.0.0.0");
|
||
dns_config.bind_port = 53;
|
||
dns_config.enable_cache = true;
|
||
dns_config.cache_size = 50000;
|
||
dns_config.default_ttl = 3600;
|
||
dns_config.query_timeout = 5000;
|
||
dns_config.worker_threads = 2;
|
||
dns_config.enable_phantom_fallback = true;
|
||
dns_config.enable_traditional_fallback = true;
|
||
|
||
// Добавление публичных DNS серверов
|
||
for (int i = 0; i < PUBLIC_DNS_COUNT && i < MAX_UPSTREAM_SERVERS; i++) {
|
||
upstream_server_t *server = &dns_config.upstream_servers[dns_config.upstream_count];
|
||
strcpy(server->address, PUBLIC_DNS_SERVERS[i]);
|
||
server->port = 53;
|
||
server->is_phantom = false;
|
||
server->is_available = true;
|
||
dns_config.upstream_count++;
|
||
}
|
||
|
||
// Добавление настроенных Phantom узлов
|
||
for (int i = 0; i < router->config.phantom_node_count; i++) {
|
||
if (dns_config.phantom_count >= MAX_PHANTOM_NODES) break;
|
||
|
||
upstream_server_t *node = &dns_config.phantom_nodes[dns_config.phantom_count];
|
||
strcpy(node->address, router->config.phantom_nodes[i]);
|
||
node->port = 8053;
|
||
node->is_phantom = true;
|
||
node->is_available = true;
|
||
dns_config.phantom_count++;
|
||
}
|
||
|
||
// Создание и запуск DNS Gateway
|
||
router->dns_gateway = phantom_dns_gateway_create(&dns_config);
|
||
if (!router->dns_gateway) {
|
||
return -1;
|
||
}
|
||
|
||
if (phantom_dns_gateway_start(router->dns_gateway) != 0) {
|
||
phantom_dns_gateway_destroy(router->dns_gateway);
|
||
router->dns_gateway = NULL;
|
||
return -1;
|
||
}
|
||
|
||
printf("Phantom DNS Gateway запущен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Запуск веб-интерфейса
|
||
*/
|
||
int phantom_router_start_web_interface(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Запуск веб-интерфейса на порту %d...\n", router->config.web_interface_port);
|
||
|
||
// Создание простого веб-сервера
|
||
pthread_t web_thread;
|
||
if (pthread_create(&web_thread, NULL, phantom_router_web_server_thread, router) != 0) {
|
||
return -1;
|
||
}
|
||
|
||
pthread_detach(web_thread);
|
||
|
||
printf("Веб-интерфейс запущен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Поток веб-сервера
|
||
*/
|
||
void* phantom_router_web_server_thread(void *arg) {
|
||
phantom_router_t *router = (phantom_router_t*)arg;
|
||
|
||
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (server_fd < 0) {
|
||
return NULL;
|
||
}
|
||
|
||
int opt = 1;
|
||
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||
|
||
struct sockaddr_in address;
|
||
address.sin_family = AF_INET;
|
||
address.sin_addr.s_addr = INADDR_ANY;
|
||
address.sin_port = htons(router->config.web_interface_port);
|
||
|
||
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
|
||
close(server_fd);
|
||
return NULL;
|
||
}
|
||
|
||
if (listen(server_fd, 10) < 0) {
|
||
close(server_fd);
|
||
return NULL;
|
||
}
|
||
|
||
while (router->is_running) {
|
||
struct sockaddr_in client_addr;
|
||
socklen_t client_len = sizeof(client_addr);
|
||
|
||
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
|
||
if (client_fd < 0) {
|
||
continue;
|
||
}
|
||
|
||
// Обработка HTTP запроса
|
||
phantom_router_handle_web_request(router, client_fd);
|
||
|
||
close(client_fd);
|
||
}
|
||
|
||
close(server_fd);
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* Обработка веб-запроса
|
||
*/
|
||
void phantom_router_handle_web_request(phantom_router_t *router, int client_fd) {
|
||
if (!router || client_fd < 0) {
|
||
return;
|
||
}
|
||
|
||
char buffer[4096];
|
||
ssize_t received = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
|
||
|
||
if (received <= 0) {
|
||
return;
|
||
}
|
||
|
||
buffer[received] = '\0';
|
||
|
||
// Простой парсинг HTTP запроса
|
||
char method[16], path[256], version[16];
|
||
if (sscanf(buffer, "%s %s %s", method, path, version) != 3) {
|
||
return;
|
||
}
|
||
|
||
// Генерация ответа
|
||
char response[8192];
|
||
char content[4096];
|
||
|
||
if (strcmp(path, "/") == 0 || strcmp(path, "/index.html") == 0) {
|
||
phantom_router_generate_main_page(router, content, sizeof(content));
|
||
} else if (strcmp(path, "/status") == 0) {
|
||
phantom_router_generate_status_page(router, content, sizeof(content));
|
||
} else if (strcmp(path, "/devices") == 0) {
|
||
phantom_router_generate_devices_page(router, content, sizeof(content));
|
||
} else if (strcmp(path, "/api/status") == 0) {
|
||
phantom_router_generate_status_json(router, content, sizeof(content));
|
||
} else {
|
||
strcpy(content, "<html><body><h1>404 Not Found</h1></body></html>");
|
||
}
|
||
|
||
snprintf(response, sizeof(response),
|
||
"HTTP/1.1 200 OK\r\n"
|
||
"Content-Type: text/html\r\n"
|
||
"Content-Length: %zu\r\n"
|
||
"Connection: close\r\n"
|
||
"\r\n"
|
||
"%s", strlen(content), content);
|
||
|
||
send(client_fd, response, strlen(response), 0);
|
||
}
|
||
|
||
/**
|
||
* Генерация главной страницы
|
||
*/
|
||
void phantom_router_generate_main_page(phantom_router_t *router, char *content, size_t size) {
|
||
if (!router || !content) {
|
||
return;
|
||
}
|
||
|
||
time_t uptime = time(NULL) - router->start_time;
|
||
int hours = uptime / 3600;
|
||
int minutes = (uptime % 3600) / 60;
|
||
|
||
snprintf(content, size,
|
||
"<!DOCTYPE html>\n"
|
||
"<html>\n"
|
||
"<head>\n"
|
||
" <title>Phantom Router</title>\n"
|
||
" <meta charset=\"utf-8\">\n"
|
||
" <style>\n"
|
||
" body { font-family: Arial, sans-serif; margin: 20px; }\n"
|
||
" .header { background: #2c3e50; color: white; padding: 20px; border-radius: 5px; }\n"
|
||
" .status { background: #ecf0f1; padding: 15px; margin: 10px 0; border-radius: 5px; }\n"
|
||
" .phantom-active { color: #27ae60; font-weight: bold; }\n"
|
||
" .phantom-inactive { color: #e74c3c; font-weight: bold; }\n"
|
||
" </style>\n"
|
||
"</head>\n"
|
||
"<body>\n"
|
||
" <div class=\"header\">\n"
|
||
" <h1>🌐 Phantom Router</h1>\n"
|
||
" <p>Версия %s | Время работы: %d ч %d мин</p>\n"
|
||
" </div>\n"
|
||
" \n"
|
||
" <div class=\"status\">\n"
|
||
" <h2>Состояние системы</h2>\n"
|
||
" <p>WiFi SSID: <strong>%s</strong></p>\n"
|
||
" <p>Phantom SSID: <strong>%s</strong></p>\n"
|
||
" <p>Phantom DNS: <span class=\"%s\">%s</span></p>\n"
|
||
" <p>Подключенных устройств: <strong>%d</strong></p>\n"
|
||
" <p>DNS запросов: <strong>%llu</strong></p>\n"
|
||
" <p>Phantom запросов: <strong>%llu</strong></p>\n"
|
||
" </div>\n"
|
||
" \n"
|
||
" <div class=\"status\">\n"
|
||
" <h2>Навигация</h2>\n"
|
||
" <p><a href=\"/status\">Подробный статус</a></p>\n"
|
||
" <p><a href=\"/devices\">Подключенные устройства</a></p>\n"
|
||
" <p><a href=\"/api/status\">API статус (JSON)</a></p>\n"
|
||
" </div>\n"
|
||
" \n"
|
||
" <div class=\"status\">\n"
|
||
" <h2>Как подключиться к Phantom сети</h2>\n"
|
||
" <ol>\n"
|
||
" <li>Подключитесь к WiFi сети <strong>%s</strong></li>\n"
|
||
" <li>Используйте пароль: <strong>%s</strong></li>\n"
|
||
" <li>Все .phantom домены будут работать автоматически!</li>\n"
|
||
" </ol>\n"
|
||
" <p><em>Никаких дополнительных настроек не требуется</em></p>\n"
|
||
" </div>\n"
|
||
"</body>\n"
|
||
"</html>",
|
||
PHANTOM_ROUTER_VERSION, hours, minutes,
|
||
router->config.ssid,
|
||
router->config.phantom_ssid,
|
||
router->config.enable_phantom_dns ? "phantom-active" : "phantom-inactive",
|
||
router->config.enable_phantom_dns ? "АКТИВЕН" : "НЕАКТИВЕН",
|
||
router->device_count,
|
||
router->total_dns_queries,
|
||
router->phantom_dns_queries,
|
||
router->config.phantom_ssid,
|
||
router->config.phantom_password);
|
||
}
|
||
|
||
/**
|
||
* Запуск мониторинга устройств
|
||
*/
|
||
int phantom_router_start_device_monitoring(phantom_router_t *router) {
|
||
if (!router) {
|
||
return -1;
|
||
}
|
||
|
||
printf("Запуск мониторинга устройств...\n");
|
||
|
||
pthread_t monitor_thread;
|
||
if (pthread_create(&monitor_thread, NULL, phantom_router_device_monitor_thread, router) != 0) {
|
||
return -1;
|
||
}
|
||
|
||
pthread_detach(monitor_thread);
|
||
|
||
printf("Мониторинг устройств запущен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Поток мониторинга устройств
|
||
*/
|
||
void* phantom_router_device_monitor_thread(void *arg) {
|
||
phantom_router_t *router = (phantom_router_t*)arg;
|
||
|
||
while (router->is_running) {
|
||
// Сканирование ARP таблицы для обнаружения устройств
|
||
phantom_router_scan_connected_devices(router);
|
||
|
||
// Обновление статистики
|
||
phantom_router_update_device_stats(router);
|
||
|
||
// Сохранение статуса в файл
|
||
phantom_router_save_status(router);
|
||
|
||
// Ожидание 30 секунд
|
||
sleep(30);
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* Сканирование подключенных устройств
|
||
*/
|
||
void phantom_router_scan_connected_devices(phantom_router_t *router) {
|
||
if (!router) {
|
||
return;
|
||
}
|
||
|
||
FILE *arp_file = fopen("/proc/net/arp", "r");
|
||
if (!arp_file) {
|
||
return;
|
||
}
|
||
|
||
char line[256];
|
||
// Пропускаем заголовок
|
||
fgets(line, sizeof(line), arp_file);
|
||
|
||
pthread_mutex_lock(&router->lock);
|
||
|
||
// Сброс счетчика устройств
|
||
router->device_count = 0;
|
||
|
||
while (fgets(line, sizeof(line), arp_file) && router->device_count < MAX_CONNECTED_DEVICES) {
|
||
char ip[16], hw_type[8], flags[8], mac[18], mask[8], device[16];
|
||
|
||
if (sscanf(line, "%s %s %s %s %s %s", ip, hw_type, flags, mac, mask, device) == 6) {
|
||
// Проверка, что это не пустая запись
|
||
if (strcmp(mac, "00:00:00:00:00:00") != 0) {
|
||
connected_device_t *dev = &router->devices[router->device_count];
|
||
|
||
strcpy(dev->ip_address, ip);
|
||
strcpy(dev->mac_address, mac);
|
||
dev->last_seen = time(NULL);
|
||
|
||
// Попытка получить hostname
|
||
phantom_router_get_device_hostname(dev);
|
||
|
||
router->device_count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
pthread_mutex_unlock(&router->lock);
|
||
fclose(arp_file);
|
||
}
|
||
|
||
/**
|
||
* Получение hostname устройства
|
||
*/
|
||
void phantom_router_get_device_hostname(connected_device_t *device) {
|
||
if (!device) {
|
||
return;
|
||
}
|
||
|
||
// Попытка reverse DNS lookup
|
||
struct sockaddr_in addr;
|
||
addr.sin_family = AF_INET;
|
||
inet_pton(AF_INET, device->ip_address, &addr.sin_addr);
|
||
|
||
char hostname[64];
|
||
if (getnameinfo((struct sockaddr*)&addr, sizeof(addr),
|
||
hostname, sizeof(hostname), NULL, 0, 0) == 0) {
|
||
strcpy(device->hostname, hostname);
|
||
} else {
|
||
strcpy(device->hostname, "Unknown");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Сохранение статуса в файл
|
||
*/
|
||
void phantom_router_save_status(phantom_router_t *router) {
|
||
if (!router) {
|
||
return;
|
||
}
|
||
|
||
json_object *status = json_object_new_object();
|
||
json_object *timestamp = json_object_new_int64(time(NULL));
|
||
json_object *uptime = json_object_new_int64(time(NULL) - router->start_time);
|
||
json_object *device_count = json_object_new_int(router->device_count);
|
||
json_object *dns_queries = json_object_new_int64(router->total_dns_queries);
|
||
json_object *phantom_queries = json_object_new_int64(router->phantom_dns_queries);
|
||
|
||
json_object_object_add(status, "timestamp", timestamp);
|
||
json_object_object_add(status, "uptime", uptime);
|
||
json_object_object_add(status, "device_count", device_count);
|
||
json_object_object_add(status, "dns_queries", dns_queries);
|
||
json_object_object_add(status, "phantom_queries", phantom_queries);
|
||
|
||
// Сохранение в файл
|
||
FILE *status_file = fopen(STATUS_FILE, "w");
|
||
if (status_file) {
|
||
fprintf(status_file, "%s\n", json_object_to_json_string(status));
|
||
fclose(status_file);
|
||
}
|
||
|
||
json_object_put(status);
|
||
}
|
||
|
||
/**
|
||
* Обработчик сигналов
|
||
*/
|
||
void phantom_router_signal_handler(int signal) {
|
||
if (g_router) {
|
||
printf("\nПолучен сигнал %d, остановка роутера...\n", signal);
|
||
g_router->is_running = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Главная функция
|
||
*/
|
||
int main(int argc, char *argv[]) {
|
||
printf("Phantom Router v%s\n", PHANTOM_ROUTER_VERSION);
|
||
printf("Специализированная прошивка роутера для Phantom Protocol\n\n");
|
||
|
||
// Проверка прав root
|
||
if (getuid() != 0) {
|
||
fprintf(stderr, "Ошибка: Требуются права root для запуска\n");
|
||
return 1;
|
||
}
|
||
|
||
// Создание роутера
|
||
g_router = phantom_router_create();
|
||
if (!g_router) {
|
||
fprintf(stderr, "Не удалось создать роутер\n");
|
||
return 1;
|
||
}
|
||
|
||
// Установка обработчиков сигналов
|
||
signal(SIGINT, phantom_router_signal_handler);
|
||
signal(SIGTERM, phantom_router_signal_handler);
|
||
|
||
// Запуск роутера
|
||
if (phantom_router_start(g_router) != 0) {
|
||
fprintf(stderr, "Не удалось запустить роутер\n");
|
||
phantom_router_destroy(g_router);
|
||
return 1;
|
||
}
|
||
|
||
printf("\n=== Phantom Router запущен ===\n");
|
||
printf("Веб-интерфейс: http://192.168.1.1:%d\n", g_router->config.web_interface_port);
|
||
printf("Нажмите Ctrl+C для остановки\n\n");
|
||
|
||
// Основной цикл
|
||
while (g_router->is_running) {
|
||
sleep(1);
|
||
}
|
||
|
||
// Остановка и очистка
|
||
printf("Остановка роутера...\n");
|
||
phantom_router_stop(g_router);
|
||
phantom_router_destroy(g_router);
|
||
|
||
printf("Phantom Router остановлен\n");
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Остановка роутера
|
||
*/
|
||
void phantom_router_stop(phantom_router_t *router) {
|
||
if (!router) {
|
||
return;
|
||
}
|
||
|
||
pthread_mutex_lock(&router->lock);
|
||
router->is_running = false;
|
||
pthread_mutex_unlock(&router->lock);
|
||
|
||
// Остановка DNS Gateway
|
||
if (router->dns_gateway) {
|
||
phantom_dns_gateway_stop(router->dns_gateway);
|
||
}
|
||
|
||
// Остановка сетевых сервисов
|
||
system("killall hostapd 2>/dev/null");
|
||
system("killall dnsmasq 2>/dev/null");
|
||
}
|
||
|
||
/**
|
||
* Уничтожение роутера
|
||
*/
|
||
void phantom_router_destroy(phantom_router_t *router) {
|
||
if (!router) {
|
||
return;
|
||
}
|
||
|
||
if (router->dns_gateway) {
|
||
phantom_dns_gateway_destroy(router->dns_gateway);
|
||
}
|
||
|
||
pthread_mutex_destroy(&router->lock);
|
||
free(router);
|
||
}
|
||
|