This commit is contained in:
2024-10-16 11:07:13 +08:00
parent 7b1e27db87
commit 95c3e1cda8
14 changed files with 256 additions and 44 deletions

View File

@@ -3,6 +3,11 @@
"files.associations": {
"string.h": "c",
"stdlib.h": "c",
"ip2region.h": "c"
"ip2region.h": "c",
"common.h": "c",
"prctl.h": "c",
"resource.h": "c",
"wait.h": "c",
"stdio.h": "c"
}
}

3
IP_region_query/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module ipquery
go 1.22.2

BIN
IP_region_query/ipquery Normal file

Binary file not shown.

52
IP_region_query/main.go Normal file
View File

@@ -0,0 +1,52 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
type IPInfo struct {
Code string `json:"code"`
Data struct {
Continent string `json:"continent"`
Country string `json:"country"`
} `json:"data"`
IP string `json:"ip"`
Msg string `json:"msg"`
}
func main() {
if len(os.Args) < 2 {
log.Fatalf("Usage: %s <IP>", os.Args[0])
}
// 目标 URL
url := "https://qifu.baidu.com/ip/geo/v1/district?ip=" + os.Args[1]
// 发送 GET 请求
resp, err := http.Get(url)
if err != nil {
log.Fatalf("Error making GET request: %v", err)
}
defer resp.Body.Close()
// 读取响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Error reading response body: %v", err)
}
// 解析 JSON 数据
var ipInfo IPInfo
if err := json.Unmarshal(body, &ipInfo); err != nil {
log.Fatalf("Error parsing JSON: %v", err)
}
// 提取并打印 continent 和 country 字段
fmt.Printf("%s%s\n", ipInfo.Data.Continent, ipInfo.Data.Country)
}

View File

@@ -5,12 +5,17 @@ CFLAGS += -g -Os -Wall -Iip2region -Iqqwry
LIBS = -lm -static
BIN := denyip
all: main.o ip2region/ip2region.o ip2region/xdb_searcher.o qqwry/qqwry.o
all: $(BIN) # 默认目标
ipquery: # Go 构建目标
cd IP_region_query && CGO_ENABLED=0 go build -ldflags '-w -s'
$(BIN): main.o common.o ip2region/ip2region.o ip2region/xdb_searcher.o qqwry/qqwry.o
$(CC) $(CFLAGS) -o $(BIN) $^ $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -rf $(BIN)
rm -rf main.o ip2region/ip2region.o ip2region/xdb_searcher.o qqwry/qqwry.o
rm -rf $(BIN) ipquery
rm -rf main.o common.o ip2region/ip2region.o ip2region/xdb_searcher.o qqwry/qqwry.o

145
common.c Normal file
View File

@@ -0,0 +1,145 @@
#include "common.h"
// 计算字符串长度
int _strlen(char *str)
{
char *_p = NULL;
if (str == NULL)
return 0;
_p = strchr(str, '\0');
if (_p == NULL)
return 0;
return _p - str;
}
// 自定义 printf 函数
void my_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
// 打印到控制台
vprintf(format, args);
va_end(args); // 结束对变参列表的处理
// 重新启动变参列表
va_start(args, format);
// 打开日志文件(追加模式)
FILE *log_file = fopen(PRINT_LOG_FILE, "a");
if (log_file != NULL) {
// 获取当前时间
time_t now = time(NULL);
struct tm local_time;
localtime_r(&now, &local_time);
char time_str[20]; // YYYY-MM-DD HH:MM:SS 格式
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time);
// 打印时间戳到日志文件
fprintf(log_file, "[%s] ", time_str);
// 打印内容到日志文件
vfprintf(log_file, format, args);
// 关闭日志文件
fclose(log_file);
} else {
perror("Unable to open log file");
}
va_end(args); // 结束对变参列表的处理
}
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i = 0;
char *result = NULL;
char temp[WHITELIST_IP_NUM]; // 创建一个足够大的副本缓冲区
// 复制原始字符串到副本
strncpy(temp, string, sizeof(temp) - 1);
temp[sizeof(temp) - 1] = '\0'; // 确保字符串以 '\0' 结尾
result = strtok(temp, delims); // 使用副本进行拆分
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++;
result = strtok(NULL, delims);
}
}
// IP段白名单对比
int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i;
for (i = 0; i < WHITELIST_IP_NUM; i++) { // 从 i = 0 开始
// 如果白名单 IP 是空字符串,跳出循环
if (whitelist_ip[i][0] == '\0') {
break;
}
// 对比client_ip的前缀是否与白名单中的IP段匹配
if (strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i])) == 0) {
return 1; // 匹配成功
}
}
return 0; // 未找到匹配
}
// 地域段白名单对比
int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
{
int i;
char *p;
for (i = 0; i < WHITELIST_IP_NUM; i++) {
// 如果region_list[i]为空字符串,跳出循环
if (region_list[i][0] == '\0') {
break;
}
// 在str中查找region_list[i]
p = strstr(str, region_list[i]);
if (p != NULL) {
return 1; // 匹配成功返回1
}
}
return 0; // 没有匹配返回0
}
int8_t copy_new_mem(char *src, int src_len, char **dest)
{
*dest = (char *)malloc(src_len + 1);
if (*dest == NULL)
return 1;
memcpy(*dest, src, src_len);
*((*dest) + src_len) = '\0';
return 0;
}
char *_time()
{
char temp[BUFFER];
char *wday[] = { "0", "1", "2", "3", "4", "5", "6" };
time_t t;
struct tm *p;
time(&t);
p = localtime(&t); // 取得当地时间
memset(temp, 0, BUFFER);
snprintf(temp, BUFFER, "[%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 strdup(temp);
}

34
common.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/utsname.h>
#define PRINT_LOG_FILE "Gateway.log"
#define BUFFER 1024
#define WHITELIST_IP_NUM 1024
extern int _strlen(char *str);
extern void my_printf(const char *format, ...);
extern void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM]);
extern int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM]);
extern char *_time();
extern int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM]);
extern int8_t copy_new_mem(char *src, int src_len, char **dest);
#endif

