From b48804cfc29d83daf72517b095c0741a703f475d Mon Sep 17 00:00:00 2001 From: dongjianli Date: Sun, 26 Aug 2018 14:54:26 -0600 Subject: [PATCH] net/netdev/netdev_ioctl.c: Add si_ioctl callback and net_ioctl_arglen so usrsock could forward the ioctl to the remote end --- include/net/route.h | 3 - include/nuttx/net/net.h | 4 + include/nuttx/net/netdev.h | 19 +++++ net/netdev/netdev_ioctl.c | 157 +++++++++++++++++++++++++++++++++++-- 4 files changed, 175 insertions(+), 8 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 7f0a1834fd0..8f5765ed460 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -46,8 +46,6 @@ #include -#ifdef CONFIG_NET_ROUTE - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -131,5 +129,4 @@ int delroute(int sockfd, FAR struct sockaddr_storage *target, } #endif -#endif /* CONFIG_NET_ROUTE */ #endif /* __INCLUDE_NET_ROUTE_H */ diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 9a40d38901a..93569abae1c 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -180,6 +180,10 @@ struct sock_intf_s size_t len, int flags, FAR struct sockaddr *from, FAR socklen_t *fromlen); CODE int (*si_close)(FAR struct socket *psock); +#ifdef CONFIG_NET_USRSOCK + CODE int (*si_ioctl)(FAR struct socket *psock, int cmd, + FAR void *arg, size_t arglen); +#endif }; /* This is the internal representation of a socket reference by a file diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index c7def20c7e1..78bf31117bb 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -599,6 +599,25 @@ int devif_loopback(FAR struct net_driver_s *dev); int netdev_carrier_on(FAR struct net_driver_s *dev); int netdev_carrier_off(FAR struct net_driver_s *dev); +/**************************************************************************** + * Name: net_ioctl_arglen + * + * Description: + * Calculate the ioctl argument buffer length. + * + * Input Parameters: + * + * cmd The ioctl command + * + * Returned Value: + * The argument buffer length, or error code. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_USRSOCK +ssize_t net_ioctl_arglen(int cmd); +#endif + /**************************************************************************** * Name: net_chksum * diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index c68accae62a..c1baf47e6c1 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -63,10 +63,8 @@ # include #endif -#ifdef CONFIG_NET_IGMP -# include -# include -#endif +#include +#include #ifdef CONFIG_NETDEV_WIRELESS_IOCTL # include @@ -1429,10 +1427,149 @@ static int netdev_rt_ioctl(FAR struct socket *psock, int cmd, } #endif +/**************************************************************************** + * Name: netdev_usrsock_ioctl + * + * Description: + * Perform user private ioctl operations. + * + * Parameters: + * psock Socket structure + * cmd The ioctl command + * arg The argument of the ioctl cmd + * + * Return: + * >=0 on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_USRSOCK +static int netdev_usrsock_ioctl(FAR struct socket *psock, int cmd, + unsigned long arg) +{ + if (psock->s_sockif && psock->s_sockif->si_ioctl) + { + ssize_t arglen; + + arglen = net_ioctl_arglen(cmd); + if (arglen < 0) + { + return arglen; + } + + return psock->s_sockif->si_ioctl(psock, cmd, (FAR void *)arg, arglen); + } + else + { + return -ENOTTY; + } +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: net_ioctl_arglen + * + * Description: + * Calculate the ioctl argument buffer length. + * + * Input Parameters: + * + * cmd The ioctl command + * + * Returned Value: + * The argument buffer length, or error code. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_USRSOCK +ssize_t net_ioctl_arglen(int cmd) +{ + switch (cmd) + { + case SIOCGIFADDR: + case SIOCSIFADDR: + case SIOCGIFDSTADDR: + case SIOCSIFDSTADDR: + case SIOCGIFBRDADDR: + case SIOCSIFBRDADDR: + case SIOCGIFNETMASK: + case SIOCSIFNETMASK: + case SIOCGIFMTU: + case SIOCGIFHWADDR: + case SIOCSIFHWADDR: + case SIOCDIFADDR: + case SIOCGIFCOUNT: + case SIOCSIFFLAGS: + case SIOCGIFFLAGS: + return sizeof(struct ifreq); + case SIOCGLIFADDR: + case SIOCSLIFADDR: + case SIOCGLIFDSTADDR: + case SIOCSLIFDSTADDR: + case SIOCGLIFBRDADDR: + case SIOCSLIFBRDADDR: + case SIOCGLIFNETMASK: + case SIOCSLIFNETMASK: + case SIOCGLIFMTU: + case SIOCIFAUTOCONF: + return sizeof(struct lifreq); + case SIOCGIFCONF: + return sizeof(struct ifconf); + case SIOCGLIFCONF: + return sizeof(struct lifconf); + case SIOCGIPMSFILTER: + case SIOCSIPMSFILTER: + return sizeof(struct ip_msfilter); + case SIOCSARP: + case SIOCDARP: + case SIOCGARP: + return sizeof(struct arpreq); + case SIOCADDRT: + case SIOCDELRT: + return sizeof(struct rtentry); + case SIOCMIINOTIFY: + return sizeof(struct mii_iotcl_notify_s); + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + return sizeof(struct mii_ioctl_data_s); + default: +#ifdef CONFIG_NETDEV_IOCTL +# ifdef CONFIG_NETDEV_WIRELESS_IOCTL + if (_WLIOCVALID(cmd) && _IOC_NR(cmd) <= WL_NNETCMDS) + { + return sizeof(struct iwreq); + } +# endif +# ifdef CONFIG_WIRELESS_IEEE802154 + if (_MAC802154IOCVALID(cmd)) + { + return sizeof(struct ieee802154_netmac_s); + } +# endif +# ifdef CONFIG_WIRELESS_PKTRADIO + if (WL_ISPKTRADIOCMD(cmd)) + { + return sizeof(struct pktradio_ifreq_s); + } +# endif +# ifdef CONFIG_WIRELESS_BLUETOOTH + if (WL_IBLUETOOTHCMD(cmd)) + { + return sizeof(struct btreq_s); + } +# endif +#endif + return -ENOTTY; + } +} +#endif + /**************************************************************************** * Name: psock_ioctl * @@ -1477,7 +1614,17 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg) /* Execute the command. First check for a standard network IOCTL command. */ - ret = netdev_ifr_ioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg)); +#ifdef CONFIG_NET_USRSOCK + /* Check for a USRSOCK ioctl command */ + + ret = netdev_usrsock_ioctl(psock, cmd, arg); + if (ret == -ENOTTY) +#endif + { + /* Check for a standard network IOCTL command. */ + + ret = netdev_ifr_ioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg)); + } #if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL) /* Check for a wireless network command */