当网卡收到一个包的目的地址不是自己的地址时
当网卡收到一个包的目的不是自己的IP
或者问题变成了,多网卡的机器路由选择
机器有两张网卡A和B,我将pingB的包发送给A这个时候是能ping通的,所以这里涉及到一个问题,网卡怎么知道这个数据包是不是自己的?拿到ICMP数据包后会怎么做呢?所以这里就涉及到ICMP协议了xx
这是因为这台机器上所有的网卡都标志了这台机器的身份,所以
那这么说的话,我从树莓派里面去ping我主机上的这些地址其实也是能ping通的shi 。
在树莓派上玩了,确实是这样的,和tap机制一样,当我给与树莓派直连的网卡上
但是无论是从qemu上ping还是从树莓派ping,宿主机上直连的网卡必须与树莓派和宿主机是同一个网段,这里不是很明白啊,为啥一定要是同一个网段的呢?
这里涉及到ARP协议,ARP协议发送的是一个地址的信息;
所以ARP协议接收端发生了啥?
tap0和虚机中的eth0是直连的,但是tap0:192.168.11.3/24, 但是虚机eth0是:192.168.0.110/24,增加了一条路由:route add default eth0,也就是说,其实tap0能收到来自eth0的包,并且实际从tap0上确实也观测到了相关的包,BUT。。。就是ping不同;也就是说掩码只在发送端才有意义,这是个错的!之前假设ARP中是不会发送掩码的!这个也是错的么?
当把eth0的掩码换成255.255.0.0 即18的时候,奇迹发生了,这个时候就ping通了,这说明:ARP协议的接受端会判断来的IP地址和自己是不是一个子网(通过自己的IP地址和netmask),如果是那就直接返回了。【ARP接受部分的代码】
还有问题宿主机上除了tap0,还有另外一块网卡是enp0s25,这个网卡的IP地址是11.11.11.11/255.255.255.0, 此时从虚拟机中去ping这个地址能ping通么?
答案是:能ping通!
直接上wiresharp抓到的包:不方便截图,下次自己手动操作一下吧
eth0 虚机 <-----> tap0 <-------> enp0s25
监控tap0,发现了:who has 11.11.11.11 tell 192.168.0.110 MAC 地址是86:04:41是tap0的mac地址
也就是说tap0收到了从虚机中eth0中来的包之后,开始在自己的广播域中发起了一条ARP广播,谁的IP地址是11.11.11.11,告诉192.168.0.110,那么都有谁在这个广播域中,问题就来了,我这台机器上有docker0,enp0s25,等等诸多的网卡,是所有人都能听到这个ARP信息么?docker0看不到. 看下arp的代码
inet_confirm_addr ---> confirm_addr_indev
当一台宿主机上有多个网卡时,当arp包到了之后,就会用inet_c
这个函数也是顾名思义的,“确认一下addr是否在这个dev中”
下面这篇文章详细详细说明了我现在面临的情况:机器A上有两个网卡eth0和eth1,我网eth0上发目的地址是eth1上的包,能否接收到,这里面也提到了inet_confirm_addr
http://blog.csdn.net/dog250/article/details/5846449
被教做人:一个网卡只有一个Mac地址,但是可以有很多的网络层地址
ARP请求从哪个网卡进入则一定从哪个网卡出去
最关键的配置是in_device
struct ipv4_devconf { void *sysctl; int data[IPV4_DEVCONF_MAX]; DECLARE_BITMAP(state, IPV4_DEVCONF_MAX); };
这里有每个设备的配置,其中主要的设置如下图所示:
IPV4_DEVCONF_FORWARDING=1, IPV4_DEVCONF_MC_FORWARDING, IPV4_DEVCONF_PROXY_ARP, IPV4_DEVCONF_ACCEPT_REDIRECTS, IPV4_DEVCONF_SECURE_REDIRECTS, IPV4_DEVCONF_SEND_REDIRECTS, IPV4_DEVCONF_SHARED_MEDIA, IPV4_DEVCONF_RP_FILTER, IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, IPV4_DEVCONF_BOOTP_RELAY, IPV4_DEVCONF_LOG_MARTIANS, IPV4_DEVCONF_TAG, IPV4_DEVCONF_ARPFILTER, IPV4_DEVCONF_MEDIUM_ID, IPV4_DEVCONF_NOXFRM, IPV4_DEVCONF_NOPOLICY, IPV4_DEVCONF_FORCE_IGMP_VERSION, IPV4_DEVCONF_ARP_ANNOUNCE, IPV4_DEVCONF_ARP_IGNORE, IPV4_DEVCONF_PROMOTE_SECONDARIES, IPV4_DEVCONF_ARP_ACCEPT, IPV4_DEVCONF_ARP_NOTIFY, IPV4_DEVCONF_ACCEPT_LOCAL, IPV4_DEVCONF_SRC_VMARK, IPV4_DEVCONF_PROXY_ARP_PVLAN, IPV4_DEVCONF_ROUTE_LOCALNET, IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, IPV4_DEVCONF_DROP_GRATUITOUS_ARP, __IPV4_DEVCONF_MAX
修改的方法:
修改方法 临时修改方法: 1. 修改/proc文件系统: echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore echo "1">/proc/sys/net/ipv4/conf/eth0/arp_ignore echo "2">/proc/sys/net/ipv4/conf/all/arp_announce echo "2">/proc/sys/net/ipv4/conf/eth0/arp_announce 2. 使用sysctl -w直接写入内存: sysctl -w net.ipv4.conf.all.arp_ignore=1 sysctl -w net.ipv4.conf.eth0.arp_ignore=1 sysctl -w net.ipv4.conf.all.arp_announce=2 sysctl -w net.ipv4.conf.eth0.arp_announce=2 永久修改需要写入配置文件: 修改/etc/sysctl.conf文件,然后sysctl -p刷新到内存。 net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.eth0.arp_ignore=1 net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.eth0.arp_announce=2 备注: arp_ignore和arp_announce参数分别有all,default,lo,eth0等对应不同网卡。当all和具体网卡的参数值不一致时,配置为较大值的生效。一般只需修改all和某个具体网卡的参数即可。
0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。 1:只响应目的IP地址为接收网卡上的本地地址的arp请求。 2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。 3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。 4~7:预留。 8:不回应所有的arp请求。
亲试有效!
当设置成0的时候,能ping通,但是这说明了一个问题,因为1和2的检查会更严格一些
当设置成1后,可以不是一个网段的:192.168.0.110 经192.168.11.3/24 ping 192.168.199.120 应该能ping通才对呢,但是为啥子ping不通呢,从代码上看也是能ping通的才对呢