目录

1. 背景:

2. 需要的技术手段:

3. 实现逻辑:

4. 应用实例:


1. 背景:

一台电脑允许接多个网口,当然大部分只有一个网口其余都是USB扩展而来,而每个网口之间需要配置不同的网段IP,这就造成了和同一台电脑不通网口相连的设备处于不通的网段,虽然电脑与两台设备沟通无压力,但是两台设备间通信由于处于不通网段而变得相对比较困难。对于开发人员,这并不是一个问题,直接接到交换机或者HUB上一样工作。。。而且扩展性也无与伦比。。。对一般windows系统而言,都支持网卡桥接,因此两设备间通信也是很好的选择。但是总有一些人不喜欢桥接这种模式,甚至不允许网卡间的桥接,也不采用交换机这种神器。

简单的说,使用场合的不同导致好多很容易的事情变成了问题,这就要求具体情况具体分析。

如上图所示,这是简单的拓扑,其中DHCP Server 和DHCP Client 可以自行替换成不同设备,但是具体的功能实现可能不同,但是原理都是一样的。

条件:

1)电脑的网卡1IP设置为192.168.1.6/24,电脑的网卡2 IP设置无要求,无要求,无要求(任意但是不得同一网段,因为同一网段电脑提示设置失败。如果你能设置上那这篇文章就无需阅读了)。

2)DHCP Server 的IP设置为192.168.1.1/24,并且开启DHCP功能

目标:

DHCP Client可以成功的获取到DHCP Server分配的IP。

2. 需要的技术手段:

a. 实现此目标有需要几个简单的技术手段:

1)电脑上实现一个数据包转发软件,也就是上图的界面;

2)获取到电脑网卡MAC信息;

3)获取到DHCP Server的MAC信息;

4)电脑上分别抓取到流经网卡1和网卡2的链路层数据包;

b.  相关技术手段的实现:

1)转发软件可以使用任何一种编程语言,但是要求能提供获取到链路层信息的库。我当时用的是C实现的控制台程序。这并不是关键问题。

2)获取本机的mac信息对任何语言都不是什么问题,视具体情况去百度

3)获取DHCP Server的Mac信息,这需要电脑和DHCP Server之间有信息的交互,而我们可以利用获取到的链路层报文将其MAC地址提取到。至于如何进行信息交互,这里不提供具体的方法,是具体情况而定,方法肯定是存在的。实在没有,ping一包亦可以。(注:一般情况DHCP Server都集成到某些主控设备上,而主控设备和电脑间是存在报文交互的,因此获取主控设备与电脑相连的那个网卡MAC就很简单了)

4)至于如何采集链路层数据包,这个也是具体情况具体分析。我用的Wpcap提供的动态库函数,然后去分别监控两个网卡信息。

3. 实现逻辑:

具体的实现逻辑和原理倒是很简单:

与DHCP Server 相连的网卡1:转发源Mac 为DHCP Server且不是发给本机IP的报文

与DHCP Client 相连的网卡2:转发除了(源mac为DHCP Server,或者本机发出的报文)以外的其他报文

逻辑就是这么简单,而且使用范围不仅限于文章提供的拓扑,因为从实现上将它的转发条件很大,可以实现多个设备间的数据转发。

4. 应用实例:

注:此实例只是工程中的一小部分,但是是该功能实现的精华所在,它只提供参考,并不是拿来就可以使用的。



