IP Multicast API

Philippe Dax

Documents and pointers on IP Multicast

  • RTP/RTCP

    API Multicast on the socket level

    Needed supports

    Multicasting IP is currently supported only An multicast address is an IP address which belongs to classe D included in the range between 224.0.0.0 and 239.255.255.255. There is no network field nor host field. It acts in fact of an address of group.
    #define GROUP "239.137.194.111"
    
    It will be also need to define a wearing of communication as that is usually done in traditional unicast mode.
    #define PORT 55501
    
    The creation of the socket is done in the usual way, as indicated below:
    /*
     * Include files
     */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    /*
     * sockets descriptors
     *
     * sdr:  for receive
     * sdw:  for transmit
     */
    int sdr, sdw;
    
    /*
     * sockets
     *
     * sock_r:  for receive
     * sock_w:  for transmit
     */
    struct sockaddr_in sock_r, sock_w;
    
        /*
         * sockets creation
         */
        sdr = socket(PF_INET, SOCK_DGRAM, 0);
        if (sdr < 0) {
            perror("socket");
            exit(1);
        }
        sdw = socket(PF_INET, SOCK_DGRAM, 0);
        if (sdw < 0) {
            perror("socket");
            exit(1);
        }
    
        /*
         * initialization of the reception socket
         */
        memset(&sock_r, 0, sizeof(sock_r));
        sock_r.sin_family = AF_INET;
        sock_r.sin_port = htons(PORT);
    #ifdef SOLARIS
        sock_r.sin_addr.s_addr = htonl(INADDR_ANY);
    #else
        sock_r.sin_addr.s_addr = inet_addr(GROUP);
    #endif
    
        /*
         * initialization of the socket of emission
         */
        memset(&sock_w, 0, sizeof(sock_w));
        sock_w.sin_family = AF_INET;
        sock_w.sin_port = htons(PORT);
        sock_w.sin_addr.s_addr = htonl(INADDR_ANY);
    
        len_r = sizeof(sock_r);
        len_w = sizeof(sock_w);
    
    The function inet_addr("string") makes it possible to convert the character string of 4 decimal bytes representing address IP into a binary value coded on 32 bits network formated.

    Reception of a datagram multicast

    Before a machine can receive datagrams multicast, it must be member of the group. The application can require of the machine on which it is carried out to join the multicast group by using the following option socket:
        if (setsockopt(sdr, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, \
            sizeof(struct ip_mreq)) < 0) {
            perror("setsockopt - IP_ADD_MEMBERSHIP");
            exit(1);
        }
    
    where imr is a structure of the type ip_mreq, defined in the file /usr/include/netinet/in.h, which is described as follows:
        struct ip_mreq {
             struct in_addr imr_multiaddr; /* multicast group to join */
             struct in_addr imr_interface; /* interface to join one */
        }
        /*
         * allowance of the structure imr
         */
         struct ip_mreq imr;
    
         /*
          * initialization of the structure imr
          */
          imr.imr_multiaddr.s_addr = inet_addr(GROUP);
          imr.imr_interface.s_addr = htonl(INADDR_ANY);
    
    In reception mode it is also necessary to carry out an operation bind() between the socket and its descriptor:
        /*
         * bind the socket
         */
         if (bind(sdr, &sock_r, sizeof(sock_r)) < 0) {
             perror("bind");
             exit(1);
         }
    
    The reception itself of the data will be carried out by the system call recvfrom() through the interface socket.
        /*
         * reception of datagrams
         */
         while (1) {
             cnt = recvfrom(sdr, buf, sizeof(buf), 0, &sock_r, &len_r);
             if (cnt < 0) {
                 perror("recvfrom");
                 exit(1);
             }
             else if (cnt == 0) { /* end of transmission */
                 break;
             }
             printf("%s\n", buf); /* posting of the message */
          }
    

    Sending multicast datagrams

    By default the datagrams multicast are sent with a TTL (time-to-live) of 1 which corresponds to the sub-network on which the machine by its Ethernet interface is physically connected. The TTL controls carried emission. Usually a TTL of 31 makes it possible to diffuse the datagrams on the whole site, a TTL of 64 allows a national diffusion and a TTL of 127 and beyond a world diffusion.

    The addresses ranging between 224.0.0.0 and 224.0.0.255 can be used locally on the sub-network but will never be forwarded by the routers for they are reserved for the protocols of routing.

    To make tests it is advised to use a TTL of 1 and one address of the type "239.jj.mm.aa" where jj means the day, mm the month and aa the year.

    The operation which makes it possible to fix the value of the TTL is the following one:

        unsigned char ttl = 1;
    
        setsockopt(sdw, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
    
    The sending itself of the datas will be done by the system call sendto() through the interface socket.
        /*
         * emission of the datagrams
         */
         cnt = sendto(sdw, buf, strlen(buf), 0, &sock_w, len_w);
         if (cnt < 0) {
             perror("sendto");
             exit(1);
         }
    

    To leave a group

    If the application decides to leave the group in which it is currently, it must announce it by the following system call:
        setsockopt(sdr, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(imr));
    

    Reusable port

    More than one process can bind to same port UDP if the system call bind() is preceded by:
        int reuse = 1;
    
        setsockopt(sdr, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
    
    This system call must precede the system call bind().

    Looping of test (loopback)

    If a datagram is sent towards a group which is already had by the local machine, an internal copy, on the level of layer IP, is carried out so that it is delivered locally. An option makes it possible to control this operation. If the variable loop is worth 1, allowing the loopback, the performances will be better.
        unsigned char loop = 1; /* 0 = disable, 1 = enable * /
    
        setsockopt(sdr, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
    

    Use of RSVP

    On the machines which support the routers multicast "mrouted", it is possible to indicate which direction will take the packages multicast by choosing a virtual interface (vif), for example a tunnel towards another machine supporting a router mrouted.
        int vif = -1; /* -1 = enable normal multicast forwarding * /
    
        setsockopt(sdr, IPPROTO_IP, IP_MULTICAST_VIF, &vif, sizeof(vif));
    

    API Multicast RMP (Applicable Multicast Protocol) in C++

    RMP (Applicable Multicast Protocol) is an interface of programming of application (API) which implements the operations of the transport layer for the multicast. RMP is API which can be used only by applications written in C++.

    RMP defines 4 classes of objects:

    Classify Rmp

    To join a group

    To leave a group

    ... to be completed ...
    ©(Copyright) Philippe Dax - 1995,1996