20250423
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -10,6 +10,7 @@
|
||||
"cache.h": "c",
|
||||
"errno.h": "c",
|
||||
"stdlib.h": "c",
|
||||
"string.h": "c"
|
||||
"string.h": "c",
|
||||
"stat.h": "c"
|
||||
}
|
||||
}
|
||||
25
cache.c
25
cache.c
@@ -1,6 +1,5 @@
|
||||
#include "cache.h"
|
||||
|
||||
|
||||
struct ip_cache_node *ip_cache_head = NULL; // 缓存链表的头节点
|
||||
int cache_size = 0; // 当前缓存中的 IP 数量
|
||||
|
||||
@@ -27,7 +26,6 @@ void add_ip_to_cache(const char *ip)
|
||||
free(current);
|
||||
cache_size--;
|
||||
}
|
||||
|
||||
// 创建新的缓存节点并添加到链表头部
|
||||
struct ip_cache_node *new_node = (struct ip_cache_node *)malloc(sizeof(struct ip_cache_node));
|
||||
if (new_node == NULL) {
|
||||
@@ -48,7 +46,8 @@ int is_ip_in_cache(const char *ip)
|
||||
struct ip_cache_node *current = ip_cache_head;
|
||||
struct ip_cache_node *prev = NULL;
|
||||
|
||||
if (ip_cache_head == NULL) return 0; // 如果 ip_cache_head == NULL,current->next 可能导致段错误 (Segmentation Fault)。
|
||||
if (ip_cache_head == NULL)
|
||||
return 0; // 如果 ip_cache_head == NULL,current->next 可能导致段错误 (Segmentation Fault)。
|
||||
|
||||
while (current != NULL) {
|
||||
// 如果 IP 匹配并且未过期
|
||||
@@ -89,8 +88,6 @@ void free_ip_cache()
|
||||
cache_size = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 };
|
||||
|
||||
// 添加一个 IP 到集合(如果已存在则不添加)
|
||||
@@ -133,20 +130,38 @@ int is_ip_in_set(char cn_ip[MAXIPSET_][MAXIPLEN], const char *ip)
|
||||
int cn_ip_len(char cn_ip[MAXIPSET_][MAXIPLEN])
|
||||
{
|
||||
int count = 0; // 用于计数非空IP
|
||||
|
||||
for (int i = 0; i < MAXIPSET_; i++) {
|
||||
if (cn_ip[i][0] != '\0') {
|
||||
count++; // 非空IP计数
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int truncate_file(const char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
// 以只写模式打开文件并截断到0字节
|
||||
fd = open(path, O_WRONLY | O_TRUNC);
|
||||
if (fd == -1) {
|
||||
perror("truncate_file: Failed to open file");
|
||||
return -1;
|
||||
}
|
||||
// 关闭文件描述符(此时文件已被截断)
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 安全的清理IP地址集合,将所有位置置为空字符串
|
||||
void clear_ip_set(char cn_ip[MAXIPSET_][MAXIPLEN])
|
||||
{
|
||||
if (cn_ip == NULL) {
|
||||
return; // 如果指针无效,则直接返回
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAXIPSET_; i++) {
|
||||
memset(cn_ip[i], '\0', MAXIPLEN);
|
||||
}
|
||||
|
||||
7
cache.h
7
cache.h
@@ -18,6 +18,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
@@ -25,7 +29,7 @@
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXIPSET_ 10240
|
||||
#define MAXIPSET_ 65535
|
||||
#define MAXIPLEN 32
|
||||
|
||||
#define CACHE_TTL 180 // 设定缓存的存活时间为 600 秒 (10 分钟)
|
||||
@@ -54,5 +58,6 @@ extern int append_string_to_file(const char *filepath, const char *str);
|
||||
extern int read_file_to_array(const char *filepath, char cn_ip[MAXIPSET_][MAXIPLEN], int *line_count);
|
||||
|
||||
extern int file_exists_access(const char *filepath);
|
||||
extern int truncate_file(const char *path);
|
||||
|
||||
#endif
|
||||
|
||||
16
cap.c
16
cap.c
@@ -4,7 +4,6 @@
|
||||
#include "libcurl.h"
|
||||
#include "cache.h"
|
||||
|
||||
|
||||
pcap_if_t *alldevs, *device;
|
||||
pcap_t *handle; // 会话句柄
|
||||
struct bpf_program fp; // 编译后的过滤器
|
||||
@@ -16,14 +15,11 @@ int shmid = -1;
|
||||
int RULE_NAME_NUMBER = 0; // ipset 集合集合数
|
||||
char *RULE_NAME = NULL; // 共享内存
|
||||
|
||||
|
||||
char *ip2region_area = NULL; // ip2region 解析结果
|
||||
char *command_result = NULL; // 执行命令的结果
|
||||
|
||||
|
||||
void Processing_IP_addresses(char *src_ip)
|
||||
{
|
||||
|
||||
// 地域白名单
|
||||
char _region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } };
|
||||
char _REGION_LIST[BUFFER] = { 0 };
|
||||
@@ -53,8 +49,9 @@ void Processing_IP_addresses(char *src_ip)
|
||||
printf("%s ", cn_ip[i]);
|
||||
}
|
||||
}
|
||||
if (cn_ip_len(cn_ip) >= 1024) { // 清理集合
|
||||
if (cn_ip_len(cn_ip) >= 10240) { // 清理集合
|
||||
clear_ip_set(cn_ip);
|
||||
truncate_file("cn.txt"); // 清空文件
|
||||
}
|
||||
|
||||
printf("cn_ip_len(cn_ip): %d\n", cn_ip_len(cn_ip));
|
||||
@@ -98,7 +95,9 @@ void Processing_IP_addresses(char *src_ip)
|
||||
_printf(RED "CurlGetIpArea(): %s %s\n" REDEND, src_ip, response.continent_country);
|
||||
add_ip_to_ipset(RULE_NAME, src_ip);
|
||||
} else { // 这时是国内IP
|
||||
add_cn_ip(cn_ip, src_ip); // 添加国内IP到缓存
|
||||
if (-1 == add_cn_ip(cn_ip, src_ip)) { // 添加国内IP到缓存
|
||||
_printf(RED "add_cn_ip() Error!!! 错误:集合已满\n" REDEND);
|
||||
}
|
||||
_printf("IP: %s 离线库为国外, API 判断为国内, 标记为已处理!!!\n", src_ip);
|
||||
|
||||
if (append_string_to_file("cn.txt", src_ip) != 0) {
|
||||
@@ -128,12 +127,11 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
|
||||
int ethernet_header_len = 14;
|
||||
//struct ip *ip_header = (struct ip *)(packet + ethernet_header_len);
|
||||
struct ip *ip_header = (struct ip *)(packet + ethernet_header_len);
|
||||
if (ip_header->ip_v != 4) return; // 只处理 IPv4
|
||||
if (ip_header->ip_v != 4)
|
||||
return; // 只处理 IPv4
|
||||
|
||||
char src_ip[INET_ADDRSTRLEN] = { 0 };
|
||||
|
||||
|
||||
|
||||
inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN);
|
||||
Processing_IP_addresses(src_ip);
|
||||
|
||||
|
||||
35
common.c
35
common.c
@@ -1,7 +1,8 @@
|
||||
#include "common.h"
|
||||
|
||||
// 计算字符串长度
|
||||
int _strlen(const char *str) {
|
||||
int _strlen(const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -9,7 +10,6 @@ int _strlen(const char *str) {
|
||||
return _p - str;
|
||||
}
|
||||
|
||||
|
||||
// 自定义 printf 函数
|
||||
void _printf(const char *format, ...)
|
||||
{
|
||||
@@ -60,8 +60,7 @@ void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_I
|
||||
temp[sizeof(temp) - 1] = '\0'; // 确保字符串以 '\0' 结尾
|
||||
|
||||
result = strtok(temp, delims); // 使用副本进行拆分
|
||||
while (result != NULL && i < WHITELIST_IP_NUM)
|
||||
{
|
||||
while (result != NULL && i < WHITELIST_IP_NUM) {
|
||||
strncpy(whitelist_ip[i], result, WHITELIST_IP_NUM - 1);
|
||||
whitelist_ip[i][WHITELIST_IP_NUM - 1] = '\0'; // 确保每个元素以 '\0' 结尾
|
||||
i++;
|
||||
@@ -79,7 +78,6 @@ int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
|
||||
if (whitelist_ip[i][0] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
// 对比 client_ip 的前缀是否与白名单中的IP段匹配
|
||||
if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) {
|
||||
return 1; // 匹配成功
|
||||
@@ -100,7 +98,6 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
|
||||
if (region_list[i][0] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
// 在str中查找 region_list[i]
|
||||
p = strstr(str, region_list[i]);
|
||||
if (p != NULL) {
|
||||
@@ -123,7 +120,8 @@ int8_t _copy_new_mem(char *src, int src_len, char **dest)
|
||||
}
|
||||
|
||||
// 返回的时间字符串存储在静态缓冲区中
|
||||
char *_time() {
|
||||
char *_time()
|
||||
{
|
||||
static char temp[BUFFER];
|
||||
const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
time_t t = time(NULL);
|
||||
@@ -134,9 +132,7 @@ char *_time() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(temp, sizeof(temp), "[%d/%02d/%02d %s %02d:%02d:%02d]",
|
||||
1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday,
|
||||
wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
|
||||
snprintf(temp, sizeof(temp), "[%d/%02d/%02d %s %02d:%02d:%02d]", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
|
||||
|
||||
return temp; // 返回静态缓冲区地址
|
||||
}
|
||||
@@ -152,7 +148,8 @@ int is_valid_ip(const char *ip)
|
||||
}
|
||||
|
||||
// 修改进程优先级
|
||||
int _nice(int increment) {
|
||||
int _nice(int increment)
|
||||
{
|
||||
// 获取当前优先级
|
||||
int oldprio = getpriority(PRIO_PROCESS, getpid());
|
||||
if (oldprio == -1 && errno != 0) {
|
||||
@@ -163,12 +160,10 @@ int _nice(int increment) {
|
||||
printf("Current priority: %d\n", oldprio);
|
||||
|
||||
// 检查是否溢出
|
||||
if ((increment > 0 && oldprio > INT_MAX - increment) ||
|
||||
(increment < 0 && oldprio < INT_MIN - increment)) {
|
||||
if ((increment > 0 && oldprio > INT_MAX - increment) || (increment < 0 && oldprio < INT_MIN - increment)) {
|
||||
fprintf(stderr, "Priority overflow error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 计算新的优先级
|
||||
int newprio = oldprio + increment;
|
||||
|
||||
@@ -177,7 +172,6 @@ int _nice(int increment) {
|
||||
fprintf(stderr, "New priority out of range: %d (valid range is %d to %d)\n", newprio, PRIO_MIN, PRIO_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 设置新的优先级
|
||||
if (setpriority(PRIO_PROCESS, getpid(), newprio) == -1) {
|
||||
perror("setpriority failed");
|
||||
@@ -189,7 +183,8 @@ int _nice(int increment) {
|
||||
}
|
||||
|
||||
// 判断命令是否存在
|
||||
int _command_exists(const char *command) {
|
||||
int _command_exists(const char *command)
|
||||
{
|
||||
const char *path_env = getenv("PATH");
|
||||
if (!path_env) {
|
||||
return 0; // 如果 PATH 不存在,返回不存在
|
||||
@@ -207,13 +202,11 @@ int _command_exists(const char *command) {
|
||||
if (snprintf(filepath, sizeof(filepath), "%.*s/%s", (int)len, dir, command) >= (int)sizeof(filepath)) {
|
||||
return 0; // 缓冲区溢出,返回不存在
|
||||
}
|
||||
|
||||
// 检查文件是否存在且可执行
|
||||
if (access(filepath, X_OK) == 0) {
|
||||
puts(filepath);
|
||||
return 1; // 命令存在
|
||||
}
|
||||
|
||||
// 更新 dir 指针
|
||||
dir = end ? end + 1 : NULL;
|
||||
}
|
||||
@@ -222,7 +215,8 @@ int _command_exists(const char *command) {
|
||||
}
|
||||
|
||||
// 执行命令并返回输出
|
||||
char *_execute_command(const char *command) {
|
||||
char *_execute_command(const char *command)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[1024];
|
||||
char *output = NULL;
|
||||
@@ -235,7 +229,6 @@ char *_execute_command(const char *command) {
|
||||
perror("popen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 读取命令的输出
|
||||
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
||||
size_t len = strlen(buffer);
|
||||
@@ -259,7 +252,6 @@ char *_execute_command(const char *command) {
|
||||
if (output_size > 0) {
|
||||
output[total_read] = '\0';
|
||||
}
|
||||
|
||||
// 关闭管道
|
||||
if (pclose(fp) == -1) {
|
||||
perror("pclose");
|
||||
@@ -281,4 +273,3 @@ void remove_char(char *str, char c)
|
||||
}
|
||||
str[j] = '\0';
|
||||
}
|
||||
|
||||
|
||||
1
common.h
1
common.h
@@ -27,7 +27,6 @@
|
||||
#define BUFFER 1024
|
||||
#define WHITELIST_IP_NUM 1024
|
||||
|
||||
|
||||
extern char *_time();
|
||||
extern int _strlen(const char *str);
|
||||
extern void _printf(const char *format, ...);
|
||||
|
||||
11
libcurl.c
11
libcurl.c
@@ -1,6 +1,5 @@
|
||||
#include "libcurl.h"
|
||||
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
@@ -101,7 +100,6 @@ char *CurlGetIpArea(char *ip)
|
||||
char url[256] = { 0 };
|
||||
snprintf(url, sizeof(url), "https://qifu.baidu.com/ip/geo/v1/district?ip=%s", ip);
|
||||
|
||||
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
|
||||
@@ -169,7 +167,8 @@ char *CurlGetIpArea(char *ip)
|
||||
}
|
||||
|
||||
// 函数用于从 cJSON 对象提取字段内容
|
||||
void parse_string_field(cJSON *parent, const char *field_name, char *output, size_t max_len) {
|
||||
void parse_string_field(cJSON *parent, const char *field_name, char *output, size_t max_len)
|
||||
{
|
||||
cJSON *item = cJSON_GetObjectItemCaseSensitive(parent, field_name);
|
||||
if (cJSON_IsString(item) && item->valuestring) {
|
||||
strncpy(output, item->valuestring, max_len - 1);
|
||||
@@ -186,7 +185,6 @@ int parse_json_to_struct(const char *json_string, Response *response)
|
||||
fprintf(stderr, "Invalid input parameters!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 初始化结构体
|
||||
memset(response, 0, sizeof(Response));
|
||||
|
||||
@@ -196,7 +194,6 @@ int parse_json_to_struct(const char *json_string, Response *response)
|
||||
fprintf(stderr, "Error parsing JSON: %s\n", cJSON_GetErrorPtr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 解析字段
|
||||
parse_string_field(root, "code", response->code, sizeof(response->code));
|
||||
parse_string_field(root, "ip", response->ip, sizeof(response->ip));
|
||||
@@ -207,7 +204,6 @@ int parse_json_to_struct(const char *json_string, Response *response)
|
||||
cJSON_Delete(root);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 解析 data 对象
|
||||
cJSON *data_item = cJSON_GetObjectItemCaseSensitive(root, "data");
|
||||
if (cJSON_IsObject(data_item)) {
|
||||
@@ -222,12 +218,10 @@ int parse_json_to_struct(const char *json_string, Response *response)
|
||||
parse_string_field(data_item, "district", response->data.district, sizeof(response->data.district));
|
||||
parse_string_field(data_item, "region", response->data.region, sizeof(response->data.region));
|
||||
}
|
||||
|
||||
// ----------- 拼接 continent_country ---------------
|
||||
if (snprintf(response->continent_country, sizeof(response->continent_country), "%s%s", response->data.continent, response->data.country) >= sizeof(response->continent_country)) {
|
||||
fprintf(stderr, "continent_country truncated!\n");
|
||||
}
|
||||
|
||||
//snprintf(response->continent_country, 256, "%s%s", response->data.continent, response->data.country);
|
||||
|
||||
// 清理 JSON 对象
|
||||
@@ -235,7 +229,6 @@ int parse_json_to_struct(const char *json_string, Response *response)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@@ -42,11 +42,8 @@ typedef struct {
|
||||
char continent_country[256];
|
||||
} Response;
|
||||
|
||||
|
||||
extern char *CurlGetIpArea(char *ip);
|
||||
extern char *GetLocalAddr(char *url);
|
||||
extern int parse_json_to_struct(const char *json_string, Response * response);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -86,14 +86,12 @@ int create_ipset(char *set_name)
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 设置自定义错误和输出处理函数
|
||||
if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) {
|
||||
fprintf(stderr, "设置自定义打印函数失败。\n");
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 创建集合
|
||||
char *args[] = { "ipset", "create", set_name, "hash:ip", NULL };
|
||||
if (ipset_parse_argv(ipset, 4, args) != 0) {
|
||||
@@ -101,7 +99,6 @@ int create_ipset(char *set_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ipset_fini(ipset);
|
||||
|
||||
return 0;
|
||||
@@ -135,14 +132,12 @@ int add_ip_to_ipset(char *set_name, char *ip)
|
||||
ipset_fini(ipset);
|
||||
return -1; // 返回 -1,但不退出
|
||||
}
|
||||
|
||||
// 设置自定义错误和输出处理函数
|
||||
if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) {
|
||||
fprintf(stderr, "设置自定义打印函数失败。\n");
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 将ip添加到集合
|
||||
char *args[] = { "ipset", "add", set_name, ip, NULL };
|
||||
if (ipset_parse_argv(ipset, 4, args) != 0) {
|
||||
@@ -150,7 +145,6 @@ int add_ip_to_ipset(char *set_name, char *ip)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ipset_fini(ipset);
|
||||
|
||||
return 0; // 始终返回 0,表示执行成功
|
||||
@@ -173,7 +167,6 @@ int flush_ipset(char *set_name)
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 清空集合
|
||||
char *args[] = { "ipset", "flush", set_name, NULL };
|
||||
if (ipset_parse_argv(ipset, 3, args) != 0) {
|
||||
@@ -204,14 +197,12 @@ int get_ip_count_in_ipset(char *set_name)
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 列出集合
|
||||
char *args[] = { "ipset", "list", set_name, NULL };
|
||||
if (ipset_parse_argv(ipset, 3, args) != 0) {
|
||||
ipset_fini(ipset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 释放资源
|
||||
ipset_fini(ipset);
|
||||
return ip_count;
|
||||
|
||||
Reference in New Issue
Block a user