mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
Add basic structure to support netdevice ioctls
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@344 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -190,10 +190,14 @@ void uipdriver_loop(void)
|
|||||||
|
|
||||||
int uipdriver_init(void)
|
int uipdriver_init(void)
|
||||||
{
|
{
|
||||||
|
/* Internal initalization */
|
||||||
|
|
||||||
timer_set(&g_periodic_timer, 500);
|
timer_set(&g_periodic_timer, 500);
|
||||||
timer_set(&g_arp_timer, 10000 );
|
timer_set(&g_arp_timer, 10000 );
|
||||||
|
|
||||||
tapdev_init();
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -79,13 +79,15 @@
|
|||||||
|
|
||||||
int close(int fd)
|
int close(int fd)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
FAR struct filelist *list;
|
FAR struct filelist *list;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Did we get a valid file descriptor? */
|
/* Did we get a valid file descriptor? */
|
||||||
|
|
||||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Close a socket descriptor */
|
/* Close a socket descriptor */
|
||||||
|
|
||||||
@@ -101,6 +103,8 @@ int close(int fd)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
/* Get the thread-specific file list */
|
/* Get the thread-specific file list */
|
||||||
|
|
||||||
list = sched_getfiles();
|
list = sched_getfiles();
|
||||||
@@ -154,6 +158,7 @@ int close(int fd)
|
|||||||
inode_release(inode);
|
inode_release(inode);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
#endif
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
*get_errno_ptr() = err;
|
*get_errno_ptr() = err;
|
||||||
|
|||||||
+83
-16
@@ -1,5 +1,5 @@
|
|||||||
/************************************************************
|
/****************************************************************************
|
||||||
* fs_ioctl.c
|
* fs/fs_ioctl.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* 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
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/************************************************************
|
/****************************************************************************
|
||||||
* Compilation Switches
|
* Compilation Switches
|
||||||
************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/************************************************************
|
/****************************************************************************
|
||||||
* Included Files
|
* Included Files
|
||||||
************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
|
# include <nuttx/net.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fs_internal.h"
|
#include "fs_internal.h"
|
||||||
|
|
||||||
/************************************************************
|
/****************************************************************************
|
||||||
* Global Functions
|
* 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 ioctl(int fd, int req, unsigned long arg)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
FAR struct filelist *list;
|
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 */
|
/* Get the thread-specific file list */
|
||||||
|
|
||||||
list = sched_getfiles();
|
list = sched_getfiles();
|
||||||
if (!list)
|
if (!list)
|
||||||
{
|
{
|
||||||
*get_errno_ptr() = EMFILE;
|
err = EMFILE;
|
||||||
return ERROR;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Were we give a valid file descriptor? */
|
/* 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? */
|
/* Is a driver registered? Does it support the ioctl method? */
|
||||||
|
|
||||||
if (inode && inode->u.i_ops && inode->u.i_ops->ioctl)
|
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;
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
errout:
|
||||||
|
*get_errno_ptr() = err;
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
@@ -42,7 +42,9 @@
|
|||||||
#ifndef __UIP_ARCH_H
|
#ifndef __UIP_ARCH_H
|
||||||
#define __UIP_ARCH_H
|
#define __UIP_ARCH_H
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <net/uip/uip.h>
|
#include <net/uip/uip.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -84,9 +86,22 @@
|
|||||||
|
|
||||||
struct uip_driver_s
|
struct uip_driver_s
|
||||||
{
|
{
|
||||||
/* The uIP packet buffer.
|
/* 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.
|
||||||
* The d_buf array is used to hold incoming and outgoing
|
*/
|
||||||
|
|
||||||
|
#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
|
* packets. The device driver should place incoming data into this
|
||||||
* buffer. When sending data, the device driver should read the link
|
* buffer. When sending data, the device driver should read the link
|
||||||
* level headers and the TCP/IP headers from this buffer. The size of
|
* level headers and the TCP/IP headers from this buffer. The size of
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* net_sockets.c *************************************************************/
|
/* net_sockets.c *************************************************************/
|
||||||
|
/* There interfaces are called only from OS scheduling and iniialization logic
|
||||||
|
* under sched/
|
||||||
|
*/
|
||||||
|
|
||||||
EXTERN void weak_function net_initialize(void);
|
EXTERN void weak_function net_initialize(void);
|
||||||
EXTERN FAR struct socketlist *net_alloclist(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);
|
EXTERN int net_releaselist(FAR struct socketlist *list);
|
||||||
|
|
||||||
/* net-close.c ***************************************************************/
|
/* net-close.c ***************************************************************/
|
||||||
|
/* The standard close() operation redirects operations on socket descriptors
|
||||||
|
* to this function.
|
||||||
|
*/
|
||||||
|
|
||||||
EXTERN int net_close(int sockfd);
|
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
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,16 @@
|
|||||||
* Included Files
|
* 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
|
* Type Definitions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|||||||
+9
-6
@@ -39,24 +39,27 @@ CFLAGS += -I./uip
|
|||||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET),y)
|
ifeq ($(CONFIG_NET),y)
|
||||||
STD_ASRCS =
|
SOCK_ASRCS =
|
||||||
STD_CSRCS = socket.c bind.c connect.c send.c sendto.c recv.c recvfrom.c \
|
SOCK_CSRCS = socket.c bind.c connect.c send.c sendto.c recv.c recvfrom.c \
|
||||||
net-sockets.c net-close.c
|
net-sockets.c net-close.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET_SOCKOPTS),y)
|
ifeq ($(CONFIG_NET_SOCKOPTS),y)
|
||||||
STD_CSRCS += setsockopt.c getsockopt.c
|
SOCK_CSRCS += setsockopt.c getsockopt.c
|
||||||
ifneq ($(CONFIG_DISABLE_CLOCK),y)
|
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
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
NETDEV_ASRCS =
|
||||||
|
NETDEV_CSRCS = netdev-register.c netdev-ioctl.c netdev-find.c
|
||||||
|
|
||||||
include uip/Make.defs
|
include uip/Make.defs
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ASRCS = $(STD_ASRCS) $(UIP_ASRCS)
|
ASRCS = $(SOCK_ASRCS) $(NETDEV_ASRCS) $(UIP_ASRCS)
|
||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
|
|
||||||
CSRCS = $(STD_CSRCS) $(UIP_CSRCS)
|
CSRCS = $(SOCK_CSRCS) $(NETDEV_CSRCS) $(UIP_CSRCS)
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
|
|
||||||
SRCS = $(ASRCS) $(CSRCS)
|
SRCS = $(ASRCS) $(CSRCS)
|
||||||
|
|||||||
@@ -122,6 +122,13 @@
|
|||||||
* Public Variables
|
* 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
|
* Pulblic Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -148,6 +155,19 @@ EXTERN socktimeo_t net_timeval2dsec(struct timeval *tv);
|
|||||||
EXTERN void net_dsec2timeval(uint16 dsec, struct timeval *tv);
|
EXTERN void net_dsec2timeval(uint16 dsec, struct timeval *tv);
|
||||||
#endif
|
#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
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -38,6 +38,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
#ifdef CONFIG_NET
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
@@ -71,6 +72,7 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
static void _net_semtake(FAR struct socketlist *list)
|
static void _net_semtake(FAR struct socketlist *list)
|
||||||
{
|
{
|
||||||
/* Take the semaphore (perhaps waiting) */
|
/* 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 */
|
/* This is called from the initialization logic to configure the socket layer */
|
||||||
@@ -99,9 +102,15 @@ void net_initialize(void)
|
|||||||
|
|
||||||
uip_init();
|
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 */
|
/* Allocate a list of files for a new task */
|
||||||
|
|
||||||
FAR struct socketlist *net_alloclist(void)
|
FAR struct socketlist *net_alloclist(void)
|
||||||
@@ -261,3 +270,6 @@ FAR struct socket *sockfd_socket(int sockfd)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
|
||||||
|
#endif /* CONFIG_NET */
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
+176
-138
@@ -102,9 +102,10 @@ static uint8 tmpage;
|
|||||||
|
|
||||||
void uip_arp_init(void)
|
void uip_arp_init(void)
|
||||||
{
|
{
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
|
||||||
memset(arp_table[i].ipaddr, 0, 4);
|
{
|
||||||
}
|
memset(arp_table[i].ipaddr, 0, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Periodic ARP processing function.
|
/* Periodic ARP processing function.
|
||||||
@@ -119,73 +120,87 @@ void uip_arp_timer(void)
|
|||||||
struct arp_entry *tabptr;
|
struct arp_entry *tabptr;
|
||||||
|
|
||||||
++arptime;
|
++arptime;
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
|
||||||
tabptr = &arp_table[i];
|
{
|
||||||
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
|
tabptr = &arp_table[i];
|
||||||
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
|
if ((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && arptime - tabptr->time >= UIP_ARP_MAXAGE)
|
||||||
memset(tabptr->ipaddr, 0, 4);
|
{
|
||||||
|
memset(tabptr->ipaddr, 0, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
|
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
|
/* Walk through the ARP mapping table and try to find an entry to
|
||||||
update. If none is found, the IP -> MAC address mapping is
|
* update. If none is found, the IP -> MAC address mapping is
|
||||||
inserted in the ARP table. */
|
* inserted in the ARP table.
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
*/
|
||||||
|
|
||||||
tabptr = &arp_table[i];
|
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
|
||||||
/* Only check those entries that are actually in use. */
|
{
|
||||||
if(tabptr->ipaddr[0] != 0 &&
|
tabptr = &arp_table[i];
|
||||||
tabptr->ipaddr[1] != 0) {
|
|
||||||
|
|
||||||
/* Check if the source IP address of the incoming packet matches
|
/* Only check those entries that are actually in use. */
|
||||||
the IP address in this ARP table entry. */
|
|
||||||
if(pipaddr[0] == tabptr->ipaddr[0] &&
|
|
||||||
pipaddr[1] == tabptr->ipaddr[1]) {
|
|
||||||
|
|
||||||
/* An old entry found, update this and return. */
|
if (tabptr->ipaddr[0] != 0 && tabptr->ipaddr[1] != 0)
|
||||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
{
|
||||||
tabptr->time = arptime;
|
/* 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
|
/* If we get here, no existing ARP table entry was found, so we
|
||||||
create one. */
|
create one. */
|
||||||
|
|
||||||
/* First, we try to find an unused entry in the ARP table. */
|
/* First, we try to find an unused entry in the ARP table. */
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
tabptr = &arp_table[i];
|
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
|
||||||
if(tabptr->ipaddr[0] == 0 &&
|
{
|
||||||
tabptr->ipaddr[1] == 0) {
|
tabptr = &arp_table[i];
|
||||||
break;
|
if (tabptr->ipaddr[0] == 0 && tabptr->ipaddr[1] == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If no unused entry is found, we try to find the oldest entry and
|
/* If no unused entry is found, we try to find the oldest entry and
|
||||||
throw it away. */
|
* throw it away.
|
||||||
if(i == UIP_ARPTAB_SIZE) {
|
*/
|
||||||
tmpage = 0;
|
|
||||||
c = 0;
|
if (i == UIP_ARPTAB_SIZE)
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
{
|
||||||
|
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];
|
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
|
/* Now, i is the ARP table entry which we will fill with the new
|
||||||
information. */
|
* information.
|
||||||
|
*/
|
||||||
|
|
||||||
memcpy(tabptr->ipaddr, pipaddr, 4);
|
memcpy(tabptr->ipaddr, pipaddr, 4);
|
||||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||||
tabptr->time = arptime;
|
tabptr->time = arptime;
|
||||||
@@ -210,17 +225,16 @@ void uip_arp_ipin(void)
|
|||||||
|
|
||||||
/* Only insert/update an entry if the source IP address of the
|
/* Only insert/update an entry if the source IP address of the
|
||||||
incoming IP packet comes from a host on the local network. */
|
incoming IP packet comes from a host on the local network. */
|
||||||
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
if ((IPBUF->srcipaddr[0] & uip_netmask[0]) != (uip_hostaddr[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));
|
|
||||||
|
|
||||||
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 */
|
#endif /* 0 */
|
||||||
|
|
||||||
@@ -247,49 +261,57 @@ void uip_arp_ipin(void)
|
|||||||
|
|
||||||
void uip_arp_arpin(struct uip_driver_s *dev)
|
void uip_arp_arpin(struct uip_driver_s *dev)
|
||||||
{
|
{
|
||||||
if(dev->d_len < sizeof(struct arp_hdr)) {
|
if (dev->d_len < sizeof(struct arp_hdr))
|
||||||
dev->d_len = 0;
|
{
|
||||||
return;
|
dev->d_len = 0;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
dev->d_len = 0;
|
dev->d_len = 0;
|
||||||
|
|
||||||
switch(BUF->opcode) {
|
switch(BUF->opcode)
|
||||||
case HTONS(ARP_REQUEST):
|
{
|
||||||
/* ARP request. If it asked for our address, we send out a
|
case HTONS(ARP_REQUEST):
|
||||||
reply. */
|
/* 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);
|
|
||||||
|
|
||||||
/* The reply opcode is 2. */
|
if (uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr))
|
||||||
BUF->opcode = HTONS(2);
|
{
|
||||||
|
/* 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);
|
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
||||||
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];
|
/* The reply opcode is 2. */
|
||||||
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);
|
BUF->opcode = HTONS(2);
|
||||||
dev->d_len = sizeof(struct arp_hdr);
|
|
||||||
|
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
|
/* 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. */
|
packet with an ARP request for the IP address. */
|
||||||
|
|
||||||
/* First check if destination is a local broadcast. */
|
/* 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);
|
if (uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr))
|
||||||
} else {
|
{
|
||||||
/* Check if the destination address is on the local network. */
|
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if the destination address is on the local network. */
|
||||||
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
if (!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask))
|
||||||
tabptr = &arp_table[i];
|
{
|
||||||
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
|
/* Destination address was not on the local network, so we need to
|
||||||
break;
|
* 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);
|
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||||
|
|
||||||
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <net/uip/uip.h>
|
#include <net/uip/uip.h>
|
||||||
#include <net/uip/uip-arch.h>
|
#include <net/uip/uip-arch.h>
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -139,8 +139,10 @@ extern void uip_log(char *msg);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* The IP address of this host. If it is defined to be fixed (by
|
/* 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
|
* setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
|
||||||
here. Otherwise, the address */
|
* here.
|
||||||
|
*/
|
||||||
|
|
||||||
#if UIP_FIXEDADDR > 0
|
#if UIP_FIXEDADDR > 0
|
||||||
const uip_ipaddr_t uip_hostaddr =
|
const uip_ipaddr_t uip_hostaddr =
|
||||||
{HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
|
{HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
|
||||||
@@ -1625,7 +1627,7 @@ tcp_send_synack:
|
|||||||
{
|
{
|
||||||
uip_urglen = 0;
|
uip_urglen = 0;
|
||||||
#else /* UIP_URGDATA > 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];
|
dev->d_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||||
#endif /* UIP_URGDATA > 0 */
|
#endif /* UIP_URGDATA > 0 */
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user