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