LINUX.ORG.RU

История изменений

Исправление Tumyq, (текущая версия) :

Пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят, но их все так же видит WireShark. Судя по man, INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:

        int sockfd;
        char buf[30];
        struct sockaddr_in sendaddr;
        struct sockaddr_in recvaddr;
        int numbytes;
        socklen_t addr_len;
        int broadcast=1;

        if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
            perror("socket");
            exit(1);
        }
        if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
                        &broadcast, sizeof broadcast)) == -1) {
            perror("setsockopt - SO_SOCKET ");
            exit(1);
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
                       "enp4s0", strlen("enp4s0")) == -1) {
            perror("setsockopt (SO_BINDTODEVICE)");
            exit(1);
        }
        printf("Socket created\n");

        memset(&sendaddr, 0, sizeof sendaddr);
        sendaddr.sin_family = AF_INET;
        sendaddr.sin_port = htons(PORT);
        sendaddr.sin_addr.s_addr = INADDR_BROADCAST;

        memset(&recvaddr, 0, sizeof recvaddr);
        recvaddr.sin_family = AF_INET;
        recvaddr.sin_port = htons(PORT);
        recvaddr.sin_addr.s_addr = INADDR_ANY;
        if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
            perror("bind");
            exit(1);
        }
        numbytes = sendto(sockfd, "Hello", 5 , 0,
                          (struct sockaddr *)&sendaddr, sizeof sendaddr);
        if (numbytes < 0)
        {
            perror("sendto");
            //exit(1);
        }
        else
        {
            printf("sent %d bytes to %s\n", numbytes,
                   inet_ntoa(sendaddr.sin_addr));
        }

        for (;;) {
            int n;
            fd_set set;
            struct timeval time_500ms = { 0, 500*1000 };
            FD_ZERO(&set);
            FD_SET(sockfd, &set);

            n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
            if (n < 0) {
                perror("select");
                break;
            }
            else if (n == 0) {
                printf("sleep(5)\n");
                sleep(5);
            }
            else if (!FD_ISSET(sockfd, &set)) {
                perror("FD_ISSET");
                break;
            }
            else {
                addr_len = sizeof recvaddr;
                if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
                                         (struct sockaddr *)&recvaddr, &addr_len)) > 0)
                {
                    time_t now = time(NULL);
                    printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
                }
                else
                    perror("recvfrom");
            }
        }
        close(sockfd);
    }

«дропать по RFC» Имеется в виду DHCP(RFC 2131)?

Исправление Tumyq, :

Пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят, но их все так же видит WireShark. Судя по man, INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:

        int sockfd;
        char buf[30];
        struct sockaddr_in sendaddr;
        struct sockaddr_in recvaddr;
        int numbytes;
        socklen_t addr_len;
        int broadcast=1;

        if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
            perror("socket");
            exit(1);
        }
        if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
                        &broadcast, sizeof broadcast)) == -1) {
            perror("setsockopt - SO_SOCKET ");
            exit(1);
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
                       "enp4s0", strlen("enp4s0")) == -1) {
            perror("setsockopt (SO_BINDTODEVICE)");
            exit(1);
        }
        printf("Socket created\n");

        memset(&sendaddr, 0, sizeof sendaddr);
        sendaddr.sin_family = AF_INET;
        sendaddr.sin_port = htons(PORT);
        sendaddr.sin_addr.s_addr = INADDR_BROADCAST;

        memset(&recvaddr, 0, sizeof recvaddr);
        recvaddr.sin_family = AF_INET;
        recvaddr.sin_port = htons(PORT);
        recvaddr.sin_addr.s_addr = INADDR_ANY;
        if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
            perror("bind");
            exit(1);
        }
        numbytes = sendto(sockfd, "Hello", 5 , 0,
                          (struct sockaddr *)&sendaddr, sizeof sendaddr);
        if (numbytes < 0)
        {
            perror("sendto");
            //exit(1);
        }
        else
        {
            printf("sent %d bytes to %s\n", numbytes,
                   inet_ntoa(sendaddr.sin_addr));
        }

        for (;;) {
            int n;
            fd_set set;
            struct timeval time_500ms = { 0, 500*1000 };
            FD_ZERO(&set);
            FD_SET(sockfd, &set);

            n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
            if (n < 0) {
                perror("select");
                break;
            }
            else if (n == 0) {
                printf("sleep(5)\n");
                sleep(5);
            }
            else if (!FD_ISSET(sockfd, &set)) {
                perror("FD_ISSET");
                break;
            }
            else {
                addr_len = sizeof recvaddr;
                if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
                                         (struct sockaddr *)&recvaddr, &addr_len)) > 0)
                {
                    time_t now = time(NULL);
                    printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
                }
                else
                    perror("recvfrom");
            }
        }
        close(sockfd);
    }

Исходная версия Tumyq, :

Я пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят - их все так же видит WireShark. Я так понял, что INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:

        int sockfd;
        char buf[30];
        struct sockaddr_in sendaddr;
        struct sockaddr_in recvaddr;
        int numbytes;
        socklen_t addr_len;
        int broadcast=1;

        if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
            perror("socket");
            exit(1);
        }
        if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
                        &broadcast, sizeof broadcast)) == -1) {
            perror("setsockopt - SO_SOCKET ");
            exit(1);
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
                       "enp4s0", strlen("enp4s0")) == -1) {
            perror("setsockopt (SO_BINDTODEVICE)");
            exit(1);
        }
        printf("Socket created\n");

        memset(&sendaddr, 0, sizeof sendaddr);
        sendaddr.sin_family = AF_INET;
        sendaddr.sin_port = htons(PORT);
        sendaddr.sin_addr.s_addr = INADDR_BROADCAST;

        memset(&recvaddr, 0, sizeof recvaddr);
        recvaddr.sin_family = AF_INET;
        recvaddr.sin_port = htons(PORT);
        recvaddr.sin_addr.s_addr = INADDR_ANY;
        if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
            perror("bind");
            exit(1);
        }
        numbytes = sendto(sockfd, "Hello", 5 , 0,
                          (struct sockaddr *)&sendaddr, sizeof sendaddr);
        if (numbytes < 0)
        {
            perror("sendto");
            //exit(1);
        }
        else
        {
            printf("sent %d bytes to %s\n", numbytes,
                   inet_ntoa(sendaddr.sin_addr));
        }

        for (;;) {
            int n;
            fd_set set;
            struct timeval time_500ms = { 0, 500*1000 };
            FD_ZERO(&set);
            FD_SET(sockfd, &set);

            n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
            if (n < 0) {
                perror("select");
                break;
            }
            else if (n == 0) {
                printf("sleep(5)\n");
                sleep(5);
            }
            else if (!FD_ISSET(sockfd, &set)) {
                perror("FD_ISSET");
                break;
            }
            else {
                addr_len = sizeof recvaddr;
                if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
                                         (struct sockaddr *)&recvaddr, &addr_len)) > 0)
                {
                    time_t now = time(NULL);
                    printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
                }
                else
                    perror("recvfrom");
            }
        }
        close(sockfd);
    }