BIN
common.o Normal file

Binary file not shown.

BIN
denyip

Binary file not shown.

BIN
ipquery

Binary file not shown.

46
main.c
View File

@@ -10,10 +10,10 @@
#include "ip2region.h"
#include "qqwry.h"
#include "common.h"
#define RED "\033[31m"
#define RESET "\033[0m"
#define BUFFER 512
#define WHITELIST_IP_NUM 1024
#define MAXIPSET 65534
@@ -21,42 +21,6 @@ char *xdb_path = "ip2region.xdb";
pid_t pid1, pid2; // 保存子进程的 PID
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i = 0;
char *result = NULL;
result = strtok(string, delims);
while (result != NULL) {
strcpy(whitelist_ip[i], result);
result = strtok(NULL, delims);
i++;
}
}
// 地域段白名单对比
int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
{
int i;
char *p;
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
if (strcmp(region_list[i], "\0") == 0) // 如果字符串为空就跳出循环
{
break;
}
//printf("%s %s\n", str, region_list[i]);
// 在str中查找region_list[i]
p = strstr(str, region_list[i]);
if (p != NULL) {
return 1;
}
}
return 0;
}
int is_valid_ip(const char *ip)
{
struct sockaddr_in sa;
@@ -231,6 +195,7 @@ int main(int argc, char *argv[])
perror("daemon");
return -1;
}
// 进程优先级
if (-1 == (nice_(-20)))
perror("nice_");
@@ -239,6 +204,7 @@ int main(int argc, char *argv[])
if ((r = system("ipset create root hash:ip > /dev/null 2>&1")) != -1) {
;
}
// 判断必要命令是否存在
if (command_exists("which tcpdump")) {
;
@@ -263,7 +229,6 @@ int main(int argc, char *argv[])
}
printf("%s\n", line);
pclose(fp);
sleep(3);
}
@@ -291,12 +256,14 @@ int main(int argc, char *argv[])
return -1;
}
}
// 打开管道来执行命令
FILE *fp = popen(command_tcpdump, "r");
if (fp == NULL) {
perror("popen failed");
return 1;
}
// 逐行读取命令输出
while (fgets(line, sizeof(line), fp) != NULL) {
line[strcspn(line, "\n")] = '\0';
@@ -334,12 +301,13 @@ int main(int argc, char *argv[])
;
} else {
char ipquery_command[BUFFER + 100] = { 0 };
snprintf(ipquery_command, BUFFER + 100, "./ipquery %s", line);
snprintf(ipquery_command, BUFFER + 100, "./IP_region_query/ipquery %s", line);
FILE *fp = popen(ipquery_command, "r");
if (fp == NULL) {
perror("popen failed");
return 1;
}
// 创建足够大的缓冲区来存储命令输出
char buffer[1024 * 2]; // 2KB 缓冲区
size_t bytesRead = fread(buffer, 1, sizeof(buffer) - 1, fp);

BIN
main.o

Binary file not shown.

View File

@@ -357,7 +357,7 @@ char *qqwry_(char *ip)
return NULL;
}
}
qqwry_init("qqwry.dat");
qqwry_init(qqdb_path);
get_location(ip);

Binary file not shown.