9
0
Fork 0

Add basic structure to support netdevice ioctls

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@344 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2007-09-16 17:46:25 +00:00
parent 6fa5d025d2
commit b185533aba
16 changed files with 831 additions and 172 deletions

View File

@ -190,10 +190,14 @@ void uipdriver_loop(void)
int uipdriver_init(void)
{
/* Internal initalization */
timer_set(&g_periodic_timer, 500);
timer_set(&g_arp_timer, 10000 );
tapdev_init();
uip_init();
/* Register the device with the OS so that socket IOCTLs can be performed */
(void)netdev_register(&g_sim_dev);
return OK;
}

View File

@ -79,13 +79,15 @@
int close(int fd)
{
int err;
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct filelist *list;
FAR struct inode *inode;
int err;
/* Did we get a valid file descriptor? */
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
#endif
{
/* Close a socket descriptor */
@ -101,6 +103,8 @@ int close(int fd)
goto errout;
}
}
#if CONFIG_NFILE_DESCRIPTORS > 0
/* Get the thread-specific file list */
list = sched_getfiles();
@ -154,6 +158,7 @@ int close(int fd)
inode_release(inode);
return OK;
#endif
errout:
*get_errno_ptr() = err;

View File

@ -1,5 +1,5 @@
/************************************************************
* fs_ioctl.c
/****************************************************************************
* fs/fs_ioctl.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@ -31,39 +31,96 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************/
****************************************************************************/
/************************************************************
/****************************************************************************
* Compilation Switches
************************************************************/
****************************************************************************/
/************************************************************
/****************************************************************************
* Included Files
************************************************************/
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h>
#include <errno.h>
#include <sys/ioctl.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
# include <nuttx/net.h>
#endif
#include "fs_internal.h"
/************************************************************
/****************************************************************************
* Global Functions
************************************************************/
****************************************************************************/
/****************************************************************************
* Name: ioctl
*
* Description:
* Perform device specific operations.
*
* Parameters:
* fd Filt/socket descriptor of device
* req The ioctl command
* arg The argument of the ioctl cmd
*
* Return:
* >=0 on success (positive non-zero values are cmd-specific)
* -1 on failure withi errno set properly:
*
* EBADF
* 'fd' is not a valid descriptor.
* EFAULT
* 'arg' references an inaccessible memory area.
* EINVAL
* 'cmd' or 'arg' is not valid.
* ENOTTY
* 'fd' is not associated with a character special device.
* ENOTTY
* The specified request does not apply to the kind of object that the
* descriptor 'fd' references.
*
****************************************************************************/
int ioctl(int fd, int req, unsigned long arg)
{
int err;
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR struct filelist *list;
int ret = EBADF;
int ret = OK;
/* Did we get a valid file descriptor? */
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
#endif
{
/* Perform the socket ioctl */
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
{
return netdev_ioctl(fd, req, (struct ifreq*)arg);
}
else
#endif
{
err = EBADF;
goto errout;
}
}
#if CONFIG_NFILE_DESCRIPTORS > 0
/* Get the thread-specific file list */
list = sched_getfiles();
if (!list)
{
*get_errno_ptr() = EMFILE;
return ERROR;
err = EMFILE;
goto errout;
}
/* Were we give a valid file descriptor? */
@ -76,12 +133,22 @@ int ioctl(int fd, int req, unsigned long arg)
/* Is a driver registered? Does it support the ioctl method? */
if (inode && inode->u.i_ops && inode->u.i_ops->ioctl)
{
/* Yes, then let it perform the ioctl */
{
/* Yes, then let it perform the ioctl */
ret = (int)inode->u.i_ops->ioctl(this_file, req, arg);
}
ret = (int)inode->u.i_ops->ioctl(this_file, req, arg);
if (ret < 0)
{
err = -ret;
goto errout;
}
}
}
return ret;
#endif
errout:
*get_errno_ptr() = err;
return ERROR;
}

104
nuttx/include/net/ioctls.h Normal file
View File

