summaryrefslogtreecommitdiff
path: root/nuttx/net/netdev-ioctl.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-09-16 22:12:04 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-09-16 22:12:04 +0000
commit9e15c4be04516ac9957f33ea179a188cc2a081a0 (patch)
tree77fe706483352a68b683ecde64215d54cbc89f4f /nuttx/net/netdev-ioctl.c
parent4077a70fc256a7dd65febe986f176b8ac62091fc (diff)
downloadpx4-nuttx-9e15c4be04516ac9957f33ea179a188cc2a081a0.tar.gz
px4-nuttx-9e15c4be04516ac9957f33ea179a188cc2a081a0.tar.bz2
px4-nuttx-9e15c4be04516ac9957f33ea179a188cc2a081a0.zip
Associate address with network driver; implement ioctl calls to set addresses
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@345 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net/netdev-ioctl.c')
-rw-r--r--nuttx/net/netdev-ioctl.c148
1 files changed, 140 insertions, 8 deletions
diff --git a/nuttx/net/netdev-ioctl.c b/nuttx/net/netdev-ioctl.c
index 3e8c1a933..cdc7c80b8 100644
--- a/nuttx/net/netdev-ioctl.c
+++ b/nuttx/net/netdev-ioctl.c
@@ -42,12 +42,55 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <string.h>
#include <errno.h>
#include <nuttx/net.h>
+#include <net/uip/uip-arch.h>
+#include <net/uip/uip.h>
+
#include "net-internal.h"
/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: _get_ipaddr / _set_ipaddr
+ *
+ * Description:
+ * Copy IP addresses into and out of device structure
+ *
+ ****************************************************************************/
+
+static void _get_ipaddr(struct sockaddr *outaddr, uip_ipaddr_t *inaddr)
+{
+#ifdef CONFIG_NET_IPv6
+ struct sockaddr_in6 *dest = (struct sockaddr_in6 *)outaddr;
+ memcpy(&dest->sin6_addr.in6_u, inaddr, IFHWADDRLEN);
+#else
+ struct sockaddr_in *dest = (struct sockaddr_in *)outaddr;
+ dest->sin_addr.s_addr = *inaddr;
+#endif
+}
+
+static void _set_ipaddr(uip_ipaddr_t *outaddr, struct sockaddr *inaddr)
+{
+#ifdef CONFIG_NET_IPv6
+ struct sockaddr_in6 *src = (struct sockaddr_in6 *)inaddr;
+ memcpy(outaddr, &src->sin6_addr.in6_u, IFHWADDRLEN);
+#else
+ struct sockaddr_in *src = (struct sockaddr_in *)inaddr;
+ *outaddr = src->sin_addr.s_addr;
+#endif
+}
+
+/****************************************************************************
* Global Functions
****************************************************************************/
@@ -58,7 +101,7 @@
* Perform network device specific operations.
*
* Parameters:
- * fd Socket descriptor of device
+ * sockfd Socket descriptor of device
* cmd The ioctl command
* req The argument of the ioctl cmd
*
@@ -67,23 +110,112 @@
* -1 on failure withi errno set properly:
*
* EBADF
- * 'fd' is not a valid descriptor.
+ * 'sockfd' is not a valid descriptor.
* EFAULT
- * 'arg' references an inaccessible memory area.
+ * 'req' references an inaccessible memory area.
* EINVAL
- * 'cmd' or 'arg' is not valid.
+ * 'cmd' or 'req' is not valid.
* ENOTTY
- * 'fd' is not associated with a character special device.
+ * 'sockfd' is not associated with a network device.
* ENOTTY
* The specified request does not apply to the kind of object that the
- * descriptor 'fd' references.
+ * descriptor 'sockfd' references.
*
****************************************************************************/
int netdev_ioctl(int sockfd, int cmd, struct ifreq *req)
{
-#warning "Network ioctls not implemented"
- *get_errno_ptr() = ENOSYS;
+ FAR struct socket *psock = sockfd_socket(sockfd);
+ FAR struct uip_driver_s *dev;
+ int err;
+
+ if (!_SIOCVALID(cmd) || !req)
+ {
+ err = EINVAL;
+ goto errout;
+ }
+
+ /* Verify that the sockfd corresponds to valid, allocated socket */
+
+ if (!psock || psock->s_crefs <= 0)
+ {
+ err = EBADF;
+ goto errout;
+ }
+
+ /* Find the network device associated with the device name
+ * in the request data.
+ */
+
+ dev = netdev_find(req->ifr_name);
+ if (!dev)
+ {
+ err = EINVAL;
+ goto errout;
+ }
+
+ /* Execute the command */
+
+ switch (cmd)
+ {
+ case SIOCGIFADDR: /* Get IP address */
+ _get_ipaddr(&req->ifr_addr, &dev->d_ipaddr);
+ break;
+
+ case SIOCSIFADDR: /* Set IP address */
+ _set_ipaddr(&dev->d_ipaddr, &req->ifr_addr);
+ break;
+
+ case SIOCGIFDSTADDR: /* Get P-to-P address */
+ _get_ipaddr(&req->ifr_dstaddr, &dev->d_draddr);
+ break;
+
+ case SIOCSIFDSTADDR: /* Set P-to-P address */
+ _set_ipaddr(&dev->d_draddr, &req->ifr_dstaddr);
+ break;
+
+ case SIOCGIFNETMASK: /* Get network mask */
+ _get_ipaddr(&req->ifr_addr, &dev->d_netmask);
+ break;
+
+ case SIOCSIFNETMASK: /* Set network mask */
+ _set_ipaddr(&dev->d_netmask, &req->ifr_addr);
+ break;
+
+ case SIOCGIFMTU: /* Get MTU size */
+ req->ifr_mtu = UIP_BUFSIZE;
+ break;
+
+ case SIOCGIFHWADDR: /* Get hardware address */
+ memcpy(req->ifr_hwaddr.sa_data, dev->d_mac.addr, IFHWADDRLEN);
+ break;
+
+ case SIOCSIFHWADDR: /* Set hardware address */
+ memcpy(dev->d_mac.addr, req->ifr_hwaddr.sa_data, IFHWADDRLEN);
+ break;
+
+ case SIOCDIFADDR: /* Delete IP address */
+ memset(&dev->d_ipaddr, 0, sizeof(uip_ipaddr_t));
+ break;
+
+ case SIOCGIFCOUNT: /* Get number of devices */
+ req->ifr_count = netdev_count();
+ break;
+
+ case SIOCGIFBRDADDR: /* Get broadcast IP address */
+ case SIOCSIFBRDADDR: /* Set broadcast IP address */
+ err = ENOSYS;
+ goto errout;
+
+ default:
+ err = EINVAL;
+ goto errout;
+ }
+
+ return OK;
+
+errout:
+ *get_errno_ptr() = err;
return ERROR;
}