From 65140ec16c77862c7105dd2a49abb252e464269a Mon Sep 17 00:00:00 2001 From: flykhan Date: Thu, 21 Sep 2023 15:20:01 +0800 Subject: [PATCH] =?UTF-8?q?router=E6=A8=A1=E5=9D=97:=20=E5=A2=9E=E5=8A=A06?= =?UTF-8?q?=E3=80=819=E3=80=810=E8=8F=9C=E5=8D=95=E9=A1=B9,=20arp=20?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E9=80=9A=E8=BF=87=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=B9=B6=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/net_task_thread.c | 55 ++++++++- router/router.c | 248 +++++++++++++++++++++++---------------- router/router.h | 1 + 3 files changed, 200 insertions(+), 104 deletions(-) diff --git a/router/net_task_thread.c b/router/net_task_thread.c index 5a36577..c2b7e9b 100644 --- a/router/net_task_thread.c +++ b/router/net_task_thread.c @@ -1,11 +1,12 @@ #include "net_task_thread.h" +#include "db.h" void *net_task(void *arg) { printf("net_task\n"); char *dev1 = "ens33"; // 第一个网卡 - char *dev2 = "ens38"; // 第二个网卡 + char *dev2 = "ens34"; // 第二个网卡 // 打开网卡设备 // libnet_context1 使用 open_device 函数打开网卡设备1 后返回的 libnet 上下文 @@ -126,6 +127,9 @@ void process_packet(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char libnet, 0); + // 组包测试(如果能打印到这行,则说明组包成功) + printf("testssss\n"); + if (t == -1) { perror("libnet_build_ethernet"); @@ -152,5 +156,52 @@ void process_packet(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char void process_arp_packet(const u_char *packet) { struct ether_header *eth_hdr = (struct ether_header *)packet; - + 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); + } + } } \ No newline at end of file diff --git a/router/router.c b/router/router.c index 1e388b6..f4b11c3 100644 --- a/router/router.c +++ b/router/router.c @@ -7,6 +7,9 @@ int main(int argc, char const *argv[]) // 初始化 net_init(); // 初始化网络和数据库 + // 打开菜单 + menu_choice(); + // pthread_t thread_net_task; // pthread_create(&thread_net_task, NULL, net_task, NULL); // pthread_join(thread_net_task, NULL); @@ -36,108 +39,6 @@ void net_init() printf("数据库连接成功\n"); else printf("数据库连接错误\n"); - - // 选择标志位 - int choice = 0; - show(); // 打印菜单 - int pthread_flag = 0; - while (1) - { - printf("请输入你的选择: \n"); - scanf("%d", &choice); - getchar(); // 清空缓冲区 - if (1 == choice) - { - char add_blacked_ip[INET_ADDRSTRLEN] = ""; - printf("请输入要添加的黑名单IP:格式如 192.168.6.5\n"); - fgets(add_blacked_ip, sizeof(add_blacked_ip), stdin); - add_blacked_ip[strlen(add_blacked_ip) - 1] = '\0'; // 将最后的换行符替换为字符串结束符 - printf("add_blacked_ip: %s\n", add_blacked_ip); - // IP 格式检查 - if (is_ip_valid(add_blacked_ip) != 0) - { - printf("IP地址格式错误\n"); - continue; - } - - // 将IP地址加入黑名单 - MYSQL_BIND parmas[1]; - parmas[0].buffer_type = MYSQL_TYPE_STRING; - parmas[0].buffer = add_blacked_ip; - parmas[0].buffer_length = strlen(add_blacked_ip); - parmas[0].is_null = 0; - parmas[0].length = &parmas[0].buffer_length; - const char *insert_ip_fw_sql = "insert into ip_fw(ip) values(?)"; - int result = insert(insert_ip_fw_sql, parmas); - if (result > 0) - { - printf("黑名单添加成功\n"); - } - else - { - printf("黑名单添加失败\n"); - } - } - - else if (2 == choice) - { - const char *select_ip_fw_sql = "select * from ip_fw"; - query(select_ip_fw_sql, printResult); - } - - else if (3 == choice) - { - char delete_blacked_ip[INET_ADDRSTRLEN] = ""; - printf("请输入要删除的黑名单IP:格式如 192.168.6.5\n"); - fgets(delete_blacked_ip, sizeof(delete_blacked_ip), stdin); - delete_blacked_ip[strlen(delete_blacked_ip) - 1] = '\0'; // 将最后的换行符替换为字符串结束符 - printf("delete_blacked_ip: %s\n", delete_blacked_ip); - // IP 格式检查 - if (is_ip_valid(delete_blacked_ip) != 0) - { - printf("IP地址格式错误\n"); - continue; - } - - // 将IP地址从黑名单中删除 - MYSQL_BIND parmas[1]; - parmas[0].buffer_type = MYSQL_TYPE_STRING; - parmas[0].buffer = delete_blacked_ip; - parmas[0].buffer_length = strlen(delete_blacked_ip); - parmas[0].is_null = 0; - parmas[0].length = &parmas[0].buffer_length; - const char *delete_ip_fw_sql = "delete from ip_fw where ip = ?"; - int result = delete (delete_ip_fw_sql, parmas); - if (result > 0) - { - printf("黑名单删除成功\n"); - } - else - { - printf("黑名单删除失败\n"); - } - } - - else if (4 == choice) - { - if (0 == pthread_flag) - { - printf("开启路由器\n"); - pthread_flag += 1; // 线程标志位修改 - pthread_t thread_net_task; - pthread_create(&thread_net_task, NULL, net_task, NULL); - pthread_detach(thread_net_task); - } - else - { - printf("路由器正在运行......\n"); - } - } - - else if (5 == choice) - { - } - } } // MySQL 测试 @@ -236,3 +137,146 @@ int is_ip_valid(const char *ip) } // 发送ARP请求方法 + +// 后台菜单 +void menu_choice() +{ + // 选择标志位 + int choice = 0; + show(); // 打印菜单 + int pthread_flag = 0; + while (1) + { + printf("请输入你的选择: \n"); + scanf("%d", &choice); + getchar(); // 清空缓冲区 + + // 后端添加黑名单 ip + if (1 == choice) + { + char add_blacked_ip[INET_ADDRSTRLEN] = ""; + printf("请输入要添加的黑名单IP:格式如 192.168.6.5\n"); + fgets(add_blacked_ip, sizeof(add_blacked_ip), stdin); + add_blacked_ip[strlen(add_blacked_ip) - 1] = '\0'; // 将最后的换行符替换为字符串结束符 + printf("add_blacked_ip: %s\n", add_blacked_ip); + // IP 格式检查 + if (is_ip_valid(add_blacked_ip) != 0) + { + printf("IP地址格式错误\n"); + continue; + } + + // 将IP地址加入黑名单 + MYSQL_BIND parmas[1]; + parmas[0].buffer_type = MYSQL_TYPE_STRING; + parmas[0].buffer = add_blacked_ip; + parmas[0].buffer_length = strlen(add_blacked_ip); + parmas[0].is_null = 0; + parmas[0].length = &parmas[0].buffer_length; + const char *insert_ip_fw_sql = "insert into ip_fw(ip) values(?)"; + int result = insert(insert_ip_fw_sql, parmas); + if (result > 0) + { + printf("黑名单添加成功\n"); + } + else + { + printf("黑名单添加失败\n"); + } + } + + // 后端查询黑名单 ip + else if (2 == choice) + { + const char *select_ip_fw_sql = "select * from ip_fw"; + query(select_ip_fw_sql, printResult); + } + + // 后端删除黑名单 ip + else if (3 == choice) + { + char delete_blacked_ip[INET_ADDRSTRLEN] = ""; + printf("请输入要删除的黑名单IP:格式如 192.168.6.5\n"); + fgets(delete_blacked_ip, sizeof(delete_blacked_ip), stdin); + delete_blacked_ip[strlen(delete_blacked_ip) - 1] = '\0'; // 将最后的换行符替换为字符串结束符 + printf("delete_blacked_ip: %s\n", delete_blacked_ip); + // IP 格式检查 + if (is_ip_valid(delete_blacked_ip) != 0) + { + printf("IP地址格式错误\n"); + continue; + } + + // 将IP地址从黑名单中删除 + MYSQL_BIND parmas[1]; + parmas[0].buffer_type = MYSQL_TYPE_STRING; + parmas[0].buffer = delete_blacked_ip; + parmas[0].buffer_length = strlen(delete_blacked_ip); + parmas[0].is_null = 0; + parmas[0].length = &parmas[0].buffer_length; + const char *delete_ip_fw_sql = "delete from ip_fw where ip = ?"; + int result = delete (delete_ip_fw_sql, parmas); + if (result > 0) + { + printf("黑名单删除成功\n"); + } + else + { + printf("黑名单删除失败\n"); + } + } + + else if (4 == choice) + { + if (0 == pthread_flag) + { + printf("开启路由器\n"); + pthread_flag += 1; // 线程标志位修改 + pthread_t thread_net_task; + pthread_create(&thread_net_task, NULL, net_task, NULL); + pthread_detach(thread_net_task); + } + else + { + printf("路由器正在运行......\n"); + } + } + + else if (5 == choice) + { + } + + // 显示 ARP 表 + else if (6 == choice) + { + const char *select_arp_result_sql = "select * from ip_mac"; + query(select_arp_result_sql, printResult); + } + + // 重新打印菜单 + else if (9 == choice) + { + show(); + } + + // 退出此系统 + else if (0 == choice) + { + + close(sockfd); // 关闭原始套接字 + close_mysql(); // 关闭数据库连接 + + // 关闭网络设备 + pcap_close(device1); + pcap_close(device2); + + printf("退出此系统\n"); + return; + } + + else + { + printf("输入错误,请重新输入\n"); + } + } +} \ No newline at end of file diff --git a/router/router.h b/router/router.h index c22eba6..983963c 100644 --- a/router/router.h +++ b/router/router.h @@ -28,6 +28,7 @@ char **dbResult; int nrow; int ncolumn; +void menu_choice(); void show(void); // 后端控制菜单 void net_init(); // 网络初始化 void *net_task(void *arg); // 网络任务