@ -0,0 +1,104 @@
/****************************************************************************
* net/ioctls.h
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __NET_IOCTLS_H
#define __NET_IOCTLS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
/****************************************************************************
* Definitions
****************************************************************************/
/* These are ioctl commands to use with a socket FD. At present, commnads
* are accepted onloy to set/get IP addresses, broadcast address, network
* masks, and hardware address, and a few others
*/
#define _SIOCBASE (0x8900)
#define _SIOCMASK (0x00ff)
#define _SIOCVALID(c) (((c) & ~_SIOCMASK) == _SIOCBASE)
#define SIOCGIFADDR (_SIOCBASE|0x0001) /* Get IP address */
#define SIOCSIFADDR (_SIOCBASE|0x0002) /* Set IP address */
#define SIOCGIFBRDADDR (_SIOCBASE|0x0003) /* Get broadcast IP address */
#define SIOCSIFBRDADDR (_SIOCBASE|0x0004) /* Set broadcast IP address */
#define SIOCGIFNETMASK (_SIOCBASE|0x0005) /* Get network mask */
#define SIOCSIFNETMASK (_SIOCBASE|0x0006) /* Set network mask */
#define SIOCGIFMTU (_SIOCBASE|0x0007) /* Get MTU size */
#define SIOCSIFHWADDR (_SIOCBASE|0x0008) /* Set hardware address */
#define SIOCGIFHWADDR (_SIOCBASE|0x0009) /* Get hardware address */
#define SIOCDIFADDR (_SIOCBASE|0x000a) /* Delete IP address */
#define SIOCGIFCOUNT (_SIOCBASE|0x000b) /* Get number of devices */
/* Sizing parameters */
#define IFNAMSIZ 6
#define IFHWADDRLEN 6
/****************************************************************************
* Type Definitions
****************************************************************************/
struct ifreq
{
char ifr_name[IFNAMSIZ]; /* Network device name (e.g. "eth0") */
union
{
struct sockaddr ifru_addr; /* IP Address */
struct sockaddr ifru_broadaddr; /* Broadcast address */
struct sockaddr ifru_netmask; /* Netmask */
struct sockaddr ifru_hwaddr; /* MAC address */
int ifru_count; /* Number of devices */
int ifru_mtu; /* MTU size */
} ifr_ifru;
};
#define ifr_addr ifr_ifru.ifru_addr /* Address */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* Broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* Interface net mask */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
#define ifr_mtu ifr_ifru.ifru_mtu /* MTU */
#define ifr_count ifr_ifru.ifru_count /* Number of devices */
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __NET_IOCTLS_H */

View File

@ -42,7 +42,9 @@
#ifndef __UIP_ARCH_H
#define __UIP_ARCH_H
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/uip/uip.h>
/****************************************************************************
@ -84,9 +86,22 @@
struct uip_driver_s
{
/* The uIP packet buffer.
*
* The d_buf array is used to hold incoming and outgoing
/* This link is used to maintain a single-linked list of ethernet drivers.
* Must be the first field in the structure due to blink type casting.
*/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
FAR struct uip_driver_s *flink;
/* This is the name of network device assigned when netdev_register was called.
* This name is only used to support socket ioctl lookups by device name
* Examples: "eth0"
*/
char d_ifname[IFNAMSIZ];
#endif
/* The d_buf array is used to hold incoming and outgoing
* packets. The device driver should place incoming data into this
* buffer. When sending data, the device driver should read the link
* level headers and the TCP/IP headers from this buffer. The size of

View File

@ -124,6 +124,9 @@ extern "C" {
#endif
/* net_sockets.c *************************************************************/
/* There interfaces are called only from OS scheduling and iniialization logic
* under sched/
*/
EXTERN void weak_function net_initialize(void);
EXTERN FAR struct socketlist *net_alloclist(void);
@ -131,9 +134,30 @@ EXTERN int net_addreflist(FAR struct socketlist *list);
EXTERN int net_releaselist(FAR struct socketlist *list);
/* net-close.c ***************************************************************/
/* The standard close() operation redirects operations on socket descriptors
* to this function.
*/
EXTERN int net_close(int sockfd);
/* net-ioctl.c ***************************************************************/
/* The standard ioctl() operation redirects operations on socket descriptors
* to this function.
*/
struct ifreq; /* Forward reference -- see net/ioctls.h */
EXTERN int netdev_ioctl(int sockfd, int cmd, struct ifreq *req);
/* net-register.c ************************************************************/
/* This function is called by network interface device drivers to inform the
* socket layer of their existence. This registration is necesary to support
* ioctl() operations on network devices to, for example, set MAC and IP
* addresses
*/
struct uip_driver_s; /* Forward reference. See net/uip/uip-arch.h */
EXTERN int netdev_register(FAR struct uip_driver_s *dev);
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -40,6 +40,16 @@
* Included Files
************************************************************/
/* Get NuttX configuration */
#include <nuttx/config.h>
/* Include network ioctls info */
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
# include <net/ioctls.h>
#endif
/************************************************************
* Type Definitions
************************************************************/

