This commit is contained in:
2025-04-23 11:41:06 +08:00
parent 1e00348e84
commit 1c28d55681
11 changed files with 89 additions and 102 deletions

View File

@@ -10,6 +10,7 @@
"cache.h": "c", "cache.h": "c",
"errno.h": "c", "errno.h": "c",
"stdlib.h": "c", "stdlib.h": "c",
"string.h": "c" "string.h": "c",
"stat.h": "c"
} }
} }

25
cache.c
View File

@@ -1,6 +1,5 @@
#include "cache.h" #include "cache.h"
struct ip_cache_node *ip_cache_head = NULL; // 缓存链表的头节点 struct ip_cache_node *ip_cache_head = NULL; // 缓存链表的头节点
int cache_size = 0; // 当前缓存中的 IP 数量 int cache_size = 0; // 当前缓存中的 IP 数量
@@ -27,7 +26,6 @@ void add_ip_to_cache(const char *ip)
free(current); free(current);
cache_size--; cache_size--;
} }
// 创建新的缓存节点并添加到链表头部 // 创建新的缓存节点并添加到链表头部
struct ip_cache_node *new_node = (struct ip_cache_node *)malloc(sizeof(struct ip_cache_node)); struct ip_cache_node *new_node = (struct ip_cache_node *)malloc(sizeof(struct ip_cache_node));
if (new_node == NULL) { 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 *current = ip_cache_head;
struct ip_cache_node *prev = NULL; struct ip_cache_node *prev = NULL;
if (ip_cache_head == NULL) return 0; // 如果 ip_cache_head == NULLcurrent->next 可能导致段错误 (Segmentation Fault)。 if (ip_cache_head == NULL)
return 0; // 如果 ip_cache_head == NULLcurrent->next 可能导致段错误 (Segmentation Fault)。
while (current != NULL) { while (current != NULL) {
// 如果 IP 匹配并且未过期 // 如果 IP 匹配并且未过期
@@ -89,8 +88,6 @@ void free_ip_cache()
cache_size = 0; cache_size = 0;
} }
char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 }; char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 };
// 添加一个 IP 到集合(如果已存在则不添加) // 添加一个 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 cn_ip_len(char cn_ip[MAXIPSET_][MAXIPLEN])
{ {
int count = 0; // 用于计数非空IP int count = 0; // 用于计数非空IP
for (int i = 0; i < MAXIPSET_; i++) { for (int i = 0; i < MAXIPSET_; i++) {
if (cn_ip[i][0] != '\0') { if (cn_ip[i][0] != '\0') {
count++; // 非空IP计数 count++; // 非空IP计数
} }
} }
return count; 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地址集合将所有位置置为空字符串 // 安全的清理IP地址集合将所有位置置为空字符串
void clear_ip_set(char cn_ip[MAXIPSET_][MAXIPLEN]) void clear_ip_set(char cn_ip[MAXIPSET_][MAXIPLEN])
{ {
if (cn_ip == NULL) { if (cn_ip == NULL) {
return; // 如果指针无效,则直接返回 return; // 如果指针无效,则直接返回
} }
for (int i = 0; i < MAXIPSET_; i++) { for (int i = 0; i < MAXIPSET_; i++) {
memset(cn_ip[i], '\0', MAXIPLEN); memset(cn_ip[i], '\0', MAXIPLEN);
} }

View File

@@ -18,6 +18,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
@@ -25,7 +29,7 @@
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
#define MAXIPSET_ 10240 #define MAXIPSET_ 65535
#define MAXIPLEN 32 #define MAXIPLEN 32
#define CACHE_TTL 180 // 设定缓存的存活时间为 600 秒 (10 分钟) #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 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 file_exists_access(const char *filepath);
extern int truncate_file(const char *path);
#endif #endif

34
cap.c
View File

@@ -4,26 +4,22 @@
#include "libcurl.h" #include "libcurl.h"
#include "cache.h" #include "cache.h"
pcap_if_t *alldevs, *device;
pcap_if_t *alldevs, *device; pcap_t *handle; // 会话句柄
pcap_t *handle; // 会话句柄
struct bpf_program fp; // 编译后的过滤器 struct bpf_program fp; // 编译后的过滤器
pid_t pid = -1; // 子进程全局PID pid_t pid = -1; // 子进程全局PID
#define SHM_SIZE 1024 // 共享内存大小 #define SHM_SIZE 1024 // 共享内存大小
#define SHM_KEY 0124 // 共享内存键值 #define SHM_KEY 0124 // 共享内存键值
int shmid = -1; int shmid = -1;
int RULE_NAME_NUMBER = 0; // ipset 集合集合数 int RULE_NAME_NUMBER = 0; // ipset 集合集合数
char *RULE_NAME = NULL; // 共享内存 char *RULE_NAME = NULL; // 共享内存
char *ip2region_area = NULL; // ip2region 解析结果
char *command_result = NULL; // 执行命令的结果
char *ip2region_area = NULL; // ip2region 解析结果
char *command_result = NULL; // 执行命令的结果
void Processing_IP_addresses(char *src_ip) void Processing_IP_addresses(char *src_ip)
{ {
// 地域白名单 // 地域白名单
char _region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } }; char _region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } };
char _REGION_LIST[BUFFER] = { 0 }; char _REGION_LIST[BUFFER] = { 0 };
@@ -53,8 +49,9 @@ void Processing_IP_addresses(char *src_ip)
printf("%s ", cn_ip[i]); printf("%s ", cn_ip[i]);
} }
} }
if (cn_ip_len(cn_ip) >= 1024) { // 清理集合 if (cn_ip_len(cn_ip) >= 10240) { // 清理集合
clear_ip_set(cn_ip); clear_ip_set(cn_ip);
truncate_file("cn.txt"); // 清空文件
} }
printf("cn_ip_len(cn_ip): %d\n", cn_ip_len(cn_ip)); printf("cn_ip_len(cn_ip): %d\n", cn_ip_len(cn_ip));
@@ -97,8 +94,10 @@ void Processing_IP_addresses(char *src_ip)
if (NULL == strstr(response.continent_country, "中国")) { // 这时是国外IP if (NULL == strstr(response.continent_country, "中国")) { // 这时是国外IP
_printf(RED "CurlGetIpArea(): %s %s\n" REDEND, src_ip, response.continent_country); _printf(RED "CurlGetIpArea(): %s %s\n" REDEND, src_ip, response.continent_country);
add_ip_to_ipset(RULE_NAME, src_ip); add_ip_to_ipset(RULE_NAME, src_ip);
} else { // 这时是国内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); _printf("IP: %s 离线库为国外, API 判断为国内, 标记为已处理!!!\n", src_ip);
if (append_string_to_file("cn.txt", src_ip) != 0) { if (append_string_to_file("cn.txt", src_ip) != 0) {
@@ -119,7 +118,7 @@ void Processing_IP_addresses(char *src_ip)
ip2region_area = NULL; ip2region_area = NULL;
} }
return ; return;
} }
// 回调函数,在捕获到每个数据包时调用 // 回调函数,在捕获到每个数据包时调用
@@ -128,12 +127,11 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
int ethernet_header_len = 14; 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);
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 }; char src_ip[INET_ADDRSTRLEN] = { 0 };
inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN); inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN);
Processing_IP_addresses(src_ip); Processing_IP_addresses(src_ip);

