(前戏)利用PCAP实现端口中继
libpcap是一个常用的抓取数据的开源库,它可以简单的从网卡复制一份数据出来,供上层应用分析,嗅探。
端口中继,我也是自己创造出来了一个概念,就是原有场景如下
然后我们在中间增加一个中介主机,该主机有两个网口,X和Y,不需要配置IP,让数据从端口X抓到,然后复制到端口Y,反之也是,由端口Y抓到数据,复制到端口X,整个过程对AB是无感的。
下面是主要部分的代码
#include "user.h"
void mvdata(u_char *user,const struct pcap_pkthdr *pkthdr,const u_char *packet)
{
pcap_t *dev_out;
unsigned packetSize;
dev_out = (pcap_t *)user;
packetSize = pkthdr->len;
pcap_sendpacket(dev_out, packet, packetSize);
}
void *a2b(void *netlinkinfo)
{
char *device_in= "enp5s0";
char *device_out= "enp6s0";
pcap_t *dev_in;
pcap_t *dev_out;
char errBuf[PCAP_ERRBUF_SIZE];
char errbuf2[PCAP_ERRBUF_SIZE];
//打开设备device,最大字节数65535,不处于混杂模式,不抓到数据包不返回,错误提示消息
dev_in = pcap_open_live(device_in,65535,1,0,errBuf);
if(dev_in)
{
printf("a2b:Open dev_in success!\n");
}
else
{
printf("a2b:Open dev_in failed. %s\n",errBuf);
return 0;
}
dev_out= pcap_open_live(device_out,65535,1,0,errbuf2 ) ;
if(dev_out)
{
printf("a2b:Open dev_out success!\n");
}
else
{
printf("a2b:Open dev_out failed. %s\n",errbuf2);
return 0;
}
pcap_setdirection(dev_in,PCAP_D_IN);
pcap_setdirection(dev_out,PCAP_D_OUT);
pcap_loop(dev_in,-1,mvdata,(u_char *)dev_out);
pcap_close(dev_in);
pcap_close(dev_out);
return 0;
}
int a2b_process(void)
{
pthread_t nlk_process;
pthread_attr_t attr_nlk;
pthread_attr_init(&attr_nlk);
pthread_attr_setdetachstate(&attr_nlk, PTHREAD_CREATE_DETACHED);
pthread_create(&nlk_process, &attr_nlk, a2b, NULL);
return 0;
}
void *b2a(void *netlinkinfo)
{
char *device_in= "enp6s0";
char *device_out= "enp5s0";
pcap_t *dev_in;
pcap_t *dev_out;
char errBuf[PCAP_ERRBUF_SIZE];
char errbuf2[PCAP_ERRBUF_SIZE];
dev_in = pcap_open_live(device_in,65535,1,0,errBuf);
if(dev_in)
{
printf("b2a:Open dev_in success!\n");
}
else
{
printf("b2a:Open dev_in failed. %s\n",errBuf);
return 0;
}
dev_out= pcap_open_live(device_out,65535,1,0,errbuf2 ) ;
if(dev_out)
{
printf("b2a:Open dev_out success!\n");
}
else
{
printf("b2a:Open dev_out failed. %s\n",errbuf2);
return 0;
}
pcap_setdirection(dev_in,PCAP_D_IN);
pcap_setdirection(dev_out,PCAP_D_OUT);
pcap_loop(dev_in,-1,mvdata,(u_char *)dev_out);
pcap_close(dev_in);
pcap_close(dev_out);
return 0;
}
int b2a_process(void)
{
pthread_t nlk_process;
pthread_attr_t attr_nlk;
pthread_attr_init(&attr_nlk);
pthread_attr_setdetachstate(&attr_nlk, PTHREAD_CREATE_DETACHED);
pthread_create(&nlk_process, &attr_nlk, b2a, NULL);
return 0;
}
/*
用一下这个接口:int pcap_setdirection(pcap_t *, pcap_direction_t);
第二个参数设为PCAP_D_IN;
*/
int main(int argc, char* argv[])
{
int i;
for (i = 1; i < argc; i++)
{
printf("%s",argv[i]);
}
printf("\n");
if(strcmp(argv[1],"526")==0)
{
a2b_process();
}
else if(strcmp(argv[1],"625")==0)
{
b2a_process();
}
else
{
a2b_process();
b2a_process();
}
while(1)
{
sleep(1);
}
}
代码可以同时创建两个线程,线程的含义就是打开入口,打开出口,然后利用pcap抓取入口数据,写到出口。
这么做的目的,就是我们可以将中间传输的数据,进行截获,或者修改,或者加密,都是可以做的。
不过这种纯软件的方式,速度可能不是很理想。
下一篇我们进行数据包的编辑修改后再传输。