优化
This commit is contained in:
@@ -6,3 +6,4 @@
|
|||||||
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.6"}
|
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.6"}
|
||||||
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.7"}
|
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.7"}
|
||||||
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.8"}
|
{"code":"Success","data":{"continent":"北美洲","country":"美国","zipcode":"","owner":"","isp":"Cloudflare, Inc.","adcode":"","prov":"","city":"","district":""},"ip":"1.1.1.8"}
|
||||||
|
{"code":"Success","data":{"continent":"亚洲","country":"中国","zipcode":"999077","owner":"Censys, Inc.","isp":"Censys, Inc.","adcode":"810000","prov":"中国香港","city":"中国香港","district":""},"ip":"199.45.154.152"}
|
||||||
|
|||||||
156
cap.c
156
cap.c
@@ -3,7 +3,6 @@
|
|||||||
#include "libipset.h"
|
#include "libipset.h"
|
||||||
#include "libcurl.h"
|
#include "libcurl.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; // 编译后的过滤器
|
||||||
@@ -30,6 +29,68 @@ struct ip_cache_node {
|
|||||||
struct ip_cache_node *next; // 指向下一个节点
|
struct ip_cache_node *next; // 指向下一个节点
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAXIPSET_ 100
|
||||||
|
#define MAXIPLEN 32
|
||||||
|
char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 };
|
||||||
|
|
||||||
|
// 添加一个 IP 到集合(如果已存在则不添加)
|
||||||
|
int add_cn_ip(char cn_ip[MAXIPSET_][MAXIPLEN], char *ip)
|
||||||
|
{
|
||||||
|
if (ip == NULL || strlen(ip) >= MAXIPLEN) {
|
||||||
|
return -1; // 错误:无效的 IP 地址或过长
|
||||||
|
}
|
||||||
|
// 检查是否已存在
|
||||||
|
for (int i = 0; i < MAXIPSET_; i++) {
|
||||||
|
if (cn_ip[i][0] != '\0' && strcmp(cn_ip[i], ip) == 0) {
|
||||||
|
return 1; // IP 已存在,返回特殊代码
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 查找空位并添加
|
||||||
|
for (int i = 0; i < MAXIPSET_; i++) {
|
||||||
|
if (cn_ip[i][0] == '\0') { // 检查是否为空
|
||||||
|
strcpy(cn_ip[i], ip);
|
||||||
|
return 0; // 成功添加
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // 错误:集合已满
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断给定的IP地址是否在集合中
|
||||||
|
int is_ip_in_set(char cn_ip[MAXIPSET_][MAXIPLEN], const char *ip)
|
||||||
|
{
|
||||||
|
if (ip == NULL) {
|
||||||
|
return 0; // 错误:无效的IP地址指针
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MAXIPSET_; i++) {
|
||||||
|
if (cn_ip[i][0] != '\0' && strcmp(cn_ip[i], ip) == 0) {
|
||||||
|
return 1; // 找到匹配的IP地址
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // 没有找到匹配的IP地址
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算集合中非空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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全的清理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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查 IP 是否已在缓存中并是否过期
|
// 检查 IP 是否已在缓存中并是否过期
|
||||||
int is_ip_in_cache(const char *ip)
|
int is_ip_in_cache(const char *ip)
|
||||||
@@ -132,12 +193,7 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
|
|||||||
// 定义 Response 结构体
|
// 定义 Response 结构体
|
||||||
Response response;
|
Response response;
|
||||||
|
|
||||||
int r = 0;
|
|
||||||
//char *t = _time();
|
|
||||||
|
|
||||||
inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN);
|
||||||
//_printf("%s\n", src_ip);
|
|
||||||
|
|
||||||
|
|
||||||
// 如果 IP 地址已在缓存中且未过期,则跳过查询
|
// 如果 IP 地址已在缓存中且未过期,则跳过查询
|
||||||
if (is_ip_in_cache(src_ip)) {
|
if (is_ip_in_cache(src_ip)) {
|
||||||
@@ -152,6 +208,25 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (1 == is_ip_in_set(cn_ip, src_ip)) {
|
||||||
|
_printf(RED "IP:%s 已经标记为国内,跳过!!!\n" REDEND, src_ip);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAXIPSET_; i++) {
|
||||||
|
if (cn_ip[i][0] != '\0') {
|
||||||
|
printf("%s ", cn_ip[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cn_ip_len(cn_ip) >= 100) { // 清理集合
|
||||||
|
clear_ip_set(cn_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("cn_ip_len(cn_ip): %d\n", cn_ip_len(cn_ip));
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 执行查询并添加到缓存
|
// 执行查询并添加到缓存
|
||||||
ip2region_area = ip2region("ip2region/ip2region.xdb", src_ip);
|
ip2region_area = ip2region("ip2region/ip2region.xdb", src_ip);
|
||||||
if (ip2region_area == NULL) {
|
if (ip2region_area == NULL) {
|
||||||
@@ -179,25 +254,17 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
|
|||||||
_printf("缓存 IP 数 %d\n", cache_size);
|
_printf("缓存 IP 数 %d\n", cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_ip_to_cache(src_ip); // 添加到缓存
|
||||||
|
|
||||||
char *p = curl_get_area(src_ip);
|
char *p = curl_get_area(src_ip);
|
||||||
//puts(p);
|
|
||||||
if (parse_json_to_struct(p, &response) == 0) { // 解析 JSON 到结构体
|
if (parse_json_to_struct(p, &response) == 0) { // 解析 JSON 到结构体
|
||||||
// 输出解析结果
|
|
||||||
/*
|
|
||||||
printf("Code: %s\n", response.code);
|
|
||||||
printf("IP: %s\n", response.ip);
|
|
||||||
printf("Continent: %s\n", response.data.continent);
|
|
||||||
printf("Country: %s\n", response.data.country);
|
|
||||||
printf("ISP: %s\n", response.data.isp);
|
|
||||||
printf("Region: %s\n", response.data.region);
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *p1 = strstr(response.continent_country, "中国");
|
if (NULL == strstr(response.continent_country, "中国")) { // 这时是国外IP
|
||||||
if (p1 == NULL) {
|
|
||||||
_printf(RED "%s %s\n" REDEND, src_ip, response.continent_country);
|
_printf(RED "%s %s\n" REDEND, src_ip, response.continent_country);
|
||||||
r = add_ip_to_ipset(RULE_NAME, src_ip);
|
add_ip_to_ipset(RULE_NAME, src_ip);
|
||||||
//_printf("add_ip_to_ipset() return %d\n", r);
|
} else { // 这时是国内IP
|
||||||
|
add_cn_ip(cn_ip, src_ip); // 添加国内IP到缓存
|
||||||
|
_printf("IP: %s 离线库为国外, API 判断为国内, 标记为已处理!!!\n", src_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -206,38 +273,13 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
|
|||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
//go 执行命令方法
|
|
||||||
snprintf(ip_query_command, sizeof(ip_query_command), "./IP_region_query/ipquery %s", src_ip);
|
|
||||||
command_result = _execute_command(ip_query_command);
|
|
||||||
if (command_result != NULL) {
|
|
||||||
add_ip_to_cache(src_ip); // 添加 IP 到缓存
|
|
||||||
|
|
||||||
char *p = strstr(command_result, "中国");
|
|
||||||
if (p == NULL) {
|
|
||||||
_printf(RED "%s %s\n" REDEND, src_ip, command_result);
|
|
||||||
r = add_ip_to_ipset(RULE_NAME, src_ip);
|
|
||||||
_printf("add_ip_to_ipset() return %d\n", r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(command_result);
|
if (ip2region_area != NULL) {
|
||||||
command_result = NULL;
|
|
||||||
} else {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command_result != NULL)
|
|
||||||
free(command_result);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ip2region_area != NULL)
|
|
||||||
{
|
|
||||||
free(ip2region_area);
|
free(ip2region_area);
|
||||||
ip2region_area = NULL;
|
ip2region_area = NULL;
|
||||||
}
|
}
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage()
|
void usage()
|
||||||
@@ -292,7 +334,6 @@ void cleanup_(int signum)
|
|||||||
pcap_freealldevs(alldevs); // 释放设备列表
|
pcap_freealldevs(alldevs); // 释放设备列表
|
||||||
//pcap_close(handle); // 关闭会话句柄
|
//pcap_close(handle); // 关闭会话句柄
|
||||||
|
|
||||||
|
|
||||||
// 退出主进程
|
// 退出主进程
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
@@ -327,8 +368,7 @@ int main(int argc, char **argv)
|
|||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
while (-1 != (opt = getopt_long(argc, argv, optstring, longopts, &longindex)))
|
while (-1 != (opt = getopt_long(argc, argv, optstring, longopts, &longindex))) {
|
||||||
{
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
if (daemon(1, 1)) {
|
if (daemon(1, 1)) {
|
||||||
@@ -346,17 +386,13 @@ int main(int argc, char **argv)
|
|||||||
if (strcmp(optarg, "start") == 0) {
|
if (strcmp(optarg, "start") == 0) {
|
||||||
memset(Ipset_Command, 0, BUFFER);
|
memset(Ipset_Command, 0, BUFFER);
|
||||||
// 将 MAXIPSET_RULT_NAME_NUM 替换为实际值
|
// 将 MAXIPSET_RULT_NAME_NUM 替换为实际值
|
||||||
snprintf(Ipset_Command, sizeof(Ipset_Command),
|
snprintf(Ipset_Command, sizeof(Ipset_Command), "for n in $(seq 0 %d); do iptables -A INPUT -p tcp -m set --match-set root$n src -j DROP 2> /dev/null; done", MAXIPSET_RULT_NAME_NUM);
|
||||||
"for n in $(seq 0 %d); do iptables -A INPUT -p tcp -m set --match-set root$n src -j DROP 2> /dev/null; done",
|
|
||||||
MAXIPSET_RULT_NAME_NUM);
|
|
||||||
system(Ipset_Command);
|
system(Ipset_Command);
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if (strcmp(optarg, "stop") == 0) {
|
} else if (strcmp(optarg, "stop") == 0) {
|
||||||
memset(Ipset_Command, 0, BUFFER);
|
memset(Ipset_Command, 0, BUFFER);
|
||||||
// 将 MAXIPSET_RULT_NAME_NUM 替换为实际值
|
// 将 MAXIPSET_RULT_NAME_NUM 替换为实际值
|
||||||
snprintf(Ipset_Command, sizeof(Ipset_Command),
|
snprintf(Ipset_Command, sizeof(Ipset_Command), "for n in $(seq 0 %d); do iptables -D INPUT -p tcp -m set --match-set root$n src -j DROP 2> /dev/null; done", MAXIPSET_RULT_NAME_NUM);
|
||||||
"for n in $(seq 0 %d); do iptables -D INPUT -p tcp -m set --match-set root$n src -j DROP 2> /dev/null; done",
|
|
||||||
MAXIPSET_RULT_NAME_NUM);
|
|
||||||
system(Ipset_Command);
|
system(Ipset_Command);
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
@@ -377,7 +413,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 创建共享内存
|
// 创建共享内存
|
||||||
shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
|
shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
|
||||||
if (shmid < 0) {
|
if (shmid < 0) {
|
||||||
@@ -392,7 +427,6 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pid = fork(); // 创建子进程
|
pid = fork(); // 创建子进程
|
||||||
if (pid == 0) // 子进程
|
if (pid == 0) // 子进程
|
||||||
{
|
{
|
||||||
@@ -404,13 +438,12 @@ int main(int argc, char **argv)
|
|||||||
_printf("创建 IPSet %s 失败\n", RULE_NAME);
|
_printf("创建 IPSet %s 失败\n", RULE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
//_printf("子进程当前 Ipset Rule 名 %s\n", RULE_NAME);
|
//_printf("子进程当前 Ipset Rule 名 %s\n", RULE_NAME);
|
||||||
|
|
||||||
count = get_ip_count_in_ipset(RULE_NAME);
|
count = get_ip_count_in_ipset(RULE_NAME);
|
||||||
if (count >= 0) {
|
if (count >= 0) {
|
||||||
_printf("子进程当前 Ipset Rule 名 %s, 数量: %d\n", RULE_NAME, count);
|
_printf("子进程当前 Ipset Rule 名 %s, 数量: %d \n", RULE_NAME, count);
|
||||||
if (count >= MAXIPSET && RULE_NAME_NUMBER <= MAXIPSET_RULT_NAME_NUM) // RULE_中的IP数量不超过MAXIPSET,并且集合不能超过 MAXIPSET_RULT_NAME_NUM 个
|
if (count >= MAXIPSET && RULE_NAME_NUMBER <= MAXIPSET_RULT_NAME_NUM) // RULE_中的IP数量不超过MAXIPSET,并且集合不能超过 MAXIPSET_RULT_NAME_NUM 个
|
||||||
{
|
{
|
||||||
RULE_NAME_NUMBER++;
|
RULE_NAME_NUMBER++;
|
||||||
@@ -437,7 +470,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 查找可用的网络设备
|
// 查找可用的网络设备
|
||||||
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
|
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
|
||||||
fprintf(stderr, "无法找到设备: %s\n", errbuf);
|
fprintf(stderr, "无法找到设备: %s\n", errbuf);
|
||||||
|
|||||||
BIN
ip2region/a.out
BIN
ip2region/a.out
Binary file not shown.
@@ -6,7 +6,7 @@
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// 执行查询并添加到缓存
|
// 执行查询并添加到缓存
|
||||||
char *area = ip2region("ip2region.xdb", "1.1.1.1");
|
char *area = ip2region("ip2region.xdb", "199.45.154.152");
|
||||||
if (area == NULL) {
|
if (area == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user