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 <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h> #include <nuttx/net/net.h>
#include <netinet/in.h> #include <netinet/in.h>
#include "netdev/netdev.h"
#include "igmp/igmp.h"
#include "inet/inet.h" #include "inet/inet.h"
#ifdef CONFIG_NET_IPv4 #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) FAR const void *value, socklen_t value_len)
{ {
#ifdef CONFIG_NET_IGMP #ifdef CONFIG_NET_IGMP
int ret;
ninfo("option: %d\n", option);
/* With IPv4, the multicast-related socket options are simply an alternative /* With IPv4, the multicast-related socket options are simply an alternative
* way to access IGMP. That IGMP functionality can also be accessed via * way to access IGMP. That IGMP functionality can also be accessed via
* IOCTL commands (see netdev/netdev_ioctl.c) * IOCTL commands (see netdev/netdev_ioctl.c)
@ -91,6 +99,42 @@ int ipv4_setsockopt(FAR struct socket *psock, int option,
switch (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 case IP_MULTICAST_IF: /* Set local device for a multicast
* socket */ * socket */
case IP_MULTICAST_TTL: /* Set/read the time-to-live value of 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 case IP_DROP_SOURCE_MEMBERSHIP: /* Leave a source-specific group. Stop
* receiving data from a given multicast * receiving data from a given multicast
* group that come from a given source */ * 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 case IP_MULTICAST_ALL: /* Modify the delivery policy of
* multicast messages bound to * multicast messages bound to
* INADDR_ANY */ * INADDR_ANY */
#warning Missing logic
nwarn("WARNING: Unimplemented IPv4 option: %d\n", option);
ret = -ENOSYS;
break;
default: default:
nerr("ERROR: Unrecognized IPv4 option: %d\n", option);
ret = -ENOPROTOOPT;
break; break;
} }
#warning Missing logic return ret;
return -ENOSYS;
#else #else
return -ENOPROTOOPT; return -ENOPROTOOPT;
#endif #endif

View File

@ -41,6 +41,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <debug.h>
#include <netinet/in.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) FAR const void *value, socklen_t value_len)
{ {
#ifdef CONFIG_NET_MLD #ifdef CONFIG_NET_MLD
int ret;
ninfo("option: %d\n", option);
/* Handle MLD-related socket options */ /* Handle MLD-related socket options */
switch (option) switch (option)
{ {
/* The following IPv6 socket options are defined, but not implemented */
case IPV6_JOIN_GROUP: /* Join a multicast group */ case IPV6_JOIN_GROUP: /* Join a multicast group */
case IPV6_LEAVE_GROUP: /* Quit a multicast group */ case IPV6_LEAVE_GROUP: /* Quit a multicast group */
case IPV6_MULTICAST_HOPS: /* Multicast hop limit */ 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_UNICAST_HOPS: /* Unicast hop limit */
case IPV6_V6ONLY: /* Restrict AF_INET6 socket to IPv6 case IPV6_V6ONLY: /* Restrict AF_INET6 socket to IPv6
* communications only */ * communications only */
#warning Missing logic
nwarn("WARNING: Unimplemented IPv6 option: %d\n", option);
ret = -ENOSYS;
break;
default: default:
nerr("ERROR: Unrecognized IPv6 option: %d\n", option);
ret = -ENOPROTOOPT;
break; break;
} }
#warning Missing logic return ret;
return -ENOSYS;
#else #else
return -ENOPROTOOPT; return -ENOPROTOOPT;
#endif #endif