路由黑名单可从终端添加到mysql数据库中,包含插入前ip格式检查

This commit is contained in:
flykhan 2023-09-20 16:13:41 +08:00
parent cdf2350d9f
commit 7a0a6e0a29
22 changed files with 525 additions and 2010 deletions

View File

@ -3,14 +3,16 @@ SRC_DIR = ./
OBJ_DIR = ./ OBJ_DIR = ./
BIN_DIR = ./ BIN_DIR = ./
# CFLAGS = -Wall -Wextra -Werror
# 定义编译器 # 定义编译器
CC = gcc CC = gcc
# 定义目标文件 # 定义目标文件
TARGET = $(BIN_DIR)/debug TARGET = $(BIN_DIR)/router
# 定义源文件 # 定义源文件
SRCS = $(wildcard $(SRC_DIR)/*.c) SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(OBJ_DIR)/t1.o $(OBJ_DIR)/get_interface.o # OBJS = $(OBJ_DIR)/t1.o $(OBJ_DIR)/get_interface.o
# OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS)) OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
# 编译规则 # 编译规则
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
@ -18,7 +20,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
# 链接规则 # 链接规则
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
$(CC) $^ -o $@ -lpcap -lpthread $(CC) $^ -o $@ -lpcap -lpthread -lmysqlclient
# 默认构建目标 # 默认构建目标
all: $(TARGET) all: $(TARGET)

120
router/db.c Normal file
View File

@ -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;
}

22
router/db.h Normal file
View File

@ -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);

Binary file not shown.

BIN
router/router Executable file

Binary file not shown.

340
router/router.c Normal file
View File

@ -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),IPv641
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(&regex, "^((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(&regex, ip, 0, NULL, 0);
regfree(&regex); // 释放正则表达式
if (ret == 0)
{
printf("IP地址格式正确\n");
return 0;
}
else if (ret == REG_NOMATCH)
{
printf("IP地址格式非法\n");
return -1;
}
else
{
printf("正则表达式匹配错误\n");
return -1;
}
}

37
router/router.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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;
}
//*************************过滤链表******************************

View File

@ -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

View File

@ -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缓存表*****************************

View File

@ -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);
//*************************过滤链表******************************

View File

@ -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, &ethreq) == -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);
}
//网卡2ech1的MAC00: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 源IPsrc_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;
}

View File

Binary file not shown.

View File

@ -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, &ethreq3);
//定义一个网络接口变量
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, &ethreq4);
//定义一个网络接口变量
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, &ethreq);
//定义一个网络接口变量
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, &ethreq);
//定义一个网络接口变量
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++;
}
}
}
}
}
}
}