diff --git a/blockip/bip b/blockip/bip index c4d1000..8444be5 100644 Binary files a/blockip/bip and b/blockip/bip differ diff --git a/blockip/include/install.h b/blockip/include/install.h index 1b01171..f3c86d2 100644 --- a/blockip/include/install.h +++ b/blockip/include/install.h @@ -2,6 +2,7 @@ #define INSTALL_H #include "common.h" +#include /* 安装服务 */ int install_service(void); diff --git a/blockip/src/install.c b/blockip/src/install.c index b1583a7..e09d14c 100644 --- a/blockip/src/install.c +++ b/blockip/src/install.c @@ -116,19 +116,29 @@ int install_service(void) { if (len != -1) { exe_path[len] = '\0'; - char copy_cmd[MAX_COMMAND_LEN]; - snprintf(copy_cmd, sizeof(copy_cmd), "cp -f %s %s && chmod +x %s", - exe_path, INSTALL_PATH, INSTALL_PATH); - system(copy_cmd); + FILE *src = fopen(exe_path, "rb"); + FILE *dst = fopen(INSTALL_PATH, "wb"); + if (src && dst) { + char buf[8192]; + size_t n; + while ((n = fread(buf, 1, sizeof(buf), src)) > 0) { + fwrite(buf, 1, n, dst); + } + fclose(src); + fclose(dst); + chmod(INSTALL_PATH, 0755); + } else { + if (src) fclose(src); + if (dst) fclose(dst); + } } /* 创建必要的目录和文件 */ - char mkdir_cmd[MAX_COMMAND_LEN]; - snprintf(mkdir_cmd, sizeof(mkdir_cmd), "mkdir -p %s && chmod 700 %s", CONFIG_DIR, CONFIG_DIR); - system(mkdir_cmd); + mkdir(CONFIG_DIR, 0700); + chmod(CONFIG_DIR, 0700); - snprintf(mkdir_cmd, sizeof(mkdir_cmd), "mkdir -p %s && chmod 770 %s", RECORD_DIR, RECORD_DIR); - system(mkdir_cmd); + mkdir(RECORD_DIR, 0770); + chmod(RECORD_DIR, 0770); FILE *fp = fopen(PERSIST_FILE, "a"); if (fp) { diff --git a/blockip/src/stats.c b/blockip/src/stats.c index a59349b..49308b5 100644 --- a/blockip/src/stats.c +++ b/blockip/src/stats.c @@ -81,6 +81,20 @@ void show_active_bans(void) { printf("\n"); } +/* 检查段idx是否会被更精确的段取代(相同count但更小mask) */ +static inline bool is_agg_replaced(void *agg_array, int agg_count, int idx) { + struct agg_entry { char subnet[64]; int count; int mask; }; + struct agg_entry *agg = (struct agg_entry *)agg_array; + + for (int j = 0; j < agg_count; ++j) { + if (agg[j].mask > agg[idx].mask && agg[j].count == agg[idx].count && + strncmp(agg[j].subnet, agg[idx].subnet, strlen(agg[idx].subnet)) == 0) { + return true; + } + } + return false; +} + void show_subnet_aggregation(void) { msg(C_CYAN, "=== 📊 攻击源聚合统计 (自动识别 IP 段) ==="); @@ -192,38 +206,20 @@ void show_subnet_aggregation(void) { int aggregated_count = 0; for (int i = 0; i < agg_count && show_count < 10; ++i) { - if (agg[i].count < 2) continue; - - /* 检查是否被更精确的段取代(相同count但更小mask) */ - bool replaced = false; - for (int j = 0; j < agg_count; ++j) { - if (agg[j].mask > agg[i].mask && agg[j].count == agg[i].count && - strncmp(agg[j].subnet, agg[i].subnet, strlen(agg[i].subnet)) == 0) { - replaced = true; - break; - } + if (agg[i].count < 2 || is_agg_replaced(agg, agg_count, i)) { + continue; } - if (replaced) continue; has_output = true; /* 检查是否被已显示的更大段覆盖,避免重复计数 */ bool covered = false; for (int k = 0; k < i; ++k) { - if (agg[k].count >= 2 && agg[k].mask < agg[i].mask) { - /* 检查k是否也被取代 */ - bool k_replaced = false; - for (int m = 0; m < agg_count; ++m) { - if (agg[m].mask > agg[k].mask && agg[m].count == agg[k].count && - strncmp(agg[m].subnet, agg[k].subnet, strlen(agg[k].subnet)) == 0) { - k_replaced = true; - break; - } - } - if (!k_replaced && strncmp(agg[i].subnet, agg[k].subnet, strlen(agg[k].subnet)) == 0) { - covered = true; - break; - } + if (agg[k].count >= 2 && agg[k].mask < agg[i].mask && + !is_agg_replaced(agg, agg_count, k) && + strncmp(agg[i].subnet, agg[k].subnet, strlen(agg[k].subnet)) == 0) { + covered = true; + break; } } @@ -256,14 +252,13 @@ void show_subnet_aggregation(void) { } int scattered_count = total_ipv4 - aggregated_count; - if (!has_output) { + /* 显示散乱IP */ + if (scattered_count > 0 || (!has_output && total_ipv4 > 0)) { if (scattered_count > 0) { printf(" - (散乱 IPv4) (%d 个)\n", scattered_count); - } else if (total_ipv4 > 0) { + } else { printf(" - (散乱 IPv4)\n"); } - } else if (scattered_count > 0) { - printf(" - (散乱 IPv4) (%d 个)\n", scattered_count); } if (v6_count > 0) {