From f5ed6bf672ab0d5df5b24b5ec5af0adba53acfa1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 31 Oct 2018 17:15:23 -0600 Subject: [PATCH] net/inet/ipv4_setsockopt.c: Add implementation for all IPv4 socket options that have implemented IOCTL command counterparts. --- net/inet/ipv4_setsockopt.c | 56 +++++++++++++++++++++++++++++++++++--- net/inet/ipv6_setsockopt.c | 17 ++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/net/inet/ipv4_setsockopt.c b/net/inet/ipv4_setsockopt.c index bb1ba152b8..01f3aae1d7 100644 --- a/net/inet/ipv4_setsockopt.c +++ b/net/inet/ipv4_setsockopt.c @@ -40,12 +40,16 @@ #include #include +#include #include +#include #include #include +#include "netdev/netdev.h" +#include "igmp/igmp.h" #include "inet/inet.h" #ifdef CONFIG_NET_IPv4 @@ -82,6 +86,10 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, FAR const void *value, socklen_t value_len) { #ifdef CONFIG_NET_IGMP + int ret; + + ninfo("option: %d\n", option); + /* With IPv4, the multicast-related socket options are simply an alternative * way to access IGMP. That IGMP functionality can also be accessed via * IOCTL commands (see netdev/netdev_ioctl.c) @@ -91,6 +99,42 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, switch (option) { + case IP_MSFILTER: /* Access advanced, full-state filtering API */ + { + FAR const struct ip_msfilter *imsf; + FAR struct net_driver_s *dev; + + imsf = (FAR const struct ip_msfilter *)value; + if (imsf == NULL || value_len < sizeof(struct ip_msfilter)) + { + nerr("ERROR: Bad value or value_len\n"); + ret = -EINVAL; + } + else + { + /* Get the device associated with the local interface address */ + + dev = netdev_findby_lipv4addr(imsf->imsf_interface.s_addr); + if (dev == NULL) + { + nwarn("WARNING: Could not find device for imsf_interface\n"); + ret = -ENODEV; + } + else if (imsf->imsf_fmode == MCAST_INCLUDE) + { + ret = igmp_joingroup(dev, &imsf->imsf_multiaddr); + } + else + { + DEBUGASSERT(imsf->imsf_fmode == MCAST_EXCLUDE); + ret = igmp_leavegroup(dev, &imsf->imsf_multiaddr); + } + } + } + break; + + /* The following IPv4 socket options are defined, but not implemented */ + case IP_MULTICAST_IF: /* Set local device for a multicast * socket */ case IP_MULTICAST_TTL: /* Set/read the time-to-live value of @@ -110,17 +154,21 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, case IP_DROP_SOURCE_MEMBERSHIP: /* Leave a source-specific group. Stop * receiving data from a given multicast * group that come from a given source */ - case IP_MSFILTER: /* Access advanced, full-state filtering - * API */ case IP_MULTICAST_ALL: /* Modify the delivery policy of * multicast messages bound to * INADDR_ANY */ +#warning Missing logic + nwarn("WARNING: Unimplemented IPv4 option: %d\n", option); + ret = -ENOSYS; + break; + default: + nerr("ERROR: Unrecognized IPv4 option: %d\n", option); + ret = -ENOPROTOOPT; break; } -#warning Missing logic - return -ENOSYS; + return ret; #else return -ENOPROTOOPT; #endif diff --git a/net/inet/ipv6_setsockopt.c b/net/inet/ipv6_setsockopt.c index 16a9a4dcb3..cea4b457d5 100644 --- a/net/inet/ipv6_setsockopt.c +++ b/net/inet/ipv6_setsockopt.c @@ -41,6 +41,7 @@ #include #include +#include #include @@ -82,10 +83,16 @@ int ipv6_setsockopt(FAR struct socket *psock, int option, FAR const void *value, socklen_t value_len) { #ifdef CONFIG_NET_MLD + int ret; + + ninfo("option: %d\n", option); + /* Handle MLD-related socket options */ switch (option) { + /* The following IPv6 socket options are defined, but not implemented */ + case IPV6_JOIN_GROUP: /* Join a multicast group */ case IPV6_LEAVE_GROUP: /* Quit a multicast group */ case IPV6_MULTICAST_HOPS: /* Multicast hop limit */ @@ -96,12 +103,18 @@ int ipv6_setsockopt(FAR struct socket *psock, int option, case IPV6_UNICAST_HOPS: /* Unicast hop limit */ case IPV6_V6ONLY: /* Restrict AF_INET6 socket to IPv6 * communications only */ +#warning Missing logic + nwarn("WARNING: Unimplemented IPv6 option: %d\n", option); + ret = -ENOSYS; + break; + default: + nerr("ERROR: Unrecognized IPv6 option: %d\n", option); + ret = -ENOPROTOOPT; break; } -#warning Missing logic - return -ENOSYS; + return ret; #else return -ENOPROTOOPT; #endif