View File

@ -39,24 +39,27 @@ CFLAGS += -I./uip
MKDEP = $(TOPDIR)/tools/mkdeps.sh
ifeq ($(CONFIG_NET),y)
STD_ASRCS =
STD_CSRCS = socket.c bind.c connect.c send.c sendto.c recv.c recvfrom.c \
SOCK_ASRCS =
SOCK_CSRCS = socket.c bind.c connect.c send.c sendto.c recv.c recvfrom.c \
net-sockets.c net-close.c
ifeq ($(CONFIG_NET_SOCKOPTS),y)
STD_CSRCS += setsockopt.c getsockopt.c
SOCK_CSRCS += setsockopt.c getsockopt.c
ifneq ($(CONFIG_DISABLE_CLOCK),y)
STD_CSRCS += net-timeo.c net-dsec2timeval.c net-timeval2dsec.c
SOCK_CSRCS += net-timeo.c net-dsec2timeval.c net-timeval2dsec.c
endif
endif
NETDEV_ASRCS =
NETDEV_CSRCS = netdev-register.c netdev-ioctl.c netdev-find.c
include uip/Make.defs
endif
ASRCS = $(STD_ASRCS) $(UIP_ASRCS)
ASRCS = $(SOCK_ASRCS) $(NETDEV_ASRCS) $(UIP_ASRCS)
AOBJS = $(ASRCS:.S=$(OBJEXT))
CSRCS = $(STD_CSRCS) $(UIP_CSRCS)
CSRCS = $(SOCK_CSRCS) $(NETDEV_CSRCS) $(UIP_CSRCS)
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)

View File

@ -122,6 +122,13 @@
* Public Variables
****************************************************************************/
/* List of registered ethernet device drivers */
#if CONFIG_NSOCKET_DESCRIPTORS > 0
extern struct uip_driver_s *g_netdevices;
extern sem_t g_netdev_sem;
#endif
/****************************************************************************
* Pulblic Function Prototypes
****************************************************************************/
@ -148,6 +155,19 @@ EXTERN socktimeo_t net_timeval2dsec(struct timeval *tv);
EXTERN void net_dsec2timeval(uint16 dsec, struct timeval *tv);
#endif
/* net-register.c ************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN void netdev_semtake(void);
# define netdev_semgive() sem_post(&g_netdev_sem)
#endif
/* net-find.c ****************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
FAR struct uip_driver_s *netdev_find(const char *ifname);
#endif
#undef EXTERN
#if defined(__cplusplus)
}

View File

@ -38,6 +38,7 @@
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_NET
#include <string.h>
#include <semaphore.h>
@ -71,6 +72,7 @@
* Private Functions
****************************************************************************/
#if CONFIG_NSOCKET_DESCRIPTORS > 0
static void _net_semtake(FAR struct socketlist *list)
{
/* Take the semaphore (perhaps waiting) */
@ -85,10 +87,11 @@ static void _net_semtake(FAR struct socketlist *list)
}
}
#define _net_semgive(list) sem_post(&list->sl_sem)
# define _net_semgive(list) sem_post(&list->sl_sem)
#endif
/****************************************************************************
* Pulblic Functions
* Public Functions
****************************************************************************/
/* This is called from the initialization logic to configure the socket layer */
@ -99,9 +102,15 @@ void net_initialize(void)
uip_init();
/* Initialize the socket lay -- nothing to do */
/* Initialize the socket layer */
#if CONFIG_NSOCKET_DESCRIPTORS > 0
sem_init(&g_netdev_sem, 0, 1);
#endif
}
#if CONFIG_NSOCKET_DESCRIPTORS > 0
/* Allocate a list of files for a new task */
FAR struct socketlist *net_alloclist(void)
@ -261,3 +270,6 @@ FAR struct socket *sockfd_socket(int sockfd)
}
return NULL;
}
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
#endif /* CONFIG_NET */

116
nuttx/net/netdev-find.c Normal file
View File

