#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)
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).
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.
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];
};
No authorization is required.
setsourcefilter() returns an integer. Possible values are:
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. |

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);
}