2023-09-20 16:13:41 +08:00
|
|
|
|
#include "router.h"
|
|
|
|
|
#include "db.h"
|
2023-09-21 09:51:03 +08:00
|
|
|
|
#include "net_task_thread.h"
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
|
|
|
|
int main(int argc, char const *argv[])
|
|
|
|
|
{
|
|
|
|
|
// 初始化
|
|
|
|
|
net_init(); // 初始化网络和数据库
|
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 打开菜单
|
|
|
|
|
menu_choice();
|
|
|
|
|
|
2023-09-20 16:13:41 +08:00
|
|
|
|
// pthread_t thread_net_task;
|
|
|
|
|
// pthread_create(&thread_net_task, NULL, net_task, NULL);
|
|
|
|
|
// pthread_join(thread_net_task, NULL);
|
|
|
|
|
|
|
|
|
|
close(sockfd); // 关闭原始套接字
|
|
|
|
|
close_mysql(); // 关闭数据库连接
|
|
|
|
|
|
2023-09-21 09:51:03 +08:00
|
|
|
|
// 关闭网络设备
|
|
|
|
|
pcap_close(device1);
|
|
|
|
|
pcap_close(device2);
|
|
|
|
|
|
2023-09-20 16:13:41 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void net_init()
|
|
|
|
|
{
|
|
|
|
|
// 创建原始套接字
|
|
|
|
|
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); // 参数列表:协议族、套接字类型、协议类型
|
|
|
|
|
if (sockfd < 0)
|
|
|
|
|
{
|
|
|
|
|
perror("socket");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据连接测试
|
|
|
|
|
if (connect_mysql("localhost", 3306, "flykhan", "1202", "router") == 0)
|
|
|
|
|
printf("数据库连接成功\n");
|
|
|
|
|
else
|
|
|
|
|
printf("数据库连接错误\n");
|
2023-09-21 15:20:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MySQL 测试
|
|
|
|
|
int is_blocked_ip(unsigned char *ip)
|
|
|
|
|
{
|
|
|
|
|
char sql[1024] = "";
|
|
|
|
|
sprintf(sql, "select * from ip_fw where ip = '%s'", ip);
|
|
|
|
|
int rows = result_rows(sql);
|
|
|
|
|
|
|
|
|
|
printf("打印 %s\n", sql);
|
|
|
|
|
printf("rows: %d\n", rows);
|
|
|
|
|
|
|
|
|
|
// execlp("iptables", "iptables", "-A", "FORWARD", "-s", ip, "-j", "DROP", NULL); // 将源IP地址加入防火墙
|
|
|
|
|
execlp("iptables", "iptables", "-D", "FORWARD", "-s", ip, "-j", "DROP", NULL); // 将源IP地址加入防火墙
|
|
|
|
|
|
|
|
|
|
// 获取行数
|
|
|
|
|
if (rows > 0)
|
|
|
|
|
{
|
|
|
|
|
printf("IP地址 %s 在黑名单中\n", ip);
|
|
|
|
|
// execlp("iptables", "iptables", "-A", "FORWARD", "-s", ip, "-j", "DROP", NULL); // 将源IP地址加入防火墙
|
|
|
|
|
// 从防火墙删除
|
|
|
|
|
execlp("iptables", "iptables", "-D", "FORWARD", "-s", ip, "-j", "DROP", NULL); // 将源IP地址加入防火墙
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("IP地址 %s 不在黑名单中\n", ip);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void printResult(MYSQL_ROW row, char (*columns)[30], int cols)
|
|
|
|
|
{
|
|
|
|
|
// printf("printResult\n");
|
|
|
|
|
// printf("cols: %d\n", cols);
|
|
|
|
|
// printf("row: %s\n", row[0]);
|
|
|
|
|
|
|
|
|
|
// printf("%s\n", columns[0]);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < cols; i++)
|
|
|
|
|
{
|
|
|
|
|
printf("%s: %s \t", columns[i], row[i]);
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void show()
|
|
|
|
|
{
|
|
|
|
|
printf("************************************************\n");
|
|
|
|
|
printf("**********路由器黑名单管理系统******************\n");
|
|
|
|
|
printf("**************1.添加黑名单IP********************\n");
|
|
|
|
|
printf("**************2.显示所有黑名单******************\n");
|
|
|
|
|
printf("**************3.删除黑名单**********************\n");
|
|
|
|
|
printf("**************4.开启路由器**********************\n");
|
|
|
|
|
printf("**************5.刷新ARP表缓存*******************\n");
|
|
|
|
|
printf("**************6.显示所有ARP表缓存***************\n");
|
|
|
|
|
printf("**************9.重新打印菜单********************\n");
|
|
|
|
|
printf("**************0.退出此系统**********************\n");
|
|
|
|
|
printf("************************************************\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断IP地址格式是否正确
|
|
|
|
|
int is_ip_valid(const char *ip)
|
|
|
|
|
{
|
|
|
|
|
regex_t regex; // 正则表达式
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
// 编译正则表达式
|
|
|
|
|
// /^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$/
|
|
|
|
|
ret = regcomp(®ex, "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", REG_EXTENDED); // REG_EXTENDED 扩展正则表达式
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
|
|
|
|
printf("regcomp error\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 执行正则表达式
|
|
|
|
|
ret = regexec(®ex, ip, 0, NULL, 0);
|
|
|
|
|
regfree(®ex); // 释放正则表达式
|
|
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
|
{
|
|
|
|
|
printf("IP地址格式正确\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (ret == REG_NOMATCH)
|
|
|
|
|
{
|
|
|
|
|
printf("IP地址格式非法\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("正则表达式匹配错误\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送ARP请求方法
|
|
|
|
|
|
|
|
|
|
// 后台菜单
|
|
|
|
|
void menu_choice()
|
|
|
|
|
{
|
2023-09-20 16:13:41 +08:00
|
|
|
|
// 选择标志位
|
|
|
|
|
int choice = 0;
|
|
|
|
|
show(); // 打印菜单
|
|
|
|
|
int pthread_flag = 0;
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
printf("请输入你的选择: \n");
|
|
|
|
|
scanf("%d", &choice);
|
|
|
|
|
getchar(); // 清空缓冲区
|
2023-09-21 15:20:01 +08:00
|
|
|
|
|
|
|
|
|
// 后端添加黑名单 ip
|
2023-09-20 16:13:41 +08:00
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 后端查询黑名单 ip
|
2023-09-20 16:51:37 +08:00
|
|
|
|
else if (2 == choice)
|
2023-09-20 16:13:41 +08:00
|
|
|
|
{
|
2023-09-20 16:51:37 +08:00
|
|
|
|
const char *select_ip_fw_sql = "select * from ip_fw";
|
|
|
|
|
query(select_ip_fw_sql, printResult);
|
2023-09-20 16:13:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 后端删除黑名单 ip
|
2023-09-20 16:51:37 +08:00
|
|
|
|
else if (3 == choice)
|
2023-09-20 16:13:41 +08:00
|
|
|
|
{
|
2023-09-20 16:51:37 +08:00
|
|
|
|
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)
|
2023-09-20 16:13:41 +08:00
|
|
|
|
{
|
2023-09-20 16:51:37 +08:00
|
|
|
|
printf("IP地址格式错误\n");
|
2023-09-20 16:13:41 +08:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 16:51:37 +08:00
|
|
|
|
// 将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 = ?";
|
2023-09-20 17:02:08 +08:00
|
|
|
|
int result = delete (delete_ip_fw_sql, parmas);
|
2023-09-20 16:51:37 +08:00
|
|
|
|
if (result > 0)
|
|
|
|
|
{
|
|
|
|
|
printf("黑名单删除成功\n");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("黑名单删除失败\n");
|
|
|
|
|
}
|
2023-09-20 16:13:41 +08:00
|
|
|
|
}
|
2023-09-21 09:51:03 +08:00
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-09-20 16:51:37 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 显示 ARP 表
|
|
|
|
|
else if (6 == choice)
|
|
|
|
|
{
|
|
|
|
|
const char *select_arp_result_sql = "select * from ip_mac";
|
|
|
|
|
query(select_arp_result_sql, printResult);
|
|
|
|
|
}
|
2023-09-20 16:51:37 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 重新打印菜单
|
|
|
|
|
else if (9 == choice)
|
|
|
|
|
{
|
|
|
|
|
show();
|
|
|
|
|
}
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 退出此系统
|
|
|
|
|
else if (0 == choice)
|
|
|
|
|
{
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
close(sockfd); // 关闭原始套接字
|
|
|
|
|
close_mysql(); // 关闭数据库连接
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
// 关闭网络设备
|
|
|
|
|
pcap_close(device1);
|
|
|
|
|
pcap_close(device2);
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
printf("退出此系统\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-09-20 16:13:41 +08:00
|
|
|
|
|
2023-09-21 15:20:01 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("输入错误,请重新输入\n");
|
|
|
|
|
}
|
2023-09-20 16:13:41 +08:00
|
|
|
|
}
|
2023-09-21 15:20:01 +08:00
|
|
|
|
}
|