unsigned char hostMAC[6][6]; /*记录本机电脑的mac*/
unsigned char remoteMAC[6]; /*记录远端mac*/
unsigned char broadcastMAC[6];/*记录广播mac(全0xff)*/
unsigned char netCnt; /*记录本机中网卡的个数,*/
unsigned char netZeboxLink; /*记录本机中那个网卡与远端设备连接*/ /****************************************************************************
* getLocalMac2 :
* 获取本机的所有网卡的mac地址,经将其存起来
*
*****************************************************************************/
int getLocalMac2() /*sunzd 20181129*/
{
ULONG ulSize=0;
PIP_ADAPTER_INFO pInfo=NULL,pInfoTemp;
int temp=0; PIP_ADDR_STRING pIpAddress; while(netCnt<2){
ulSize=0;pInfo=NULL;temp=0;pInfoTemp=NULL;netCnt=0; PILMemSet(hostMAC,0xff,sizeof(hostMAC));
PILMemSet(remoteMAC,0xff,sizeof(remoteMAC));
PILMemSet(broadcastMAC,0xff,sizeof(broadcastMAC)); temp = GetAdaptersInfo(pInfo,&ulSize);//第一处调用,获取缓冲区大小
pInfo=(PIP_ADAPTER_INFO)malloc(ulSize);
temp = GetAdaptersInfo(pInfo,&ulSize);
pInfoTemp = pInfo; while(pInfoTemp)//遍历每一张网卡
{
pIpAddress = &pInfoTemp->IpAddressList;
while(pIpAddress){//遍历网卡下的IP
PILMemCpy(hostMAC[netCnt++], pInfoTemp->Address, (int)pInfoTemp->AddressLength);
break;
}
pInfoTemp = pInfoTemp->Next;
}
free(pInfo); if(netCnt<2) PILSleep(10000); }
return -1; } void PacketWpcapProc1()
{
struct pcap_pkthdr *header;
U8 *packHdr;
S32 retVal;
U8 packetBuf[2048];
U32 bufLength;
U8 pcapNum,i,flag_mac=0; U8 pktHead[4] = {0x68,0x01,0x08,0x13};
while(1){
retVal = pcap_next_ex(wpcapFp[0], &header, &packHdr);
if(retVal <= 0){
continue;
}
bufLength = header->len;
PILMemCpy(packetBuf, packHdr, bufLength); for(i=0;i<netCnt;i++){
if(!PILMemCmp(broadcastMAC, packetBuf, 6) && !PILMemCmp(pktHead, packetBuf+0x2a, 4)){
PILMemCpy(remoteMAC, packetBuf+6, 6);
netZeboxLink = 1;/*发给电脑的KA*/
flag_mac = 1;
break;
}else if(!PILMemCmp(hostMAC[i], packetBuf + 6, 6)){
flag_mac = 1; //本机发出
break;
}
}
if(netZeboxLink==1){/*wpcapFp[0] ---- zebox*/
if(!PILMemCmp(remoteMAC, packetBuf + 6, 6)&&!flag_mac){
retVal = pcap_sendpacket(wpcapFp[1], packetBuf, bufLength);
if(retVal == -1){
continue;
}
}
}else if(netZeboxLink==2){/*wpcapFp[1] ---- zebox*/
if((!PILMemCmp(remoteMAC, packetBuf + 6, 6))||flag_mac){
flag_mac = 0;
continue;
}
retVal = pcap_sendpacket(wpcapFp[1], packetBuf, bufLength); }else{ } flag_mac = 0;
} return SUCCESS;
} void PacketWpcapProc2()
{
struct pcap_pkthdr *header;
U8 *packHdr;
S32 retVal;
U8 packetBuf[2048];
U32 bufLength;
U8 pcapNum,i,flag_mac=0; U8 pktHead[4] = {0x68,0x01,0x08,0x13};
while(1){
retVal = pcap_next_ex(wpcapFp[1], &header, &packHdr);
if(retVal <= 0){
continue;
}
bufLength = header->len;
PILMemCpy(packetBuf, packHdr, bufLength); for(i=0;i<netCnt;i++){
if(!PILMemCmp(broadcastMAC, packetBuf, 6) && !PILMemCmp(pktHead, packetBuf+0x2a, 4)){
PILMemCpy(remoteMAC, packetBuf+6, 6);
netZeboxLink = 2;/*发给电脑的KA*/
flag_mac = 1; //发给本机
break;
}else if(!PILMemCmp(hostMAC[i], packetBuf + 6, 6)){
flag_mac = 1; //本机发出
break;
}
}
if(netZeboxLink==1){/*wpcapFp[0] ---- zebox*/
if((!PILMemCmp(remoteMAC, packetBuf + 6, 6))||flag_mac){
flag_mac = 0;
continue;
}
retVal = pcap_sendpacket(wpcapFp[0], packetBuf, bufLength);
}else if(netZeboxLink==2){/*wpcapFp[1] ---- zebox*/
if(!PILMemCmp(remoteMAC, packetBuf + 6, 6)&&!flag_mac){
retVal = pcap_sendpacket(wpcapFp[0], packetBuf, bufLength);
if(retVal == -1){
continue;
}
} }else{ }
flag_mac = 0; } return SUCCESS;
}

