2023-09-20 17:02:08 +08:00
|
|
|
|
#include "net_task_thread.h"
|
2023-09-21 15:20:01 +08:00
|
|
|
|
#include "db.h"
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
|
|
|
|
void *net_task(void *arg)
|
|
|
|
|
{
|
|
|
|
|
printf("net_task\n");
|
|
|
|
|
|
2023-09-22 15:16:23 +08:00
|
|
|
|
char *dev1 = "ens38"; // 第一个网卡
|
|
|
|
|
char *dev2 = "ens33"; // 第二个网卡
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 打开网卡设备
|
2023-09-21 11:26:50 +08:00
|
|
|
|
// libnet_context1 使用 open_device 函数打开网卡设备1 后返回的 libnet 上下文
|
|
|
|
|
libnet_context1 = open_device(&device1, dev1);
|
|
|
|
|
libnet_context2 = open_device(&device2, dev2);
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 开始捕获数据包:
|
|
|
|
|
// pcap_loop: 网卡设备、捕获的数据包个数、回调函数、传递给回调函数的参数
|
|
|
|
|
pcap_loop(device1, -1, process_packet, NULL); // -1 表示无限循环
|
|
|
|
|
pcap_loop(device2, -1, process_packet, NULL); // -1 表示无限循环
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 打开网卡设备
|
2023-09-21 11:26:50 +08:00
|
|
|
|
// 如果成功打开网卡设备,就返回 libnet 上下文
|
|
|
|
|
libnet_t *open_device(pcap_t **device, char *dev_name)
|
2023-09-21 09:51:03 +08:00
|
|
|
|
{
|
|
|
|
|
// 打开网卡设备: 设备名、最大字节数、混杂模式、超时时间、错误信息缓冲区
|
|
|
|
|
*device = pcap_open_live(dev_name, MAX_BYTE, 1, 512, errbuf);
|
|
|
|
|
if (*device == NULL)
|
2023-09-20 17:02:08 +08:00
|
|
|
|
{
|
2023-09-21 09:51:03 +08:00
|
|
|
|
perror("pcap_open_live");
|
|
|
|
|
exit(-1);
|
2023-09-20 17:02:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 处理数据包
|
2023-09-21 11:26:50 +08:00
|
|
|
|
libnet_t *libnet = libnet_init(LIBNET_LINK, dev_name, errbuf); // 初始化 libnet
|
|
|
|
|
if (libnet == NULL)
|
2023-09-20 17:02:08 +08:00
|
|
|
|
{
|
2023-09-21 09:51:03 +08:00
|
|
|
|
perror("libnet_init");
|
|
|
|
|
exit(-1);
|
2023-09-20 17:02:08 +08:00
|
|
|
|
}
|
2023-09-21 11:26:50 +08:00
|
|
|
|
|
|
|
|
|
return libnet; // 返回 libnet 上下文
|
2023-09-21 09:51:03 +08:00
|
|
|
|
}
|
2023-09-20 17:02:08 +08:00
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 处理数据包
|
2023-09-21 11:26:50 +08:00
|
|
|
|
// 参数: 传递给回调函数的参数、数据包头部、数据包
|
2023-09-21 09:51:03 +08:00
|
|
|
|
void process_packet(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
|
|
|
|
|
{
|
2023-09-21 11:26:50 +08:00
|
|
|
|
// 将数据包从一个网卡发送到另一个网卡
|
|
|
|
|
// 实际路由中,需要根据路由表进行路由选择
|
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
printf("process_packet\n");
|
2023-09-21 11:26:50 +08:00
|
|
|
|
/*
|
|
|
|
|
libnet_ptag_t t; // libnet 标签: 用于标识数据包中的某一部分
|
|
|
|
|
libnet_t *libnet; // libnet 上下文: 用于发送数据包
|
|
|
|
|
|
|
|
|
|
// 根据网卡设备选择 libnet 上下文,以便发送数据包
|
|
|
|
|
// 规则是: 如果是从网卡1接收到的数据包,就从网卡2发送出去
|
|
|
|
|
if (arg == (u_char *)device1)
|
|
|
|
|
{
|
|
|
|
|
libnet = libnet_context2;
|
|
|
|
|
}
|
|
|
|
|
else if (arg == (u_char *)device2)
|
|
|
|
|
{
|
|
|
|
|
libnet = libnet_context1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t = libnet_build_ethernet(
|
|
|
|
|
((struct libnet_ethernet_hdr *)packet)->ether_dhost, // 目的MAC地址
|
|
|
|
|
((struct libnet_ethernet_hdr *)packet)->ether_shost, // 源MAC地址
|
|
|
|
|
((struct libnet_ethernet_hdr *)packet)->ether_type, // 以太网类型
|
|
|
|
|
packet + LIBNET_ETH_H, // 负载数据(携带的数据)
|
|
|
|
|
pkthdr->len - LIBNET_ETH_H, // 以太网数据包的数据部分
|
|
|
|
|
libnet, // libnet 上下文
|
|
|
|
|
0 // 标记
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (t == -1)
|
|
|
|
|
{
|
|
|
|
|
perror("libnet_build_ethernet");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送数据包
|
|
|
|
|
int res = libnet_write(libnet);
|
|
|
|
|
if (res == -1)
|
|
|
|
|
{
|
|
|
|
|
perror("libnet_write");
|
|
|
|
|
exit(-1);
|
|
|
|
|
} */
|
|
|
|
|
|
|
|
|
|
struct libnet_ethernet_hdr *eth_hdr = (struct libnet_ethernet_hdr *)packet;
|
|
|
|
|
|
|
|
|
|
// 如果是IP数据包,就打印源IP地址和目的IP地址
|
|
|
|
|
if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP)
|
|
|
|
|
{
|
|
|
|
|
struct libnet_ipv4_hdr *ip_hdr = (struct libnet_ipv4_hdr *)(packet + LIBNET_ETH_H);
|
|
|
|
|
if (ip_hdr->ip_p == IPPROTO_TCP)
|
|
|
|
|
{
|
|
|
|
|
struct libnet_tcp_hdr *tcp_hdr = (struct libnet_tcp_hdr *)(packet + LIBNET_ETH_H + LIBNET_IPV4_H);
|
|
|
|
|
printf("TCP: %s:%d -> %s:%d\n", inet_ntoa(ip_hdr->ip_src), ntohs(tcp_hdr->th_sport), inet_ntoa(ip_hdr->ip_dst), ntohs(tcp_hdr->th_dport));
|
|
|
|
|
}
|
|
|
|
|
else if (ip_hdr->ip_p == IPPROTO_UDP)
|
|
|
|
|
{
|
|
|
|
|
struct libnet_udp_hdr *udp_hdr = (struct libnet_udp_hdr *)(packet + LIBNET_ETH_H + LIBNET_IPV4_H);
|
|
|
|
|
printf("UDP: %s:%d -> %s:%d\n", inet_ntoa(ip_hdr->ip_src), ntohs(udp_hdr->uh_sport), inet_ntoa(ip_hdr->ip_dst), ntohs(udp_hdr->uh_dport));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
libnet_t *libnet;
|
|
|
|
|
if (arg == (u_char *)device1)
|
|
|
|
|
{
|
|
|
|
|
libnet = libnet_context2;
|
|
|
|
|
}
|
|
|
|
|
else if (arg == (u_char *)device2)
|
|
|
|
|
{
|
|
|
|
|
libnet = libnet_context1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 15:16:23 +08:00
|
|
|
|
printf("testssssxxxxs\n");
|
|
|
|
|
|
2023-09-21 11:26:50 +08:00
|
|
|
|
libnet_ptag_t t = libnet_build_ethernet(
|
|
|
|
|
eth_hdr->ether_dhost,
|
|
|
|
|
eth_hdr->ether_shost,
|
|
|
|
|
ETHERTYPE_IP,
|
|
|
|
|
packet + LIBNET_ETH_H,
|
|
|
|
|
pkthdr->len - LIBNET_ETH_H,
|
|
|
|
|
libnet,
|
|
|
|
|
0);
|
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 组包测试(如果能打印到这行,则说明组包成功)
|
|
|
|
|
printf("testssss\n");
|
|
|
|
|
|
2023-09-21 11:26:50 +08:00
|
|
|
|
if (t == -1)
|
|
|
|
|
{
|
|
|
|
|
perror("libnet_build_ethernet");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int res = libnet_write(libnet);
|
|
|
|
|
if (res == -1)
|
|
|
|
|
{
|
|
|
|
|
perror("libnet_write");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是ARP数据包,就打印源IP地址和目的IP地址
|
|
|
|
|
if (ntohs(eth_hdr->ether_type) == ETHERTYPE_ARP)
|
|
|
|
|
{
|
|
|
|
|
struct libnet_arp_hdr *arp_hdr = (struct libnet_arp_hdr *)(packet + LIBNET_ETH_H);
|
|
|
|
|
// printf("ARP: %s -> %s\n", inet_ntoa(*(struct in_addr *)arp_hdr->arp_spa), inet_ntoa(*(struct in_addr *)arp_hdr->arp_tpa));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ARP 数据报处理函数
|
|
|
|
|
void process_arp_packet(const u_char *packet)
|
|
|
|
|
{
|
|
|
|
|
struct ether_header *eth_hdr = (struct ether_header *)packet;
|
2023-09-21 15:20:01 +08:00
|
|
|
|
struct ether_arp *arp_hdr = (struct ether_arp *)(packet + LIBNET_ETH_H); // packet + 14
|
|
|
|
|
|
|
|
|
|
if (ntohs(eth_hdr->ether_type) == ETHERTYPE_ARP)
|
|
|
|
|
{
|
|
|
|
|
char ip_address[INET_ADDRSTRLEN];
|
|
|
|
|
char mac_address[ETH_ALEN * 3]; // ETH_ALEN * 3 是为了申请足够的空间存储 MAC 地址
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
inet_ntop 用于将二进制的 IP 地址转换为可读的字符串形式
|
|
|
|
|
|
|
|
|
|
参数说明:
|
|
|
|
|
AF_INET:指定要转换的地址族,这里是 IPv4 地址。
|
|
|
|
|
arp_hdr->arp_spa:源 IP 地址的指针,它是一个二进制的网络字节序的 IPv4 地址。
|
|
|
|
|
ip_address:用于存储转换后的 IP 地址字符串的缓冲区。
|
|
|
|
|
sizeof(ip_address):指定缓冲区的大小,以确保不会发生缓冲区溢出。
|
|
|
|
|
*/
|
|
|
|
|
inet_ntop(AF_INET, arp_hdr->arp_spa, ip_address, sizeof(ip_address));
|
|
|
|
|
snprintf(mac_address, sizeof(mac_address),
|
|
|
|
|
"%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
arp_hdr->arp_sha[0],
|
|
|
|
|
arp_hdr->arp_sha[1],
|
|
|
|
|
arp_hdr->arp_sha[2],
|
|
|
|
|
arp_hdr->arp_sha[3],
|
|
|
|
|
arp_hdr->arp_sha[4],
|
|
|
|
|
arp_hdr->arp_sha[5]);
|
|
|
|
|
|
|
|
|
|
// printf("ARP: %s -> %s\n", ip_address, mac_address);
|
|
|
|
|
|
|
|
|
|
MYSQL_BIND parmas[2];
|
|
|
|
|
parmas[0].buffer_type = MYSQL_TYPE_STRING;
|
|
|
|
|
parmas[0].buffer = ip_address;
|
|
|
|
|
parmas[0].buffer_length = strlen(ip_address);
|
|
|
|
|
parmas[0].is_null = 0;
|
|
|
|
|
parmas[0].length = &parmas[0].buffer_length;
|
|
|
|
|
parmas[1].buffer_type = MYSQL_TYPE_STRING;
|
|
|
|
|
parmas[1].buffer = mac_address;
|
|
|
|
|
parmas[1].buffer_length = strlen(mac_address);
|
|
|
|
|
parmas[1].is_null = 0;
|
|
|
|
|
parmas[1].length = &parmas[1].buffer_length;
|
|
|
|
|
// snprintf(arp_result_sql, sizeof(arp_result_sql), "insert into arp_result(ip, mac) values('%s', '%s')", ip_address, mac_address);
|
|
|
|
|
char arp_result_sql[1024] = "insert into arp_result(ip, mac) values(?, ?)";
|
|
|
|
|
int result = insert(arp_result_sql, parmas);
|
|
|
|
|
|
|
|
|
|
if (result > 0)
|
|
|
|
|
{
|
|
|
|
|
printf("ARP: %s -> %s\n", ip_address, mac_address);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-22 15:16:23 +08:00
|
|
|
|
}
|