当网卡收到一个包的目的地址不是自己的地址时

当网卡收到一个包的目的不是自己的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通的才对呢

posted @ 2018-02-12 19:37  honpey  阅读(1443)  评论(0编辑  收藏  举报