一。模拟场景
window机器 ip 192.168.88.20 (本机局域网配置) 192.168.58.1(vmware虚拟网卡ip 作为NAT虚拟机网关)
linux虚拟机ip 192.168.58.134(NAT模式下生成ip 网卡 eno16777736) 192.168.88.21(桥接的局域网ip 网卡eno33554984 具体过程参 考http://blog.csdn.net/liaomin416100569/article/details/73300692 1.1.3》安装桥接虚拟网卡)
二。解释arp_ignore和arp_announce
机器A 需要访问机器B 首先必须知道机器B的物理地址 程序可能只知道B的ip的地址 此时A需要发送一个arp请求给B
机器B对于该arp的请求回应方式 可以通过参数arp_ignore进行处理
图示:
模拟场景
window机器 ip 192.168.88.20 (本机局域网配置) 192.168.58.1(vmware虚拟网卡ip 作为NAT虚拟机网关)
linux虚拟机ip 192.168.58.134(NAT模式下生成ip 网卡 eno16777736) 192.168.88.21(桥接的局域网ip 网卡eno33554984 具体过程参 考http://blog.csdn.net/liaomin416100569/article/details/73300692 1.1.3》安装桥接虚拟网卡)
需要用到的命令
ping 确定目标ip是否能通 数据链路层找到目标机器 必须通过物理地址 所以 一定会发送一个arp请求
arp 查看目标机器的路由表 -a ip 删除 -d ip
通过编程模拟发送arp请求#include "stdafx.h"
#include
#include
#include
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"Iphlpapi")
int _tmain(int argc, _TCHAR* argv[])
{
//设置发起arp的源ip
char* srcIpChar=new char[15];
srcIpChar="192.168.58.1";
//设置需要获取物理地址的目标ip
char* targetIpChar=new char[15];
targetIpChar="192.168.58.134";
ULONG targetIP = inet_addr(targetIpChar);
if(targetIP==INADDR_NONE){
fprintf(stderr,"Invalid IP: %s/n",targetIpChar);
return -1;
}
ULONG macBuf[2];
ULONG macLen = 6;
ULONG localIP = inet_addr(srcIpChar);
DWORD retValue = SendARP(targetIP,localIP,macBuf,&macLen);
if(retValue!=NO_ERROR){
fprintf(stderr,"SendARP error/n");
return -1;
}
unsigned char *mac = (unsigned char*)macBuf;
printf("%s --> ",argv[1]);
for(int i=0; i
修改arp_ignore的值
echo 状态值 默认0>/proc/sys/net/ipv4/conf/网卡名/arp_ignore
这里存在两个网卡eno16777736和eno33554984
echo "1" >/proc/sys/net/ipv4/conf/eno16777736/arp_ignore
echo "1" >/proc/sys/net/ipv4/conf/eno33554984/arp_ignore
window的网络接口(也就是网卡)查看
arp -a
接口: 192.168.88.20 --- 0xb
接口: 192.168.58.1 --- 0x11
查看window本地路由表是否存在 linux机器 88.21和58.134的路由 (如果存在 通过 arp -d192.168.58.134 两项都删除)
C:\Users\jiaozi>arp -a 192.168.58.134
未找到 ARP 项。
C:\Users\jiaozi>arp -a 192.168.88.21
未找到 ARP 项。
测试通过ping是否能获取linux机器的路由 发现ping哪个ip才能获取哪个ip的路由 58.134 走的是58.1网卡 因为同一网段
C:\Users\jiaozi>ping 192.168.58.134
正在 Ping 192.168.58.134 具有 32 字节的数据:
来自 192.168.58.134 的回复: 字节=32 时间<1ms TTL=64
192.168.58.134 的 Ping 统计信息:
数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
Control-C
^C
C:\Users\jiaozi>arp -a 192.168.88.21
未找到 ARP 项。
C:\Users\jiaozi>arp -a 192.168.58.134
接口: 192.168.58.1 --- 0x11
Internet 地址 物理地址 类型
192.168.58.134 00-0c-29-49-29-6c 动态
arp_ignore的值
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
通过代码方式发起arp 使用window上不同的网络接口的ip访问linux目标地址 58.134
srcIpChar="192.168.58.1";targetIpChar="192.168.58.134"; 获取到了 58.134的物理地址( 00-0C-29-49-29-6C/n)
srcIpChar="192.168.88.20";targetIpChar="192.168.58.134"; 获取到了linux机器 88.21的物理地址( 00-0C-29-49-29-76/n)
arp_ignore=0时 58.1发起的arp直接可以响应到 58.134的物理地址
88.20发起的arp直接响应到了 88.21的物理地址
所以0 是来者不拒 所有接口访问直接返回对应网络接口的物理地址
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求
srcIpChar="192.168.58.1";argetIpChar="192.168.58.134"; 获取到了 58.134的物理地址( 00-0C-29-49-29-6C/n)
srcIpChar="192.168.88.20";argetIpChar="192.168.58.134"; 无法获取到物理地址 因为 88.20访问的明显是虚拟机88.21的网络接口(只能访问相同网络 断)但是目标ip却不是88.21 是58.134 所以linux拒绝回应
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内 (可能相同的网络接口 ip被划分为不同子网)
arp_announce (主动发送本机ip和物理地址给目标ip)
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.