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:
parent
6fa5d025d2
commit
b185533aba
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
************************************************************/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue