zoukankan      html  css  js  c++  java
  • 当网卡收到一个包的目的地址不是自己的地址时

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

  • 相关阅读:
    齐文词根词缀---1、第一讲
    元音发音规则
    英语重读规则
    英语单词重读规则
    unicode,ansi,utf-8,unicode big endian编码的区别
    Netty中粘包和拆包的解决方案
    【转载】 DirectByteBuffer内存释放
    Netty 中ChannelOption的含义以及使用的场景Netty 中ChannelOption的含义以及使用的场景
    Connection reset原因分析和解决方案
    Netty实现Socket
  • 原文地址:https://www.cnblogs.com/honpey/p/8445388.html
Copyright © 2011-2022 走看看