20250423
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -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
25
cache.c
@@ -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 == NULL,current->next 可能导致段错误 (Segmentation Fault)。
|
if (ip_cache_head == NULL)
|
||||||
|
return 0; // 如果 ip_cache_head == NULL,current->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);
|
||||||
}
|
}
|
||||||
|
|||||||
7
cache.h
7
cache.h
@@ -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
34
cap.c
@@ -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);
|
||||||
|
|
||||||
|
|||||||
77
common.c
77
common.c
@@ -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';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
common.h
1
common.h
@@ -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, ...);
|
||||||
|
|||||||
19
libcurl.c
19
libcurl.c
@@ -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[])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user