mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
New option ipv6-join-source-group
This commit is contained in:
parent
003ca09721
commit
9f632ec651
8 changed files with 229 additions and 3 deletions
3
CHANGES
3
CHANGES
|
@ -17,6 +17,9 @@ Features:
|
||||||
not internally used by Socat.
|
not internally used by Socat.
|
||||||
Tests: SIGTERM_NOLOG SIG31_LOG
|
Tests: SIGTERM_NOLOG SIG31_LOG
|
||||||
|
|
||||||
|
Added option ipv6-join-source-group.
|
||||||
|
Thanks to Martin Buck and David Schweizer for sending patches.
|
||||||
|
|
||||||
Corrections:
|
Corrections:
|
||||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||||
0, its last sent data might have been lost depending on timing of read/
|
0, its last sent data might have been lost depending on timing of read/
|
||||||
|
|
|
@ -388,6 +388,9 @@
|
||||||
/* Define if you have struct ip_mreq_source */
|
/* Define if you have struct ip_mreq_source */
|
||||||
#undef HAVE_STRUCT_IP_MREQ_SOURCE
|
#undef HAVE_STRUCT_IP_MREQ_SOURCE
|
||||||
|
|
||||||
|
/* Define if you have struct group_source_req */
|
||||||
|
#undef HAVE_STRUCT_GROUP_SOURCE_REQ
|
||||||
|
|
||||||
/* Define if you have struct ifreq */
|
/* Define if you have struct ifreq */
|
||||||
#undef HAVE_STRUCT_IFREQ
|
#undef HAVE_STRUCT_IFREQ
|
||||||
|
|
||||||
|
|
14
configure.ac
14
configure.ac
|
@ -1256,6 +1256,20 @@ if test $sc_cv_struct_ip_mreq_source = yes; then
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT($sc_cv_struct_ip_mreqn)
|
AC_MSG_RESULT($sc_cv_struct_ip_mreqn)
|
||||||
|
|
||||||
|
# struct group_source_req (for multicasting options)
|
||||||
|
AC_MSG_CHECKING(for struct group_source_req)
|
||||||
|
AC_CACHE_VAL(sc_cv_struct_group_source_req,
|
||||||
|
[AC_TRY_COMPILE([#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/ip.h>],[struct group_source_req s;],
|
||||||
|
[sc_cv_struct_group_source_req=yes],
|
||||||
|
[sc_cv_struct_group_source_req=no])])
|
||||||
|
if test $sc_cv_struct_group_source_req = yes; then
|
||||||
|
AC_DEFINE(HAVE_STRUCT_GROUP_SOURCE_REQ)
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($sc_cv_struct_group_source_req)
|
||||||
|
|
||||||
|
|
||||||
# struct ifreq (for network interfaces)
|
# struct ifreq (for network interfaces)
|
||||||
AC_MSG_CHECKING(for struct ifreq)
|
AC_MSG_CHECKING(for struct ifreq)
|
||||||
|
|
23
doc/socat.yo
23
doc/socat.yo
|
@ -413,6 +413,7 @@ label(ADDRESS_IP_DATAGRAM)dit(bf(tt(IP-DATAGRAM:<address>:<protocol>)))
|
||||||
link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP),
|
link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP),
|
||||||
link(ip-add-source-membership)(OPTION_IP_ADD_SOURCE_MEMBERSHIP),
|
link(ip-add-source-membership)(OPTION_IP_ADD_SOURCE_MEMBERSHIP),
|
||||||
link(ipv6-join-group)(OPTION_IPV6_JOIN_GROUP),
|
link(ipv6-join-group)(OPTION_IPV6_JOIN_GROUP),
|
||||||
|
link(ipv6-join-source-group)(OPTION_IPV6_JOIN_SOURCE_GROUP),
|
||||||
link(ttl)(OPTION_TTL),
|
link(ttl)(OPTION_TTL),
|
||||||
link(tos)(OPTION_TOS),
|
link(tos)(OPTION_TOS),
|
||||||
link(pf)(OPTION_PROTOCOL_FAMILY)nl()
|
link(pf)(OPTION_PROTOCOL_FAMILY)nl()
|
||||||
|
@ -1129,6 +1130,7 @@ label(ADDRESS_UDP_DATAGRAM)dit(bf(tt(UDP-DATAGRAM:<address>:<port>)))
|
||||||
link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP),
|
link(ip-add-membership)(OPTION_IP_ADD_MEMBERSHIP),
|
||||||
link(ip-add-source-membership)(OPTION_IP_ADD_SOURCE_MEMBERSHIP),
|
link(ip-add-source-membership)(OPTION_IP_ADD_SOURCE_MEMBERSHIP),
|
||||||
link(ipv6-join-group)(OPTION_IPV6_JOIN_GROUP),
|
link(ipv6-join-group)(OPTION_IPV6_JOIN_GROUP),
|
||||||
|
link(ipv6-join-source-group)(OPTION_IPV6_JOIN_SOURCE_GROUP),
|
||||||
link(ttl)(OPTION_TTL),
|
link(ttl)(OPTION_TTL),
|
||||||
link(tos)(OPTION_TOS),
|
link(tos)(OPTION_TOS),
|
||||||
link(sourceport)(OPTION_SOURCEPORT),
|
link(sourceport)(OPTION_SOURCEPORT),
|
||||||
|
@ -2172,9 +2174,13 @@ dit(bf(tt(ip-add-membership=<multicast-address:interface-address:interface-index
|
||||||
procan().
|
procan().
|
||||||
label(OPTION_IP_ADD_SOURCE_MEMBERSHIP)
|
label(OPTION_IP_ADD_SOURCE_MEMBERSHIP)
|
||||||
dit(bf(tt(ip-add-source-membership=<multicast-address:interface-address:source-address>)))
|
dit(bf(tt(ip-add-source-membership=<multicast-address:interface-address:source-address>)))
|
||||||
Makes the socket member of the specified multicast group for the specified
|
Makes the socket member of the specified multicast group for the
|
||||||
source, i.e. only multicast traffic from this address is to be delivered.
|
specified source, i.e. only multicast traffic from this address is to be
|
||||||
This is currently only implemented for IPv4.nl()
|
delivered. This only works for IPv4, see
|
||||||
|
link(ipv6-join-source-group)(OPTION_IPV6_JOIN_SOURCE_GROUP) for the IPv6
|
||||||
|
variant. The option takes the IP address of the multicast group, the IP
|
||||||
|
address of the desired network interface and the source IP address of the
|
||||||
|
multicast traffic.
|
||||||
label(OPTION_IPV6_JOIN_GROUP)
|
label(OPTION_IPV6_JOIN_GROUP)
|
||||||
dit(bf(tt(ipv6-join-group=<multicast-address:interface-name>)))
|
dit(bf(tt(ipv6-join-group=<multicast-address:interface-name>)))
|
||||||
dit(bf(tt(ipv6-join-group=<multicast-address:interface-index>)))
|
dit(bf(tt(ipv6-join-group=<multicast-address:interface-index>)))
|
||||||
|
@ -2184,6 +2190,17 @@ dit(bf(tt(ipv6-join-group=<multicast-address:interface-index>)))
|
||||||
group and info about the desired network interface.
|
group and info about the desired network interface.
|
||||||
The indices of active network interfaces can be shown using the utility
|
The indices of active network interfaces can be shown using the utility
|
||||||
procan().
|
procan().
|
||||||
|
label(OPTION_IPV6_JOIN_SOURCE_GROUP)
|
||||||
|
dit(bf(tt(ipv6-join-source-group=<multicast-address:interface-name:source-address>)))
|
||||||
|
dit(bf(tt(ipv6-join-source-group=<multicast-address:interface-index:source-address>)))
|
||||||
|
Makes the socket member of the specified multicast group for the
|
||||||
|
specified source, i.e. only multicast traffic from this address is to be
|
||||||
|
delivered. This only works for IPv6, see
|
||||||
|
link(ip-add-source-membership)(OPTION_IP_ADD_SOURCE_MEMBERSHIP) for the
|
||||||
|
IPv4 variant. The option takes the IP address of the multicast group,
|
||||||
|
info about the desired network interface and the source IP address of the
|
||||||
|
multicast traffic. The indices of active network interfaces can be shown
|
||||||
|
using the utility procan().
|
||||||
label(OPTION_IP_MULTICAST_IF)
|
label(OPTION_IP_MULTICAST_IF)
|
||||||
dit(bf(tt(ip-multicast-if=<hostname>)))
|
dit(bf(tt(ip-multicast-if=<hostname>)))
|
||||||
Specifies hostname or address of the network interface to be used for
|
Specifies hostname or address of the network interface to be used for
|
||||||
|
|
152
xio-ip6.c
152
xio-ip6.c
|
@ -14,6 +14,7 @@
|
||||||
#include "xio-ip.h" /* xiogetaddrinfo() */
|
#include "xio-ip.h" /* xiogetaddrinfo() */
|
||||||
|
|
||||||
#include "xio-ip6.h"
|
#include "xio-ip6.h"
|
||||||
|
#include "nestlex.h"
|
||||||
|
|
||||||
|
|
||||||
static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen);
|
static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen);
|
||||||
|
@ -25,6 +26,9 @@ const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6O
|
||||||
#ifdef IPV6_JOIN_GROUP
|
#ifdef IPV6_JOIN_GROUP
|
||||||
const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP };
|
const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SOCKOPT, SOL_IPV6, IPV6_JOIN_GROUP };
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MCAST_JOIN_SOURCE_GROUP
|
||||||
|
const struct optdesc opt_ipv6_join_source_group = { "ipv6-join-source-group", "join-source-group", OPT_IPV6_JOIN_SOURCE_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_GROUP_SOURCE_REQ, OFUNC_SOCKOPT, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP };
|
||||||
|
#endif
|
||||||
#ifdef IPV6_PKTINFO
|
#ifdef IPV6_PKTINFO
|
||||||
const struct optdesc opt_ipv6_pktinfo = { "ipv6-pktinfo", "pktinfo", OPT_IPV6_PKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_PKTINFO };
|
const struct optdesc opt_ipv6_pktinfo = { "ipv6-pktinfo", "pktinfo", OPT_IPV6_PKTINFO, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_PKTINFO };
|
||||||
#endif
|
#endif
|
||||||
|
@ -502,4 +506,152 @@ int xioapply_ipv6_join_group(
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_STRUCT_IPV6_MREQ) */
|
#endif /* defined(HAVE_STRUCT_IPV6_MREQ) */
|
||||||
|
|
||||||
|
#if HAVE_STRUCT_GROUP_SOURCE_REQ
|
||||||
|
int xiotype_ip6_join_source_group(
|
||||||
|
char *token, const struct optname *ent, struct opt *opt)
|
||||||
|
{
|
||||||
|
/* We do not resolve the addresses here because we do not yet know
|
||||||
|
if we are coping with an IPv4 or IPv6 socat address */
|
||||||
|
const char *ends[] = { ":", NULL };
|
||||||
|
const char *nests[] = { "[","]", NULL };
|
||||||
|
char buff[512], *buffp=buff; size_t bufspc = sizeof(buff)-1;
|
||||||
|
char *tokp = token;
|
||||||
|
int parsres;
|
||||||
|
|
||||||
|
/* Parse first IP address (mcast group), expect ':' */
|
||||||
|
parsres =
|
||||||
|
nestlex((const char **)&tokp, &buffp, &bufspc,
|
||||||
|
ends, NULL, NULL, nests,
|
||||||
|
true, false, false);
|
||||||
|
if (parsres < 0) {
|
||||||
|
Error1("option too long: \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
} else if (parsres > 0) {
|
||||||
|
Error1("syntax error in \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*tokp != ':') {
|
||||||
|
Error1("syntax in option %s: missing ':'", token);
|
||||||
|
}
|
||||||
|
*buffp++ = '\0';
|
||||||
|
if ((opt->value.u_string/*mcaddr*/ = strdup(buff)) == NULL) {
|
||||||
|
int _errno = errno;
|
||||||
|
Error1("strdup(\"%s\"): out of memory", buff);
|
||||||
|
errno = _errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
++tokp;
|
||||||
|
/* Parse interface name/index, expect ':' or '\0'' */
|
||||||
|
buffp = buff;
|
||||||
|
parsres =
|
||||||
|
nestlex((const char **)&tokp, &buffp, &bufspc,
|
||||||
|
ends, NULL, NULL, nests,
|
||||||
|
true, false, false);
|
||||||
|
if (parsres < 0) {
|
||||||
|
Error1("option too long: \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
} else if (parsres > 0) {
|
||||||
|
Error1("syntax error in \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*tokp != ':') {
|
||||||
|
Error1("syntax in option %s: missing ':'", token);
|
||||||
|
}
|
||||||
|
*buffp++ = '\0';
|
||||||
|
if ((opt->value2.u_string/*ifindex*/ = Malloc(IF_NAMESIZE)) == NULL) {
|
||||||
|
int _errno = errno;
|
||||||
|
free(opt->value.u_string);
|
||||||
|
errno = _errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strncpy(opt->value2.u_string/*ifindex*/, buff, IF_NAMESIZE);
|
||||||
|
|
||||||
|
++tokp;
|
||||||
|
/* Parse second IP address (source address), expect ':' or '\0'' */
|
||||||
|
buffp = buff;
|
||||||
|
parsres =
|
||||||
|
nestlex((const char **)&tokp, &buffp, &bufspc,
|
||||||
|
ends, NULL, NULL, nests,
|
||||||
|
true, false, false);
|
||||||
|
if (parsres < 0) {
|
||||||
|
Error1("option too long: \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
} else if (parsres > 0) {
|
||||||
|
Error1("syntax error in \"%s\"", token);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*tokp) {
|
||||||
|
Error1("syntax in option %s: trailing cruft", token);
|
||||||
|
}
|
||||||
|
*buffp++ = '\0';
|
||||||
|
if ((opt->value3.u_string/*srcaddr*/ = strdup(buff)) == NULL) {
|
||||||
|
int _errno = errno;
|
||||||
|
Error1("strdup(\"%s\"): out of memory", buff);
|
||||||
|
free(opt->value.u_string);
|
||||||
|
errno = _errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info4("setting option \"%s\" to {\"%s\",\"%s\",\"%s\"}",
|
||||||
|
ent->desc->defname,
|
||||||
|
opt->value.u_string/*mcaddr*/,
|
||||||
|
opt->value2.u_string/*ifindex*/,
|
||||||
|
opt->value3.u_string/*srcaddr*/);
|
||||||
|
|
||||||
|
if (!xioparms.experimental) {
|
||||||
|
Warn("option ipv6-join-source-group is experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) {
|
||||||
|
struct group_source_req ip6_gsr = {0};
|
||||||
|
union sockaddr_union sockaddr1;
|
||||||
|
socklen_t socklen1 = sizeof(sockaddr1.ip6);
|
||||||
|
union sockaddr_union sockaddr2;
|
||||||
|
socklen_t socklen2 = sizeof(sockaddr2.ip6);
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/* First parameter is always multicast address */
|
||||||
|
if ((res =
|
||||||
|
xiogetaddrinfo(opt->value.u_string/*mcaddr*/, NULL,
|
||||||
|
xfd->para.socket.la.soa.sa_family,
|
||||||
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
|
&sockaddr1, &socklen1, 0, 0)) != STAT_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
memcpy(&ip6_gsr.gsr_group, &sockaddr1.ip6, socklen1);
|
||||||
|
/* Second parameter is interface name/index */
|
||||||
|
if (ifindex(opt->value2.u_string/*ifindex*/,
|
||||||
|
&ip6_gsr.gsr_interface, -1)
|
||||||
|
< 0) {
|
||||||
|
Error1("interface \"%s\" not found",
|
||||||
|
opt->value.u_string/*ifindex*/);
|
||||||
|
ip6_gsr.gsr_interface = 0;
|
||||||
|
}
|
||||||
|
/* Third parameter is source address */
|
||||||
|
if ((res =
|
||||||
|
xiogetaddrinfo(opt->value3.u_string/*srcaddr*/, NULL,
|
||||||
|
xfd->para.socket.la.soa.sa_family,
|
||||||
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
|
&sockaddr2, &socklen2, 0, 0)) != STAT_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
memcpy(&ip6_gsr.gsr_source, &sockaddr2.ip6, socklen2);
|
||||||
|
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
|
||||||
|
&ip6_gsr, sizeof(ip6_gsr)) < 0) {
|
||||||
|
Error6("setsockopt(%d, %d, %d, {%d,...}, "F_Zu"): %s",
|
||||||
|
xfd->fd, opt->desc->major, opt->desc->minor,
|
||||||
|
ip6_gsr.gsr_interface,
|
||||||
|
sizeof(ip6_gsr),
|
||||||
|
strerror(errno));
|
||||||
|
opt->desc = ODESC_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_STRUCT_GROUP_SOURCE_REQ */
|
||||||
|
|
||||||
#endif /* WITH_IP6 */
|
#endif /* WITH_IP6 */
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
extern const struct optdesc opt_ipv6_v6only;
|
extern const struct optdesc opt_ipv6_v6only;
|
||||||
extern const struct optdesc opt_ipv6_join_group;
|
extern const struct optdesc opt_ipv6_join_group;
|
||||||
|
extern const struct optdesc opt_ipv6_join_source_group;
|
||||||
extern const struct optdesc opt_ipv6_pktinfo;
|
extern const struct optdesc opt_ipv6_pktinfo;
|
||||||
extern const struct optdesc opt_ipv6_recvpktinfo;
|
extern const struct optdesc opt_ipv6_recvpktinfo;
|
||||||
extern const struct optdesc opt_ipv6_rthdr;
|
extern const struct optdesc opt_ipv6_rthdr;
|
||||||
|
@ -50,6 +51,9 @@ xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen,
|
||||||
struct sockaddr_in6 *sa, int ipproto);
|
struct sockaddr_in6 *sa, int ipproto);
|
||||||
extern int xioapply_ipv6_join_group(xiosingle_t *xfd, struct opt *opt);
|
extern int xioapply_ipv6_join_group(xiosingle_t *xfd, struct opt *opt);
|
||||||
|
|
||||||
|
extern int xiotype_ip6_join_source_group(char* token, const struct optname *ent, struct opt *opt);
|
||||||
|
extern int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt);
|
||||||
|
|
||||||
#endif /* WITH_IP6 */
|
#endif /* WITH_IP6 */
|
||||||
|
|
||||||
#endif /* !defined(__xio_ip6_h_included) */
|
#endif /* !defined(__xio_ip6_h_included) */
|
||||||
|
|
29
xioopts.c
29
xioopts.c
|
@ -786,6 +786,9 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IPV6_JOIN_GROUP
|
#ifdef IPV6_JOIN_GROUP
|
||||||
IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group)
|
IF_IP6 ("ipv6-add-membership", &opt_ipv6_join_group)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MCAST_JOIN_SOURCE_GROUP
|
||||||
|
IF_IP6 ("ipv6-add-source-membership", &opt_ipv6_join_source_group)
|
||||||
|
#endif
|
||||||
#ifdef IPV6_AUTHHDR
|
#ifdef IPV6_AUTHHDR
|
||||||
IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr)
|
IF_IP6 ("ipv6-authhdr", &opt_ipv6_authhdr)
|
||||||
#endif
|
#endif
|
||||||
|
@ -804,6 +807,9 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IPV6_JOIN_GROUP
|
#ifdef IPV6_JOIN_GROUP
|
||||||
IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group)
|
IF_IP6 ("ipv6-join-group", &opt_ipv6_join_group)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MCAST_JOIN_SOURCE_GROUP
|
||||||
|
IF_IP6 ("ipv6-join-source-group", &opt_ipv6_join_source_group)
|
||||||
|
#endif
|
||||||
#ifdef IPV6_PKTINFO
|
#ifdef IPV6_PKTINFO
|
||||||
IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo)
|
IF_IP6 ("ipv6-pktinfo", &opt_ipv6_pktinfo)
|
||||||
#endif
|
#endif
|
||||||
|
@ -856,6 +862,9 @@ const struct optname optionnames[] = {
|
||||||
#ifdef IPV6_JOIN_GROUP
|
#ifdef IPV6_JOIN_GROUP
|
||||||
IF_IP6 ("join-group", &opt_ipv6_join_group)
|
IF_IP6 ("join-group", &opt_ipv6_join_group)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MCAST_JOIN_SOURCE_GROUP
|
||||||
|
IF_IP6 ("join-source-group", &opt_ipv6_join_source_group)
|
||||||
|
#endif
|
||||||
#if WITH_FS && defined(FS_JOURNAL_DATA_FL)
|
#if WITH_FS && defined(FS_JOURNAL_DATA_FL)
|
||||||
IF_ANY ("journal", &opt_fs_journal_data)
|
IF_ANY ("journal", &opt_fs_journal_data)
|
||||||
IF_ANY ("journal-data", &opt_fs_journal_data)
|
IF_ANY ("journal-data", &opt_fs_journal_data)
|
||||||
|
@ -2490,6 +2499,12 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_STRUCT_GROUP_SOURCE_REQ
|
||||||
|
case TYPE_GROUP_SOURCE_REQ:
|
||||||
|
xiotype_ip6_join_source_group(token, ent, opt);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
case TYPE_IP4NAME:
|
case TYPE_IP4NAME:
|
||||||
{
|
{
|
||||||
|
@ -3331,6 +3346,12 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
||||||
++opt; continue;
|
++opt; continue;
|
||||||
#endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
|
#endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */
|
||||||
|
|
||||||
|
#if defined(HAVE_STRUCT_GROUP_SOURCE_REQ)
|
||||||
|
case TYPE_GROUP_SOURCE_REQ:
|
||||||
|
/* handled in applyopts_single */
|
||||||
|
++opt; continue;
|
||||||
|
#endif /* defined(HAVE_STRUCT_GROUP_SOURCE_REQ) */
|
||||||
|
|
||||||
/*! still many types missing; implement on demand */
|
/*! still many types missing; implement on demand */
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
case TYPE_IP4NAME:
|
case TYPE_IP4NAME:
|
||||||
|
@ -3984,6 +4005,14 @@ int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
|
#endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
|
||||||
|
|
||||||
|
#if WITH_IP6 && defined(HAVE_STRUCT_GROUP_SOURCE_REQ)
|
||||||
|
case OPT_IPV6_JOIN_SOURCE_GROUP:
|
||||||
|
if (xioapply_ip6_join_source_group(xfd, opt) < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */
|
||||||
default:
|
default:
|
||||||
/* ignore here */
|
/* ignore here */
|
||||||
++opt; continue;
|
++opt; continue;
|
||||||
|
|
|
@ -76,6 +76,9 @@ enum e_types {
|
||||||
#if HAVE_STRUCT_IP_MREQ_SOURCE
|
#if HAVE_STRUCT_IP_MREQ_SOURCE
|
||||||
TYPE_IP_MREQ_SOURCE, /* for struct ip_mreq_source */
|
TYPE_IP_MREQ_SOURCE, /* for struct ip_mreq_source */
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_STRUCT_GROUP_SOURCE_REQ
|
||||||
|
TYPE_GROUP_SOURCE_REQ, /* for struct group_source_req */
|
||||||
|
#endif
|
||||||
|
|
||||||
TYPE_GENERIC, /* type is determined from (text) data provided (dalan syntax) */
|
TYPE_GENERIC, /* type is determined from (text) data provided (dalan syntax) */
|
||||||
} ;
|
} ;
|
||||||
|
@ -370,6 +373,7 @@ enum e_optcode {
|
||||||
OPT_IPV6_HOPLIMIT,
|
OPT_IPV6_HOPLIMIT,
|
||||||
OPT_IPV6_HOPOPTS,
|
OPT_IPV6_HOPOPTS,
|
||||||
OPT_IPV6_JOIN_GROUP,
|
OPT_IPV6_JOIN_GROUP,
|
||||||
|
OPT_IPV6_JOIN_SOURCE_GROUP,
|
||||||
OPT_IPV6_PKTINFO,
|
OPT_IPV6_PKTINFO,
|
||||||
OPT_IPV6_RECVDSTOPTS,
|
OPT_IPV6_RECVDSTOPTS,
|
||||||
OPT_IPV6_RECVERR,
|
OPT_IPV6_RECVERR,
|
||||||
|
|
Loading…
Reference in a new issue