路由黑名单可从终端添加到mysql数据库中,包含插入前ip格式检查
This commit is contained in:
parent
cdf2350d9f
commit
7a0a6e0a29
|
@ -3,14 +3,16 @@ SRC_DIR = ./
|
|||
OBJ_DIR = ./
|
||||
BIN_DIR = ./
|
||||
|
||||
|
||||
# CFLAGS = -Wall -Wextra -Werror
|
||||
# 定义编译器
|
||||
CC = gcc
|
||||
# 定义目标文件
|
||||
TARGET = $(BIN_DIR)/debug
|
||||
TARGET = $(BIN_DIR)/router
|
||||
# 定义源文件
|
||||
SRCS = $(wildcard $(SRC_DIR)/*.c)
|
||||
OBJS = $(OBJ_DIR)/t1.o $(OBJ_DIR)/get_interface.o
|
||||
# OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
|
||||
# OBJS = $(OBJ_DIR)/t1.o $(OBJ_DIR)/get_interface.o
|
||||
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
|
||||
|
||||
# 编译规则
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
|
@ -18,7 +20,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
|||
|
||||
# 链接规则
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $^ -o $@ -lpcap -lpthread
|
||||
$(CC) $^ -o $@ -lpcap -lpthread -lmysqlclient
|
||||
|
||||
# 默认构建目标
|
||||
all: $(TARGET)
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#include "db.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int connect_mysql(const char *host, int port, const char *user, const char *pwd, const char *db_name)
|
||||
{
|
||||
if (conn_db == NULL)
|
||||
{
|
||||
conn_db = (MYSQL *)malloc(sizeof(MYSQL));
|
||||
if (mysql_init(conn_db) != NULL)
|
||||
{
|
||||
mysql_set_character_set(conn_db, "utf8");
|
||||
// if (mysql_real_connect(conn_db, "localhost", "disen", "disen", "db1",
|
||||
// 3306, NULL, 0) == NULL)
|
||||
if (mysql_real_connect(conn_db, host, user, pwd, db_name,
|
||||
port, NULL, 0) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int query(const char *sql, void (*callback)(MYSQL_ROW row, char (*columns)[30], int cols))
|
||||
{
|
||||
if (NULL == conn_db)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ret = mysql_real_query(conn_db, sql, strlen(sql));
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MYSQL_RES *res = mysql_store_result(conn_db);
|
||||
if (res != NULL)
|
||||
{
|
||||
my_ulonglong rows = mysql_num_rows(res);
|
||||
// printf("查找到的数据库的行数为 %llu\n", rows);
|
||||
unsigned int cols = mysql_num_fields(res);
|
||||
char colunm_names[cols][30];
|
||||
int i = 0;
|
||||
|
||||
MYSQL_FIELD *field = NULL;
|
||||
while ((field = mysql_fetch_field(res)) != NULL)
|
||||
{
|
||||
strcpy(colunm_names[i++], field->name);
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
if (callback != NULL)
|
||||
callback(row, colunm_names, cols);
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int insert(const char *sql, MYSQL_BIND *params)
|
||||
{
|
||||
MYSQL_STMT *stmt = mysql_stmt_init(conn_db);
|
||||
mysql_stmt_prepare(stmt, sql, strlen(sql));
|
||||
|
||||
if (params != NULL)
|
||||
{
|
||||
if (mysql_stmt_bind_param(stmt, params)) // 11)错误 0)成功
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (mysql_stmt_execute(stmt) != 0)
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
return -1;
|
||||
}
|
||||
int ret = mysql_stmt_fetch(stmt);
|
||||
mysql_stmt_close(stmt);
|
||||
return ret; // 返回是影响的行数
|
||||
}
|
||||
|
||||
int close_mysql()
|
||||
{
|
||||
if (conn_db != NULL)
|
||||
{
|
||||
mysql_close(conn_db);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result_rows(const char *sql)
|
||||
{
|
||||
if (NULL == conn_db)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ret = mysql_real_query(conn_db, sql, strlen(sql));
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
my_ulonglong rows = 0;
|
||||
MYSQL_RES *res = mysql_store_result(conn_db);
|
||||
if (res != NULL)
|
||||
{
|
||||
rows = mysql_num_rows(res);
|
||||
// printf("查找到的数据库的行数为 %llu\n", rows);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include <mysql/mysql.h>
|
||||
#include <string.h>
|
||||
|
||||
static MYSQL *conn_db = NULL;
|
||||
|
||||
// 连接
|
||||
extern int connect_mysql(const char *host, int port, const char *user, const char *pwd, const char *db_name);
|
||||
|
||||
// 关闭
|
||||
extern int close_mysql();
|
||||
|
||||
// 查询
|
||||
extern int query(const char *sql, void (*callback)(MYSQL_ROW row, char (*columns)[30], int cols));
|
||||
|
||||
// 返回查询结果的行数
|
||||
extern int result_rows(const char *sql);
|
||||
|
||||
// 插入
|
||||
extern int insert(const char *sql, MYSQL_BIND *params);
|
||||
|
||||
// 更新
|
||||
extern int update(const char *sql, MYSQL_BIND *params);
|
BIN
router/debug
BIN
router/debug
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,340 @@
|
|||
#include "router.h"
|
||||
#include "db.h"
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
// 初始化
|
||||
net_init(); // 初始化网络和数据库
|
||||
|
||||
// pthread_t thread_net_task;
|
||||
// pthread_create(&thread_net_task, NULL, net_task, NULL);
|
||||
// pthread_join(thread_net_task, NULL);
|
||||
|
||||
close(sockfd); // 关闭原始套接字
|
||||
close_mysql(); // 关闭数据库连接
|
||||
|
||||
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");
|
||||
|
||||
// 选择标志位
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *net_task(void *arg)
|
||||
{
|
||||
printf("net_task\n");
|
||||
|
||||
// 1. 获取可用的网络设备名称
|
||||
char errbuf[PCAP_ERRBUF_SIZE]; // 错误信息
|
||||
pcap_if_t *alldevs;
|
||||
if (pcap_findalldevs(&alldevs, errbuf) == -1)
|
||||
{
|
||||
printf("pcap_findalldevs error: %s\n", errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 2. 打印网络设备名称
|
||||
pcap_if_t *d;
|
||||
for (d = alldevs; d != NULL; d = d->next)
|
||||
{
|
||||
printf("%s\n", d->name);
|
||||
}
|
||||
|
||||
// 3. 获取第一个网络设备的IP地址
|
||||
pcap_addr_t *a;
|
||||
for (a = alldevs->addresses; a != NULL; a = a->next)
|
||||
{
|
||||
if (a->addr->sa_family == AF_INET)
|
||||
{
|
||||
// ntoa 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
printf("%s\n", inet_ntoa(((struct sockaddr_in *)a->addr)->sin_addr));
|
||||
}
|
||||
}
|
||||
|
||||
// 获取网卡的网络号和网络掩码
|
||||
bpf_u_int32 netip, netmask;
|
||||
if (pcap_lookupnet(alldevs->name, &netip, &netmask, NULL) != 0)
|
||||
{
|
||||
printf("网络号和网络掩码获取错误\n");
|
||||
return -1;
|
||||
}
|
||||
unsigned char ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char mask[INET_ADDRSTRLEN] = "";
|
||||
// ntop 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
inet_ntop(AF_INET, &netip, ip, INET_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, &netmask, mask, INET_ADDRSTRLEN);
|
||||
printf("网络号: %s 网络掩码: %s\n", ip, mask);
|
||||
|
||||
// 获取网卡的MAC地址
|
||||
struct ifreq ifr;
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
strcpy(ifr.ifr_name, alldevs->name);
|
||||
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
|
||||
{
|
||||
printf("MAC地址获取失败\n");
|
||||
return -1;
|
||||
}
|
||||
unsigned char mac[6];
|
||||
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
|
||||
printf("MAC地址: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
// 打开网络设备,开始抓包(捕获数据包)
|
||||
pcap_t *pcap_handle = pcap_open_live(alldevs->name, 65535, 1, 0, errbuf); // 65535 最大捕获的字节数 1 混杂模式 0 不超时 errbuf 错误信息
|
||||
if (pcap_handle == NULL)
|
||||
{
|
||||
printf("pcap_open_live error: %s\n", errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 4. 抓包
|
||||
struct pcap_pkthdr pcap_header; // 数据包头
|
||||
bzero(&pcap_header, sizeof(pcap_header)); // 清空
|
||||
const u_char *packet; // 数据包数据
|
||||
while (1)
|
||||
{
|
||||
packet = pcap_next(pcap_handle, &pcap_header); // 抓包
|
||||
if (packet == NULL)
|
||||
{
|
||||
printf("pcap_next error\n");
|
||||
return 1;
|
||||
}
|
||||
printf("数据包长度: %d\n", pcap_header.len);
|
||||
printf("捕获的数据长度: %d\n", pcap_header.caplen);
|
||||
// printf("数据包时间: %s", ctime((const time_t *)&pcap_header.ts.tv_sec));
|
||||
// printf("数据包内容: ");
|
||||
// for (int i = 0; i < pcap_header.len; i++)
|
||||
// {
|
||||
// printf("%02x ", packet[i]);
|
||||
// }
|
||||
|
||||
// 5. 解析数据包
|
||||
struct ether_header *eth_header = (struct ether_header *)packet; // 以太网帧头
|
||||
unsigned char src_mac[18] = "";
|
||||
unsigned char dst_mac[18] = "";
|
||||
sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x", eth_header->ether_shost[0], eth_header->ether_shost[1], eth_header->ether_shost[2], eth_header->ether_shost[3], eth_header->ether_shost[4], eth_header->ether_shost[5]); // 将MAC地址转换为点分十进制的字符串
|
||||
sprintf(dst_mac, "%02x:%02x:%02x:%02x:%02x:%02x", eth_header->ether_dhost[0], eth_header->ether_dhost[1], eth_header->ether_dhost[2], eth_header->ether_dhost[3], eth_header->ether_dhost[4], eth_header->ether_dhost[5]);
|
||||
unsigned short eth_type = ntohs(eth_header->ether_type); // type 字段是网络字节序,需要转换为主机字节序
|
||||
printf("以太网帧类型: %04x\n", eth_type); // 0x080 IP协议 0x0806 ARP协议 0x8035 RARP协议 0x86dd IPv6协议
|
||||
printf("目的MAC地址: %s\n", dst_mac);
|
||||
printf("源MAC地址: %s\n", src_mac);
|
||||
|
||||
// 如果是ARP协议
|
||||
if (eth_type == 0x0806)
|
||||
{
|
||||
// // 分析 arp 报文
|
||||
// struct ether_arp *arp_header = (struct ether_arp *)(packet + sizeof(struct ether_header)); // arp 报文
|
||||
// unsigned short this_arp_op = ntohs(arp_header->arp_op); // 操作码
|
||||
// printf("ARP操作码: %d\n", this_arp_op); // 1 ARP请求 2 ARP应答 3 RARP请求 4 RARP应答
|
||||
// if (this_arp_op == 1 || this_arp_op == 2)
|
||||
// {
|
||||
// unsigned char src_ip[INET_ADDRSTRLEN] = "";
|
||||
// unsigned char dst_ip[INET_ADDRSTRLEN] = "";
|
||||
// inet_ntop(AF_INET, arp_header->arp_spa, src_ip, INET_ADDRSTRLEN); // 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
// inet_ntop(AF_INET, arp_header->arp_tpa, dst_ip, INET_ADDRSTRLEN);
|
||||
// printf("源IP地址: %s\n", src_ip);
|
||||
// printf("目的IP地址: %s\n", dst_ip);
|
||||
// }
|
||||
|
||||
// 发送 ARP 请求,用于广播获取网段内的所有已连接设备的mac地址,并存入 ip_mac 映射表
|
||||
}
|
||||
|
||||
// 如果是IP协议
|
||||
if (eth_type == 0x800)
|
||||
{
|
||||
// 分析 ip 报文
|
||||
struct iphdr *ip_header = (struct iphdr *)(packet + sizeof(struct ether_header)); // ip 报文 (sizeof(struct ether_header) = 14 (MAC)以太网帧头长度)
|
||||
unsigned char src_ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char dst_ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char ip_protocol[INET_ADDRSTRLEN] = ""; // 协议类型
|
||||
inet_ntop(AF_INET, &ip_header->saddr, src_ip, INET_ADDRSTRLEN); // 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
inet_ntop(AF_INET, &ip_header->daddr, dst_ip, INET_ADDRSTRLEN);
|
||||
printf("IP协议类型: %d\n", ip_header->protocol); // ICMP(1),IGMP(2),TCP(6),UDP(17),IPv6(41)
|
||||
printf("源IP地址: %s\n", src_ip);
|
||||
printf("目的IP地址: %s\n", dst_ip);
|
||||
|
||||
// 如果是黑名单IP,则跳过本次循环,即屏蔽本ip的数据
|
||||
if (is_blocked_ip(src_ip) == 0 || is_blocked_ip(dst_ip) == 0)
|
||||
{
|
||||
printf("数据报已被过滤\n");
|
||||
continue;
|
||||
}
|
||||
// is_blocked_ip(src_ip);
|
||||
printf("数据报正常\n");
|
||||
|
||||
// 不在黑名单时,进行数据报中ip和mac地址的转换和转发
|
||||
|
||||
// 先检查ip对应的mac地址是否存在(mysql->ip_mac表查询),存在时进行下一步;不存在时,调用三次循环,来进行ARP广播,获取最新的设备ip--mac
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// 3. 释放资源
|
||||
pcap_close(pcap_handle); // 关闭网络设备
|
||||
pcap_freealldevs(alldevs); // 释放资源
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
int printResult(MYSQL_ROW row, char (*columns)[30], int cols)
|
||||
{
|
||||
printf("printResult\n");
|
||||
printf("cols: %d\n", cols);
|
||||
printf("row: %s\n", row[0]);
|
||||
for (int i = 0; i < cols; i++)
|
||||
{
|
||||
printf("%s: %s\n", columns[i], row[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
int rows = atoi(row[0]);
|
||||
if (rows > 0)
|
||||
{
|
||||
printf("IP地址 在黑名单中\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("IP地址不在黑名单中\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return atoi(row[0]); // 返回行数
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 执行正则表达式
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef __ROUTER_H__
|
||||
#define __ROUTER_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> //recvfrom
|
||||
#include <netinet/ether.h> //ETH_P_ALL
|
||||
#include <arpa/inet.h> //inet_ntop
|
||||
#include <net/if.h> //ifreq
|
||||
#include <sys/ioctl.h> //ioctl
|
||||
#include <netpacket/packet.h> //sockaddr_ll
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <mysql/mysql.h> // mysql
|
||||
#include <netinet/ip.h> // ip
|
||||
#include <pcap/pcap.h>
|
||||
#include <regex.h> // 正则表达式,用于ip地址检查
|
||||
|
||||
// 定义全局变量
|
||||
int sockfd; // 原始套接字
|
||||
int ret; // 调用数据库的返回值
|
||||
char *errmsg; // 错误信息
|
||||
char **dbResult;
|
||||
int nrow;
|
||||
int ncolumn;
|
||||
|
||||
void show(void); // 后端控制菜单
|
||||
void net_init(); // 网络初始化
|
||||
void *net_task(void *arg); // 网络任务
|
||||
int is_blocked_ip(unsigned char *ip); // 黑名单探测
|
||||
int printResult(MYSQL_ROW row, char (*columns)[30], int cols);
|
||||
int is_ip_valid(const char *ip); // 检查ip地址是否合法
|
||||
|
||||
#endif
|
175
router/t1.c
175
router/t1.c
|
@ -1,175 +0,0 @@
|
|||
#include <pcap/pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h> // ioctl 函数 SIOCGIFHWADDR SIOCGIFADDR
|
||||
// #include <netinet/if_ether.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include "get_interface.h"
|
||||
|
||||
void *input_task(void *arg)
|
||||
{
|
||||
char buf[1024];
|
||||
while (1)
|
||||
{
|
||||
bzero(buf, sizeof(buf));
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
printf("input: %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
void *net_task(void *arg)
|
||||
{
|
||||
// 1. 获取可用的网络设备名称
|
||||
char errbuf[PCAP_ERRBUF_SIZE]; // 错误信息
|
||||
pcap_if_t *alldevs;
|
||||
if (pcap_findalldevs(&alldevs, errbuf) == -1)
|
||||
{
|
||||
printf("pcap_findalldevs error: %s\n", errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* // 2. 打印网络设备名称
|
||||
pcap_if_t *d;
|
||||
for (d = alldevs; d != NULL; d = d->next)
|
||||
{
|
||||
printf("%s\n", d->name);
|
||||
} */
|
||||
|
||||
// 3. 获取第一个网络设备的IP地址
|
||||
pcap_addr_t *a;
|
||||
for (a = alldevs->addresses; a != NULL; a = a->next)
|
||||
{
|
||||
if (a->addr->sa_family == AF_INET)
|
||||
{
|
||||
// ntoa 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
printf("%s\n", inet_ntoa(((struct sockaddr_in *)a->addr)->sin_addr));
|
||||
}
|
||||
}
|
||||
|
||||
// 获取网卡的网络号和网络掩码
|
||||
bpf_u_int32 netip, netmask;
|
||||
if (pcap_lookupnet(alldevs->name, &netip, &netmask, NULL) != 0)
|
||||
{
|
||||
printf("网络号和网络掩码获取错误\n");
|
||||
return -1;
|
||||
}
|
||||
unsigned char ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char mask[INET_ADDRSTRLEN] = "";
|
||||
// ntop 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
inet_ntop(AF_INET, &netip, ip, INET_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, &netmask, mask, INET_ADDRSTRLEN);
|
||||
printf("网络号: %s 网络掩码: %s\n", ip, mask);
|
||||
|
||||
// 获取网卡的MAC地址
|
||||
struct ifreq ifr;
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
strcpy(ifr.ifr_name, alldevs->name);
|
||||
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
|
||||
{
|
||||
printf("MAC地址获取失败\n");
|
||||
return -1;
|
||||
}
|
||||
unsigned char mac[6];
|
||||
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
|
||||
printf("MAC地址: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
// 打开网络设备,开始抓包(捕获数据包)
|
||||
pcap_t *pcap_handle = pcap_open_live(alldevs->name, 65535, 1, 0, errbuf); // 65535 最大捕获的字节数 1 混杂模式 0 不超时 errbuf 错误信息
|
||||
if (pcap_handle == NULL)
|
||||
{
|
||||
printf("pcap_open_live error: %s\n", errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 4. 抓包
|
||||
struct pcap_pkthdr pcap_header; // 数据包头
|
||||
bzero(&pcap_header, sizeof(pcap_header)); // 清空
|
||||
const u_char *packet; // 数据包数据
|
||||
while (1)
|
||||
{
|
||||
packet = pcap_next(pcap_handle, &pcap_header); // 抓包
|
||||
if (packet == NULL)
|
||||
{
|
||||
printf("pcap_next error\n");
|
||||
return 1;
|
||||
}
|
||||
printf("数据包长度: %d\n", pcap_header.len);
|
||||
printf("捕获的数据长度: %d\n", pcap_header.caplen);
|
||||
// printf("数据包时间: %s", ctime((const time_t *)&pcap_header.ts.tv_sec));
|
||||
// printf("数据包内容: ");
|
||||
// for (int i = 0; i < pcap_header.len; i++)
|
||||
// {
|
||||
// printf("%02x ", packet[i]);
|
||||
// }
|
||||
|
||||
// 5. 解析数据包
|
||||
struct ether_header *eth_header = (struct ether_header *)packet; // 以太网帧头
|
||||
unsigned char src_mac[18] = "";
|
||||
unsigned char dst_mac[18] = "";
|
||||
sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x", eth_header->ether_shost[0], eth_header->ether_shost[1], eth_header->ether_shost[2], eth_header->ether_shost[3], eth_header->ether_shost[4], eth_header->ether_shost[5]); // 将MAC地址转换为点分十进制的字符串
|
||||
sprintf(dst_mac, "%02x:%02x:%02x:%02x:%02x:%02x", eth_header->ether_dhost[0], eth_header->ether_dhost[1], eth_header->ether_dhost[2], eth_header->ether_dhost[3], eth_header->ether_dhost[4], eth_header->ether_dhost[5]);
|
||||
unsigned short eth_type = ntohs(eth_header->ether_type); // type 字段是网络字节序,需要转换为主机字节序
|
||||
printf("以太网帧类型: %04x\n", eth_type); // 0x0800 IP协议 0x0806 ARP协议 0x8035 RARP协议 0x86dd IPv6协议
|
||||
printf("目的MAC地址: %s\n", dst_mac);
|
||||
printf("源MAC地址: %s\n", src_mac);
|
||||
|
||||
// 如果是ARP协议
|
||||
if (eth_type == 0x0806)
|
||||
{
|
||||
// 分析 arp 报文
|
||||
struct ether_arp *arp_header = (struct ether_arp *)(packet + sizeof(struct ether_header)); // arp 报文
|
||||
unsigned short this_arp_op = ntohs(arp_header->arp_op); // 操作码
|
||||
printf("ARP操作码: %d\n", this_arp_op); // 1 ARP请求 2 ARP应答 3 RARP请求 4 RARP应答
|
||||
if (this_arp_op == 1 || this_arp_op == 2)
|
||||
{
|
||||
unsigned char src_ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char dst_ip[INET_ADDRSTRLEN] = "";
|
||||
inet_ntop(AF_INET, arp_header->arp_spa, src_ip, INET_ADDRSTRLEN); // 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
inet_ntop(AF_INET, arp_header->arp_tpa, dst_ip, INET_ADDRSTRLEN);
|
||||
printf("源IP地址: %s\n", src_ip);
|
||||
printf("目的IP地址: %s\n", dst_ip);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是IP协议
|
||||
if (eth_type == 0x800)
|
||||
{
|
||||
// 分析 ip 报文
|
||||
struct iphdr *ip_header = (struct iphdr *)(packet + sizeof(struct ether_header)); // ip 报文 (sizeof(struct ether_header) = 14 (MAC)以太网帧头长度)
|
||||
unsigned char src_ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char dst_ip[INET_ADDRSTRLEN] = "";
|
||||
unsigned char ip_protocol[INET_ADDRSTRLEN] = ""; // 协议类型
|
||||
inet_ntop(AF_INET, &ip_header->saddr, src_ip, INET_ADDRSTRLEN); // 将网络字节序的IP地址转换为点分十进制的字符串
|
||||
inet_ntop(AF_INET, &ip_header->daddr, dst_ip, INET_ADDRSTRLEN);
|
||||
printf("IP协议类型: %d\n", ip_header->protocol); // 4 IPv4 6 IPv6
|
||||
printf("源IP地址: %s\n", src_ip);
|
||||
printf("目的IP地址: %s\n", dst_ip);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// 3. 释放资源
|
||||
pcap_close(pcap_handle); // 关闭网络设备
|
||||
pcap_freealldevs(alldevs); // 释放资源
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
// 开启两个线程
|
||||
pthread_t tid1, tid2;
|
||||
pthread_create(&tid1, NULL, input_task, NULL);
|
||||
pthread_create(&tid2, NULL, net_task, NULL);
|
||||
pthread_join(tid1, NULL);
|
||||
pthread_
|
||||
pthread_join(tid2, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
11
router/t2.c
11
router/t2.c
|
@ -1,11 +0,0 @@
|
|||
#include "get_interface.h"
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
// 获取接口数量和接口信息
|
||||
getinterface();
|
||||
// 打印接口数量
|
||||
// printf("interface_num=%d\n\n", get_interface_num());
|
||||
// 打印接口信息
|
||||
return 0;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
# 定义路径变量
|
||||
SRC_DIR = ./
|
||||
OBJ_DIR = ./
|
||||
BIN_DIR = ./
|
||||
|
||||
# 定义编译器
|
||||
CC = gcc
|
||||
# 定义目标文件
|
||||
TARGET = $(BIN_DIR)/debug
|
||||
# 定义源文件
|
||||
SRCS = $(wildcard $(SRC_DIR)/*.c)
|
||||
# OBJS = $(OBJ_DIR)/t1.o $(OBJ_DIR)/get_interface.o
|
||||
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
|
||||
|
||||
# 编译规则
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) -c $< -o $@
|
||||
|
||||
# 链接规则
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $^ -o $@ -lpcap -lpthread
|
||||
|
||||
# 默认构建目标
|
||||
all: $(TARGET)
|
||||
|
||||
# 创建目录
|
||||
$(shell mkdir -p $(OBJ_DIR) $(BIN_DIR))
|
||||
|
||||
# 清理规则
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)/*.o $(TARGET)
|
||||
|
||||
# 伪目标
|
||||
.PHONY: all clean
|
|
@ -1,152 +0,0 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <netinet/ether.h>
|
||||
#include "get_interface.h"
|
||||
|
||||
int interface_num=0;//接口数量
|
||||
INTERFACE net_interface[MAXINTERFACES];//接口数据
|
||||
|
||||
/******************************************************************
|
||||
函 数: int get_interface_num()
|
||||
功 能: 获取接口数量
|
||||
参 数: 无
|
||||
*******************************************************************/
|
||||
int get_interface_num(){
|
||||
return interface_num;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
函 数: int getinterface()
|
||||
功 能: 获取接口信息
|
||||
参 数: 无
|
||||
*******************************************************************/
|
||||
void getinterface()
|
||||
{
|
||||
struct ifreq buf[MAXINTERFACES]; /* ifreq结构数组 */
|
||||
struct ifconf ifc; /* ifconf结构 */
|
||||
|
||||
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
/* 初始化ifconf结构 */
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = (caddr_t) buf;
|
||||
|
||||
/* 获得接口列表,所有接口的清单 */
|
||||
if (ioctl(sock_raw_fd, SIOCGIFCONF, (char *) &ifc) == -1){
|
||||
perror("SIOCGIFCONF ioctl");
|
||||
return ;
|
||||
}
|
||||
interface_num = ifc.ifc_len / sizeof(struct ifreq); /* 接口数量 */
|
||||
printf("interface_num=%d\n\n", interface_num);
|
||||
char buff[20]="";
|
||||
int ip;
|
||||
int if_len = interface_num;
|
||||
while (if_len-- > 0)
|
||||
{ /* 遍历每个接口 */
|
||||
printf("%s\n", buf[if_len].ifr_name); /* 接口名称 */
|
||||
sprintf(net_interface[if_len].name, "%s", buf[if_len].ifr_name); /* 接口名称 */
|
||||
printf("-%d-%s--\n",if_len,net_interface[if_len].name);
|
||||
/* 获得接口标志、flags值 */
|
||||
if (!(ioctl(sock_raw_fd, SIOCGIFFLAGS, (char *) &buf[if_len])))
|
||||
{
|
||||
/* 接口状态 */
|
||||
/*IFF_UP :网络装置是否正常启用,不会因插拔网络线而有任何变化*/
|
||||
if (buf[if_len].ifr_flags & IFF_UP){
|
||||
printf("UP\n");
|
||||
net_interface[if_len].flag = 1;
|
||||
}
|
||||
else{
|
||||
printf("DOWN\n");
|
||||
net_interface[if_len].flag = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "SIOCGIFFLAGS ioctl %s", buf[if_len].ifr_name);
|
||||
perror(str);
|
||||
}
|
||||
|
||||
/* IP地址 */
|
||||
if (!(ioctl(sock_raw_fd, SIOCGIFADDR, (char *) &buf[if_len])))
|
||||
{
|
||||
/*inet_ntoa将一个网络字节序的IP地址(也就是结构体in_addr类型变量)
|
||||
转化为点分十进制的IP地址(字符串)*/
|
||||
printf("IP:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
bzero(buff,sizeof(buff));
|
||||
sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
|
||||
/*新型网路地址转化函数inet_pton:
|
||||
将点分十进制的ip地址转化为用于网络传输的数值格式*/
|
||||
inet_pton(AF_INET, buff, &ip);
|
||||
memcpy(net_interface[if_len].ip, &ip, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "SIOCGIFADDR ioctl %s", buf[if_len].ifr_name);
|
||||
perror(str);
|
||||
}
|
||||
|
||||
/* 子网掩码 */
|
||||
if (!(ioctl(sock_raw_fd, SIOCGIFNETMASK, (char *) &buf[if_len])))
|
||||
{
|
||||
printf("netmask:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
bzero(buff,sizeof(buff));
|
||||
sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
inet_pton(AF_INET, buff, &ip);
|
||||
memcpy(net_interface[if_len].netmask, &ip, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "SIOCGIFADDR ioctl %s", buf[if_len].ifr_name);
|
||||
perror(str);
|
||||
}
|
||||
|
||||
/* 广播地址 */
|
||||
if (!(ioctl(sock_raw_fd, SIOCGIFBRDADDR, (char *) &buf[if_len])))
|
||||
{
|
||||
printf("br_ip:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
bzero(buff,sizeof(buff));
|
||||
sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr));
|
||||
inet_pton(AF_INET, buff, &ip);
|
||||
memcpy(net_interface[if_len].br_ip, &ip, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "SIOCGIF./ADDR ioctl %s", buf[if_len].ifr_name);
|
||||
perror(str);
|
||||
}
|
||||
|
||||
/*MAC地址 */
|
||||
if (!(ioctl(sock_raw_fd, SIOCGIFHWADDR, (char *) &buf[if_len])))
|
||||
{
|
||||
printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x\n\n",
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[0],
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[1],
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[2],
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[3],
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[4],
|
||||
(unsigned char) buf[if_len].ifr_hwaddr.sa_data[5]);
|
||||
memcpy(net_interface[if_len].mac, (unsigned char *)buf[if_len].ifr_hwaddr.sa_data, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "SIOCGIFHWADDR ioctl %s", buf[if_len].ifr_name);
|
||||
perror(str);
|
||||
}
|
||||
}//–while end
|
||||
close(sock_raw_fd); //关闭socket
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#ifndef IP_FILE_H
|
||||
#define IP_FILE_H
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
//*************************过滤链表******************************
|
||||
typedef struct myrouter
|
||||
{
|
||||
unsigned char ip[32] ;
|
||||
struct myrouter* next;
|
||||
}MY_ROU;
|
||||
|
||||
//释放链表
|
||||
extern MY_ROU* rou_freeLink(MY_ROU *head);
|
||||
//尾插
|
||||
extern MY_ROU *rou_pTailInsert(MY_ROU *head);
|
||||
//遍历
|
||||
extern void rou_print_link(MY_ROU *head);
|
||||
//查找ip
|
||||
extern int rou_searcharpLink(MY_ROU *head,char *ip);
|
||||
//删除
|
||||
extern MY_ROU *rou_pDeleteLink(MY_ROU *head);
|
||||
//*************************过滤链表******************************
|
||||
|
||||
/******************************************************************
|
||||
函 数: void init_ip_link()
|
||||
功 能: 读取配置文件数据到链表
|
||||
参 数: 无
|
||||
返回值: 无
|
||||
*******************************************************************/
|
||||
extern void init_ip_link();
|
||||
|
||||
/******************************************************************
|
||||
函 数: IP_LINK *find_ip(IP_LINK *head, unsigned char *ip)
|
||||
功 能: 插入ip过滤链表
|
||||
参 数: IP_LINK *head ip过滤链表头 IP_LINK* p 待插入节点
|
||||
返回值: IP_LINK *找到的节点
|
||||
*******************************************************************/
|
||||
extern MY_ROU *inner_ip_link(MY_ROU *head,MY_ROU* p);
|
||||
|
||||
/******************************************************************
|
||||
函 数: void save_ip_link()
|
||||
功 能: 保存链表数据到配置文件
|
||||
参 数: 无
|
||||
返回值: 无
|
||||
*******************************************************************/
|
||||
extern void save_ip_link();
|
||||
|
||||
#endif
|
|
@ -1,249 +0,0 @@
|
|||
#include "ip_file.h"
|
||||
#include "link.h"
|
||||
#include <netinet/in.h>
|
||||
#define ip_config_name "ip_config"
|
||||
|
||||
//与main.c共用一个结构体指针变量,保存过滤IP链表头节点
|
||||
MY_ROU * roulink_head = NULL;
|
||||
|
||||
//--------------------操作文件中的过滤IP----------------------//
|
||||
void init_ip_link()
|
||||
{
|
||||
FILE *ip_config = NULL;
|
||||
ip_config = fopen(ip_config_name,"rb+");
|
||||
if(ip_config == NULL){
|
||||
perror("!!!configure file,in main.c");
|
||||
_exit(1);
|
||||
}
|
||||
puts("filter IP:");
|
||||
int i = 0;
|
||||
while(1)
|
||||
{
|
||||
|
||||
char buff[500]="";
|
||||
bzero(buff, sizeof(buff));
|
||||
int ip;
|
||||
if(fgets(buff, sizeof(buff), ip_config) == NULL)
|
||||
{
|
||||
printf("ip_config 文件为空\n");
|
||||
break;
|
||||
}
|
||||
if(strlen(buff) < 7)//1.1.1.1
|
||||
{
|
||||
break;
|
||||
}
|
||||
buff[strlen(buff)-1]=0;//注意文件中存在\r
|
||||
//printf("IP[%d] = %s\n",i++,buff);
|
||||
inet_pton(AF_INET, buff, &ip);
|
||||
|
||||
MY_ROU *pb = (MY_ROU *)malloc(sizeof(MY_ROU));
|
||||
char ip_buf[16] = "";
|
||||
inet_ntop(AF_INET, &ip, ip_buf, 16);
|
||||
//printf("ip_buf[%d] = %s\n", ++i, ip_buf);
|
||||
//strcpy(pb->ip, ip_buf);
|
||||
memcpy(pb->ip, ip_buf, 16);
|
||||
printf("pb->ip[%d] = %s\n", i, pb->ip);
|
||||
|
||||
//传入变化的头节点 + 带有IP信息的结构体指针变量
|
||||
roulink_head = inner_ip_link(roulink_head, pb);
|
||||
i++;
|
||||
}
|
||||
|
||||
//rou_print_link(ip_head);
|
||||
fclose(ip_config);
|
||||
}
|
||||
|
||||
MY_ROU *inner_ip_link(MY_ROU *head, MY_ROU* p)
|
||||
{
|
||||
|
||||
// head = (MY_ROU*)malloc(sizeof(MY_ROU)); //创建头结点
|
||||
// head->next = NULL;
|
||||
MY_ROU * pb = head;
|
||||
int a = rou_searcharpLink(head, p->ip);//查找是否有该记录
|
||||
if(a == 0)
|
||||
{
|
||||
if(pb==NULL)
|
||||
{//未查找到,插入链表,直接插入表头方便
|
||||
p->next = NULL;
|
||||
head = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1 //头插法--寻找插入的节点
|
||||
MY_ROU * p2_new = (MY_ROU*)malloc(sizeof(MY_ROU));
|
||||
strcpy(p2_new->ip, p->ip);
|
||||
// printf("继续头插!!!!p2_new->ip = %s!!!!!!\n",p2_new->ip);
|
||||
p2_new->next = pb->next;
|
||||
pb->next = p2_new;
|
||||
#endif
|
||||
#if 0 //尾插法--正确
|
||||
MY_ROU *p1=pb;
|
||||
while(p1->next!=NULL)
|
||||
{
|
||||
p1=p1->next;
|
||||
}
|
||||
//插入
|
||||
p1->next=p;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
void save_ip_link()
|
||||
{
|
||||
FILE *ip_config = fopen(ip_config_name,"wb+");
|
||||
if(ip_config == NULL){
|
||||
perror("!!!configure file,in main.c");
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
char buff[20]="";
|
||||
MY_ROU *pb=roulink_head;
|
||||
while(pb != NULL)
|
||||
{
|
||||
printf("!保存2命令输入IP\n");
|
||||
memcpy(buff, pb->ip, 16);//一次拷贝16个字节
|
||||
buff[strlen(buff)+1]='\n';//注意文件中存在\r
|
||||
|
||||
//一个IP新切换一行保存到文件
|
||||
fprintf(ip_config, "%s\n", buff);
|
||||
pb = pb->next;
|
||||
}
|
||||
fclose(ip_config);
|
||||
}
|
||||
//--------------------操作文件中的过滤IP----------------------//
|
||||
|
||||
|
||||
|
||||
|
||||
//*************************过滤链表******************************//
|
||||
//尾插
|
||||
MY_ROU *rou_pTailInsert(MY_ROU *head)
|
||||
{
|
||||
|
||||
//申请一个待插入的空间
|
||||
MY_ROU *pi=(MY_ROU*)malloc(sizeof(MY_ROU));
|
||||
pi->next=NULL;
|
||||
printf("输入过滤ip:");
|
||||
//向空间中插入数据
|
||||
scanf("%s",pi->ip);
|
||||
//判断是否有数据
|
||||
if(head==NULL)
|
||||
{
|
||||
head=pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
//寻找插入的节点
|
||||
MY_ROU *p1=head;
|
||||
while(p1->next!=NULL)
|
||||
{
|
||||
p1=p1->next;
|
||||
}
|
||||
//插入
|
||||
p1->next=pi;
|
||||
}
|
||||
|
||||
|
||||
printf("设置完成\n");
|
||||
return head;
|
||||
}
|
||||
|
||||
//遍历
|
||||
void rou_print_link(MY_ROU *head)
|
||||
{
|
||||
if(head==NULL)
|
||||
{
|
||||
printf("没有数据\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while(head!=NULL)
|
||||
{
|
||||
printf("ip:%s\n",head->ip);
|
||||
head=head->next;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//释放链表
|
||||
MY_ROU* rou_freeLink(MY_ROU *head)
|
||||
{
|
||||
MY_ROU *pd;
|
||||
pd=head;
|
||||
while(head!=NULL)
|
||||
{
|
||||
head=pd->next;
|
||||
free(pd);
|
||||
pd=head;
|
||||
}
|
||||
printf("过滤链表释放完毕\n");
|
||||
return head;
|
||||
}
|
||||
|
||||
//查找ip
|
||||
int rou_searcharpLink(MY_ROU *head,char *ip)
|
||||
{
|
||||
MY_ROU * pb = head;
|
||||
int i=0;
|
||||
while(pb!=NULL)
|
||||
{
|
||||
if(strcmp(ip, pb->ip)==0)
|
||||
{
|
||||
i++;
|
||||
//printf("存在相同ip\n");
|
||||
return 1;
|
||||
}
|
||||
pb = pb->next;
|
||||
}
|
||||
if(0==i)
|
||||
{
|
||||
//printf("未找到ip\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
MY_ROU *rou_pDeleteLink(MY_ROU *head)
|
||||
{
|
||||
char num[16]="";
|
||||
MY_ROU *pe=head;
|
||||
MY_ROU *pf=head;
|
||||
|
||||
printf("请输入你要删除的ip:");
|
||||
scanf("%s",num);
|
||||
|
||||
if(NULL==head)
|
||||
{
|
||||
printf("无可删除数据\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while(strcmp(pe->ip,num))
|
||||
{
|
||||
pf=pe;
|
||||
pe=pe->next;
|
||||
if(NULL==pf->next)
|
||||
{
|
||||
printf("未找到要删除数据\n");
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
if(pe==head)
|
||||
{
|
||||
head=pe->next;
|
||||
free(pe);
|
||||
}
|
||||
else
|
||||
{
|
||||
pf->next=pe->next;
|
||||
free(pe);
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
//*************************过滤链表******************************
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef GET_INTERFACE_H
|
||||
#define GET_INTERFACE_H
|
||||
|
||||
#define MAXINTERFACES 16 /* 最大接口数 */
|
||||
|
||||
typedef struct interface{
|
||||
char name[20]; //接口名字
|
||||
unsigned char ip[4]; //IP地址
|
||||
unsigned char mac[6]; //MAC地址
|
||||
unsigned char netmask[4]; //子网掩码
|
||||
unsigned char br_ip[4]; //广播地址
|
||||
int flag; //状态
|
||||
}INTERFACE;
|
||||
extern INTERFACE net_interface[MAXINTERFACES];//接口数据
|
||||
|
||||
/******************************************************************
|
||||
函 数: int getinterface()
|
||||
功 能: 获取接口信息
|
||||
参 数: 无
|
||||
*******************************************************************/
|
||||
extern void getinterface();
|
||||
|
||||
/******************************************************************
|
||||
函 数: int get_interface_num()
|
||||
功 能: 获取实际接口数量
|
||||
参 数: 接口数量
|
||||
*******************************************************************/
|
||||
int get_interface_num();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
#include "link.h"
|
||||
|
||||
void title()
|
||||
{
|
||||
printf("[人机交互线程的全部功能]\n");
|
||||
printf("2:设置过滤 IP \n");
|
||||
printf("3:删除过滤 IP \n");
|
||||
printf("4:查看过滤 IP \n");
|
||||
printf("5:查看 arp 缓存 \n");
|
||||
printf("10:退出路由器\n");
|
||||
}
|
||||
|
||||
|
||||
//*************************过滤链表******************************
|
||||
//尾插
|
||||
MY_ROU *rou_pTailInsert(MY_ROU *head)
|
||||
{
|
||||
//申请一个待插入的空间
|
||||
MY_ROU *pi=(MY_ROU*)malloc(sizeof(MY_ROU));
|
||||
pi->next=NULL;
|
||||
printf("输入过滤ip:");
|
||||
//向空间中插入数据
|
||||
scanf("%s",pi->ip);
|
||||
//判断是否有数据
|
||||
if(head==NULL)
|
||||
{
|
||||
head=pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
//寻找插入的节点
|
||||
MY_ROU *p1=head;
|
||||
while(p1->next!=NULL)
|
||||
{
|
||||
p1=p1->next;
|
||||
}
|
||||
//插入
|
||||
p1->next=pi;
|
||||
}
|
||||
printf("设置完成\n");
|
||||
return head;
|
||||
}
|
||||
|
||||
//遍历
|
||||
void rou_print_link(MY_ROU *head)
|
||||
{
|
||||
if(head==NULL)
|
||||
{
|
||||
printf("没有数据\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while(head!=NULL)
|
||||
{
|
||||
printf("ip:%s\n",head->ip);
|
||||
head=head->next;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//释放链表
|
||||
MY_ROU* rou_freeLink(MY_ROU *head)
|
||||
{
|
||||
MY_ROU *pd;
|
||||
pd=head;
|
||||
while(head!=NULL)
|
||||
{
|
||||
head=pd->next;
|
||||
free(pd);
|
||||
pd=head;
|
||||
}
|
||||
printf("过滤链表释放完毕\n");
|
||||
return head;
|
||||
}
|
||||
|
||||
//查找ip
|
||||
int rou_searcharpLink(MY_ROU *head,char *ip)
|
||||
{
|
||||
int i=0;
|
||||
while(head!=NULL)
|
||||
{
|
||||
if(strcmp(ip,head->ip)==0)
|
||||
{
|
||||
i++;
|
||||
//printf("存在相同ip\n");
|
||||
return 1;
|
||||
}
|
||||
head=head->next;
|
||||
}
|
||||
if(0==i)
|
||||
{
|
||||
//printf("未找到ip\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
MY_ROU *rou_pDeleteLink(MY_ROU *head)
|
||||
{
|
||||
char num[16]="";
|
||||
MY_ROU *pe=head;
|
||||
MY_ROU *pf=head;
|
||||
|
||||
printf("请输入你要删除的ip:");
|
||||
scanf("%s",num);
|
||||
|
||||
if(NULL==head)
|
||||
{
|
||||
printf("无可删除数据\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while(strcmp(pe->ip,num))
|
||||
{
|
||||
pf=pe;
|
||||
pe=pe->next;
|
||||
if(NULL==pf->next)
|
||||
{
|
||||
printf("未找到要删除数据\n");
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
if(pe==head)
|
||||
{
|
||||
head=pe->next;
|
||||
free(pe);
|
||||
}
|
||||
else
|
||||
{
|
||||
pf->next=pe->next;
|
||||
free(pe);
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
//*************************过滤链表******************************
|
||||
|
||||
//*************************arp缓存表*****************************
|
||||
//arp缓存表尾插
|
||||
MY_ARP *arp_pTailInsert(MY_ARP *head,char *mac,char *ip)
|
||||
{
|
||||
//申请一个待插入的空间
|
||||
MY_ARP *pi=(MY_ARP*)malloc(sizeof(MY_ARP));
|
||||
pi->next=NULL;
|
||||
//向空间中插入数据
|
||||
strcpy(pi->ip,ip);
|
||||
strcpy(pi->mac,mac);
|
||||
//判断是否有数据
|
||||
if(head==NULL)
|
||||
{
|
||||
head=pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
//寻找插入的节点
|
||||
MY_ARP *p1=head;
|
||||
while(p1->next!=NULL)
|
||||
{
|
||||
p1=p1->next;
|
||||
}
|
||||
//插入
|
||||
p1->next=pi;
|
||||
}
|
||||
printf("插入一个ip:%s mac:%s 到arp缓存表\n",pi->ip,pi->mac);
|
||||
return head;
|
||||
}
|
||||
|
||||
//arp中查找ip和mac
|
||||
int arp_searcharpLink(MY_ARP *head,char *ip)
|
||||
{
|
||||
int i=0;
|
||||
while(head!=NULL)
|
||||
{
|
||||
if(strcmp(ip,head->ip)==0)
|
||||
{
|
||||
i++;
|
||||
//printf("存在相同ip和mac\n");
|
||||
return 1;
|
||||
}
|
||||
head=head->next;
|
||||
}
|
||||
if(0==i)
|
||||
{
|
||||
//printf("未找到ip和mac\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//遍历arp缓存表
|
||||
void arp_print_link(MY_ARP *head)
|
||||
{
|
||||
if(head==NULL)
|
||||
{
|
||||
printf("没有数据\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
while(head!=NULL)
|
||||
{
|
||||
printf("ip:%s mac:%s\n",head->ip,head->mac);
|
||||
head=head->next;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//释放arp链表
|
||||
MY_ARP* arp_freeLink(MY_ARP *head)
|
||||
{
|
||||
MY_ARP *pd;
|
||||
pd=head;
|
||||
while(head!=NULL)
|
||||
{
|
||||
head=pd->next;
|
||||
free(pd);
|
||||
pd=head;
|
||||
}
|
||||
printf("arp链表释放完毕\n");
|
||||
return head;
|
||||
}
|
||||
//*************************arp缓存表*****************************
|
|
@ -1,63 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define RECV_SIZE 2048
|
||||
typedef struct My_buf
|
||||
{
|
||||
unsigned char buf[RECV_SIZE];
|
||||
int my_buf_date_len;
|
||||
}ip_buf;
|
||||
|
||||
|
||||
|
||||
typedef struct Arp_mac_ip
|
||||
{
|
||||
char stc_mac[18];
|
||||
char stc_ip[16];
|
||||
}arp_mac_ip;
|
||||
|
||||
|
||||
extern void title();
|
||||
|
||||
//*************************arp缓存表*****************************
|
||||
typedef struct myarp
|
||||
{
|
||||
unsigned char mac[32] ;
|
||||
unsigned char ip[32] ;
|
||||
|
||||
struct myarp* next;
|
||||
}MY_ARP;
|
||||
|
||||
|
||||
//arp缓存表尾插
|
||||
extern MY_ARP *arp_pTailInsert(MY_ARP *head,char *mac,char *ip);
|
||||
//arp中查找ip
|
||||
extern int arp_searcharpLink(MY_ARP *head,char *ip);
|
||||
//遍历arp缓存表
|
||||
extern void arp_print_link(MY_ARP *head);
|
||||
//释放arp链表
|
||||
extern MY_ARP* arp_freeLink(MY_ARP *head);
|
||||
//*************************arp缓存表*****************************
|
||||
|
||||
|
||||
|
||||
|
||||
//*************************过滤链表******************************
|
||||
typedef struct myrouter
|
||||
{
|
||||
unsigned char ip[32] ;
|
||||
struct myrouter* next;
|
||||
}MY_ROU;
|
||||
|
||||
//释放链表
|
||||
extern MY_ROU* rou_freeLink(MY_ROU *head);
|
||||
//尾插
|
||||
extern MY_ROU *rou_pTailInsert(MY_ROU *head);
|
||||
//遍历
|
||||
extern void rou_print_link(MY_ROU *head);
|
||||
//查找ip
|
||||
extern int rou_searcharpLink(MY_ROU *head,char *ip);
|
||||
//删除
|
||||
extern MY_ROU *rou_pDeleteLink(MY_ROU *head);
|
||||
//*************************过滤链表******************************
|
|
@ -1,419 +0,0 @@
|
|||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "get_interface.h"
|
||||
#include "link.h"
|
||||
|
||||
|
||||
MY_ROU * roulink_head = NULL;
|
||||
MY_ARP * arplink_head = NULL;
|
||||
int sockfd = 0;
|
||||
//*************************人机交互线程**********************************
|
||||
void *callback1(void *arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
printf("输入相应的序号,实现对应功能\n");
|
||||
int usercmd = -1;
|
||||
scanf("%d", &usercmd);
|
||||
switch (usercmd)
|
||||
{
|
||||
case 0:
|
||||
getchar();
|
||||
title();
|
||||
break;
|
||||
case 2:
|
||||
getchar();//接收输入2的回车
|
||||
roulink_head=rou_pTailInsert(roulink_head);
|
||||
break;
|
||||
case 3:
|
||||
getchar();
|
||||
roulink_head=rou_pDeleteLink(roulink_head);
|
||||
break;
|
||||
case 4:
|
||||
getchar();
|
||||
rou_print_link(roulink_head);/*将指针pHead传入输出函数遍历输出*/
|
||||
printf("链表打印完毕!\n");
|
||||
break;
|
||||
case 5:
|
||||
arp_print_link(arplink_head);
|
||||
break;
|
||||
case 10:
|
||||
printf("10:退出路由器,释放IP、ARP链表\n");
|
||||
getchar();
|
||||
arp_freeLink(arplink_head);
|
||||
rou_freeLink(roulink_head);//释放链表
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
//*************************人机交互线程**********************************
|
||||
|
||||
|
||||
//*************************ARP应答的IP和MAC存入缓存链表线程【开始】**************//
|
||||
void * callback2_arp(void *arg)
|
||||
{
|
||||
arp_mac_ip *p = (arp_mac_ip*)arg;
|
||||
|
||||
//printf("将 ARP 应答的 IP 和 MAC 存入缓存链\n");
|
||||
//printf("### %s\n", p->stc_ip);
|
||||
if(arp_searcharpLink(arplink_head, p->stc_ip) == 0)
|
||||
{
|
||||
printf("插入链表中没有的ARP 应答 IP 和 MAC\n");
|
||||
arplink_head = arp_pTailInsert( arplink_head, p->stc_mac ,p->stc_ip);
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
//*************************ARP应答的IP和MAC存入缓存链表线程【结束】***************//
|
||||
|
||||
|
||||
//*************************IP包转发线程【开始】**********************************//
|
||||
void *callback3_ip(void *arg)
|
||||
{
|
||||
|
||||
//发送接口的结构体
|
||||
struct sockaddr_ll sll;
|
||||
ip_buf *pthread_ip_buf = (ip_buf *)arg;
|
||||
|
||||
|
||||
unsigned char * ip_head= pthread_ip_buf->buf + 14;
|
||||
char dst_ip[16] = "";
|
||||
|
||||
inet_ntop(AF_INET, ip_head + 16, dst_ip, 16);
|
||||
printf("IP包转发线程中 目的 dst_ip = %s\n", dst_ip);
|
||||
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
|
||||
unsigned char ip[16]="";
|
||||
inet_ntop(AF_INET,net_interface[i].ip, ip, 16);//get_interface文件中得到的都是32位无符号整形数据(计算机数据),现转成成点分十进制(人能够书别的)
|
||||
|
||||
//---------------------[调试]----------------------------------------//
|
||||
//printf("设置网卡循环进入次数 i = %d\n", i);
|
||||
//printf("检索到的所有网卡名字net_interface[i].name = %s\n", net_interface[i].name);
|
||||
//printf("net_interface[i].ip = %s\n",ip);
|
||||
//---------------------[调试]----------------------------------------//
|
||||
|
||||
if(strncmp(ip, dst_ip, 9) == 0)//根据目标网段 查找活跃网卡
|
||||
{
|
||||
//网卡结构体
|
||||
struct ifreq ethreq;
|
||||
strncpy(ethreq.ifr_name, net_interface[i].name , IFNAMSIZ);//指定网卡名字
|
||||
printf("网卡名字:%s\n", ethreq.ifr_name);
|
||||
|
||||
if(ioctl(sockfd, SIOCGIFINDEX, ðreq) == -1)//获取网卡接口地址
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzero(&sll, sizeof(sll));
|
||||
sll.sll_ifindex = ethreq.ifr_ifindex;//将网卡的接口类型赋值给发送接口
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("找不到网段对应的网卡,继续查\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【开始】------------------------------------------------------//
|
||||
if(strcmp(dst_ip + strlen(dst_ip) - 3, "255") == 0)//是 否为广 播地址
|
||||
{
|
||||
// printf("是广播地址, 退出线\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("不是广播地址,判断是否为回 环地址\n");
|
||||
if(strcmp("127.0.0.1", dst_ip) == 0)
|
||||
{
|
||||
//printf("是回 环地址, 退出线\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("查找ARP缓存表 对应 MAC\n");
|
||||
//指定目的MAC地址
|
||||
//可以在链表中找到目的IP,组ICMP包的目的MAC就可以了
|
||||
//之所以这样,是因为在网络中的ICMP包里,变化的只有目的MAC,源MAC、IP都不会发生变动
|
||||
if(arp_searcharpLink(arplink_head, dst_ip) == 1)
|
||||
{
|
||||
//1网段中 指定目标IP是主机的IP、MAC
|
||||
//2C-4D-54-57-04-7F
|
||||
//printf("****icmp****\n");
|
||||
if(strncmp("192.168.1.49", dst_ip, 9) == 0)
|
||||
{
|
||||
pthread_ip_buf->buf[0]=0x2C;
|
||||
pthread_ip_buf->buf[1]=0x4D;
|
||||
pthread_ip_buf->buf[2]=0x54;
|
||||
pthread_ip_buf->buf[3]=0x57;
|
||||
pthread_ip_buf->buf[4]=0x04;
|
||||
pthread_ip_buf->buf[5]=0x7F;//目标
|
||||
int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
|
||||
//-------------------[调试]------------------------//
|
||||
//printf("****1 网段 icmp缓存表****\n");
|
||||
// printf("send_len ICMP 1 = %d\n", send_len);
|
||||
//-------------------[调试]------------------------//
|
||||
|
||||
}
|
||||
//2网段中 指定目标IP是开发板的IP、MAC
|
||||
// 00:53:50:00:01:33
|
||||
else if(strncmp("192.168.2.100", dst_ip, 9) == 0)
|
||||
{
|
||||
pthread_ip_buf->buf[0]=0x00;
|
||||
pthread_ip_buf->buf[1]=0x53;
|
||||
pthread_ip_buf->buf[2]=0x50;
|
||||
pthread_ip_buf->buf[3]=0x00;
|
||||
pthread_ip_buf->buf[4]=0x59;
|
||||
pthread_ip_buf->buf[5]=0x12;
|
||||
|
||||
//发送给套接字的数据长度,是实际传送过来的长度(main中的IP包有收到具体长度信息)
|
||||
int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
|
||||
//-------------------[调试]------------------------//
|
||||
//printf("****2 网段 icmp缓存表****\n");
|
||||
// printf("send_len ICMP 2 = %d\n", send_len);
|
||||
//-------------------[调试]------------------------//
|
||||
}
|
||||
}
|
||||
else
|
||||
{//没在链表中没有找到目的IP,需要重新组arp包才行
|
||||
|
||||
//printf("***************组ARP包\n");
|
||||
int i = 0;
|
||||
for(; i < 3; i++)
|
||||
{
|
||||
//printf("%s\n",dst_ip);
|
||||
//比对到1网段的数据
|
||||
if(strstr(dst_ip,"192.168.1") != 0)
|
||||
{
|
||||
printf("发送网段1arp包\n");
|
||||
unsigned char arp_buf[42] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac,广播的形式发出去,等待目的IP恢复后覆盖
|
||||
0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac
|
||||
0x08, 0x00,//协议类型
|
||||
0, 1,//硬件类型
|
||||
6,
|
||||
4,
|
||||
0, 1,//op
|
||||
0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac(网卡1 ech0的MAC)
|
||||
192,168,1,88,//源IP是路由器1网段的网关,通过它发送到2网段
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,//目的mac,等待目的IP恢复后覆盖
|
||||
0,0,0,0
|
||||
//192,168,1,49,
|
||||
};
|
||||
int int_ip=0;
|
||||
inet_pton(AF_INET, dst_ip, &int_ip);
|
||||
unsigned char *intp=(char *)&int_ip;
|
||||
arp_buf[38]=intp[0];
|
||||
arp_buf[39]=intp[1];
|
||||
arp_buf[40]=intp[2];
|
||||
arp_buf[41]=intp[3];
|
||||
int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
printf("send_len 11 = %d\n",send_len);
|
||||
|
||||
}
|
||||
//网卡2,ech1的MAC:00:0c:29:fa:7c:a8
|
||||
else if(strstr(dst_ip,"192.168.2") != 0)
|
||||
{
|
||||
printf("发送网段2arp包\n");
|
||||
unsigned char arp_buf[42] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac
|
||||
0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac
|
||||
0x08, 0x00,//协议类型
|
||||
0, 1,//硬件类型
|
||||
6,
|
||||
4,
|
||||
0, 1,//op
|
||||
0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac
|
||||
192,168,2,89,//源IP是路由器2网段的网关,通过它发送到1网段
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,//目的mac
|
||||
192,168,2,100,
|
||||
};
|
||||
int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
printf("send_len 22 = %d\n",send_len);
|
||||
|
||||
}
|
||||
|
||||
if(arp_searcharpLink(arplink_head, dst_ip) == 1)
|
||||
{
|
||||
//1
|
||||
//2C-4D-54-57-04-7F
|
||||
if(strncmp("192.168.0.11", dst_ip, 9) == 0)
|
||||
{
|
||||
pthread_ip_buf->buf[0] = 0xA8;
|
||||
pthread_ip_buf->buf[1] = 0x5E;
|
||||
pthread_ip_buf->buf[2] = 0x45;
|
||||
pthread_ip_buf->buf[3] = 0xC1;
|
||||
pthread_ip_buf->buf[4] = 0x8B;
|
||||
pthread_ip_buf->buf[5] = 0x99;
|
||||
int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
//-------------------[调试]------------------------//
|
||||
//printf("****3次发ARP过程中检索到ICMP包 1 网段****\n");
|
||||
// printf("send_len ICMP 1 = %d\n", send_len);
|
||||
//-------------------[调试]------------------------//
|
||||
}
|
||||
//2
|
||||
// 开发板MAC(每次启动都会变化):1C:59:74:81:4A:43
|
||||
// 1C:59:74:81:4A:43
|
||||
|
||||
else if(strncmp("192.168.1.1", dst_ip, 9) == 0)
|
||||
{
|
||||
pthread_ip_buf->buf[0] = 0x1c;
|
||||
pthread_ip_buf->buf[1] = 0x59;
|
||||
pthread_ip_buf->buf[2] = 0x74;
|
||||
pthread_ip_buf->buf[3] = 0x81;
|
||||
pthread_ip_buf->buf[4] = 0x4A;
|
||||
pthread_ip_buf->buf[5] = 0x43;
|
||||
int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
|
||||
//-------------------[调试]------------------------//
|
||||
//printf("****3次发ARP过程中检索到ICMP包 2 网段****\n");
|
||||
// printf("send_len ICMP 2 = %d\n", send_len);
|
||||
//-------------------[调试]------------------------//
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
//--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【结束】------------------------------------------------------//
|
||||
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
}
|
||||
//*************************建IP包转发线程【结束】**********************************//
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建原始套接字,接收发送方的网卡信息
|
||||
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if(sockfd<0)
|
||||
{
|
||||
perror("sockfd:");
|
||||
return 0;
|
||||
}
|
||||
getinterface();//拿取网卡信息(虚拟机的所有网卡,包括回环网卡)
|
||||
|
||||
pthread_t pth;
|
||||
pthread_create(&pth, NULL, callback1, NULL);//人机交互线程,这里可以放在main里面
|
||||
|
||||
int len = 0;
|
||||
|
||||
char recv_buff[RECV_SIZE]="";//原始套接字数据包大约为1500个字节
|
||||
ssize_t recv_len=0;
|
||||
while(1)
|
||||
{
|
||||
//开始接收其他人的网卡信息
|
||||
bzero(recv_buff,sizeof(recv_buff));
|
||||
|
||||
//[recv_len]设置成全局变量,让线程可以共用数据
|
||||
recv_len = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0, NULL, NULL);
|
||||
if(recv_len<=0||recv_len>RECV_SIZE)
|
||||
{
|
||||
perror("recvfrom");
|
||||
continue;
|
||||
}
|
||||
//printf("链路层截取数据包长度 recv_len=%d\n",recv_len);
|
||||
|
||||
//MAC包类型
|
||||
unsigned short mac_type = 0;
|
||||
mac_type = ntohs( *((unsigned short *)(recv_buff + 12)));
|
||||
if(mac_type == 0x0800)
|
||||
{
|
||||
//printf("-----------ip数据包------------\n");
|
||||
unsigned char *ip_head = recv_buff + 14;
|
||||
unsigned char dst_ip[16] ="";
|
||||
inet_ntop(AF_INET, ip_head + 16, dst_ip, 16);
|
||||
|
||||
//IP包的类型
|
||||
if(ip_head[9] == 1)
|
||||
{
|
||||
//printf("-----ICMP数据包\n");
|
||||
//查找过滤IP链表中存在我们指定的目的IP吗
|
||||
if(rou_searcharpLink(roulink_head, dst_ip) == 0)
|
||||
{
|
||||
static int i=0;
|
||||
|
||||
//-----------调试,打印原始套接字接收到的数据内容是否是空--------------------//
|
||||
//printf("i=%d IP包中的目的IP = %d\n",++i, strlen(recv_buff + 30));
|
||||
// printf("Rvfbuf=%p\n",recv_buff);
|
||||
// int kk=0;
|
||||
// while(kk<98)
|
||||
// {
|
||||
// printf("Rvfbuf[%d]=%d\n",kk,recv_buff[kk]);
|
||||
// kk++;
|
||||
|
||||
// }
|
||||
//----------------------------[调试]---------------------------------------//
|
||||
|
||||
usleep(1000);
|
||||
ip_buf *recv = (ip_buf *)malloc(sizeof(ip_buf));
|
||||
recv->my_buf_date_len = recv_len;
|
||||
memcpy(recv->buf, recv_buff, recv_len);
|
||||
|
||||
//线程的创建放在满足它的条件中,while循环,满足就进来创建一个,切记不要放到条件外面创建线程,否则只会创建一个,导致所有情况共用一个线程
|
||||
pthread_t pth2;
|
||||
//最后数据包是ICMP的整包
|
||||
pthread_create(&pth2, NULL, callback3_ip, (void*)recv);
|
||||
pthread_detach(pth2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(mac_type == 0x0806)
|
||||
{
|
||||
arp_mac_ip * head_mac_ip = NULL;//保存目的MAC\IP的结构体,安全措施,防止栈空间释放导致给线程传参为空,失败
|
||||
head_mac_ip = (arp_mac_ip *)malloc(sizeof(arp_mac_ip ));
|
||||
|
||||
|
||||
unsigned char *arp_head = recv_buff + 14;
|
||||
unsigned char * arp_src_mac = arp_head + 8;//跳过[4.硬件类型、5.协议类型、6.硬件地址长度、7.协议地址长度、8.OP,拿到源MAC地址首地址信息]
|
||||
unsigned char stc_mac[18] = "";
|
||||
sprintf(stc_mac, "%02x:%02x:%02x:%02x:%02x:%02x", arp_src_mac[0],\
|
||||
arp_src_mac[1],\
|
||||
arp_src_mac[2], \
|
||||
arp_src_mac[3],\
|
||||
arp_src_mac[4], \
|
||||
arp_src_mac[5]);
|
||||
strcpy(head_mac_ip->stc_mac, stc_mac);
|
||||
|
||||
unsigned char src_ip[16] = "";
|
||||
inet_ntop(AF_INET, arp_head + 14, src_ip, 16);//拿到源IP
|
||||
strcpy(head_mac_ip->stc_ip, src_ip);
|
||||
|
||||
//-----------------------------------[调试]-----------------------------------//
|
||||
//printf("-----------arp数据包------------\n");
|
||||
//printf("arp 源mac:%s\n",head_mac_ip->stc_mac);
|
||||
//printf("arp 源IP:src_ip = %s \n", src_ip);
|
||||
//-----------------------------------[调试]-----------------------------------//
|
||||
|
||||
//线程中只保存源ARP的MAC、IP,目的主机的MAC、IP,在IP线程中指定(写死)
|
||||
pthread_t pth1;
|
||||
pthread_create(&pth1, NULL, callback2_arp, (void*)head_mac_ip);
|
||||
pthread_detach(pth1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -1,594 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>//recvfrom
|
||||
#include <netinet/ether.h>//ETH_P_ALL
|
||||
#include <arpa/inet.h>//inet_ntop
|
||||
#include <net/if.h>//ifreq
|
||||
#include <sys/ioctl.h>//ioctl
|
||||
#include <netpacket/packet.h>//sockaddr_ll
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
void show(void);//菜单函数
|
||||
void * my_fun(void * arg);//线程的回调函数
|
||||
|
||||
//全局变量定义,方便线程使用
|
||||
int sockfd; //套接字
|
||||
int ret; //调用数据库是的返回值
|
||||
char * errmsg;
|
||||
sqlite3 *db;
|
||||
char ** dbResult;
|
||||
int nrow;
|
||||
int ncolumn;
|
||||
|
||||
int main()
|
||||
{
|
||||
//创建套接字,原始套接字
|
||||
sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
|
||||
if(sockfd > 0)
|
||||
{
|
||||
printf("原始套接字创建成功:%d\n",sockfd);
|
||||
}
|
||||
//**************************************************************************************************************************************************
|
||||
//数据库的打开使用
|
||||
//**************************************************************************************************************************************************
|
||||
|
||||
|
||||
//打开数据库
|
||||
ret = sqlite3_open("ip.db",&db);
|
||||
//如果ret==SQLITE_OK 那么就是这一条语言成功执行了
|
||||
if(ret == SQLITE_OK)
|
||||
{
|
||||
printf("防火墙数据库打开成功!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("数据库打开失败!\n");
|
||||
}
|
||||
ret = sqlite3_open("mac.db",&db);
|
||||
if(ret == SQLITE_OK)
|
||||
{
|
||||
printf("ARP缓存数据库打开成功!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("数据库打开失败!\n");
|
||||
}
|
||||
//使用非回调办法增加一张数据表
|
||||
sqlite3_get_table(db,"create table persons (IP text primary key);",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
// arp缓存的数据库
|
||||
sqlite3_get_table(db,"create table person (ip text primary key,mac text);",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
|
||||
//使用回调方法去增加数据
|
||||
|
||||
char str[128]="";
|
||||
printf("防火墙中的IP有:\n");
|
||||
//想要添加,从这个地方就可以添加
|
||||
char get_ip[16]="192.168.7.5";
|
||||
sprintf(str,"insert into persons values('%s');",get_ip);
|
||||
sqlite3_get_table(db,str,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//使用非回调函数查询数据
|
||||
ret == sqlite3_get_table(db,"select * from persons;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
if(ret==SQLITE_OK)
|
||||
{
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
printf(" %s ",dbResult[index]);
|
||||
index++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
sqlite3_free_table(dbResult);
|
||||
|
||||
}
|
||||
//选择标志位
|
||||
int chose = 0;
|
||||
show();//菜单展示
|
||||
int pthread_flag = 0;
|
||||
while(1)
|
||||
{
|
||||
printf("请输入您的选择:");
|
||||
scanf("%d",&chose);
|
||||
getchar();
|
||||
if(1 == chose)
|
||||
{
|
||||
char add_ip[32]="";
|
||||
printf("请输入添加的黑名单IP:格式如:192.168.1.1\n");
|
||||
fgets(add_ip,sizeof(add_ip),stdin);
|
||||
add_ip[strlen(add_ip)-1]='\0';
|
||||
//printf("获得到了:%s\n",add_ip);
|
||||
//格式校验
|
||||
int a=0,b=0,c=0,d=0;
|
||||
sscanf(add_ip,"%d.%d.%d.%d",&a,&b,&c,&d);
|
||||
if((a >= 0 && a <= 255) && (b >= 0 && b <= 255) && (c >= 0 && c <= 255) && (d >= 0 && d<= 255))
|
||||
{
|
||||
//写入数据库
|
||||
char sqlite3_ip[64]="";
|
||||
sprintf(sqlite3_ip,"insert into persons values('%s');",add_ip);
|
||||
sqlite3_get_table(db,sqlite3_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
printf("数据库已更新!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("您输入有误\n");
|
||||
}
|
||||
}
|
||||
else if(2 == chose)
|
||||
{
|
||||
|
||||
ret == sqlite3_get_table(db,"select * from persons;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
if(ret==SQLITE_OK)
|
||||
{
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
printf(" %s ",dbResult[index]);
|
||||
index++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
sqlite3_free_table(dbResult);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(3 == chose)
|
||||
{
|
||||
char delete_ip[32]="";
|
||||
printf("请输入删除的黑名单IP:格式如:192.168.1.1\n");
|
||||
fgets(delete_ip,sizeof(delete_ip),stdin);
|
||||
delete_ip[strlen(delete_ip)-1]='\0';
|
||||
printf("获得到了:%s\n",delete_ip);
|
||||
//格式校验
|
||||
int a=0,b=0,c=0,d=0;
|
||||
sscanf(delete_ip,"%d.%d.%d.%d",&a,&b,&c,&d);
|
||||
if((a >= 0 && a <= 255) && (b >= 0 && b <= 255) && (c >= 0 && c <= 255) && (d >= 0 && d<= 255))
|
||||
{
|
||||
//写入数据库
|
||||
char sqlite3_ip[64]="";
|
||||
sprintf(sqlite3_ip,"delete from persons where IP='%s';",delete_ip);
|
||||
sqlite3_get_table(db,sqlite3_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
printf("数据库已更新!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("您输入有误\n");
|
||||
}
|
||||
}
|
||||
else if(4 == chose)
|
||||
{
|
||||
|
||||
if(0 == pthread_flag )
|
||||
{
|
||||
printf("路由器已运行!\n");
|
||||
pthread_flag++;
|
||||
pthread_t pth;
|
||||
pthread_create(&pth,NULL,my_fun,NULL);
|
||||
pthread_detach(pth);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("路由器正在运行,请不要重复开启!\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(5 == chose)
|
||||
{
|
||||
//在路由器开启之前,发送arp广播数据包
|
||||
//两个端口均要发送广播消息
|
||||
printf("arp广播发送!\n");
|
||||
int i = 1;
|
||||
for(i = 1;i < 255 ;i++)
|
||||
{
|
||||
//ens33网口组arp的请求包
|
||||
unsigned char buf_all_1[42]={
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac广播
|
||||
0x00,0x0c,0x29,0x85,0xcc,0x53,//源mac
|
||||
0x00,0x0c,0x29,0xf3,0x98,0x3e,//发送端mac
|
||||
0x08,0x06,//帧类型
|
||||
0x00,0x01,//硬件类型
|
||||
0x08,0x00,//协议类型
|
||||
6,
|
||||
4,
|
||||
0x00,0x01,//op
|
||||
0x00,0x0c,0x29,0x85,0xcc,0x53,//发送端mac
|
||||
192,168,32,129,//发送端ip
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
192,168,32,i
|
||||
};
|
||||
//获取网络接口类型
|
||||
struct ifreq ethreq3;
|
||||
strncpy(ethreq3.ifr_name, "ens33", IFNAMSIZ);
|
||||
ioctl(sockfd, SIOCGIFINDEX, ðreq3);
|
||||
//定义一个网络接口变量
|
||||
struct sockaddr_ll sll3;
|
||||
bzero(&sll3, sizeof(sll3));
|
||||
sll3.sll_ifindex = ethreq3.ifr_ifindex;
|
||||
|
||||
//发送
|
||||
sendto(sockfd,buf_all_1,42,0,(struct sockaddr *)&sll3,sizeof(sll3));
|
||||
//ens33网口组arp的请求包
|
||||
unsigned char buf_all_2[42]={
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac广播
|
||||
0x00,0x0c,0x29,0xf3,0x98,0x48,//源mac
|
||||
0x08,0x06,//帧类型
|
||||
0x00,0x01,//硬件类型
|
||||
0x08,0x00,//协议类型
|
||||
6,
|
||||
4,
|
||||
0x00,0x01,//op
|
||||
0x00,0x0c,0x29,0xf3,0x98,0x48,//发送端mac
|
||||
192,168,8,2,//发送端ip
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
192,168,8,i
|
||||
};
|
||||
//获取网络接口类型
|
||||
struct ifreq ethreq4;
|
||||
strncpy(ethreq4.ifr_name, "ens33", IFNAMSIZ);
|
||||
ioctl(sockfd, SIOCGIFINDEX, ðreq4);
|
||||
//定义一个网络接口变量
|
||||
struct sockaddr_ll sll4;
|
||||
bzero(&sll4, sizeof(sll4));
|
||||
sll4.sll_ifindex = ethreq4.ifr_ifindex;
|
||||
|
||||
//发送
|
||||
sendto(sockfd,buf_all_2,42,0,(struct sockaddr *)&sll4,sizeof(sll4));
|
||||
}
|
||||
}
|
||||
else if(6 == chose)
|
||||
{
|
||||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
if(ret==SQLITE_OK)
|
||||
{
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
printf(" %s ",dbResult[index]);
|
||||
index++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
//sqlite3_free_table(dbResult);
|
||||
|
||||
}
|
||||
}
|
||||
else if(9 == chose)
|
||||
{
|
||||
show();
|
||||
}
|
||||
else if(0 == chose)
|
||||
{
|
||||
//关闭套接字
|
||||
close(sockfd);
|
||||
//关闭数据库
|
||||
sqlite3_close(db);
|
||||
printf("系统结束!\n");
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
printf("对不起,您的输入有误");
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************************************************************************************
|
||||
//接收数据包,并进行解析
|
||||
//**************************************************************************************************************************************************
|
||||
//接收所有的数据
|
||||
|
||||
//关闭套接字
|
||||
close(sockfd);
|
||||
//关闭数据库
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void show(void)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
void * my_fun(void * arg)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
unsigned char buf[1500] = "";
|
||||
ssize_t len = recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
|
||||
unsigned char det_mac[18] = "";
|
||||
unsigned char src_mac[18] = "";
|
||||
unsigned short mac_type = ntohs(*(unsigned short *)(buf + 12));
|
||||
//printf("mac_type=\n", mac_type);
|
||||
sprintf(det_mac,"%02x:%02x:%02x:%02x:%02x:%02x",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
|
||||
sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
|
||||
|
||||
//printf("[%3ld]MAC:[%s]->[%s]:%#x\n",len,src_mac,det_mac,mac_type);
|
||||
if(mac_type == 0x0800)
|
||||
{
|
||||
|
||||
unsigned char *ip_buf = buf + 14;
|
||||
|
||||
//源ip、目的ip
|
||||
char src_ip[16] = "";
|
||||
char dst_ip[16] = "";
|
||||
inet_ntop(AF_INET,(void *)ip_buf+12,src_ip,16);
|
||||
inet_ntop(AF_INET,(void *)ip_buf+16,dst_ip,16);
|
||||
//设置标志为
|
||||
int flag=0;
|
||||
char find_ip[64]="";
|
||||
char find_ip2[64]="";
|
||||
sprintf(find_ip,"select * from persons where IP='%s';",src_ip);
|
||||
sprintf(find_ip2,"select * from persons where IP='%s';",dst_ip);
|
||||
ret == sqlite3_get_table(db,find_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
|
||||
if(ret == SQLITE_OK)
|
||||
{
|
||||
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
//printf(" %s ",dbResult[index]);
|
||||
if(strcmp(src_ip,dbResult[index])==0)
|
||||
{
|
||||
flag ++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
sqlite3_free_table(dbResult);
|
||||
if(flag != 0)
|
||||
{
|
||||
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
flag = 0;//标志位归0
|
||||
ret == sqlite3_get_table(db,find_ip2,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
|
||||
if(ret == SQLITE_OK)
|
||||
{
|
||||
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
//printf(" %s ",dbResult[index]);
|
||||
if(strcmp(dst_ip,dbResult[index])==0)
|
||||
{
|
||||
flag ++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
sqlite3_free_table(dbResult);
|
||||
if(flag != 0)
|
||||
{
|
||||
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
flag = 0; //柏标志为清0
|
||||
|
||||
if(ip_buf[9] == 1)
|
||||
{
|
||||
//ICMP
|
||||
//通过目的ip找到目的MAC
|
||||
char find_mac[18]="";
|
||||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
|
||||
if(ret==SQLITE_OK)
|
||||
{
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
if(strcmp(dst_ip,dbResult[index]) == 0)
|
||||
{
|
||||
memcpy(find_mac,dbResult[index+1],18);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//将获得到的目的MAC 进行解包
|
||||
unsigned char find_buf_one[6]="";
|
||||
sscanf(find_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int *)&find_buf_one[0],(unsigned int *)&find_buf_one[1],(unsigned int *)&find_buf_one[2],(unsigned int *)&find_buf_one[3],(unsigned int *)&find_buf_one[4],(unsigned int *)&find_buf_one[5]);
|
||||
if(0 == strcmp(src_mac,"80:fa:5b:26:d4:10"))
|
||||
{ //printf("MAC:[%s]->[%s]\n",src_mac,det_mac);
|
||||
//printf("IP:[%s]->[%s]\n",src_ip,dst_ip);
|
||||
//根据IP判断防火墙
|
||||
//建立数据库,在数据库中遍历
|
||||
//查询数据,如果没有此ip则创建一个数据,如果有判断其mac是否更改
|
||||
//sqlite3_exec(db,"insert into persons values(arp_ip,arp_mac);",NULL,NULL,&errmsg);
|
||||
|
||||
|
||||
//printf("协议类型:ICMP\n");
|
||||
//printf("\n");
|
||||
//在数据库中找到目的IP对应的mac组装到发送的位置
|
||||
//网关到A53
|
||||
|
||||
unsigned char buf_34[1500] = "";
|
||||
|
||||
//目的MAC:00:53:50:00:2c:59
|
||||
buf[0] = find_buf_one[0];
|
||||
buf[1] = find_buf_one[1];
|
||||
buf[2] = find_buf_one[2];
|
||||
buf[3] = find_buf_one[3];
|
||||
buf[4] = find_buf_one[4];
|
||||
buf[5] = find_buf_one[5];
|
||||
//源MAC 00:0c:29:f3:98:48
|
||||
buf[6] = 0x00;
|
||||
buf[7] = 0x0c;
|
||||
buf[8] = 0x29;
|
||||
buf[9] = 0xf3;
|
||||
buf[10] = 0x98;
|
||||
buf[11] = 0x48;
|
||||
|
||||
//memcpy(buf_34,buf,strlen(buf)+1);
|
||||
//获取网络接口类型
|
||||
struct ifreq ethreq;
|
||||
strncpy(ethreq.ifr_name, "ens38", IFNAMSIZ);
|
||||
ioctl(sockfd, SIOCGIFINDEX, ðreq);
|
||||
//定义一个网络接口变量
|
||||
struct sockaddr_ll sll;
|
||||
bzero(&sll, sizeof(sll));
|
||||
sll.sll_ifindex = ethreq.ifr_ifindex;
|
||||
|
||||
//发送
|
||||
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&sll,sizeof(sll));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(0 == strcmp(src_mac,"00:53:50:00:2c:59"))
|
||||
{
|
||||
//printf("----------A53----------\n");
|
||||
//printf("MAC:[%s]->[%s]\n",src_mac,det_mac);
|
||||
//printf("IP:[%s]->[%s]\n",src_ip,dst_ip);
|
||||
//printf("协议类型:ICMP\n");
|
||||
//printf("\n");
|
||||
|
||||
//2->1
|
||||
unsigned char buf_21[1500] = "";
|
||||
|
||||
//目的MAC 80:fa:5b:26:d4:10
|
||||
buf[0] = find_buf_one[0];
|
||||
buf[1] = find_buf_one[1];
|
||||
buf[2] = find_buf_one[2];
|
||||
buf[3] = find_buf_one[3];
|
||||
buf[4] = find_buf_one[4];
|
||||
buf[5] = find_buf_one[5];
|
||||
//源MAC 00:0c:29:f3:98:3e
|
||||
buf[6] = 0x00;
|
||||
buf[7] = 0x0c;
|
||||
buf[8] = 0x29;
|
||||
buf[9] = 0xf3;
|
||||
buf[10] = 0x98;
|
||||
buf[11] = 0x3e;
|
||||
|
||||
//memcpy(buf_34,buf,strlen(buf)+1);
|
||||
//获取网络接口类型
|
||||
struct ifreq ethreq;
|
||||
strncpy(ethreq.ifr_name, "ens33", IFNAMSIZ);
|
||||
ioctl(sockfd, SIOCGIFINDEX, ðreq);
|
||||
//定义一个网络接口变量
|
||||
struct sockaddr_ll sll;
|
||||
bzero(&sll, sizeof(sll));
|
||||
sll.sll_ifindex = ethreq.ifr_ifindex;
|
||||
|
||||
//发送
|
||||
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&sll,sizeof(sll));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(mac_type == 0x0806)
|
||||
{
|
||||
unsigned char *ip_buf = buf + 14;
|
||||
|
||||
//源ip、目的ip
|
||||
char src_ip[16] = "";
|
||||
char dst_ip[16] = "";
|
||||
inet_ntop(AF_INET,(void *)ip_buf+14,src_ip,16);
|
||||
inet_ntop(AF_INET,(void *)ip_buf+24,dst_ip,16);
|
||||
//将接收RP的应答包,将其ip与mac保存在数据库中,方便组装icmp
|
||||
unsigned short arp_accept = ntohs(*(unsigned short * )(ip_buf+6));
|
||||
|
||||
if(2 == arp_accept)
|
||||
{
|
||||
int mac_flag = 0;
|
||||
//再插入数据库之前,先判断有没有一样的IP和MAC
|
||||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
if(ret==SQLITE_OK)
|
||||
{
|
||||
int i,j,index;
|
||||
index=ncolumn;
|
||||
for(i=0;i<nrow;i++)
|
||||
{
|
||||
|
||||
for(j=0;j<ncolumn;j++)
|
||||
{
|
||||
if(strcmp(src_ip,dbResult[index])== 0)
|
||||
{
|
||||
if(strcmp(src_mac,dbResult[index+1])==0)
|
||||
{
|
||||
printf("数据库中已有此arp缓存,无需添加\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("IP对应的mac更改了!\n");
|
||||
char update_buf[128]="";
|
||||
sprintf(update_buf,"updata person set mac = '%s' where ip = '%s';",src_mac,src_ip);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//取出其应答包的源MAC和源IP
|
||||
char str[128]="";
|
||||
sprintf(str,"insert into person values('%s','%s');",src_ip,src_mac);
|
||||
sqlite3_get_table(db,str,&dbResult,&nrow,&ncolumn,&errmsg);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue