1.路由器
完成不同网段之间的通信,下面通过一个代码来具体演示路由器的工作过程 总结:这个项目耗时两天半完成,旨在理解原始套接字如何接收数据,发送数据。同时熟练使用sqlite3数据库 模拟两个不同网段进行通信,主要是进行ping的时候。 1.两个不同的网段再ping的时候,是ping不通的。 2.再ping其他网段的时候,首先是发送arp的请求包,然后再发送icmp数据包,arp来获取目的IP的MAC地址,如果能够找到这个mac地址,那么就能够组装到icmp数据包上,从而完成通信。 3.当发送icmp数据包的时候,到达我们所模拟的路由器的时候,查找arp缓存表中是否有对应IP的mac地址,如果有,那么就组装到目的mac上即可,没有就ping不同啦。
这个代码看看里面的内容就好,理解一下就行,实现起来硬件也需要进行改动,因为虚拟机和windows是同一个网段上的,本来就可以直接ping通,所以需要再加上两个网卡,将window上的网关改为虚拟机一端的ip,然后另两个端口再改成不一样的。。。
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/ether.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
#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);
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);
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';
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)
{
printf("arp广播发送!\n");
int i = 1;
for(i = 1;i < 255 ;i++)
{
unsigned char buf_all_1[42]={
0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x0c,0x29,0xf3,0x98,0x3e,
0x08,0x06,
0x00,0x01,
0x08,0x00,
6,
4,
0x00,0x01,
0x00,0x0c,0x29,0xf3,0x98,0x3e,
192,168,7,2,
0x00,0x00,0x00,0x00,0x00,0x00,
192,168,7,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));
unsigned char buf_all_2[42]={
0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x0c,0x29,0xf3,0x98,0x48,
0x08,0x06,
0x00,0x01,
0x08,0x00,
6,
4,
0x00,0x01,
0x00,0x0c,0x29,0xf3,0x98,0x48,
192,168,8,2,
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");
}
}
}
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));
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]);
if(mac_type == 0x0800)
{
unsigned char *ip_buf = buf + 14;
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++)
{
if(strcmp(src_ip,dbResult[index])==0)
{
flag ++;
}
index++;
}
}
sqlite3_free_table(dbResult);
if(flag != 0)
{
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
continue;
}
}
flag = 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++)
{
if(strcmp(dst_ip,dbResult[index])==0)
{
flag ++;
}
index++;
}
}
sqlite3_free_table(dbResult);
if(flag != 0)
{
printf("防火墙发现含有隐患的IP,已将其拦截! \n");
continue;
}
}
flag = 0;
if(ip_buf[9] == 1)
{
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++;
}
}
}
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"))
{
unsigned char buf_34[1500] = "";
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];
buf[6] = 0x00;
buf[7] = 0x0c;
buf[8] = 0x29;
buf[9] = 0xf3;
buf[10] = 0x98;
buf[11] = 0x48;
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"))
{
unsigned char buf_21[1500] = "";
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];
buf[6] = 0x00;
buf[7] = 0x0c;
buf[8] = 0x29;
buf[9] = 0xf3;
buf[10] = 0x98;
buf[11] = 0x3e;
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;
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);
unsigned short arp_accept = ntohs(*(unsigned short * )(ip_buf+6));
if(2 == arp_accept)
{
int mac_flag = 0;
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
{
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++;
}
}
}
}
}
}
}
|