c-router-emulator/router/test2/t1.c

595 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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++;
}
}
}
}
}
}
}