繁体   English   中英

如何同时使用2个套接字PF_INET和PF_PACKET?

[英]How to use 2 sockets PF_INET and PF_PACKET at the same time?

我有以下两个功能

int listen_socket(unsigned int ip, int port, char *inf)
{
    struct ifreq interface;
    int fd;
    struct sockaddr_in addr;
    int n = 1;

    DEBUG(LOG_INFO, "Opening listen socket on 0x%08x:%d %s\n", ip, port, inf);
    if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
        return -1;
    }

    fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = ip;

    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) {
        close(fd);
        return -1;
    }
    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1) {
        close(fd);
        return -1;
    }

    strncpy(interface.ifr_ifrn.ifrn_name, inf, IFNAMSIZ);
    if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)) < 0) {
        close(fd);
        return -1;
    }

    if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
        close(fd);
        return -1;
    }

    return fd;
}


int raw_socket(int ifindex)
{
    int fd;
    struct sockaddr_ll sock;

    DEBUG(LOG_INFO, "Opening raw socket on ifindex %d\n", ifindex);
    if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
        DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
        return -1;
    }

    fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

    sock.sll_family = AF_PACKET;
    sock.sll_protocol = htons(ETH_P_IP);
    sock.sll_ifindex = ifindex;
    if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
        DEBUG(LOG_ERR, "bind call failed: %s", strerror(errno));
        close(fd);
        return -1;
    }

    return fd;
}

两者都是套接字侦听器功能。

我以这种方式在我的应用程序中使用了这些功能

fd = listen_socket(INADDR_ANY, 67, client_config.interface);
fd2 = raw_socket(client_config.ifindex);

现在,如果我将数据包发送到我的应用程序(目标地址为接口的ip,端口为67)。 什么插座可以接住我的包? fd2还是fd或两者皆有?

如果我向我的应用程序发送了一个数据包(目的地= broacast:255.255.255.0和port = 67)。 什么插座可以接住我的包? fd2还是fd或两者皆有?

两个套接字都将接收该数据包。 当每个数据包从网络驱动程序到达内核时,它都会被复制并发送到所有PF_PACKET(第2层)套接字。 数据包还发送到第3层(IP / TCP)内核代码,然后从那里发送到寻址的套接字。

如果没有发生,运行单独的程序进行原始数据包捕获(例如,wireshark)将阻止网络上的任何其他通信。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM