0

Problem statement -- I am able to establish connection with broadcast IP 255.255.255.255 when both applications are in two different Linux machines. Linux Machine where server is running is replying when client broadcast-ed a message to the above mentioned address. But when I am porting client to FreeBSD machine. I am not able to get message at Linux server machine when I broadcast-ed a message from server (FreeBSD machine) to 255.255.255.255 Could you please help me what change I can do in the client/broadcaster source to make it compatible for FreeBSD machine too. You can find sample source code of server/listener and client/broadcaster as below --

/*
** listener.c -- a datagram sockets "server" demo
*/

    #include <arpa/inet.h>         // for inet_ntop
    #include <netdb.h>             // for addrinfo, freeaddrinfo, gai_strerror
    #include <netinet/in.h>        // for INET6_ADDRSTRLEN, sockaddr_in, sockadd...
    #include <stdio.h>             // for printf, fprintf, perror, NULL, stderr
    #include <stdlib.h>            // for exit
    #include <string.h>            // for memset
    #include <sys/socket.h>        // for sockaddr_storage, bind, socket, AF_INET
    #include <unistd.h>            // for close

    #define MYPORT "4950" // the port users will be connecting to

    #define MAXBUFLEN 100

    // get sockaddr, IPv4 or IPv6:
    static void *get_in_addr(struct sockaddr *sa) {
        if (sa->sa_family == AF_INET) {
            return &(((struct sockaddr_in *)sa)->sin_addr);
        }

        return &(((struct sockaddr_in6 *)sa)->sin6_addr);
    }

    int main(void) {
        int sockfd;
        struct addrinfo hints, *servinfo, *p;
        int rv;
        ssize_t numbytes;
        struct sockaddr_storage their_addr;
        char buf[MAXBUFLEN];
        socklen_t addr_len;
        char s[INET6_ADDRSTRLEN];

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags = AI_PASSIVE; // use my IP

        if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }

        // loop through all the results and bind to the first we can
        for (p = servinfo; p != NULL; p = p->ai_next) {
            if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) ==
                -1) {
                perror("listener: socket");
                continue;
            }

            if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                close(sockfd);
                perror("listener: bind");
                continue;
            }

            break;
        }

        freeaddrinfo(servinfo);

        if (p == NULL) {
            fprintf(stderr, "listener: failed to bind socket\n");
            return 2;
        }

        printf("listener: waiting to recvfrom...\n");

        addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN - 1, 0,
                                 (struct sockaddr *)&their_addr, &addr_len)) ==
            -1) {
            perror("recvfrom");
            exit(1);
        }

        printf("listener: got packet from %s\n",
               inet_ntop(their_addr.ss_family,
                         get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
        printf("listener: packet is %ld bytes long\n", numbytes);
        buf[numbytes] = '\0';
        printf("listener: packet contains \"%s\"\n", buf);

        close(sockfd);

        return 0;
    }

Client/Broadcaster sample :

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>

    #define SERVERPORT 4950    // the port users will be connecting to

    int main(int argc, char *argv[])
    {
        int sockfd;
        struct sockaddr_in their_addr; // connector's address information
        struct hostent *he;
        int numbytes;
        int broadcast = 1;
        //char broadcast = '1'; // if that doesn't work, try this

        if (argc != 3) {
            fprintf(stderr,"usage: broadcaster hostname message\n");
            exit(1);
        }

        if ((he=gethostbyname(argv[1])) == NULL) {  // get the host info
            perror("gethostbyname");
            exit(1);
        }

        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }

        // this call is what allows broadcast packets to be sent:
        if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
            sizeof broadcast) == -1) {
            perror("setsockopt (SO_BROADCAST)");
            exit(1);
        }

        their_addr.sin_family = AF_INET;     // host byte order
        their_addr.sin_port = htons(SERVERPORT); // short, network byte order
        their_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);

        if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
                 (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
            perror("sendto");
            exit(1);
        }

        printf("sent %d bytes to %s\n", numbytes,
            inet_ntoa(their_addr.sin_addr));

        close(sockfd);

        return 0;
    }
Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Arish Baig
  • 31
  • 1
  • 1
    Your code works on one box, not on another, We cannot debug your notwork by remote control. You have to investigate this and fix the code/routing/protocol/whatever. Wire shark both ends, and work out why it's not working. Note that routers routinely block UDP broadasts, and sysadmins don't like it much either. – Martin James Sep 26 '18 at 15:56
  • This does not seems to be firewall issue. All machines Linux, FreeBSD are on same network. And I am able to send broadcast message from FreeBSD to Linux when I send message on broadcast address X.X.X.255 but not when I send message on 255.255.255.255 , it's not received by server machine. Can anyone let me know if there is any bug or limitation in FreeBSD that we can not broadcast UDP message on 255.255.255.255. – Arish Baig Sep 28 '18 at 05:43
  • Could anyone please check on FreeBSD(compile client code here) and Linux (compile server code here) box, let me know if you are able to replicate the issue. – Arish Baig Sep 28 '18 at 11:10
  • Which call is failing and what is the error you are getting? Also [this](https://www.juniper.net/documentation/en_US/junose15.1/topics/concept/ip-broadcast-addressing-overview.html) may be useful... – Mikhail T. Dec 14 '18 at 21:20
  • Do you have multiple network interfaces on the machine and want 255.255.255.255 to broadcast on every interface? Normally using INADDR_BROADCAST is just a shorthand to send on the first (primary) network interface with a configured broadcast address. – tsp Dec 30 '18 at 14:06

0 Answers0