@ -0,0 +1,116 @@
/****************************************************************************
* net/netdev-find.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
#include <sys/types.h>
#include <errno.h>
#include <net/uip/uip-arch.h>
#include "net-internal.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Priviate Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static int g_next_devnum = 0;
/****************************************************************************
* Public Data
****************************************************************************/
/* List of registered ethernet device drivers */
struct uip_driver_s *g_netdevices;
sem_t g_netdev_sem;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
* Function: netdev_find
*
* Description:
* Find a previously registered network device
*
* Parameters:
* ifname The interface name of the device of interest
*
* Returned Value:
* Pointer to driver on success; null on failure
*
* Assumptions:
* Called from normal user mode
*
****************************************************************************/
FAR struct uip_driver_s *netdev_find(const char *ifname)
{
struct uip_driver_s *dev;
if (ifname)
{
netdev_semtake();
for (dev = g_netdevices; dev; dev = dev->flink)
{
if (strcmp(ifname, dev->d_ifname) == 0)
{
netdev_semgive();
return dev;
}
}
netdev_semgive();
}
return NULL;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

90
nuttx/net/netdev-ioctl.c Normal file
View File

@ -0,0 +1,90 @@
/****************************************************************************
* net/netdev-ioctl.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <nuttx/net.h>
#include "net-internal.h"
/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
* Name: netdev_ioctl
*
* Description:
* Perform network device specific operations.
*
* Parameters:
* fd Socket descriptor of device
* cmd The ioctl command
* req The argument of the ioctl cmd
*
* Return:
* >=0 on success (positive non-zero values are cmd-specific)
* -1 on failure withi errno set properly:
*
* EBADF
* 'fd' is not a valid descriptor.
* EFAULT
* 'arg' references an inaccessible memory area.
* EINVAL
* 'cmd' or 'arg' is not valid.
* ENOTTY
* 'fd' is not associated with a character special device.
* ENOTTY
* The specified request does not apply to the kind of object that the
* descriptor 'fd' references.
*
****************************************************************************/
int netdev_ioctl(int sockfd, int cmd, struct ifreq *req)
{
#warning "Network ioctls not implemented"
*get_errno_ptr() = ENOSYS;
return ERROR;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

147
nuttx/net/netdev-register.c Normal file
View File

@ -0,0 +1,147 @@
/****************************************************************************
* net/netdev-register.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <semaphore.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <net/uip/uip-arch.h>
#include "net-internal.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Priviate Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static int g_next_devnum = 0;
/****************************************************************************
* Public Data
****************************************************************************/
/* List of registered ethernet device drivers */
struct uip_driver_s *g_netdevices = NULL;
sem_t g_netdev_sem;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Global Functions
****************************************************************************/
/****************************************************************************
* Function: netdev_semtake
*
* Description:
* Managed access to the network device list
*
****************************************************************************/
void netdev_semtake(void)
{
/* Take the semaphore (perhaps waiting) */
while (sem_wait(&g_netdev_sem) != 0)
{
/* The only case that an error should occr here is if
* the wait was awakened by a signal.
*/
ASSERT(*get_errno_ptr() == EINTR);
}
}
/****************************************************************************
* Function: netdev_register
*
* Description:
* Register a netword device driver and assign a name to it so tht it can
* be found in subsequent network ioctl operations on the device.
*
* Parameters:
* dev - The device driver structure to register
*
* Returned Value:
* 0:Success; -1 on failure
*
* Assumptions:
* Called during system initialization from normal user mode
*
****************************************************************************/
int netdev_register(FAR struct uip_driver_s *dev)
{
if (dev)
{
int devnum;
netdev_semtake();
/* Assign a device name to the the interface */
devnum = g_next_devnum++;
snprintf( dev->d_ifname, IFNAMSIZ, "eth%d", devnum );
/* Add the device to the list of known network devices */
dev->flink = g_netdevices;
g_netdevices = dev;
netdev_semgive();
return OK;
}
return ERROR;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

View File

@ -102,9 +102,10 @@ static uint8 tmpage;
void uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4);
}
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
memset(arp_table[i].ipaddr, 0, 4);
}
}
/* Periodic ARP processing function.
@ -119,73 +120,87 @@ void uip_arp_timer(void)
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(tabptr->ipaddr, 0, 4);
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if ((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && arptime - tabptr->time >= UIP_ARP_MAXAGE)
{
memset(tabptr->ipaddr, 0, 4);
}
}
}
}
static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr;
struct arp_entry *tabptr;
/* Walk through the ARP mapping table and try to find an entry to
update. If none is found, the IP -> MAC address mapping is
inserted in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
* update. If none is found, the IP -> MAC address mapping is
* inserted in the ARP table.
*/
tabptr = &arp_table[i];
/* Only check those entries that are actually in use. */
if(tabptr->ipaddr[0] != 0 &&
tabptr->ipaddr[1] != 0) {
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if(pipaddr[0] == tabptr->ipaddr[0] &&
pipaddr[1] == tabptr->ipaddr[1]) {
/* Only check those entries that are actually in use. */
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
if (tabptr->ipaddr[0] != 0 && tabptr->ipaddr[1] != 0)
{
/* Check if the source IP address of the incoming packet matches
* the IP address in this ARP table entry.
*/
return;
}
if (pipaddr[0] == tabptr->ipaddr[0] && pipaddr[1] == tabptr->ipaddr[1])
{
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
return;
}
}
}
}
/* If we get here, no existing ARP table entry was found, so we
create one. */
/* First, we try to find an unused entry in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] == 0 &&
tabptr->ipaddr[1] == 0) {
break;
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (tabptr->ipaddr[0] == 0 && tabptr->ipaddr[1] == 0)
{
break;
}
}
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. */
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
* throw it away.
*/
if (i == UIP_ARPTAB_SIZE)
{
tmpage = 0;
c = 0;
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (arptime - tabptr->time > tmpage)
{
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
* information.
*/
memcpy(tabptr->ipaddr, pipaddr, 4);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
@ -210,17 +225,16 @@ void uip_arp_ipin(void)
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
if ((IPBUF->srcipaddr[0] & uip_netmask[0]) != (uip_hostaddr[0] & uip_netmask[0]))
{
return;
}
return;
if ((IPBUF->srcipaddr[1] & uip_netmask[1]) != (uip_hostaddr[1] & uip_netmask[1]))
{
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
}
#endif /* 0 */
@ -247,49 +261,57 @@ void uip_arp_ipin(void)
void uip_arp_arpin(struct uip_driver_s *dev)
{
if(dev->d_len < sizeof(struct arp_hdr)) {
dev->d_len = 0;
return;
}
if (dev->d_len < sizeof(struct arp_hdr))
{
dev->d_len = 0;
return;
}
dev->d_len = 0;
switch(BUF->opcode) {
case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a
reply. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
/* First, we register the one who made the request in our ARP
table, since it is likely that we will do more communication
with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
switch(BUF->opcode)
{
case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a reply. */
/* The reply opcode is 2. */
BUF->opcode = HTONS(2);
if (uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr))
{
/* First, we register the one who made the request in our ARP
* table, since it is likely that we will do more communication
* with this host in the future.
*/
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
/* The reply opcode is 2. */
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
dev->d_len = sizeof(struct arp_hdr);
BUF->opcode = HTONS(2);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
dev->d_len = sizeof(struct arp_hdr);
}
break;
case HTONS(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
* for us.
*/
if (uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr))
{
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
break;
case HTONS(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
for us. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/* Prepend Ethernet header to an outbound IP packet and see if we need
@ -329,54 +351,70 @@ void uip_arp_out(struct uip_driver_s *dev)
packet with an ARP request for the IP address. */
/* First check if destination is a local broadcast. */
if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else {
/* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
/* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination
address when determining the MAC address. */
uip_ipaddr_copy(ipaddr, uip_draddr);
} else {
/* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
if (uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr))
{
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
}
else
{
/* Check if the destination address is on the local network. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
break;
}
if (!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask))
{
/* Destination address was not on the local network, so we need to
* use the default router's IP address instead of the destination
* address when determining the MAC address.
*/
uip_ipaddr_copy(ipaddr, uip_draddr);
}
else
{
/* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
}
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (uip_ipaddr_cmp(ipaddr, tabptr->ipaddr))
{
break;
}
}
if (i == UIP_ARPTAB_SIZE)
{
/* The destination address was not in our ARP table, so we
* overwrite the IP packet with an ARP request.
*/
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
dev->d_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
if(i == UIP_ARPTAB_SIZE) {
/* The destination address was not in our ARP table, so we
overwrite the IP packet with an ARP request. */
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
dev->d_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);

View File

@ -41,6 +41,8 @@
* Included Files
****************************************************************************/
#include <string.h>
#include <net/uip/uip.h>
#include <net/uip/uip-arch.h>

View File

@ -139,8 +139,10 @@ extern void uip_log(char *msg);
****************************************************************************/
/* The IP address of this host. If it is defined to be fixed (by
setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
here. Otherwise, the address */
* setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
* here.
*/
#if UIP_FIXEDADDR > 0
const uip_ipaddr_t uip_hostaddr =
{HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
@ -1625,7 +1627,7 @@ tcp_send_synack:
{
uip_urglen = 0;
#else /* UIP_URGDATA > 0 */
dev->d_appdata = ((char *)dev->d_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
dev->d_appdata = ((uint8*)dev->d_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
dev->d_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
#endif /* UIP_URGDATA > 0 */
}