diff --git a/boa b/boa new file mode 160000 index 0000000..85e41f3 --- /dev/null +++ b/boa @@ -0,0 +1 @@ +Subproject commit 85e41f3ef9b31925a40e5dc4a782bc818570114c diff --git a/boa_conf.sh b/boa_conf.sh new file mode 100644 index 0000000..17568ce --- /dev/null +++ b/boa_conf.sh @@ -0,0 +1,7 @@ +#! /bin/bash + +echo "向系统bin目录添加boa软连接" +sudo ln -s ~/c-router-emulator/boa/boa /usr/bin/boa + +echo "向系统bin目录添加boa.conf软连接" +sudo ln -s ~/c-router-emulator/boa/boa.conf /etc/boa/boa.conf \ No newline at end of file diff --git a/router/Makefile b/router/Makefile new file mode 100644 index 0000000..89b5901 --- /dev/null +++ b/router/Makefile @@ -0,0 +1,34 @@ +# 定义路径变量 +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 \ No newline at end of file diff --git a/router/debug b/router/debug new file mode 100755 index 0000000..20be4e1 Binary files /dev/null and b/router/debug differ diff --git a/router/get_interface.c b/router/get_interface.c new file mode 100644 index 0000000..8ac45ec --- /dev/null +++ b/router/get_interface.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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); + /* 获得接口标志 */ + if (!(ioctl(sock_raw_fd, SIOCGIFFLAGS, (char *) &buf[if_len]))){ + /* 接口状态 */ + 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]))){ + 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(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, "SIOCGIFADDR 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 +} diff --git a/router/get_interface.h b/router/get_interface.h new file mode 100644 index 0000000..ac2a98b --- /dev/null +++ b/router/get_interface.h @@ -0,0 +1,31 @@ +#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 diff --git a/router/readme.md b/router/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/router/t1.c b/router/t1.c new file mode 100644 index 0000000..9266a21 --- /dev/null +++ b/router/t1.c @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include // ioctl 函数 SIOCGIFHWADDR SIOCGIFADDR +// #include +#include +#include +#include +#include +#include +#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; +} diff --git a/router/t2.c b/router/t2.c new file mode 100644 index 0000000..3968fe2 --- /dev/null +++ b/router/t2.c @@ -0,0 +1,11 @@ +#include "get_interface.h" + +int main(int argc, char const *argv[]) +{ + // 获取接口数量和接口信息 + getinterface(); + // 打印接口数量 + // printf("interface_num=%d\n\n", get_interface_num()); + // 打印接口信息 + return 0; +} diff --git a/router/test/Makefile b/router/test/Makefile new file mode 100644 index 0000000..09d01cf --- /dev/null +++ b/router/test/Makefile @@ -0,0 +1,34 @@ +# 定义路径变量 +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 \ No newline at end of file diff --git a/router/test/get_interface.c b/router/test/get_interface.c new file mode 100644 index 0000000..0cce9c5 --- /dev/null +++ b/router/test/get_interface.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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 +} + \ No newline at end of file diff --git a/router/test/get_interface.h b/router/test/get_interface.h new file mode 100644 index 0000000..d757141 --- /dev/null +++ b/router/test/get_interface.h @@ -0,0 +1,54 @@ +#ifndef IP_FILE_H +#define IP_FILE_H +#include +#include +#include +#include +#include +#include + + +//*************************过滤链表****************************** +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 \ No newline at end of file diff --git a/router/test/ip_file.c b/router/test/ip_file.c new file mode 100644 index 0000000..3d52b55 --- /dev/null +++ b/router/test/ip_file.c @@ -0,0 +1,249 @@ +#include "ip_file.h" +#include "link.h" +#include +#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; +} +//*************************过滤链表****************************** + \ No newline at end of file diff --git a/router/test/ip_file.h b/router/test/ip_file.h new file mode 100644 index 0000000..0bff41f --- /dev/null +++ b/router/test/ip_file.h @@ -0,0 +1,32 @@ +#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 + \ No newline at end of file diff --git a/router/test/link.c b/router/test/link.c new file mode 100644 index 0000000..ea020a8 --- /dev/null +++ b/router/test/link.c @@ -0,0 +1,223 @@ +#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缓存表***************************** \ No newline at end of file diff --git a/router/test/link.h b/router/test/link.h new file mode 100644 index 0000000..4ff0a8d --- /dev/null +++ b/router/test/link.h @@ -0,0 +1,63 @@ +#include +#include +#include + +#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); +//*************************过滤链表****************************** \ No newline at end of file diff --git a/router/test/main.c b/router/test/main.c new file mode 100644 index 0000000..fa0a5f2 --- /dev/null +++ b/router/test/main.c @@ -0,0 +1,419 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/cgi/readme.md b/router/test2/ip.db similarity index 100% rename from cgi/readme.md rename to router/test2/ip.db diff --git a/router/test2/mac.db b/router/test2/mac.db new file mode 100644 index 0000000..f52cc6c Binary files /dev/null and b/router/test2/mac.db differ diff --git a/router/test2/t1.c b/router/test2/t1.c new file mode 100644 index 0000000..1ccec35 --- /dev/null +++ b/router/test2/t1.c @@ -0,0 +1,594 @@ +#include +#include +#include +#include +#include +#include //recvfrom +#include //ETH_P_ALL +#include //inet_ntop +#include //ifreq +#include //ioctl +#include //sockaddr_ll +#include +#include +#include + +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= 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= 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[%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[%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