setsourcefilter()--Set a Socket's Multicast Filter


  Syntax
  #include <netinet/in.h>

  int setsourcefilter(int socket_descriptor,
                      uint32_t interface,
                      struct sockaddr *group_address,
                      socklen_t address_length,
                      uint32_t filter_mode,
                      uint32_t number_sources,
                      struct sockaddr_storage *source_list)

  Service Program Name: QSOSRV1IP6

  Default Public Authority: *USE

  Threadsafe: Yes

The setsourcefilter() function sets the multicast filtering state for a tuple that consists of a socket (socket_descriptor), an interface (interface), and a multicast group (group_address).


Parameters

socket_descriptor
(Input) A descriptor for a socket of type SOCK_DGRAM or SOCK_RAW.
interface
(Input) Interface index (IPv6) or the interface address (IPv4) of the interface.
group_address
(Input) Pointer to structure sockaddr that contains the multicast address.

The structure sockaddr is defined in <sys/socket.h>.

The BSD 4.3 structure is:

      struct sockaddr {
         u_short sa_family;
         char    sa_data[14];
      };

The BSD 4.4/UNIX® 98 compatible structure is:

      typedef uchar   sa_family_t;

      struct sockaddr
      {
        uint8_t       sa_len;
        sa_family_t   sa_family;
        char          sa_data[14];
      };

The sa_len field is the length of the address, the sa_family field is the address family, and the sa_data field is the address whose format is dependent on the address family.

address_length
(Input) Size of the structure pointed to by group_address.
filter_mode
(Input) Value indicating the filter mode, MCAST_INCLUDE or MCAST_EXCLUDE.
number_sources
(Input) The number of addresses in the source_list array.
source_list
(Input) A pointer to structure sockaddr_storage where the array of source addresses to be included or excluded are stored.

The structure sockaddr_storage is defined in <sys/socket.h>.

The BSD 4.3 structure is:

 #define _SS_MAXSIZE 304
 #define _SS_ALIGNSIZE (sizeof (char*))
 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(sa_family_t))
 #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(sa_family_t)+
                        _SS_PAD1SIZE + _SS_ALIGNSIZE))

 struct sockaddr_storage {
     sa_family_t   ss_family;
     char         _ss_pad1[_SS_PAD1SIZE];
     char*        _ss_align;
     char         _ss_pad2[_SS_PAD2SIZE];
 };

The BSD 4.4/UNIX 98 compatible structure is:

 #define _SS_MAXSIZE 304
 #define _SS_ALIGNSIZE (sizeof (char*))
 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (sizeof(uint8_t) + sizeof(sa_family_t)))
 #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(uint8_t) + sizeof(sa_family_t)+
                        _SS_PAD1SIZE + _SS_ALIGNSIZE))

 struct sockaddr_storage {
     uint8_t       ss_len;
     sa_family_t   ss_family;
     char         _ss_pad1[_SS_PAD1SIZE];
     char*        _ss_align;
     char         _ss_pad2[_SS_PAD2SIZE];
 };

Authorities

No authorization is required.


Return Value

setsourcefilter() returns an integer. Possible values are:


Error Conditions

When setsourcefilter() fails, errno can be set to one of the following:

[EADDRNOTAVAIL] Address not available.

An incorrect address was specified for the group_address parameter value.

[EAFNOSUPPORT] The type of socket is not supported in this protocol family.

The address family specified in the sockaddr parameter is not AF_INET or AF_INET6.

[EBADF] Descriptor is not valid.
[EINVAL] Parameter not valid.

This error code indicates one of the following:

  • The group_address parameter contains an IPv4-mapped IPv6 address and the interface parameter contains an interface index instead of an interface address.

  • The group_address parameter contains an IPv6 address and the interface parameter contains an interface address instead of an interface index.

  • The address contained in the group_address parameter is an IPv6 address and the addresses contained in source_list parameter are IPv4-mapped IPv6 address or vise-versa.

  • Start of V7R1 changesThe address contained in the group_address parameter is a source specific multicast address and the filter_mode parameter is set to MCAST_EXCLUDE.End of V7R1 changes

[ENOPROTOOPT] The protocol does not support the specified option.

The socket is not of type SOCK_DGRAM or SOCK_RAW.

The address family of the group_address parameter does not match the protocol family of the socket, socket_descriptor.

[ENOTSOCK] The specified descriptor does not reference a socket.
[ENXIO] No such device or address.

The interface argument, an index or an IPv4 address, does not identify a valid interface.



Usage Notes

  1. In addition to setting the multicast source filter list, setsourcefilter() will join the multicast group, if the socket has not already joined.
  2. To determine the IPv6 interface index to use for the interface parameter, the following APIs can be used:
  3. When you develop in C-based languages and an application is compiled with the _XOPEN_SOURCE macro defined to the value 520 or greater, the setsourcefilter() API is mapped to qso_setsourcefilter98().
  4. Start of V7R1 changes
  5. To stay compliant with RFC 4604, starting in V7R1, it is invalid to join a source specifc multicast address in exclude mode. This will now result in a failure with errno set to EINVAL.
  6. End of V7R1 changes

Related Information

Example

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

The following example shows how setsourcefilter() is used:

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

#define MC_ADDRESS "FF05::abcd:320"

int main()
{
  int sd = -1, rc = -1;
  struct sockaddr_in6 multicast_address, localSock;
  int interface_index;
  int address_length;
  int filter_mode;
  int numsrc;
  struct sockaddr_storage source_list[1];

  do
  {
    rc = sd = socket(AF_INET6, SOCK_DGRAM, 0);
    if(rc < 0)
      break;

    /*
     * Bind to the proper port number with the IP address
     * specified as in6addr_any
     */
    memset(&localSock, 0, sizeof(localSock));
    localSock.sin6_family = AF_INET6;
    localSock.sin6_port   = htons(5555);;
    localSock.sin6_addr   = in6addr_any;

    rc = bind(sd, (struct sockaddr *)&localSock, sizeof(localSock));
    if(rc < 0)
      break;

    /* 
     * Retrieve the interface index value for ETHVLINE
     */
    printf("if_nametoindex()\n");
    interface_index = if_nametoindex("ETHVLINE");
    if(interface_index == 0)
      break;

    /* 
     * Join the multicast group and block all data being sent
     * by the source address 2002:1::1 to the multicast group 
     * specified in multicast_address
     */
    inet_pton(AF_INET6, MC_ADDRESS, &(multicast_address.sin6_addr));
    address_length = sizeof(multicast_address);
    filter_mode = MCAST_EXCLUDE;
    numsrc = 1;
    memset(source_list, 0, sizeof(source_list));
    ((struct sockaddr_in6 *) &source_list[0])->sin6_family = AF_INET6;
    ((struct sockaddr_in6 *) &source_list[0])->sin6_port = 0;
    inet_pton(AF_INET6, "2002:1::1", 
              &(((struct sockaddr_in6 *) &source_list[0])->sin6_addr));

    printf("setsourcefilter(%d, %d-ETHVLINE, %s)\n",
           sd, interface_index, MC_ADDRESS);
    rc = setsourcefilter(sd,
                         interface_index,
                         (struct sockaddr *) &multicast_address,
                         address_length,
                         filter_mode,
                         numsrc,
                         source_list);
    if(rc == 0)
      printf("setsourcefilter() worked as expected.\n");
    else
    {
      printf("setsourcefilter() failed with errno =  %d %s \n",
             errno, strerror(errno));
      break;
    }

  }while(0);
  /*  Close the socket */
  if(sd != -1)
    close(sd);
}


API introduced: V6R1

[ Back to top | UNIX-Type APIs | APIs by category ]