Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2003:
[Freeciv-Dev] Re: (PR#6707) Announce server on LAN
Home

[Freeciv-Dev] Re: (PR#6707) Announce server on LAN

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: andrearo@xxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#6707) Announce server on LAN
From: rt@xxxxxxxxxxx
Date: Thu, 6 Nov 2003 08:13:26 -0800

And the attached test program...

Todd

* rt@xxxxxxxxxxx <rt@xxxxxxxxxxx> [031106 10:31]:
> * Raimar Falke <i-freeciv-lists@xxxxxxxxxxxxx> [031105 17:13]:
> > On Wed, Nov 05, 2003 at 12:28:18PM -0800, Todd Goodman wrote:
> > > > As you can see, the interface eth0 has joined the 237.0.0.1 group.
> > > > After the client and server are done sending packets to each other, the
> > > > interface eth0 leaves the group 237.0.0.1. This is group management is
> > > > handled by the operating system kernel, and is invisible to the user.
> > > 
> > > I think adding the group automatically might just be a Linux thing though.
> > 
> > Is there some more data/facts on this issue?
> 
> I tried the attached test program on Solaris 2.8 without the
> setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, ...) and it would not
> receive anything sent to the mulicast address.
> 
> And my apologies to Andreas and Raimar, I see that the patch
> is using the setsockopt(..., IP_ADD_MEMBERSHIP, ...) instead of the
> SIOCADDMULTI.
> 
> They both do the same thing, but I agree that the setsockopt() is more
> portable to OS' other than BSD based ones.
> 
> Todd
> 
> > 
> >     Raimar
> > 
> > -- 
> >  email: rf13@xxxxxxxxxxxxxxxxx
> >  "Microsoft DNS service terminates abnormally when it recieves a response
> >   to a DNS query that was never made.
> >   Fix Information: Run your DNS service on a different platform."
> >     -- MS service information on bugtraq
> 

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>


int
main(int argc, char *argv[])
{
        int s, slen, size;
        struct sockaddr_in maddr, saddr;
        char buf[1024];
        struct ip_mreq mcastreq;

        maddr.sin_family = AF_INET;
        maddr.sin_port   = 15000;
        maddr.sin_addr.s_addr = inet_addr("225.0.0.1");

        while (--argc) {
                if (**++argv == '-') {
                        switch (*++*argv) {
                        case 'a':
                                if (*++*argv) {
                                        maddr.sin_addr.s_addr = 
inet_addr(*argv);
                                } else {
                                        maddr.sin_addr.s_addr = 
inet_addr(*++argv);
                                        if (! --argc)
                                                exit(0);
                                }
                                break;
                        case 's':
                                if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
                                        perror("socket");
                                        exit(-1);
                                }
                                if (bind(s, (struct sockaddr *) &maddr, 
sizeof(maddr)) < 0) {
                                        perror("bind");
                                        exit(-1);
                                }

                                mcastreq.imr_multiaddr = maddr.sin_addr;
                                mcastreq.imr_interface.s_addr = INADDR_ANY;

                                if (setsockopt(s, IPPROTO_IP, 
IP_ADD_MEMBERSHIP, &mcastreq,
                                        sizeof(mcastreq)) < 0) {
                                        perror("Adding multicast group");
                                        exit(-1);
                                }

                                slen = sizeof(saddr);
                                while ((size = recvfrom(s, buf, sizeof(buf), 0, 
                                        (struct sockaddr *) &saddr, &slen)) > 
0) {
                                        buf[size - 1] = '\0';
                                        if (! strcasecmp(buf, "END")) {
                                                printf("Goodbye...\n");
                                                break;
                                        }
                                        printf("%s\n", buf);
                                }
                                if (size < 0) {
                                        perror("recvfrom");
                                        exit(-1);
                                }
                                close(s);
                                break;
                        default:
                                fprintf(stderr, "Unknown option.\n");
                                exit(-1);
                                break;
                        }
                } else {
                        saddr.sin_family = AF_INET;
                        saddr.sin_port = 15000;
                        saddr.sin_addr.s_addr = inet_addr(*argv);
                        if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
                                perror("socket");
                                exit(-1);
                        }
                        if (bind(s, (struct sockaddr *) &maddr, sizeof(maddr)) 
< 0) {
                                perror("bind");
                                exit(-1);
                        }
                        while (fgets(buf, sizeof(buf), stdin)) {
                                if (sendto(s, buf, strlen(buf), 0, (struct 
sockaddr *) &saddr,
                                        sizeof(saddr)) < 0) {
                                        perror("sendto");
                                        exit(-1);
                                }
                        }
                        close(s);
                }
        }
        exit(0);
}

[Prev in Thread] Current Thread [Next in Thread]