3
cap.h
View File

@@ -28,7 +28,4 @@
#define _VERSION "0.2" #define _VERSION "0.2"
#endif #endif

View File

@@ -1,7 +1,8 @@
#include "common.h" #include "common.h"
// 计算字符串长度 // 计算字符串长度
int _strlen(const char *str) { int _strlen(const char *str)
{
if (str == NULL) if (str == NULL)
return 0; return 0;
@@ -9,7 +10,6 @@ int _strlen(const char *str) {
return _p - str; return _p - str;
} }
// 自定义 printf 函数 // 自定义 printf 函数
void _printf(const char *format, ...) void _printf(const char *format, ...)
{ {
@@ -20,13 +20,13 @@ void _printf(const char *format, ...)
time_t now = time(NULL); time_t now = time(NULL);
struct tm local_time; struct tm local_time;
localtime_r(&now, &local_time); localtime_r(&now, &local_time);
char time_str[20]; // YYYY-MM-DD HH:MM:SS 格式 char time_str[20]; // YYYY-MM-DD HH:MM:SS 格式
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time); strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time);
// 打印时间戳到控制台 // 打印时间戳到控制台
printf("[%s] ", time_str); printf("[%s] ", time_str);
vprintf(format, args); // 打印内容到控制台 vprintf(format, args); // 打印内容到控制台
va_end(args); // 结束对变参列表的处理 va_end(args); // 结束对变参列表的处理
// 重新启动变参列表 // 重新启动变参列表
va_start(args, format); va_start(args, format);
@@ -46,24 +46,23 @@ void _printf(const char *format, ...)
perror("Unable to open log file"); perror("Unable to open log file");
} }
va_end(args); // 结束对变参列表的处理 va_end(args); // 结束对变参列表的处理
} }
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM]) void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{ {
int i = 0; int i = 0;
char *result = NULL; char *result = NULL;
char temp[WHITELIST_IP_NUM]; // 创建一个足够大的副本缓冲区 char temp[WHITELIST_IP_NUM]; // 创建一个足够大的副本缓冲区
// 复制原始字符串到副本 // 复制原始字符串到副本
strncpy(temp, string, sizeof(temp) - 1); strncpy(temp, string, sizeof(temp) - 1);
temp[sizeof(temp) - 1] = '\0'; // 确保字符串以 '\0' 结尾 temp[sizeof(temp) - 1] = '\0'; // 确保字符串以 '\0' 结尾
result = strtok(temp, delims); // 使用副本进行拆分 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); strncpy(whitelist_ip[i], result, WHITELIST_IP_NUM - 1);
whitelist_ip[i][WHITELIST_IP_NUM - 1] = '\0'; // 确保每个元素以 '\0' 结尾 whitelist_ip[i][WHITELIST_IP_NUM - 1] = '\0'; // 确保每个元素以 '\0' 结尾
i++; i++;
result = strtok(NULL, delims); result = strtok(NULL, delims);
} }
@@ -74,19 +73,18 @@ int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{ {
int i; int i;
for (i = 0; i < WHITELIST_IP_NUM; i++) { // 从 i = 0 开始 for (i = 0; i < WHITELIST_IP_NUM; i++) { // 从 i = 0 开始
// 如果白名单 IP 是空字符串,跳出循环 // 如果白名单 IP 是空字符串,跳出循环
if (whitelist_ip[i][0] == '\0') { if (whitelist_ip[i][0] == '\0') {
break; break;
} }
// 对比 client_ip 的前缀是否与白名单中的IP段匹配 // 对比 client_ip 的前缀是否与白名单中的IP段匹配
if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) { if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) {
return 1; // 匹配成功 return 1; // 匹配成功
} }
} }
return 0; // 未找到匹配 return 0; // 未找到匹配
} }
// 地域段白名单对比 // 地域段白名单对比
@@ -100,15 +98,14 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
if (region_list[i][0] == '\0') { if (region_list[i][0] == '\0') {
break; break;
} }
// 在str中查找 region_list[i] // 在str中查找 region_list[i]
p = strstr(str, region_list[i]); p = strstr(str, region_list[i]);
if (p != NULL) { if (p != NULL) {
return 1; // 匹配成功返回1 return 1; // 匹配成功返回1
} }
} }
return 0; // 没有匹配返回0 return 0; // 没有匹配返回0
} }
int8_t _copy_new_mem(char *src, int src_len, char **dest) int8_t _copy_new_mem(char *src, int src_len, char **dest)
@@ -123,7 +120,8 @@ int8_t _copy_new_mem(char *src, int src_len, char **dest)
} }
// 返回的时间字符串存储在静态缓冲区中 // 返回的时间字符串存储在静态缓冲区中
char *_time() { char *_time()
{
static char temp[BUFFER]; static char temp[BUFFER];
const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
time_t t = time(NULL); time_t t = time(NULL);
@@ -134,11 +132,9 @@ char *_time() {
return NULL; return NULL;
} }
snprintf(temp, sizeof(temp), "[%d/%02d/%02d %s %02d:%02d:%02d]", 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);
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; // 返回静态缓冲区地址 return temp; // 返回静态缓冲区地址
} }
// 将字符串转换为IPv4地址 // 将字符串转换为IPv4地址
@@ -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()); int oldprio = getpriority(PRIO_PROCESS, getpid());
if (oldprio == -1 && errno != 0) { if (oldprio == -1 && errno != 0) {
@@ -163,12 +160,10 @@ int _nice(int increment) {
printf("Current priority: %d\n", oldprio); printf("Current priority: %d\n", oldprio);
// 检查是否溢出 // 检查是否溢出
if ((increment > 0 && oldprio > INT_MAX - increment) || if ((increment > 0 && oldprio > INT_MAX - increment) || (increment < 0 && oldprio < INT_MIN - increment)) {
(increment < 0 && oldprio < INT_MIN - increment)) {
fprintf(stderr, "Priority overflow error\n"); fprintf(stderr, "Priority overflow error\n");
return -1; return -1;
} }
// 计算新的优先级 // 计算新的优先级
int newprio = oldprio + increment; 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); fprintf(stderr, "New priority out of range: %d (valid range is %d to %d)\n", newprio, PRIO_MIN, PRIO_MAX);
return -1; return -1;
} }
// 设置新的优先级 // 设置新的优先级
if (setpriority(PRIO_PROCESS, getpid(), newprio) == -1) { if (setpriority(PRIO_PROCESS, getpid(), newprio) == -1) {
perror("setpriority failed"); perror("setpriority failed");
@@ -189,13 +183,14 @@ int _nice(int increment) {
} }
// 判断命令是否存在 // 判断命令是否存在
int _command_exists(const char *command) { int _command_exists(const char *command)
{
const char *path_env = getenv("PATH"); const char *path_env = getenv("PATH");
if (!path_env) { if (!path_env) {
return 0; // 如果 PATH 不存在,返回不存在 return 0; // 如果 PATH 不存在,返回不存在
} }
char filepath[1024]; // 缓冲区大小 char filepath[1024]; // 缓冲区大小
const char *dir = path_env; const char *dir = path_env;
while (dir && *dir) { while (dir && *dir) {
@@ -205,24 +200,23 @@ int _command_exists(const char *command) {
// 构建路径并检查长度 // 构建路径并检查长度
if (snprintf(filepath, sizeof(filepath), "%.*s/%s", (int)len, dir, command) >= (int)sizeof(filepath)) { if (snprintf(filepath, sizeof(filepath), "%.*s/%s", (int)len, dir, command) >= (int)sizeof(filepath)) {
return 0; // 缓冲区溢出,返回不存在 return 0; // 缓冲区溢出,返回不存在
} }
// 检查文件是否存在且可执行 // 检查文件是否存在且可执行
if (access(filepath, X_OK) == 0) { if (access(filepath, X_OK) == 0) {
puts(filepath); puts(filepath);
return 1; // 命令存在 return 1; // 命令存在
} }
// 更新 dir 指针 // 更新 dir 指针
dir = end ? end + 1 : NULL; dir = end ? end + 1 : NULL;
} }
return 0; // 命令不存在 return 0; // 命令不存在
} }
// 执行命令并返回输出 // 执行命令并返回输出
char *_execute_command(const char *command) { char *_execute_command(const char *command)
{
FILE *fp; FILE *fp;
char buffer[1024]; char buffer[1024];
char *output = NULL; char *output = NULL;
@@ -235,7 +229,6 @@ char *_execute_command(const char *command) {
perror("popen"); perror("popen");
return NULL; return NULL;
} }
// 读取命令的输出 // 读取命令的输出
while (fgets(buffer, sizeof(buffer), fp) != NULL) { while (fgets(buffer, sizeof(buffer), fp) != NULL) {
size_t len = strlen(buffer); size_t len = strlen(buffer);
@@ -244,7 +237,7 @@ char *_execute_command(const char *command) {
char *new_output = realloc(output, output_size); char *new_output = realloc(output, output_size);
if (new_output == NULL) { if (new_output == NULL) {
perror("realloc"); perror("realloc");
free(output); // 释放已分配的内存 free(output); // 释放已分配的内存
pclose(fp); // 关闭管道 pclose(fp); // 关闭管道
return NULL; return NULL;
} }
@@ -259,11 +252,10 @@ char *_execute_command(const char *command) {
if (output_size > 0) { if (output_size > 0) {
output[total_read] = '\0'; output[total_read] = '\0';
} }
// 关闭管道 // 关闭管道
if (pclose(fp) == -1) { if (pclose(fp) == -1) {
perror("pclose"); perror("pclose");
free(output); // pclose 失败时释放内存 free(output); // pclose 失败时释放内存
return NULL; return NULL;
} }
@@ -281,4 +273,3 @@ void remove_char(char *str, char c)
} }
str[j] = '\0'; str[j] = '\0';
} }

View File

@@ -27,7 +27,6 @@
#define BUFFER 1024 #define BUFFER 1024
#define WHITELIST_IP_NUM 1024 #define WHITELIST_IP_NUM 1024
extern char *_time(); extern char *_time();
extern int _strlen(const char *str); extern int _strlen(const char *str);
extern void _printf(const char *format, ...); extern void _printf(const char *format, ...);

View File

@@ -1,6 +1,5 @@
#include "libcurl.h" #include "libcurl.h"
struct MemoryStruct { struct MemoryStruct {
char *memory; char *memory;
size_t size; size_t size;
@@ -28,7 +27,7 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi
} }
char *GetLocalAddr(char *url) char *GetLocalAddr(char *url)
{ {
CURL *curl_handle; CURL *curl_handle;
CURLcode res; CURLcode res;
@@ -100,8 +99,7 @@ char *CurlGetIpArea(char *ip)
{ {
char url[256] = { 0 }; char url[256] = { 0 };
snprintf(url, sizeof(url), "https://qifu.baidu.com/ip/geo/v1/district?ip=%s", ip); snprintf(url, sizeof(url), "https://qifu.baidu.com/ip/geo/v1/district?ip=%s", ip);
CURL *curl_handle; CURL *curl_handle;
CURLcode res; CURLcode res;
@@ -169,13 +167,14 @@ char *CurlGetIpArea(char *ip)
} }
// 函数用于从 cJSON 对象提取字段内容 // 函数用于从 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); cJSON *item = cJSON_GetObjectItemCaseSensitive(parent, field_name);
if (cJSON_IsString(item) && item->valuestring) { if (cJSON_IsString(item) && item->valuestring) {
strncpy(output, item->valuestring, max_len - 1); strncpy(output, item->valuestring, max_len - 1);
output[max_len - 1] = '\0'; // 确保字符串以 '\0' 结尾 output[max_len - 1] = '\0'; // 确保字符串以 '\0' 结尾
} else { } else {
output[0] = '\0'; // 如果字段不存在或不是字符串,设置为空字符串 output[0] = '\0'; // 如果字段不存在或不是字符串,设置为空字符串
} }
} }
@@ -186,7 +185,6 @@ int parse_json_to_struct(const char *json_string, Response *response)
fprintf(stderr, "Invalid input parameters!\n"); fprintf(stderr, "Invalid input parameters!\n");
return -1; return -1;
} }
// 初始化结构体 // 初始化结构体
memset(response, 0, sizeof(Response)); 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()); fprintf(stderr, "Error parsing JSON: %s\n", cJSON_GetErrorPtr());
return -1; return -1;
} }
// 解析字段 // 解析字段
parse_string_field(root, "code", response->code, sizeof(response->code)); parse_string_field(root, "code", response->code, sizeof(response->code));
parse_string_field(root, "ip", response->ip, sizeof(response->ip)); 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); cJSON_Delete(root);
return -1; return -1;
} }
// 解析 data 对象 // 解析 data 对象
cJSON *data_item = cJSON_GetObjectItemCaseSensitive(root, "data"); cJSON *data_item = cJSON_GetObjectItemCaseSensitive(root, "data");
if (cJSON_IsObject(data_item)) { if (cJSON_IsObject(data_item)) {
@@ -222,20 +218,17 @@ 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, "district", response->data.district, sizeof(response->data.district));
parse_string_field(data_item, "region", response->data.region, sizeof(response->data.region)); parse_string_field(data_item, "region", response->data.region, sizeof(response->data.region));
} }
// ----------- 拼接 continent_country --------------- // ----------- 拼接 continent_country ---------------
if (snprintf(response->continent_country, sizeof(response->continent_country), "%s%s", response->data.continent, response->data.country) >= sizeof(response->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"); fprintf(stderr, "continent_country truncated!\n");
} }
//snprintf(response->continent_country, 256, "%s%s", response->data.continent, response->data.country); //snprintf(response->continent_country, 256, "%s%s", response->data.continent, response->data.country);
// 清理 JSON 对象 // 清理 JSON 对象
cJSON_Delete(root); cJSON_Delete(root);
return 0; return 0;
} }
/* /*
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {

View File

@@ -42,11 +42,8 @@ typedef struct {
char continent_country[256]; char continent_country[256];
} Response; } Response;
extern char *CurlGetIpArea(char *ip); extern char *CurlGetIpArea(char *ip);
extern char *GetLocalAddr(char *url); extern char *GetLocalAddr(char *url);
extern int parse_json_to_struct(const char *json_string, Response *response); extern int parse_json_to_struct(const char *json_string, Response * response);
#endif
#endif

View File

@@ -86,14 +86,12 @@ int create_ipset(char *set_name)
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 设置自定义错误和输出处理函数 // 设置自定义错误和输出处理函数
if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) { if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) {
fprintf(stderr, "设置自定义打印函数失败。\n"); fprintf(stderr, "设置自定义打印函数失败。\n");
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 创建集合 // 创建集合
char *args[] = { "ipset", "create", set_name, "hash:ip", NULL }; char *args[] = { "ipset", "create", set_name, "hash:ip", NULL };
if (ipset_parse_argv(ipset, 4, args) != 0) { if (ipset_parse_argv(ipset, 4, args) != 0) {
@@ -101,7 +99,6 @@ int create_ipset(char *set_name)
return -1; return -1;
} }
ipset_fini(ipset); ipset_fini(ipset);
return 0; return 0;
@@ -135,14 +132,12 @@ int add_ip_to_ipset(char *set_name, char *ip)
ipset_fini(ipset); ipset_fini(ipset);
return -1; // 返回 -1但不退出 return -1; // 返回 -1但不退出
} }
// 设置自定义错误和输出处理函数 // 设置自定义错误和输出处理函数
if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) { if (ipset_custom_printf(ipset, custom_error_handler, NULL, custom_output_handler_, NULL) != 0) {
fprintf(stderr, "设置自定义打印函数失败。\n"); fprintf(stderr, "设置自定义打印函数失败。\n");
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 将ip添加到集合 // 将ip添加到集合
char *args[] = { "ipset", "add", set_name, ip, NULL }; char *args[] = { "ipset", "add", set_name, ip, NULL };
if (ipset_parse_argv(ipset, 4, args) != 0) { if (ipset_parse_argv(ipset, 4, args) != 0) {
@@ -150,7 +145,6 @@ int add_ip_to_ipset(char *set_name, char *ip)
return -1; return -1;
} }
ipset_fini(ipset); ipset_fini(ipset);
return 0; // 始终返回 0表示执行成功 return 0; // 始终返回 0表示执行成功
@@ -173,7 +167,6 @@ int flush_ipset(char *set_name)
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 清空集合 // 清空集合
char *args[] = { "ipset", "flush", set_name, NULL }; char *args[] = { "ipset", "flush", set_name, NULL };
if (ipset_parse_argv(ipset, 3, args) != 0) { if (ipset_parse_argv(ipset, 3, args) != 0) {
@@ -204,14 +197,12 @@ int get_ip_count_in_ipset(char *set_name)
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 列出集合 // 列出集合
char *args[] = { "ipset", "list", set_name, NULL }; char *args[] = { "ipset", "list", set_name, NULL };
if (ipset_parse_argv(ipset, 3, args) != 0) { if (ipset_parse_argv(ipset, 3, args) != 0) {
ipset_fini(ipset); ipset_fini(ipset);
return -1; return -1;
} }
// 释放资源 // 释放资源
ipset_fini(ipset); ipset_fini(ipset);
return ip_count; return ip_count;

View File

@@ -5,12 +5,12 @@
#include <libipset/ipset.h> #include <libipset/ipset.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <arpa/inet.h> // 包含 inet_pton 函数 #include <arpa/inet.h> // 包含 inet_pton 函数
#define BUFFER 1024 #define BUFFER 1024
#define MAX_CMD_LENGTH 256 // 或者根据需要调整 #define MAX_CMD_LENGTH 256 // 或者根据需要调整
extern int create_ipset( char *set_name); extern int create_ipset(char *set_name);
extern int add_ip_to_ipset(char *set_name, char *ip); extern int add_ip_to_ipset(char *set_name, char *ip);
extern int get_ip_count_in_ipset(char *set_name); extern int get_ip_count_in_ipset(char *set_name);