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:
- -1 (unsuccessful)
- 0 (successful)
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:
|
| [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
- In addition to setting the multicast source filter list, setsourcefilter() will join the multicast group, if the socket has not already joined.
- To determine the IPv6 interface index to use for the interface parameter, the following APIs can be used:
- if_nameindex() (Return all interface names and indexes)
- if_nametoindex() (Map an Interface Name to its Corresponding Index)
- 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().
- 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.
Related Information
- _XOPEN_SOURCE--Using _XOPEN_SOURCE for the UNIX 98
compatible interface
- getsourcefilter()--Retrieve a Socket's Multicast Filter
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