net/inet/ipv4_setsockopt.c: Add implementation for all IPv4 socket options that have implemented IOCTL command counterparts.

This commit is contained in:
Gregory Nutt 2018-10-31 17:15:23 -06:00
parent 0330743a9d
commit f5ed6bf672
2 changed files with 67 additions and 6 deletions

View File

@ -40,12 +40,16 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include <netinet/in.h>
#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

View File

@ -41,6 +41,7 @@
#include <sys/types.h>
#include <errno.h>
#include <debug.h>
#include <netinet/in.h>
@ -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