Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux device driver 多播接收数据包的问题_Linux Device Driver - Fatal编程技术网

Linux device driver 多播接收数据包的问题

Linux device driver 多播接收数据包的问题,linux-device-driver,Linux Device Driver,我创建了一个网络设备,可以多播dev->flags=IFF\u多播 我发送一条UDP消息,但当我收到一个数据包时,我没有收到UDP消息,系统跟踪是无效的 ipv6_rcv() |--> ip6_route_input() |-->ip6_mc_input() 函数ip6_mc_input()中的ipv6_chk_mcast_addr()返回的值为0。 我想我需要在mc_列表中添加多播地址ff02::2 这是真的吗 我怎么做 谢谢。您需要加入多播组

我创建了一个网络设备,可以多播dev->flags=IFF\u多播

我发送一条UDP消息,但当我收到一个数据包时,我没有收到UDP消息,系统跟踪是无效的

   ipv6_rcv()
    |--> ip6_route_input()
          |-->ip6_mc_input() 
函数ip6_mc_input()中的ipv6_chk_mcast_addr()返回的值为0。 我想我需要在mc_列表中添加多播地址ff02::2

这是真的吗

我怎么做


谢谢。

您需要加入多播组才能在其上接收流量。
IFF\u MULTICAST
标志表示您的设备(驱动程序)支持多播。当系统想要加入或离开多播组时,驱动程序需要配置硬件(通常只是一个过滤器)

由于您正在向堆栈上传递数据包,因此您的硬件在默认情况下非常混乱,或者您在系统未加入多播组的情况下以某种方式配置了硬件筛选器


不管是什么情况,为了使ipv6\u chk\u mcast\u addr()成功,您必须加入目标多播组。在用户空间中,您可以通过
IP\u ADD\u MEMBERSHIP
setsockopt()
调用来实现这一点。由于您对all routers多播组(ff02::2)感兴趣,我相信(但不能肯定地记得),当您配置转发时,内核将自动加入该组。

我终于解决了我的问题。我需要做一个这样的插座

if ((sockEnvio = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP))){

        printf("socket() failed");

    }

 // Bind the socket to the interface we're interested in
    int err=0;
    memset(&server, 0, sizeof(server));
    server.sin6_family = AF_INET6;
    server.sin6_scope_id = if_nametoindex("eth2");
    server.sin6_port = htons(15118);
    err = bind(sockEnvio, (struct sockaddr *)&server, sizeof(server));
    if (err < 0) {
        perror("packet socket bind return failed:");
        close(sockEnvio);     
    }
    printf("ICMPv6 socket bind to interface %d OK", if_nametoindex("eth2")); //if_nametoindex(lan));

   int optval = 1;
    if (setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, sizeof(optval)) < 0) {
        perror("Error! setsockopt(IPV6_RECVPKTINFO)"); 
        close(sockEnvio);

    }

   optval = 0;
    if (setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) <0 ) {
        perror("Error! setsockopt(IPV6_MULTICAST_LOOP)");
        close(sockEnvio);

    }

    struct ipv6_mreq mreq;
    memset(&mreq, 0, sizeof(mreq));
    mreq.ipv6mr_interface = if_nametoindex("eth2");
    mreq.ipv6mr_multiaddr.s6_addr[ 0] = 0xff;
    mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
    mreq.ipv6mr_multiaddr.s6_addr[15] = 0x02;
    if (setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
        perror("Error! setsockopt(IPV6_ADD_MEMBERSHIP, ff02::02)");
        close(sockEnvio);       
    }
if((sockEnvio=socket(AF_INET6,SOCK_DGRAM,IPPROTO_UDP))){
printf(“套接字()失败”);
}
//将套接字绑定到我们感兴趣的接口
int err=0;
memset(&server,0,sizeof(server));
server.sin6_family=AF_INET6;
server.sin6_scope_id=if_nametoindex(“eth2”);
server.sin6_port=htons(15118);
err=bind(sockEnvio,(struct sockaddr*)&server,sizeof(server));
如果(误差<0){
perror(“数据包套接字绑定返回失败:”);
关闭(sockEnvio);
}
printf(“ICMPv6套接字绑定到接口%d正常”,如果名称索引(“eth2”)//如果名称索引(lan));
int optval=1;
if(setsockopt(sockEnvio,IPPROTO_IPV6,IPV6_RECVPKTINFO,&optval,sizeof(optval))<0){
perror(“错误!setsockopt(IPV6_RECVPKTINFO)”;
关闭(sockEnvio);
}
optval=0;
if(setsockopt(sockEnvio、IPPROTO_IPV6、IPV6_组播_循环和optval、sizeof(optval))