首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >接收UDP广播,没有分配给Linux/C/IPv4 4接口的地址

接收UDP广播,没有分配给Linux/C/IPv4 4接口的地址
EN

Stack Overflow用户
提问于 2016-02-10 20:24:21
回答 1查看 484关注 0票数 0

在开发一个小型DHCP客户端时,我通过绑定到IFADDR_ANY并设置SO_BROADCAST和SO_BINDTODEVICE来在特定接口上发送广播,我可以看到来自DHCP服务器的答复。

不幸的是,除非该接口配置了地址,否则我的应用程序不会接收任何数据包。这使得编写DHCP客户端变得毫无意义。

问题:如何在没有分配地址的接口上接收IPv4 UDP广播?

我知道原始套接字,但我想避免使用它们。如果发送是不可能的,我就会接受,除非配置了地址,否则不可能使用UDP,但是由于发送工作正常,而仅仅接收不可能,我想知道我是否遗漏了什么。

下面是最低限度的代码:

代码语言:javascript
运行
复制
#define _DEFAULT_SOURCE

#include <sys/types.h>
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>

#include <stdio.h>

int main(int argc, char *argv[])
{
    if(argc < 2) {
        return 0;
    }

    struct sockaddr_in src = { .sin_family=AF_INET, .sin_addr.s_addr=INADDR_ANY, .sin_port=htons(68) };

    int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

    const int on=1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    struct ifreq ifr;
    memset(&ifr, '\0', sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), argv[1]);
    ioctl(fd, SIOCGIFINDEX, &ifr);
    setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));

    bind(fd, (struct sockaddr *)&src, sizeof(src));

    char buf[512];
    ssize_t res = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0);
    printf("res=%zi\n", res);

    return 0;
}

我在"sudo strace“中运行它,它永远停留在recvmsg()中,即使我可以在wireshark的端口68上观看UDP广播。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-11 23:05:27

我解决了。“反向路径过滤”被激活,导致所有将采用不同返回路径(或没有路由)的IPv4数据包被丢弃。如果没有为该接口配置地址,则每个数据包都会被丢弃。

代码语言:javascript
运行
复制
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

成功了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35325189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档