组播到多个网卡

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组播到多个网卡相关的知识,希望对你有一定的参考价值。

一台服务器多个网卡,两个网卡未接同一个交换机,因为两个网卡走的是不同的运营商网络。
网卡1 IP:172.168.0.2 255.255.255.0 172.168.254.1
网卡2 IP: 192.168.0.2 255.255.255.0 192.168.0.1
程序组播地址:224.101.102.106:8888
程序初始化组播socket不指定网卡
程序开启组播后只有其中一个网卡能收到组播数据,通过wirshark抓包也只有其中一个网卡有组播包。可能是网卡1有组播数据,也可能是网卡2有组播数据。
目的是要求网卡1和网卡2都能到组播数据。谢谢!

参考技术A 按照网络TCP协议网段组成管理、网络流量拥堵造成影响 参考技术B 恩可以吧你可以在百度上面自己搜索一下估计有可能找到具体的解决的办法或者咨询下自己的朋友他们 参考技术C 、问题描述 
实现在多网卡设备上发送组播消息,实现设备搜索,并接收通过组播返回的搜索信息。 
设备为多网卡nvr,有一个常规网卡和一个PPPOE口;在进行发送组播搜索ipc时,只可以在常规网卡上接收到反馈的组播信息,而在ppoe上没有 
2、问题原因及解决方法

关键代码(组播socket的初始化):
在多网卡设备上实现组播需要特别注意:
1、使用setsockopt设置IP_ADD_MEMBERSHIP组播地址时,对应的本地地址必须被明确指定为要发送组播数据包的网卡的ip地址,而不可以使用INADDR_ANY设置;如果使用INADDR_ANY,则系统会默认根据路由表绑定一个明确的地址,则在接收组播信息时,无法从发送的网卡处接收到数据,发送的网卡没有被添加到组播组中。
2、必须使用setsockopt设置IP_MULTICAST_IF选项,从而修改默认的组播出口网卡。否则系统根据路由表发送到默认网关。而不一定是指定的网卡。
3、在多网卡实现多播(如设备搜索)相关的功能时,可以针对多个网卡分别执行一次操作,同时可以区分设备是从哪个网卡搜索到的。
参考技术D 北京时间2019年3月19日,猛龙队主场迎来尼克斯的挑战,本场比赛伦纳德因伤缺阵,因此球队将范弗利特提上首发。此前伦纳德轮休的时候一直是将林书豪提上首发的,不过书豪上首发的效果并不怎么好,不仅影响球队的进攻,而且自身效率也变得极其低下,因此本场比赛猛龙教练是将伤愈复出的范弗利特提上首发。 第5个回答  2019-03-19 虐了啦啦夸他不不不不哭talk啊垃圾垃圾咯啦咯啦咯啦啦啊啦啦阿狸

开发日常网卡驱动中如何设置组播mac地址?

组播mac地址映射?

    组播的mac地址:IANA规定,IPv4组播MAC地址的高24位为0x01005E,第25位为0,低23位为IPv4组播地址的低23位


如何判断该组播包是自己的?

    发送端发送组播包时,目的mac地址是根据组播ip和固定格式进行映射,并没有指向固定目标主机,向网络上进行发送。
    接收端接收组播包时,同样需要对组播ip和固定格式进行映射,生成的组播mac地址与接收到的数据包mac比对,若相通往上传。
    接收端同样可以设置混杂模式:接收所有经过它的数据流,这样不论其目的地址是否是他,都会往上传,由网络层进行判断,确定是递交上层(传输层),还是丢弃。


网卡驱动中如何设置组播mac地址?

以下是linux中9x25设置组播mac地址的部分代码

static int inline hash_bit_value(int bitnr, __u8 *addr)

        if (addr[bitnr / 8] & (1 << (bitnr % 8)))
                return 1;
        return 0;


/*
 * The hash address register is 64 bits long and takes up two locations in the memory map.
 * The least significant bits are stored in EMAC_HSL and the most significant
 * bits in EMAC_HSH.
 *
 * The unicast hash enable and the multicast hash enable bits in the network configuration
 *  register enable the reception of hash matched frames. The destination address is
 *  reduced to a 6 bit index into the 64 bit hash register using the following hash function.
 * The hash function is an exclusive or of every sixth bit of the destination address.
 *   hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
 *   hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
 *   hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
 *   hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
 *   hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
 *   hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
 * da[0] represents the least significant bit of the first byte received, that is, the multicast/
 *  unicast indicator, and da[47] represents the most significant bit of the last byte
 *  received.
 * If the hash index points to a bit that is set in the hash register then the frame will be
 *  matched according to whether the frame is multicast or unicast.
 * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and
 *  the hash index points to a bit set in the hash register.
 * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the
 *  hash index points to a bit set in the hash register.
 * To receive all multicast frames, the hash register should be set with all ones and the
 *  multicast hash enable bit should be set in the network configuration register.
 */

/*
 * Return the hash index value for the specified address.
 */
static int hash_get_index(__u8 *addr)

        int i, j, bitval;
        int hash_index = 0;

        for (j = 0; j < 6; j++) 
                for (i = 0, bitval = 0; i < 8; i++)
                        bitval ^= hash_bit_value(i*6 + j, addr);

                hash_index |= (bitval << j);
        

        return hash_index;


/*
 * Add multicast addresses to the internal multicast-hash table.
 */
static void at91ether_sethashtable(struct net_device *dev)

        struct netdev_hw_addr *ha;
        unsigned long mc_filter[2];
        unsigned int bitnr;

        mc_filter[0] = mc_filter[1] = 0;

        netdev_for_each_mc_addr(ha, dev) 
                bitnr = hash_get_index(ha->addr);
                mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
        

        at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
        at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);


/*
 * Enable/Disable promiscuous and multicast modes.
 */
static void at91ether_set_multicast_list(struct net_device *dev)

        unsigned long cfg;

        cfg = at91_emac_read(AT91_EMAC_CFG);

        if (dev->flags & IFF_PROMISC)                        /* Enable promiscuous mode */
                cfg |= AT91_EMAC_CAF;
        else if (dev->flags & (~IFF_PROMISC))                /* Disable promiscuous mode */
                cfg &= ~AT91_EMAC_CAF;

        if (dev->flags & IFF_ALLMULTI)                 /* Enable all multicast mode */
                at91_emac_write(AT91_EMAC_HSH, -1);
                at91_emac_write(AT91_EMAC_HSL, -1);
                cfg |= AT91_EMAC_MTI;
         else if (!netdev_mc_empty(dev))  /* Enable specific multicasts */
                at91ether_sethashtable(dev);
                cfg |= AT91_EMAC_MTI;
         else if (dev->flags & (~IFF_ALLMULTI))         /* Disable all multicast mode */
                at91_emac_write(AT91_EMAC_HSH, 0);
                at91_emac_write(AT91_EMAC_HSL, 0);
                cfg &= ~AT91_EMAC_MTI;
        

        at91_emac_write(AT91_EMAC_CFG, cfg);

 

以上是关于组播到多个网卡的主要内容,如果未能解决你的问题,请参考以下文章

主机网卡如何处理组播MAC地址

腾讯云发布三大独家功能:弹性网卡广播&组播专线NAT网关(内附媒体专访)

开发日常网卡驱动中如何设置组播mac地址?

MAC 地址(单播组播广播地址分类)

Linux下网卡混杂模式设置和取消

系统状体检测命令