Windos下通过Wpcap抓包实现两个网卡桥接的更多相关文章

  1. 在MacOS下使用Fiddler抓包

    在MacOS下使用Fiddler抓包 有两种方式,分别是安装Mac版的Fiddler,或者是用虚拟机,安装Windows系统,在Windows系统下运行Fiddler对Mac系统中的内容进行抓包. M ...

  2. 【转载】linux下的usb抓包方法

    1 linux下的usb抓包方法 1.配置内核使能usb monitor: make menuconfig                   Device Drivers -->        ...

  3. linux下的usb抓包方法

    1 linux下的usb抓包方法1.配置内核使能usb monitor: make menuconfig                   Device Drivers -->        ...

  4. Mac 下安装Fiddler抓包工具

    需求 我们都知道在Mac电脑下面有一个非常好的抓包工具:Charles.但是这个只能抓代理的数据包.但是有时候想要调试本地网卡的数据库 Charles 就没办法了.就想到了在windows下面的一个F ...

  5. linux下利用tcpdump抓包工具排查nginx获取客户端真实IP实例

    一.nginx后端负载服务器的API在获取客户端IP时始终只能获取nginx的代理服务器IP,排查nginx配置如下 upstream sms-resp { server ; server ; } s ...

  6. MAC下安装Fiddler抓包工具

    需求 我们都知道在Mac电脑下面有一个非常好的抓包工具:Charles.但是这个只能抓代理的数据包.但是有时候想要调试本地网卡的数据库 Charles 就没办法了.就想到了在windows下面的一个F ...

  7. centos下安装wireshark 抓包

    centos下安装wireshark相当简单.两条命令就够了.这里.主要是记录写使用方面的东西 安装:1.yum install wireshark.注意这样并无法使用wireshark命令和图形界面 ...

  8. linux下的usb抓包方法【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-4508834.html 1.配置内核使能usb monitor: make menuconfig       ...

  9. linux下使用tcpdump抓包分析tcp的三次握手

    首先贴上tcp 三次握手的原理图服务器开启ftp服务并执行tcpdump抓包服务器:192.168.3.14 ftp服务客户端:192.168.3.100 服务器执行以下命令,客户端访问服务器ftp: ...

随机推荐

  1. 3G/4G串口服务器

    Z3G/4G串口服务器 ZLAN8303-7是上海卓岚继ZLAN8100之后推出的3G/4G联网解决方案.支持7模的4G串口服务器.其产品支持Modbus功能.自定义注册包心跳包功能. ZLAN830 ...

  2. promise详解 : 实现promise(附实现代码)

    promise then 的特点 : then 函数的返回值是一个 promise, 可以继续调用 then 函数 回调函数 resolve 和 reject 的参数 value /reason, 可 ...

  3. 阿里饿死了么Android面试凉经,两轮面完被虐哭了,怒清购物车。。。卸载饿死了么

    大家应该看过很多分享面试成功的经验,但根据幸存者偏差的理论,也许多看看别人面试失败在哪里,对自己才更有帮助. 最近跟一个朋友聊天,他漫不经心地复习了几个月,就去参加了饿了么面试,第二面结束后,嗯,挂了 ...

  4. MapReduce框架原理-MapTask和ReduceTask工作机制

    MapTask工作机制 并行度决定机制 1)问题引出 maptask的并行度决定map阶段的任务处理并发度,进而影响到整个job的处理速度.那么,mapTask并行任务是否越多越好呢? 2)MapTa ...

  5. ICCV2021 |重新思考人群中的计数和定位:一个纯粹基于点的框架

    ​ 论文:Rethinking Counting and Localization in Crowds:A Purely Point-Based Framework 代码:https://github ...

  6. WPF listbox 实现动态滚轮下拉定位

    private ObservableCollection<keymodel> _listlua; public ObservableCollection<keymodel> l ...

  7. 毕业设计java实验室预约管理系统SSH机房预约系统javaweb机房实验室排课系统mysql机房管理系统 实验室管理系统 课程设计 代码讲解 调试运行

    毕业设计java实验室预约管理系统SSH机房预约系统javaweb机房实验室排课系统mysql机房管理系统 实验室管理系统 课程设计 代码讲解 调试运行 注意:该项目只展示部分功能,如需了解,评论区咨 ...

  8. 手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(四)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 这一篇文章主要实现路由组功能.实现路由 ...

  9. 从一次netty 内存泄露问题来看netty对POST请求的解析

    背景 最近生产环境一个基于 netty 的网关服务频繁 full gc 观察内存占用,并把时间维度拉的比较长,可以看到可用内存有明显的下降趋势 出现这种情况,按往常的经验,多半是内存泄露了 问题定位 ...

  10. 题解 marshland

    传送门 是个最大费用可行流 这题的建边很毒瘤 首先有危险度的点肯定要拆点 关键在于其它点怎么办 如果拆了不好保证每个点只经过一次 不拆连网络流都跑不了 但仔细观察题面,不能不难(???)发现一个L中那 ...