595 lines
20 KiB
C
595 lines
20 KiB
C
#include <stdio.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/ether.h>
|
||
#include <unistd.h>
|
||
#include <string.h>
|
||
#include <sys/types.h>//recvfrom
|
||
#include <netinet/ether.h>//ETH_P_ALL
|
||
#include <arpa/inet.h>//inet_ntop
|
||
#include <net/if.h>//ifreq
|
||
#include <sys/ioctl.h>//ioctl
|
||
#include <netpacket/packet.h>//sockaddr_ll
|
||
#include <pthread.h>
|
||
#include <stdlib.h>
|
||
#include <sqlite3.h>
|
||
|
||
void show(void);//菜单函数
|
||
void * my_fun(void * arg);//线程的回调函数
|
||
|
||
//全局变量定义,方便线程使用
|
||
int sockfd; //套接字
|
||
int ret; //调用数据库是的返回值
|
||
char * errmsg;
|
||
sqlite3 *db;
|
||
char ** dbResult;
|
||
int nrow;
|
||
int ncolumn;
|
||
|
||
int main()
|
||
{
|
||
//创建套接字,原始套接字
|
||
sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
|
||
if(sockfd > 0)
|
||
{
|
||
printf("原始套接字创建成功:%d\n",sockfd);
|
||
}
|
||
//**************************************************************************************************************************************************
|
||
//数据库的打开使用
|
||
//**************************************************************************************************************************************************
|
||
|
||
|
||
//打开数据库
|
||
ret = sqlite3_open("ip.db",&db);
|
||
//如果ret==SQLITE_OK 那么就是这一条语言成功执行了
|
||
if(ret == SQLITE_OK)
|
||
{
|
||
printf("防火墙数据库打开成功!\n");
|
||
}
|
||
else
|
||
{
|
||
printf("数据库打开失败!\n");
|
||
}
|
||
ret = sqlite3_open("mac.db",&db);
|
||
if(ret == SQLITE_OK)
|
||
{
|
||
printf("ARP缓存数据库打开成功!\n");
|
||
}
|
||
else
|
||
{
|
||
printf("数据库打开失败!\n");
|
||
}
|
||
//使用非回调办法增加一张数据表
|
||
sqlite3_get_table(db,"create table persons (IP text primary key);",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
// arp缓存的数据库
|
||
sqlite3_get_table(db,"create table person (ip text primary key,mac text);",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
|
||
//使用回调方法去增加数据
|
||
|
||
char str[128]="";
|
||
printf("防火墙中的IP有:\n");
|
||
//想要添加,从这个地方就可以添加
|
||
char get_ip[16]="192.168.7.5";
|
||
sprintf(str,"insert into persons values('%s');",get_ip);
|
||
sqlite3_get_table(db,str,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
|
||
|
||
|
||
|
||
|
||
//使用非回调函数查询数据
|
||
ret == sqlite3_get_table(db,"select * from persons;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
if(ret==SQLITE_OK)
|
||
{
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
printf(" %s ",dbResult[index]);
|
||
index++;
|
||
}
|
||
printf("\n");
|
||
}
|
||
sqlite3_free_table(dbResult);
|
||
|
||
}
|
||
//选择标志位
|
||
int chose = 0;
|
||
show();//菜单展示
|
||
int pthread_flag = 0;
|
||
while(1)
|
||
{
|
||
printf("请输入您的选择:");
|
||
scanf("%d",&chose);
|
||
getchar();
|
||
if(1 == chose)
|
||
{
|
||
char add_ip[32]="";
|
||
printf("请输入添加的黑名单IP:格式如:192.168.1.1\n");
|
||
fgets(add_ip,sizeof(add_ip),stdin);
|
||
add_ip[strlen(add_ip)-1]='\0';
|
||
//printf("获得到了:%s\n",add_ip);
|
||
//格式校验
|
||
int a=0,b=0,c=0,d=0;
|
||
sscanf(add_ip,"%d.%d.%d.%d",&a,&b,&c,&d);
|
||
if((a >= 0 && a <= 255) && (b >= 0 && b <= 255) && (c >= 0 && c <= 255) && (d >= 0 && d<= 255))
|
||
{
|
||
//写入数据库
|
||
char sqlite3_ip[64]="";
|
||
sprintf(sqlite3_ip,"insert into persons values('%s');",add_ip);
|
||
sqlite3_get_table(db,sqlite3_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
printf("数据库已更新!\n");
|
||
}
|
||
else
|
||
{
|
||
printf("您输入有误\n");
|
||
}
|
||
}
|
||
else if(2 == chose)
|
||
{
|
||
|
||
ret == sqlite3_get_table(db,"select * from persons;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
if(ret==SQLITE_OK)
|
||
{
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
printf(" %s ",dbResult[index]);
|
||
index++;
|
||
}
|
||
printf("\n");
|
||
}
|
||
sqlite3_free_table(dbResult);
|
||
|
||
}
|
||
|
||
}
|
||
else if(3 == chose)
|
||
{
|
||
char delete_ip[32]="";
|
||
printf("请输入删除的黑名单IP:格式如:192.168.1.1\n");
|
||
fgets(delete_ip,sizeof(delete_ip),stdin);
|
||
delete_ip[strlen(delete_ip)-1]='\0';
|
||
printf("获得到了:%s\n",delete_ip);
|
||
//格式校验
|
||
int a=0,b=0,c=0,d=0;
|
||
sscanf(delete_ip,"%d.%d.%d.%d",&a,&b,&c,&d);
|
||
if((a >= 0 && a <= 255) && (b >= 0 && b <= 255) && (c >= 0 && c <= 255) && (d >= 0 && d<= 255))
|
||
{
|
||
//写入数据库
|
||
char sqlite3_ip[64]="";
|
||
sprintf(sqlite3_ip,"delete from persons where IP='%s';",delete_ip);
|
||
sqlite3_get_table(db,sqlite3_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
printf("数据库已更新!\n");
|
||
}
|
||
else
|
||
{
|
||
printf("您输入有误\n");
|
||
}
|
||
}
|
||
else if(4 == chose)
|
||
{
|
||
|
||
if(0 == pthread_flag )
|
||
{
|
||
printf("路由器已运行!\n");
|
||
pthread_flag++;
|
||
pthread_t pth;
|
||
pthread_create(&pth,NULL,my_fun,NULL);
|
||
pthread_detach(pth);
|
||
}
|
||
else
|
||
{
|
||
printf("路由器正在运行,请不要重复开启!\n");
|
||
}
|
||
|
||
|
||
}
|
||
else if(5 == chose)
|
||
{
|
||
//在路由器开启之前,发送arp广播数据包
|
||
//两个端口均要发送广播消息
|
||
printf("arp广播发送!\n");
|
||
int i = 1;
|
||
for(i = 1;i < 255 ;i++)
|
||
{
|
||
//ens33网口组arp的请求包
|
||
unsigned char buf_all_1[42]={
|
||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac广播
|
||
0x00,0x0c,0x29,0x85,0xcc,0x53,//源mac
|
||
0x00,0x0c,0x29,0xf3,0x98,0x3e,//发送端mac
|
||
0x08,0x06,//帧类型
|
||
0x00,0x01,//硬件类型
|
||
0x08,0x00,//协议类型
|
||
6,
|
||
4,
|
||
0x00,0x01,//op
|
||
0x00,0x0c,0x29,0x85,0xcc,0x53,//发送端mac
|
||
192,168,32,129,//发送端ip
|
||
0x00,0x00,0x00,0x00,0x00,0x00,
|
||
192,168,32,i
|
||
};
|
||
//获取网络接口类型
|
||
struct ifreq ethreq3;
|
||
strncpy(ethreq3.ifr_name, "ens33", IFNAMSIZ);
|
||
ioctl(sockfd, SIOCGIFINDEX, ðreq3);
|
||
//定义一个网络接口变量
|
||
struct sockaddr_ll sll3;
|
||
bzero(&sll3, sizeof(sll3));
|
||
sll3.sll_ifindex = ethreq3.ifr_ifindex;
|
||
|
||
//发送
|
||
sendto(sockfd,buf_all_1,42,0,(struct sockaddr *)&sll3,sizeof(sll3));
|
||
//ens33网口组arp的请求包
|
||
unsigned char buf_all_2[42]={
|
||
0xff,0xff,0xff,0xff,0xff,0xff,//目的mac广播
|
||
0x00,0x0c,0x29,0xf3,0x98,0x48,//源mac
|
||
0x08,0x06,//帧类型
|
||
0x00,0x01,//硬件类型
|
||
0x08,0x00,//协议类型
|
||
6,
|
||
4,
|
||
0x00,0x01,//op
|
||
0x00,0x0c,0x29,0xf3,0x98,0x48,//发送端mac
|
||
192,168,8,2,//发送端ip
|
||
0x00,0x00,0x00,0x00,0x00,0x00,
|
||
192,168,8,i
|
||
};
|
||
//获取网络接口类型
|
||
struct ifreq ethreq4;
|
||
strncpy(ethreq4.ifr_name, "ens33", IFNAMSIZ);
|
||
ioctl(sockfd, SIOCGIFINDEX, ðreq4);
|
||
//定义一个网络接口变量
|
||
struct sockaddr_ll sll4;
|
||
bzero(&sll4, sizeof(sll4));
|
||
sll4.sll_ifindex = ethreq4.ifr_ifindex;
|
||
|
||
//发送
|
||
sendto(sockfd,buf_all_2,42,0,(struct sockaddr *)&sll4,sizeof(sll4));
|
||
}
|
||
}
|
||
else if(6 == chose)
|
||
{
|
||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
if(ret==SQLITE_OK)
|
||
{
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
printf(" %s ",dbResult[index]);
|
||
index++;
|
||
}
|
||
printf("\n");
|
||
}
|
||
//sqlite3_free_table(dbResult);
|
||
|
||
}
|
||
}
|
||
else if(9 == chose)
|
||
{
|
||
show();
|
||
}
|
||
else if(0 == chose)
|
||
{
|
||
//关闭套接字
|
||
close(sockfd);
|
||
//关闭数据库
|
||
sqlite3_close(db);
|
||
printf("系统结束!\n");
|
||
exit(0);
|
||
}
|
||
else
|
||
{
|
||
|
||
printf("对不起,您的输入有误");
|
||
}
|
||
}
|
||
|
||
//**************************************************************************************************************************************************
|
||
//接收数据包,并进行解析
|
||
//**************************************************************************************************************************************************
|
||
//接收所有的数据
|
||
|
||
//关闭套接字
|
||
close(sockfd);
|
||
//关闭数据库
|
||
sqlite3_close(db);
|
||
|
||
return 0;
|
||
}
|
||
|
||
void show(void)
|
||
{
|
||
printf("************************************************\n");
|
||
printf("**********路由器黑名单管理系统******************\n");
|
||
printf("**************1.添加黑名单IP********************\n");
|
||
printf("**************2.显示所有黑名单******************\n");
|
||
printf("**************3.删除黑名单**********************\n");
|
||
printf("**************4.开启路由器**********************\n");
|
||
printf("**************5.刷新ARP表缓存*******************\n");
|
||
printf("**************6.显示所有ARP表缓存***************\n");
|
||
printf("**************9.重新打印菜单********************\n");
|
||
printf("**************0.退出此系统**********************\n");
|
||
printf("************************************************\n");
|
||
}
|
||
|
||
void * my_fun(void * arg)
|
||
{
|
||
|
||
while(1)
|
||
{
|
||
unsigned char buf[1500] = "";
|
||
ssize_t len = recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
|
||
unsigned char det_mac[18] = "";
|
||
unsigned char src_mac[18] = "";
|
||
unsigned short mac_type = ntohs(*(unsigned short *)(buf + 12));
|
||
//printf("mac_type=\n", mac_type);
|
||
sprintf(det_mac,"%02x:%02x:%02x:%02x:%02x:%02x",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
|
||
sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
|
||
|
||
//printf("[%3ld]MAC:[%s]->[%s]:%#x\n",len,src_mac,det_mac,mac_type);
|
||
if(mac_type == 0x0800)
|
||
{
|
||
|
||
unsigned char *ip_buf = buf + 14;
|
||
|
||
//源ip、目的ip
|
||
char src_ip[16] = "";
|
||
char dst_ip[16] = "";
|
||
inet_ntop(AF_INET,(void *)ip_buf+12,src_ip,16);
|
||
inet_ntop(AF_INET,(void *)ip_buf+16,dst_ip,16);
|
||
//设置标志为
|
||
int flag=0;
|
||
char find_ip[64]="";
|
||
char find_ip2[64]="";
|
||
sprintf(find_ip,"select * from persons where IP='%s';",src_ip);
|
||
sprintf(find_ip2,"select * from persons where IP='%s';",dst_ip);
|
||
ret == sqlite3_get_table(db,find_ip,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
|
||
if(ret == SQLITE_OK)
|
||
{
|
||
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
//printf(" %s ",dbResult[index]);
|
||
if(strcmp(src_ip,dbResult[index])==0)
|
||
{
|
||
flag ++;
|
||
}
|
||
index++;
|
||
}
|
||
|
||
}
|
||
sqlite3_free_table(dbResult);
|
||
if(flag != 0)
|
||
{
|
||
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
|
||
continue;
|
||
}
|
||
|
||
}
|
||
flag = 0;//标志位归0
|
||
ret == sqlite3_get_table(db,find_ip2,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
|
||
if(ret == SQLITE_OK)
|
||
{
|
||
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
//printf(" %s ",dbResult[index]);
|
||
if(strcmp(dst_ip,dbResult[index])==0)
|
||
{
|
||
flag ++;
|
||
}
|
||
index++;
|
||
}
|
||
|
||
}
|
||
sqlite3_free_table(dbResult);
|
||
if(flag != 0)
|
||
{
|
||
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
|
||
continue;
|
||
}
|
||
|
||
}
|
||
flag = 0; //柏标志为清0
|
||
|
||
if(ip_buf[9] == 1)
|
||
{
|
||
//ICMP
|
||
//通过目的ip找到目的MAC
|
||
char find_mac[18]="";
|
||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
|
||
if(ret==SQLITE_OK)
|
||
{
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
if(strcmp(dst_ip,dbResult[index]) == 0)
|
||
{
|
||
memcpy(find_mac,dbResult[index+1],18);
|
||
}
|
||
|
||
index++;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
//将获得到的目的MAC 进行解包
|
||
unsigned char find_buf_one[6]="";
|
||
sscanf(find_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int *)&find_buf_one[0],(unsigned int *)&find_buf_one[1],(unsigned int *)&find_buf_one[2],(unsigned int *)&find_buf_one[3],(unsigned int *)&find_buf_one[4],(unsigned int *)&find_buf_one[5]);
|
||
if(0 == strcmp(src_mac,"80:fa:5b:26:d4:10"))
|
||
{ //printf("MAC:[%s]->[%s]\n",src_mac,det_mac);
|
||
//printf("IP:[%s]->[%s]\n",src_ip,dst_ip);
|
||
//根据IP判断防火墙
|
||
//建立数据库,在数据库中遍历
|
||
//查询数据,如果没有此ip则创建一个数据,如果有判断其mac是否更改
|
||
//sqlite3_exec(db,"insert into persons values(arp_ip,arp_mac);",NULL,NULL,&errmsg);
|
||
|
||
|
||
//printf("协议类型:ICMP\n");
|
||
//printf("\n");
|
||
//在数据库中找到目的IP对应的mac组装到发送的位置
|
||
//网关到A53
|
||
|
||
unsigned char buf_34[1500] = "";
|
||
|
||
//目的MAC:00:53:50:00:2c:59
|
||
buf[0] = find_buf_one[0];
|
||
buf[1] = find_buf_one[1];
|
||
buf[2] = find_buf_one[2];
|
||
buf[3] = find_buf_one[3];
|
||
buf[4] = find_buf_one[4];
|
||
buf[5] = find_buf_one[5];
|
||
//源MAC 00:0c:29:f3:98:48
|
||
buf[6] = 0x00;
|
||
buf[7] = 0x0c;
|
||
buf[8] = 0x29;
|
||
buf[9] = 0xf3;
|
||
buf[10] = 0x98;
|
||
buf[11] = 0x48;
|
||
|
||
//memcpy(buf_34,buf,strlen(buf)+1);
|
||
//获取网络接口类型
|
||
struct ifreq ethreq;
|
||
strncpy(ethreq.ifr_name, "ens38", IFNAMSIZ);
|
||
ioctl(sockfd, SIOCGIFINDEX, ðreq);
|
||
//定义一个网络接口变量
|
||
struct sockaddr_ll sll;
|
||
bzero(&sll, sizeof(sll));
|
||
sll.sll_ifindex = ethreq.ifr_ifindex;
|
||
|
||
//发送
|
||
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&sll,sizeof(sll));
|
||
|
||
}
|
||
|
||
|
||
if(0 == strcmp(src_mac,"00:53:50:00:2c:59"))
|
||
{
|
||
//printf("----------A53----------\n");
|
||
//printf("MAC:[%s]->[%s]\n",src_mac,det_mac);
|
||
//printf("IP:[%s]->[%s]\n",src_ip,dst_ip);
|
||
//printf("协议类型:ICMP\n");
|
||
//printf("\n");
|
||
|
||
//2->1
|
||
unsigned char buf_21[1500] = "";
|
||
|
||
//目的MAC 80:fa:5b:26:d4:10
|
||
buf[0] = find_buf_one[0];
|
||
buf[1] = find_buf_one[1];
|
||
buf[2] = find_buf_one[2];
|
||
buf[3] = find_buf_one[3];
|
||
buf[4] = find_buf_one[4];
|
||
buf[5] = find_buf_one[5];
|
||
//源MAC 00:0c:29:f3:98:3e
|
||
buf[6] = 0x00;
|
||
buf[7] = 0x0c;
|
||
buf[8] = 0x29;
|
||
buf[9] = 0xf3;
|
||
buf[10] = 0x98;
|
||
buf[11] = 0x3e;
|
||
|
||
//memcpy(buf_34,buf,strlen(buf)+1);
|
||
//获取网络接口类型
|
||
struct ifreq ethreq;
|
||
strncpy(ethreq.ifr_name, "ens33", IFNAMSIZ);
|
||
ioctl(sockfd, SIOCGIFINDEX, ðreq);
|
||
//定义一个网络接口变量
|
||
struct sockaddr_ll sll;
|
||
bzero(&sll, sizeof(sll));
|
||
sll.sll_ifindex = ethreq.ifr_ifindex;
|
||
|
||
//发送
|
||
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&sll,sizeof(sll));
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
else if(mac_type == 0x0806)
|
||
{
|
||
unsigned char *ip_buf = buf + 14;
|
||
|
||
//源ip、目的ip
|
||
char src_ip[16] = "";
|
||
char dst_ip[16] = "";
|
||
inet_ntop(AF_INET,(void *)ip_buf+14,src_ip,16);
|
||
inet_ntop(AF_INET,(void *)ip_buf+24,dst_ip,16);
|
||
//将接收RP的应答包,将其ip与mac保存在数据库中,方便组装icmp
|
||
unsigned short arp_accept = ntohs(*(unsigned short * )(ip_buf+6));
|
||
|
||
if(2 == arp_accept)
|
||
{
|
||
int mac_flag = 0;
|
||
//再插入数据库之前,先判断有没有一样的IP和MAC
|
||
ret == sqlite3_get_table(db,"select * from person;",&dbResult,&nrow,&ncolumn,&errmsg);
|
||
if(ret==SQLITE_OK)
|
||
{
|
||
int i,j,index;
|
||
index=ncolumn;
|
||
for(i=0;i<nrow;i++)
|
||
{
|
||
|
||
for(j=0;j<ncolumn;j++)
|
||
{
|
||
if(strcmp(src_ip,dbResult[index])== 0)
|
||
{
|
||
if(strcmp(src_mac,dbResult[index+1])==0)
|
||
{
|
||
printf("数据库中已有此arp缓存,无需添加\n");
|
||
}
|
||
else
|
||
{
|
||
printf("IP对应的mac更改了!\n");
|
||
char update_buf[128]="";
|
||
sprintf(update_buf,"updata person set mac = '%s' where ip = '%s';",src_mac,src_ip);
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//取出其应答包的源MAC和源IP
|
||
char str[128]="";
|
||
sprintf(str,"insert into person values('%s','%s');",src_ip,src_mac);
|
||
sqlite3_get_table(db,str,&dbResult,&nrow,&ncolumn,&errmsg);
|
||
}
|
||
index++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
}
|