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