From 5857da3fa8f88d7028d80fe270d03e779706e533 Mon Sep 17 00:00:00 2001 From: Vijay Kumar Banerjee Date: Mon, 14 Jun 2021 18:42:56 -0600 Subject: lwip: Add bbb and tms570 drivers + Add networking01 and telnetd01 tests --- rtemslwip/beaglebone/lwipopts.h | 276 +++++++ rtemslwip/common/rtems_lwip_io.c | 1323 ++++++++++++++++++++++++++++++ rtemslwip/common/rtems_lwip_sysdefs.c | 185 +++++ rtemslwip/common/syslog.c | 89 ++ rtemslwip/include/rtems_lwip_int.h | 92 +++ rtemslwip/include/sys/sysctl.h | 1 + rtemslwip/test/buffer_test_io.h | 21 + rtemslwip/test/networking01/sample_app.c | 159 ++++ rtemslwip/test/telnetd01/init.c | 149 ++++ rtemslwip/test/telnetd01/telnetd01.doc | 24 + rtemslwip/test/telnetd01/telnetd01.scn | 11 + rtemslwip/test/tmacros.h | 283 +++++++ 12 files changed, 2613 insertions(+) create mode 100644 rtemslwip/beaglebone/lwipopts.h create mode 100644 rtemslwip/common/rtems_lwip_io.c create mode 100644 rtemslwip/common/rtems_lwip_sysdefs.c create mode 100644 rtemslwip/common/syslog.c create mode 100644 rtemslwip/include/rtems_lwip_int.h create mode 100644 rtemslwip/include/sys/sysctl.h create mode 100644 rtemslwip/test/buffer_test_io.h create mode 100644 rtemslwip/test/networking01/sample_app.c create mode 100644 rtemslwip/test/telnetd01/init.c create mode 100644 rtemslwip/test/telnetd01/telnetd01.doc create mode 100644 rtemslwip/test/telnetd01/telnetd01.scn create mode 100644 rtemslwip/test/tmacros.h (limited to 'rtemslwip') diff --git a/rtemslwip/beaglebone/lwipopts.h b/rtemslwip/beaglebone/lwipopts.h new file mode 100644 index 0000000..888fae4 --- /dev/null +++ b/rtemslwip/beaglebone/lwipopts.h @@ -0,0 +1,276 @@ +#if 0 +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_LWIPOPTS_H__ +#define LWIP_HDR_LWIPOPTS_H__ + +/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ +#define NO_SYS 0 +#define LWIP_NETCONN 1 +#define LWIP_SOCKET 1 +#define LWIP_DNS 1 + +#define LWIP_IPV6 1 +#define LWIP_IPV4 1 + +#define LWIP_ETHERNET 1 +#define LWIP_NETIF_API 1 +#define LWIP_AUTOIP 1 +/* Enable DHCP to test it, disable UDP checksum to easier inject packets */ +#define LWIP_DHCP 1 +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +//#define LWIP_COMPAT_SOCKETS 2 +#ifndef FIONREAD +#define FIONREAD 1 +#endif +#ifndef FIONBIO +#define FIONBIO 1 +#endif +#define THREAD_STACK_SIZE 4096 + +#define LWIP_TIMERS 1 +/* Minimal changes to opt.h required for tcp unit tests: */ + +#define MEM_SIZE 16000 +#define TCP_SND_QUEUELEN 40 +#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN +#define TCP_SND_BUF (12 * TCP_MSS) +#define TCP_WND (10 * TCP_MSS) +#define LWIP_WND_SCALE 1 +#define TCP_RCV_SCALE 0 +#define PBUF_POOL_SIZE 400 // pbuf tests need ~200KByte + +/* Minimal changes to opt.h required for etharp unit tests: */ +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#endif /* LWIP_HDR_LWIPOPTS_H__ */ + +#endif /* 0 */ + +/** + * \file lwipopts.h - Configuration options for lwIP + * + * Copyright (c) 2010 Texas Instruments Incorporated + */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +/***************************************************************************** +** CONFIGURATIONS +*****************************************************************************/ + +/* +** The macro CPSW_DUAL_MAC_MODE shall be defined for using CPSW ports in +** Dual MAC mode. +*/ +#define CPSW_DUAL_MAC_MODE + +/* +** The below macro should be defined for using lwIP with cache. For cache +** enabling, pbuf pool shall be cache line aligned. This is done by using +** separate pool for each memory. The alignment of pbuf pool to cache line +** size is done in /ports/cpsw/include/arch/cc.h. +*/ +/*#define LWIP_CACHE_ENABLED*/ + +#define SOC_CACHELINE_SIZE_BYTES 64 /* Number of bytes in + a cache line */ +/* +** The timeout for DHCP completion. lwIP library will wait for DHCP +** completion for (LWIP_DHCP_TIMEOUT / 100) seconds. +*/ +#define LWIP_DHCP_TIMEOUT 1000 + +/* +** The number of times DHCP is attempted. Each time, the library will wait +** for (LWIP_DHCP_TIMEOUT / 100) seconds for DHCP completion. +*/ +#define NUM_DHCP_TRIES 5 + +#define LWIP_ETHERNET 1 +#define LWIP_ARP 1 +#define LWIP_DNS 1 + +/***************************************************************************** +** lwIP SPECIFIC DEFINITIONS - To be used by lwIP stack +*****************************************************************************/ +#define HOST_TMR_INTERVAL 0 +#define DYNAMIC_HTTP_HEADERS + +/***************************************************************************** +** Platform specific locking +*****************************************************************************/ +#define SYS_LIGHTWEIGHT_PROT 1 +#define NO_SYS 0 +#define NO_SYS_NO_TIMERS 0 + +/***************************************************************************** +** Memory Options +*****************************************************************************/ +#define MEM_ALIGNMENT 4 +#define MEM_SIZE (1024 * 1024) /* 4K */ + +#define MEMP_NUM_PBUF 96 +#define MEMP_NUM_TCP_PCB 32 +#define MEMP_NUM_TCP_SEG 32 +#define PBUF_POOL_SIZE 512 +#define MEMP_MEM_MALLOC 1 +#define MEMP_MEM_INIT 1 +#define MEMP_OVERFLOW_CHECK 0 + +#ifdef LWIP_CACHE_ENABLED +#define MEMP_SEPARATE_POOLS 1 /* We want the pbuf + pool cache line + aligned*/ +#endif + +//#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT) + +/***************************************************************************** +** IP Options +*****************************************************************************/ +#define IP_REASSEMBLY 0 +#define IP_FRAG 0 +#define LWIP_IPV4 1 +#define LWIP_IPV6 1 + +/***************************************************************************** +** DHCP Options +*****************************************************************************/ +#define LWIP_DHCP 1 +#define DHCP_DOES_ARP_CHECK 0 + +/***************************************************************************** +** Auto IP Options +*****************************************************************************/ +#define LWIP_AUTOIP 1 +#define LWIP_DHCP_AUTOIP_COOP ((LWIP_DHCP) && (LWIP_AUTOIP)) + +/***************************************************************************** +** TCP Options +*****************************************************************************/ +#define TCP_MSS 1500 +#define TCP_WND (8 * TCP_MSS) +#define TCP_SND_BUF (8 * TCP_MSS) +#define TCP_OVERSIZE TCP_MSS +#define LWIP_TCPIP_CORE_LOCKING 1 + +/***************************************************************************** +** PBUF Options +*****************************************************************************/ +#define PBUF_LINK_HLEN 14 +#define PBUF_POOL_BUFSIZE 1520 /* + size of struct pbuf + shall be cache line + aligned be enabled */ +#define ETH_PAD_SIZE 0 +#define LWIP_NETCONN 1 + +/***************************************************************************** +** Socket Options +*****************************************************************************/ +#define LWIP_SOCKET 1 +#define SO_REUSE 1 + +/***************************************************************************** +** Debugging options +*****************************************************************************/ +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF +#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON | LWIP_DBG_TRACE \ + |LWIP_DBG_STATE | LWIP_DBG_FRESH) +#define DHCP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define APP_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define LWIP_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define LWIP_STATS_POSIX 0 +#define LWIP_DNS_API_DEFINE_ERRORS 1 + + + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#define LWIP_COMPAT_SOCKETS 1 + + #define LWIP_TIMEVAL_PRIVATE 0 + + #define LWIP_RAW 0 + +#define tskIDLE_PRIORITY RTEMS_MAXIMUM_PRIORITY +#define portTICK_RATE_MS (rtems_clock_get_ticks_per_second() * 1000) +#define vTaskDelay(x) sys_arch_delay(x) + +#endif /* __LWIPOPTS_H__ */ diff --git a/rtemslwip/common/rtems_lwip_io.c b/rtemslwip/common/rtems_lwip_io.c new file mode 100644 index 0000000..8aa28b5 --- /dev/null +++ b/rtemslwip/common/rtems_lwip_io.c @@ -0,0 +1,1323 @@ +/* + * + * RTEMS Project (https://www.rtems.org/) + * + * Copyright (c) 2021 Vijay Kumar Banerjee . + * All rights reserved. + * + * 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. + * + * 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define LWIP_COMPAT_SOCKETS 0 + +#include +#include +/* #include */ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "lwip/err.h" +#include "lwip/tcp.h" +#include + +#include + +#include "lwip/tcpip.h" +//#include "arch/eth_lwip.h" +#include "lwip/api.h" +#include "lwip/netbuf.h" +#include "lwip/netdb.h" +#include "lwip/netifapi.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" + +#include "rtems_lwip_int.h" + +static const rtems_filesystem_file_handlers_r rtems_lwip_socket_handlers; + +static rtems_recursive_mutex rtems_lwip_mutex = + RTEMS_RECURSIVE_MUTEX_INITIALIZER( "_LWIP" ); + +void rtems_lwip_semaphore_obtain( void ) +{ + rtems_recursive_mutex_lock( &rtems_lwip_mutex ); +} + +/* + * Release network mutex + */ +void rtems_lwip_semaphore_release( void ) +{ + rtems_recursive_mutex_unlock( &rtems_lwip_mutex ); +} + +static inline int rtems_lwip_iop_to_lwipfd( rtems_libio_t *iop ) +{ + if ( iop == NULL ) { + errno = EBADF; + + return -1; + } + +/* + if ((rtems_libio_iop_flags(iop) & LIBIO_FLAGS_OPEN) == 0) { + errno = EBADF; + return -1; + } + */ + + if ( iop->pathinfo.handlers != &rtems_lwip_socket_handlers ) { + errno = ENOTSOCK; + + return -1; + } + + return iop->data0; +} + +/* + * Convert an RTEMS file descriptor to a LWIP socket pointer. + */ +int rtems_lwip_sysfd_to_lwipfd( int fd ) +{ + if ( (uint32_t) fd >= rtems_libio_number_iops ) { + errno = EBADF; + + return -1; + } + + return rtems_lwip_iop_to_lwipfd( rtems_libio_iop( fd ) ); +} + +/* + * Create an RTEMS file descriptor for a socket + */ +static int rtems_lwip_make_sysfd_from_lwipfd( int lfwipfd ) +{ + rtems_libio_t *iop; + int fd; + + iop = rtems_libio_allocate(); + + if ( iop == 0 ) + rtems_set_errno_and_return_minus_one( ENFILE ); + + fd = rtems_libio_iop_to_descriptor( iop ); + iop->data0 = lfwipfd; + iop->data1 = NULL; + iop->pathinfo.handlers = &rtems_lwip_socket_handlers; + iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; + rtems_filesystem_location_add_to_mt_entry( &iop->pathinfo ); + rtems_libio_iop_flags_set( iop, LIBIO_FLAGS_READ_WRITE | LIBIO_FLAGS_OPEN ); + + return fd; +} + +/* + ********************************************************************* + * BSD-style entry points * + ********************************************************************* + */ +int socket( + int domain, + int type, + int protocol +) +{ + int fd; + int lwipfd; + + if ( domain == rtems_lwip_sysdefs_PF_UNSPEC ) { + domain = PF_UNSPEC; + } else if ( domain == rtems_lwip_sysdefs_PF_INET ) { + domain = PF_INET; + } else if ( domain == rtems_lwip_sysdefs_PF_INET6 ) { + domain = PF_INET6; + } else { + errno = EINVAL; + + return -1; + } + + if ( type == rtems_lwip_sysdefs_SOCK_STREAM ) { + type = SOCK_STREAM; + } else if ( type == rtems_lwip_sysdefs_SOCK_DGRAM ) { + type = SOCK_DGRAM; + } else { + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + + lwipfd = lwip_socket( domain, type, 0 ); + + if ( lwipfd < 0 ) { + fd = -1; + } else { + fd = rtems_lwip_make_sysfd_from_lwipfd( lwipfd ); + + if ( fd < 0 ) { + lwip_close( lwipfd ); + } + } + + rtems_lwip_semaphore_release(); + + return fd; +} + +int bind( + int s, + const struct sockaddr *name, + socklen_t namelen +) +{ + int ret = -1; + int lwipfd; + int family; + struct sockaddr *lwipname; + socklen_t lwipnamelen; + struct sockaddr_in so_in; + + #if LWIP_IPV6 + struct sockaddr_in6 so_in6; + #endif + + family = rtems_lwip_sysdefs_sockaddr_get_family( name ); + + if ( ( family == rtems_lwip_sysdefs_AF_INET ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in_size ) ) { + so_in.sin_len = sizeof( so_in ); + so_in.sin_family = PF_INET; + so_in.sin_port = rtems_lwip_sysdefs_sockaddr_in_get_sin_port( name ); + so_in.sin_addr.s_addr = + rtems_lwip_sysdefs_sockaddr_in_get_sin_addr( name ); + lwipname = (struct sockaddr *) &so_in; + lwipnamelen = so_in.sin_len; + #if LWIP_IPV6 + } else if ( ( family == rtems_lwip_sysdefs_AF_INET6 ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in6_size ) ) { + so_in6.sin6_len = sizeof( so_in6 ); + so_in6.sin6_family = PF_INET6; + so_in6.sin6_port = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_port( name ); + memcpy( &so_in6.sin6_addr, + rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr_const( name ), + sizeof( so_in6.sin6_addr ) ); + so_in6.sin6_flowinfo = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_flowinfo( + name ); + so_in6.sin6_scope_id = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_scope_id( + name ); + lwipname = (struct sockaddr *) &so_in6; + lwipnamelen = so_in6.sin6_len; + #endif + } else { + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + ret = lwip_bind( lwipfd, lwipname, lwipnamelen ); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +int connect( + int s, + const struct sockaddr *name, + socklen_t namelen +) +{ + int ret = -1; + int lwipfd; + int family; + struct sockaddr *lwipname; + socklen_t lwipnamelen; + struct sockaddr_in so_in; + + #if LWIP_IPV6 + struct sockaddr_in6 so_in6; + #endif + + family = rtems_lwip_sysdefs_sockaddr_get_family( name ); + + if ( ( family == rtems_lwip_sysdefs_AF_INET ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in_size ) ) { + so_in.sin_len = sizeof( so_in ); + so_in.sin_family = AF_INET; + so_in.sin_port = rtems_lwip_sysdefs_sockaddr_in_get_sin_port( name ); + so_in.sin_addr.s_addr = + rtems_lwip_sysdefs_sockaddr_in_get_sin_addr( name ); + lwipname = (struct sockaddr *) &so_in; + lwipnamelen = so_in.sin_len; + #if LWIP_IPV6 + } else if ( ( family == rtems_lwip_sysdefs_AF_INET6 ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in6_size ) ) { + so_in6.sin6_len = sizeof( so_in6 ); + so_in6.sin6_family = AF_INET6; + so_in6.sin6_port = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_port( name ); + memcpy( &so_in6.sin6_addr, + rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr_const( name ), + sizeof( so_in6.sin6_addr ) ); + so_in6.sin6_flowinfo = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_flowinfo( + name ); + so_in6.sin6_scope_id = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_scope_id( + name ); + lwipname = (struct sockaddr *) &so_in6; + lwipnamelen = so_in6.sin6_len; + #endif + } else { + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + ret = lwip_connect( lwipfd, lwipname, lwipnamelen ); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +int listen( + int s, + int backlog +) +{ + int ret = -1; + int lwipfd; + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + ret = lwip_listen( lwipfd, backlog ); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +int accept( + int s, + struct sockaddr *name, + socklen_t *namelen +) +{ + int ret = -1; + int lwipfd; + struct sockaddr *lwipname = name; + socklen_t lwipnamelen = *namelen; + struct sockaddr_in so_in; + + #if LWIP_IPV6 + struct sockaddr_in6 so_in6; + #endif + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + + rtems_lwip_semaphore_release(); + lwipfd = lwip_accept( lwipfd, lwipname, &lwipnamelen ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + if ( lwipfd < 0 ) + return lwipfd; + + if ( lwipname->sa_family == AF_INET ) { + memcpy( &so_in, lwipname, sizeof( so_in ) ); + rtems_lwip_sysdefs_sockaddr_set_len( name, + rtems_lwip_sysdefs_sockaddr_in_size ); + rtems_lwip_sysdefs_sockaddr_set_family( name, rtems_lwip_sysdefs_AF_INET ); + rtems_lwip_sysdefs_sockaddr_in_set_sin_port( name, so_in.sin_port ); + rtems_lwip_sysdefs_sockaddr_in_set_sin_addr( name, so_in.sin_addr.s_addr ); + #if LWIP_IPV6 + } else if ( lwipname->sa_family == AF_INET6 ) { + memcpy( &so_in6, lwipname, sizeof( so_in6 ) ); + rtems_lwip_sysdefs_sockaddr_set_len( name, + rtems_lwip_sysdefs_sockaddr_in6_size ); + rtems_lwip_sysdefs_sockaddr_set_family( name, + rtems_lwip_sysdefs_AF_INET6 ); + + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_port( name, so_in6.sin6_port ); + memcpy( rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr( name ), + &so_in6.sin6_addr, + sizeof( so_in6.sin6_addr ) ); + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_flowinfo( name, + so_in6.sin6_flowinfo ); + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_scope_id( name, + so_in6.sin6_scope_id ); + #endif + } else { + lwip_close( lwipfd ); + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + ret = rtems_lwip_make_sysfd_from_lwipfd( lwipfd ); + + if ( ret < 0 ) { + rtems_lwip_semaphore_release(); + lwip_close( lwipfd ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + *namelen = rtems_lwip_sysdefs_sockaddr_get_len( name ); + + return ret; +} + +/* + * Shutdown routine + */ + +int shutdown( + int s, + int how +) +{ + int ret = -1; + int lwipfd; + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + rtems_lwip_semaphore_release(); + ret = lwip_shutdown( lwipfd, how ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +ssize_t recv( + int s, + void *buf, + size_t len, + int flags +) +{ + int ret = -1; + int lwipfd; + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + rtems_lwip_semaphore_release(); + ret = lwip_recv( lwipfd, buf, len, flags ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +ssize_t send( + int s, + const void *buf, + size_t len, + int flags +) +{ + int ret = -1; + int lwipfd; + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + rtems_lwip_semaphore_release(); + ret = lwip_send( lwipfd, buf, len, flags ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +ssize_t recvfrom( + int s, + void *buf, + size_t len, + int flags, + struct sockaddr *name, + socklen_t *namelen +) +{ + int ret = -1; + int lwipfd; + struct sockaddr *lwipname = name; + socklen_t lwipnamelen = *namelen; + struct sockaddr_in so_in; + + #if LWIP_IPV6 + struct sockaddr_in6 so_in6; + #endif + + if ( name == NULL ) + return recv( s, buf, len, flags ); + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + rtems_lwip_semaphore_release(); + lwipfd = lwip_recvfrom( lwipfd, buf, len, flags, lwipname, &lwipnamelen ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + if ( lwipfd < 0 ) + return lwipfd; + + if ( lwipname->sa_family == AF_INET ) { + memcpy( &so_in, lwipname, sizeof( so_in ) ); + rtems_lwip_sysdefs_sockaddr_set_len( name, + rtems_lwip_sysdefs_sockaddr_in_size ); + rtems_lwip_sysdefs_sockaddr_set_family( name, rtems_lwip_sysdefs_AF_INET ); + rtems_lwip_sysdefs_sockaddr_in_set_sin_port( name, so_in.sin_port ); + rtems_lwip_sysdefs_sockaddr_in_set_sin_addr( name, so_in.sin_addr.s_addr ); + #if LWIP_IPV6 + } else if ( lwipname->sa_family == AF_INET6 ) { + memcpy( &so_in6, lwipname, sizeof( so_in6 ) ); + rtems_lwip_sysdefs_sockaddr_set_len( name, + rtems_lwip_sysdefs_sockaddr_in6_size ); + rtems_lwip_sysdefs_sockaddr_set_family( name, + rtems_lwip_sysdefs_AF_INET6 ); + + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_port( name, so_in6.sin6_port ); + memcpy( rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr( name ), + &so_in6.sin6_addr, + sizeof( so_in6.sin6_addr ) ); + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_flowinfo( name, + so_in6.sin6_flowinfo ); + rtems_lwip_sysdefs_sockaddr_in6_set_sin6_scope_id( name, + so_in6.sin6_scope_id ); + #endif + } else { + lwip_close( lwipfd ); + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + ret = rtems_lwip_make_sysfd_from_lwipfd( lwipfd ); + + if ( ret < 0 ) { + lwip_close( lwipfd ); + } + + rtems_lwip_semaphore_release(); + + *namelen = rtems_lwip_sysdefs_sockaddr_get_len( name ); + + return ret; +} + +ssize_t sendto( + int s, + const void *buf, + size_t len, + int flags, + const struct sockaddr *name, + socklen_t namelen +) +{ + int ret = -1; + int lwipfd; + int family; + struct sockaddr *lwipname; + socklen_t lwipnamelen; + struct sockaddr_in so_in; + + #if LWIP_IPV6 + struct sockaddr_in6 so_in6; + #endif + + if ( name == NULL ) + return send( s, buf, len, flags ); + + family = rtems_lwip_sysdefs_sockaddr_get_family( name ); + + if ( ( family == rtems_lwip_sysdefs_AF_INET ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in_size ) ) { + so_in.sin_len = sizeof( so_in ); + so_in.sin_family = AF_INET; + so_in.sin_port = rtems_lwip_sysdefs_sockaddr_in_get_sin_port( name ); + so_in.sin_addr.s_addr = + rtems_lwip_sysdefs_sockaddr_in_get_sin_addr( name ); + lwipname = (struct sockaddr *) &so_in; + lwipnamelen = so_in.sin_len; + #if LWIP_IPV6 + } else if ( ( family == rtems_lwip_sysdefs_AF_INET6 ) && + ( namelen >= rtems_lwip_sysdefs_sockaddr_in6_size ) ) { + so_in6.sin6_len = sizeof( so_in6 ); + so_in6.sin6_family = AF_INET6; + so_in6.sin6_port = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_port( name ); + memcpy( &so_in6.sin6_addr, + rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr_const( name ), + sizeof( so_in6.sin6_addr ) ); + so_in6.sin6_flowinfo = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_flowinfo( + name ); + so_in6.sin6_scope_id = rtems_lwip_sysdefs_sockaddr_in6_get_sin6_scope_id( + name ); + lwipname = (struct sockaddr *) &so_in6; + lwipnamelen = so_in6.sin6_len; + #endif + } else { + errno = EINVAL; + + return -1; + } + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) >= 0 ) { + rtems_lwip_semaphore_release(); + ret = lwip_sendto( lwipfd, buf, len, flags, lwipname, lwipnamelen ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +#if 0 + +/* + * All `transmit' operations end up calling this routine. + */ +ssize_t sendmsg( + int s, + const struct msghdr *mp, + int flags +) +{ + int ret = -1; + int error; + struct uio auio; + struct iovec *iov; + int lwipfd; + struct mbuf *to; + struct mbuf *control = NULL; + int i; + int len; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = rtems_lwip_sysfd_to_lwipfd( s ) ) == NULL ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + auio.uio_iov = mp->msg_iov; + auio.uio_iovcnt = mp->msg_iovlen; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_offset = 0; + auio.uio_resid = 0; + iov = mp->msg_iov; + + for ( i = 0; i < mp->msg_iovlen; i++, iov++ ) { + if ( ( auio.uio_resid += iov->iov_len ) < 0 ) { + errno = EINVAL; + rtems_lwip_semaphore_release(); + + return -1; + } + } + + if ( mp->msg_name ) { + error = sockargstombuf( &to, mp->msg_name, mp->msg_namelen, MT_SONAME ); + + if ( error ) { + errno = error; + rtems_lwip_semaphore_release(); + + return -1; + } + } else { + to = NULL; + } + + if ( mp->msg_control ) { + if ( mp->msg_controllen < sizeof( struct cmsghdr ) ) { + errno = EINVAL; + + if ( to ) + m_freem( to ); + + rtems_lwip_semaphore_release(); + + return -1; + } + + sockargstombuf( &control, mp->msg_control, mp->msg_controllen, + MT_CONTROL ); + } else { + control = NULL; + } + + len = auio.uio_resid; + error = sosend( so, to, &auio, (struct mbuf *) 0, control, flags ); + + if ( error ) { + if ( auio.uio_resid != len && ( error == EINTR || error == EWOULDBLOCK ) ) + error = 0; + } + + if ( error ) + errno = error; + else + ret = len - auio.uio_resid; + + if ( to ) + m_freem( to ); + + rtems_lwip_semaphore_release(); + + return ( ret ); +} + +/* + * All `receive' operations end up calling this routine. + */ +ssize_t recvmsg( + int s, + struct msghdr *mp, + int flags +) +{ + int ret = -1; + int error; + struct uio auio; + struct iovec *iov; + int lwipfd; + struct mbuf *from = NULL, *control = NULL; + int i; + int len; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = rtems_lwip_sysfd_to_lwipfd( s ) ) == NULL ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + auio.uio_iov = mp->msg_iov; + auio.uio_iovcnt = mp->msg_iovlen; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_rw = UIO_READ; + auio.uio_offset = 0; + auio.uio_resid = 0; + iov = mp->msg_iov; + + for ( i = 0; i < mp->msg_iovlen; i++, iov++ ) { + if ( ( auio.uio_resid += iov->iov_len ) < 0 ) { + errno = EINVAL; + rtems_lwip_semaphore_release(); + + return -1; + } + } + + len = auio.uio_resid; + mp->msg_flags = flags; + error = soreceive( so, &from, &auio, (struct mbuf **) NULL, + mp->msg_control ? &control : (struct mbuf **) NULL, + &mp->msg_flags ); + + if ( error ) { + if ( auio.uio_resid != len && ( error == EINTR || error == EWOULDBLOCK ) ) + error = 0; + } + + if ( error ) { + errno = error; + } else { + ret = len - auio.uio_resid; + + if ( mp->msg_name ) { + len = mp->msg_namelen; + + if ( ( len <= 0 ) || ( from == NULL ) ) { + len = 0; + } else { + if ( len > from->m_len ) + len = from->m_len; + + memcpy( mp->msg_name, mtod( from, caddr_t ), len ); + } + + mp->msg_namelen = len; + } + + if ( mp->msg_control ) { + struct mbuf *m; + void *ctlbuf; + + len = mp->msg_controllen; + m = control; + mp->msg_controllen = 0; + ctlbuf = mp->msg_control; + + while ( m && ( len > 0 ) ) { + unsigned int tocopy; + + if ( len >= m->m_len ) + tocopy = m->m_len; + else { + mp->msg_flags |= MSG_CTRUNC; + tocopy = len; + } + + memcpy( ctlbuf, mtod( m, caddr_t ), tocopy ); + ctlbuf += tocopy; + len -= tocopy; + m = m->m_next; + } + + mp->msg_controllen = ctlbuf - mp->msg_control; + } + } + + if ( from ) + m_freem( from ); + + if ( control ) + m_freem( control ); + + rtems_lwip_semaphore_release(); + + return ( ret ); +} + +#endif + +int setsockopt( + int s, + int level, + int name, + const void *val, + socklen_t len +) +{ + +#if 0 + int lwipfd; + struct mbuf *m = NULL; + int error; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = rtems_lwip_sysfd_to_lwipfd( s ) ) == NULL ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + if ( len > MLEN ) { + errno = EINVAL; + rtems_lwip_semaphore_release(); + + return -1; + } + + if ( val ) { + error = sockargstombuf( &m, val, len, MT_SOOPTS ); + + if ( error ) { + errno = error; + rtems_lwip_semaphore_release(); + + return -1; + } + } + + error = sosetopt( so, level, name, m ); + + if ( error ) { + errno = error; + rtems_lwip_semaphore_release(); + + return -1; + } + + rtems_lwip_semaphore_release(); +#endif + return 0; +} + +#if 0 + +int getsockopt( + int s, + int level, + int name, + void *aval, + socklen_t *avalsize +) +{ + int lwipfd; + struct mbuf *m = NULL, *m0; + char *val = aval; + int i, op, valsize; + int error; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = rtems_lwip_sysfd_to_lwipfd( s ) ) == NULL ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + if ( val ) + valsize = *avalsize; + else + valsize = 0; + + if ( ( ( error = + sogetopt( so, level, name, + &m ) ) == 0 ) && val && valsize && m ) { + op = 0; + + while ( m && op < valsize ) { + i = valsize - op; + + if ( i > m->m_len ) + i = m->m_len; + + memcpy( val, mtod( m, caddr_t ), i ); + op += i; + val += i; + m0 = m; + MFREE( m0, m ); + } + + *avalsize = op; + } + + if ( m != NULL ) + (void) m_free( m ); + + if ( error ) { + errno = error; + rtems_lwip_semaphore_release(); + + return -1; + } + + rtems_lwip_semaphore_release(); + + return 0; +} + +static int getpeersockname( + int s, + struct sockaddr *name, + socklen_t *namelen, + int pflag +) +{ + int lwipfd; + struct mbuf *m; + int len = *namelen; + int error; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = rtems_lwip_sysfd_to_lwipfd( s ) ) == NULL ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + m = m_getclr( M_WAIT, MT_SONAME ); + + if ( m == NULL ) { + errno = ENOBUFS; + rtems_lwip_semaphore_release(); + + return -1; + } + + if ( pflag ) + error = ( *so->so_proto->pr_usrreqs->pru_peeraddr )( so, m ); + else + error = ( *so->so_proto->pr_usrreqs->pru_sockaddr )( so, m ); + + if ( error ) { + m_freem( m ); + errno = error; + rtems_lwip_semaphore_release(); + + return -1; + } + + if ( len > m->m_len ) { + len = m->m_len; + *namelen = len; + } + + memcpy( name, mtod( m, caddr_t ), len ); + m_freem( m ); + rtems_lwip_semaphore_release(); + + return 0; +} + +#endif + +int getpeername( + int s, + struct sockaddr *name, + socklen_t *namelen +) +{ + int lwipfd; + int error; + + rtems_lwip_semaphore_obtain(); + + if ( ( lwipfd = rtems_lwip_sysfd_to_lwipfd( s ) ) < 0 ) { + rtems_lwip_semaphore_release(); + + return -1; + } + + error = lwip_getpeername(lwipfd, name, namelen); + + rtems_lwip_semaphore_release(); + + return error; +} + +#if 0 + +int getsockname( + int s, + struct sockaddr *name, + socklen_t *namelen +) +{ + return getpeersockname( s, name, namelen, 0 ); +} + +int sysctl( + const int *name, + u_int namelen, + void *oldp, + size_t *oldlenp, + const void *newp, + size_t newlen +) +{ + int error; + size_t j; + + rtems_lwip_semaphore_obtain(); + error = + userland_sysctl( 0, name, namelen, oldp, oldlenp, 1, newp, newlen, &j ); + rtems_lwip_semaphore_release(); + + if ( oldlenp ) + *oldlenp = j; + + if ( error ) { + errno = error; + + return -1; + } + + return 0; +} + +#endif + +/* + ************************************************************************ + * RTEMS I/O HANDLER ROUTINES * + ************************************************************************ + */ +static int rtems_lwip_close( rtems_libio_t *iop ) +{ + int lwipfd; + int ret; + + rtems_lwip_semaphore_obtain(); + lwipfd = rtems_lwip_iop_to_lwipfd( iop ); + + if ( lwipfd < 0 ) { + ret = -1; + } else { + rtems_lwip_semaphore_release(); + ret = lwip_close( lwipfd ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +static ssize_t rtems_lwip_read( + rtems_libio_t *iop, + void *buffer, + size_t count +) +{ + int lwipfd; + int ret; + + rtems_lwip_semaphore_obtain(); + lwipfd = rtems_lwip_iop_to_lwipfd( iop ); + + if ( lwipfd < 0 ) { + ret = -1; + } else { + rtems_lwip_semaphore_release(); + ret = lwip_read( lwipfd, buffer, count ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +static ssize_t rtems_lwip_write( + rtems_libio_t *iop, + const void *buffer, + size_t count +) +{ + int lwipfd; + int ret; + + rtems_lwip_semaphore_obtain(); + lwipfd = rtems_lwip_iop_to_lwipfd( iop ); + + if ( lwipfd < 0 ) { + ret = -1; + } else { + rtems_lwip_semaphore_release(); + ret = lwip_write( lwipfd, buffer, count ); + rtems_lwip_semaphore_obtain(); + } + + rtems_lwip_semaphore_release(); + + return ret; +} + +int so_ioctl( + rtems_libio_t *iop, + int lwipfd, + uint32_t command, + void *buffer +) +{ +#if 0 + + switch ( command ) { + case FIONBIO: + + if ( *(int *) buffer ) { + iop->flags |= O_NONBLOCK; + so->so_state |= SS_NBIO; + } else { + iop->flags &= ~O_NONBLOCK; + so->so_state &= ~SS_NBIO; + } + + return 0; + + case FIONREAD: + *(int *) buffer = so->so_rcv.sb_cc; + + return 0; + } + + if ( IOCGROUP( command ) == 'i' ) + return ifioctl( so, command, buffer, NULL ); + + if ( IOCGROUP( command ) == 'r' ) + return rtioctl( command, buffer, NULL ); + + return ( *so->so_proto->pr_usrreqs->pru_control )( so, command, buffer, 0 ); +#endif + + return -1; +} + +static int rtems_lwip_ioctl( + rtems_libio_t *iop, + ioctl_command_t command, + void *buffer +) +{ +#if 0 + int lwipfd; + int error; + + rtems_lwip_semaphore_obtain(); + + if ( ( so = iop->data1 ) == NULL ) { + errno = EBADF; + rtems_lwip_semaphore_release(); + + return -1; + } + + error = so_ioctl( iop, so, command, buffer ); + rtems_lwip_semaphore_release(); + + if ( error ) { + errno = error; + + return -1; + } + + return 0; +#endif + + return -1; +} + +static int rtems_lwip_fcntl( + rtems_libio_t *iop, + int cmd +) +{ +#if 0 + int lwipfd; + + if ( cmd == F_SETFL ) { + rtems_lwip_semaphore_obtain(); + + if ( ( so = iop->data1 ) == NULL ) { + rtems_lwip_semaphore_release(); + + return EBADF; + } + + if ( rtems_libio_iop_is_no_delay( iop ) ) + so->so_state |= SS_NBIO; + else + so->so_state &= ~SS_NBIO; + + rtems_lwip_semaphore_release(); + } + + return 0; +#endif + + return -1; +} + +static int rtems_lwip_fstat( + const rtems_filesystem_location_info_t *loc, + struct stat *sp +) +{ + sp->st_mode = S_IFSOCK; + + return 0; +} + +static const rtems_filesystem_file_handlers_r rtems_lwip_socket_handlers = { + .open_h = rtems_filesystem_default_open, + .close_h = rtems_lwip_close, + .read_h = rtems_lwip_read, + .write_h = rtems_lwip_write, + .ioctl_h = rtems_lwip_ioctl, + .lseek_h = rtems_filesystem_default_lseek, + .fstat_h = rtems_lwip_fstat, + .ftruncate_h = rtems_filesystem_default_ftruncate, + .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fcntl_h = rtems_lwip_fcntl, + .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, + .poll_h = rtems_filesystem_default_poll, + .readv_h = rtems_filesystem_default_readv, + .writev_h = rtems_filesystem_default_writev +}; + +const char * +inet_ntop(int af, const void *src, char *dst, socklen_t size){ + return lwip_inet_ntop(af, src, dst, size); +} diff --git a/rtemslwip/common/rtems_lwip_sysdefs.c b/rtemslwip/common/rtems_lwip_sysdefs.c new file mode 100644 index 0000000..3877811 --- /dev/null +++ b/rtemslwip/common/rtems_lwip_sysdefs.c @@ -0,0 +1,185 @@ +/* + * + * RTEMS Project (https://www.rtems.org/) + * + * Copyright (c) 2021 Vijay Kumar Banerjee . + * All rights reserved. + * + * 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. + * + * 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. + */ + +#include +#include +#include + +#include "rtems_lwip_int.h" + +int rtems_lwip_sysdefs_AF_UNSPEC = AF_UNSPEC; +int rtems_lwip_sysdefs_AF_UNIX = AF_UNIX; +int rtems_lwip_sysdefs_AF_INET = AF_INET; +int rtems_lwip_sysdefs_AF_INET6 = AF_INET6; +int rtems_lwip_sysdefs_PF_UNSPEC = PF_UNSPEC; +int rtems_lwip_sysdefs_PF_UNIX = PF_UNIX; +int rtems_lwip_sysdefs_PF_INET = PF_INET; +int rtems_lwip_sysdefs_PF_INET6 = PF_INET6; +int rtems_lwip_sysdefs_SOCK_STREAM = SOCK_STREAM; +int rtems_lwip_sysdefs_SOCK_DGRAM = SOCK_DGRAM; +int rtems_lwip_sysdefs_SOCK_RAW = SOCK_RAW; +int rtems_lwip_sysdefs_sockaddr_in_size = sizeof( struct sockaddr_in ); +int rtems_lwip_sysdefs_sockaddr_in6_size = sizeof( struct sockaddr_in6 ); + +int rtems_lwip_sysdefs_sockaddr_get_len( const void *sockaddr ) +{ + const struct sockaddr *so = sockaddr; + + return so->sa_len; +} + +int rtems_lwip_sysdefs_sockaddr_get_family( const void *sockaddr ) +{ + const struct sockaddr *so = sockaddr; + + return so->sa_family; +} + +uint16_t rtems_lwip_sysdefs_sockaddr_in_get_sin_port( const void *sockaddr ) +{ + const struct sockaddr_in *so = sockaddr; + + return so->sin_port; +} + +uint32_t rtems_lwip_sysdefs_sockaddr_in_get_sin_addr( const void *sockaddr ) +{ + const struct sockaddr_in *so = sockaddr; + + return so->sin_addr.s_addr; +} + +uint16_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_port( const void *sockaddr ) +{ + const struct sockaddr_in6 *so = sockaddr; + + return so->sin6_port; +} + +const uint8_t *rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr_const( + const void *sockaddr ) +{ + const struct sockaddr_in6 *so = sockaddr; + + return (uint8_t *) &so->sin6_addr; +} + +uint8_t *rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr( + void *sockaddr ) +{ + struct sockaddr_in6 *so = sockaddr; + + return (uint8_t *) &so->sin6_addr; +} + +uint32_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_flowinfo( + const void *sockaddr ) +{ + const struct sockaddr_in6 *so = sockaddr; + + return so->sin6_flowinfo; +} + +uint32_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_scope_id( + const void *sockaddr ) +{ + const struct sockaddr_in6 *so = sockaddr; + + return so->sin6_scope_id; +} + +void rtems_lwip_sysdefs_sockaddr_set_len( + void *sockaddr, + int len +) +{ + struct sockaddr *so = sockaddr; + + so->sa_len = len; +} + +void rtems_lwip_sysdefs_sockaddr_set_family( + void *sockaddr, + int family +) +{ + struct sockaddr *so = sockaddr; + + so->sa_family = family; +} + +void rtems_lwip_sysdefs_sockaddr_in_set_sin_port( + void *sockaddr, + uint16_t port +) +{ + struct sockaddr_in *so = sockaddr; + + so->sin_port = port; +} + +void rtems_lwip_sysdefs_sockaddr_in_set_sin_addr( + void *sockaddr, + uint32_t addr +) +{ + struct sockaddr_in *so = sockaddr; + + so->sin_addr.s_addr = addr; +} + +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_port( + void *sockaddr, + uint16_t port +) +{ + struct sockaddr_in6 *so = sockaddr; + + so->sin6_port = port; +} + +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_flowinfo( + void *sockaddr, + uint32_t flowinfo +) +{ + struct sockaddr_in6 *so = sockaddr; + + so->sin6_flowinfo = flowinfo; +} + +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_scope_id( + void *sockaddr, + uint32_t scope_id +) +{ + struct sockaddr_in6 *so = sockaddr; + + so->sin6_scope_id = scope_id; +} diff --git a/rtemslwip/common/syslog.c b/rtemslwip/common/syslog.c new file mode 100644 index 0000000..e544074 --- /dev/null +++ b/rtemslwip/common/syslog.c @@ -0,0 +1,89 @@ +/* + * RTEMS version of syslog and associated routines + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int LogStatus = LOG_CONS; +static const char *LogTag = "syslog"; +static int LogFacility = LOG_USER; +static int LogMask = 0xff; + +void +syslog (int pri, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vsyslog (pri, fmt, ap); + va_end (ap); +} + +/* + * FIXME: Should cbuf be static? Then we wouldn't + * have to worry about blowing stacks with a local variable + * that large. Could make cbuf bigger, too. + */ +void +vsyslog (int pri, const char *fmt, va_list ap) +{ + int cnt; + char cbuf[200]; + + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, + "syslog: unknown facility/priority: %#x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) + return; + + if ((pri & LOG_FACMASK) == 0) + pri |= LogFacility; + + cnt = snprintf (cbuf, sizeof (cbuf), "<%d>", pri); + if (LogTag && cnt < sizeof (cbuf) - 1) + cnt += snprintf (cbuf + cnt, sizeof (cbuf) - cnt, "%s", LogTag); + if (LogStatus & LOG_PID && cnt < sizeof (cbuf) - 1) { + rtems_id tid; + rtems_task_ident (RTEMS_SELF, 0, &tid); + cnt += snprintf (cbuf + cnt, sizeof (cbuf) - cnt, "[%#lx]", (unsigned long)tid); + } + if (LogTag && cnt < sizeof (cbuf) - 1) + cnt += snprintf (cbuf + cnt, sizeof (cbuf) - cnt, ": "); + cnt += vsnprintf (cbuf + cnt, sizeof (cbuf) - cnt, fmt, ap); + if (cnt > sizeof (cbuf) - 1) + cnt = sizeof (cbuf) - 1; + while (cnt > 0 && cbuf[cnt-1] == '\n') + cbuf[--cnt] = '\0'; + + if (LogStatus & LOG_PERROR) + printf ("%s\n", cbuf); +} + +int +setlogmask (int pmask) +{ + int omask; + + omask = LogMask; + if (pmask != 0) + LogMask = pmask; + return (omask); +} diff --git a/rtemslwip/include/rtems_lwip_int.h b/rtemslwip/include/rtems_lwip_int.h new file mode 100644 index 0000000..9d3d548 --- /dev/null +++ b/rtemslwip/include/rtems_lwip_int.h @@ -0,0 +1,92 @@ +/* + * + * RTEMS Project (https://www.rtems.org/) + * + * Copyright (c) 2021 Vijay Kumar Banerjee . + * All rights reserved. + * + * 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. + * + * 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 RTEMS_LWIP_INT_H +#define RTEMS_LWIP_INT_H + +#include + +extern int rtems_lwip_sysdefs_AF_UNSPEC; +extern int rtems_lwip_sysdefs_AF_UNIX; +extern int rtems_lwip_sysdefs_AF_INET; +extern int rtems_lwip_sysdefs_AF_INET6; +extern int rtems_lwip_sysdefs_PF_UNSPEC; +extern int rtems_lwip_sysdefs_PF_UNIX; +extern int rtems_lwip_sysdefs_PF_INET; +extern int rtems_lwip_sysdefs_PF_INET6; +extern int rtems_lwip_sysdefs_SOCK_STREAM; +extern int rtems_lwip_sysdefs_SOCK_DGRAM; +extern int rtems_lwip_sysdefs_SOCK_RAW; +extern int rtems_lwip_sysdefs_sockaddr_in_size; +extern int rtems_lwip_sysdefs_sockaddr_in6_size; + +int rtems_lwip_sysdefs_sockaddr_get_len( const void *sockaddr ); +int rtems_lwip_sysdefs_sockaddr_get_family( const void *sockaddr ); +uint16_t rtems_lwip_sysdefs_sockaddr_in_get_sin_port( const void *sockaddr ); +uint32_t rtems_lwip_sysdefs_sockaddr_in_get_sin_addr( const void *sockaddr ); +uint16_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_port( const void *sockaddr ); +const uint8_t *rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr_const( + const void *sockaddr ); +uint8_t *rtems_lwip_sysdefs_sockaddr_in6_get_sin6_addr_ptr( + void *sockaddr ); +uint32_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_flowinfo( + const void *sockaddr ); +uint32_t rtems_lwip_sysdefs_sockaddr_in6_get_sin6_scope_id( + const void *sockaddr ); + +void rtems_lwip_sysdefs_sockaddr_set_len( + void *sockaddr, + int len +); +void rtems_lwip_sysdefs_sockaddr_set_family( + void *sockaddr, + int family +); +void rtems_lwip_sysdefs_sockaddr_in_set_sin_port( + void *sockaddr, + uint16_t port +); +void rtems_lwip_sysdefs_sockaddr_in_set_sin_addr( + void *sockaddr, + uint32_t addr +); +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_port( + void *sockaddr, + uint16_t port +); +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_flowinfo( + void *sockaddr, + uint32_t flowinfo +); +void rtems_lwip_sysdefs_sockaddr_in6_set_sin6_scope_id( + void *sockaddr, + uint32_t scope_id +); + +#endif /*RTEMS_LWIP_INT_H*/ diff --git a/rtemslwip/include/sys/sysctl.h b/rtemslwip/include/sys/sysctl.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/rtemslwip/include/sys/sysctl.h @@ -0,0 +1 @@ + diff --git a/rtemslwip/test/buffer_test_io.h b/rtemslwip/test/buffer_test_io.h new file mode 100644 index 0000000..f0eae50 --- /dev/null +++ b/rtemslwip/test/buffer_test_io.h @@ -0,0 +1,21 @@ +/* + * Support for running the test output through a buffer + */ + +#ifndef __BUFFER_TEST_IO_h +#define __BUFFER_TEST_IO_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_BEGIN() rtems_test_begin(rtems_test_name, TEST_STATE) +#define TEST_END() rtems_test_end(rtems_test_name) + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/rtemslwip/test/networking01/sample_app.c b/rtemslwip/test/networking01/sample_app.c new file mode 100644 index 0000000..576cd6b --- /dev/null +++ b/rtemslwip/test/networking01/sample_app.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "lwip/netdb.h" +#include +#include +#include "tmacros.h" + +const char rtems_test_name[] = "NETWORKING 1"; + +/* forward declarations to avoid warnings */ +static rtems_task Init(rtems_task_argument argument); + +static void fill_sa(struct sockaddr *sa, sa_family_t family) +{ + memset(sa, 0, sizeof(*sa)); + sa->sa_len = sizeof(*sa); + sa->sa_family = family; +} + +static void fill_sa_in(struct sockaddr_in *sa_in, + in_addr_t addr, in_port_t port) +{ + fill_sa((struct sockaddr *)sa_in, AF_INET); + sa_in->sin_port = htons(port); + sa_in->sin_addr.s_addr = htonl(addr); +} + +static void test_getnameinfo( + const struct sockaddr *sa, + int flags, + bool ask_node, + bool ask_service, + int expected_returnvalue, + const char *expected_node, + const char *expected_service +) +{ + char node[] = "255.255.255.255"; + char service[] = "65535"; + socklen_t salen = sa->sa_len; + int rv; + + char *node_p = node; + char *service_p = service; + size_t node_l = sizeof(node); + size_t service_l = sizeof(service); + + if(ask_node == false) { + node_p = NULL; + node_l = 0; + } + + if(ask_service == false) { + service_p = NULL; + service_l = 0; + } + + rv = getnameinfo(sa, salen, node_p, node_l, service_p, service_l, flags); + rtems_test_assert(rv == expected_returnvalue); + + if(expected_node != NULL) { + rtems_test_assert(strcmp(expected_node, node) == 0); + } + + if(expected_service != NULL) { + rtems_test_assert(strcmp(expected_service, service) == 0); + } +} + +static void test(void) +{ + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr *sa_in_p = (struct sockaddr *) &sa_in; + + const in_addr_t ip1_num = 0x7F000001u; + const char ip1_string[] = "127.0.0.1"; + + const in_addr_t ip2_num = 0xC0A86464u; + const char ip2_string[] = "192.168.100.100"; + + const in_port_t port1_num = 7u; + const char port1_string[] = "7"; + + const in_port_t port2_num = 65534u; + const char port2_string[] = "65534"; + + + puts("Try AF_INET6"); + fill_sa(&sa, AF_INET6); + test_getnameinfo(&sa, 0, true, true, EAI_FAMILY, NULL, NULL); + + puts("force node name"); + fill_sa_in(&sa_in, ip1_num, port1_num); + test_getnameinfo(sa_in_p, NI_NAMEREQD, true, true, EAI_NONAME, NULL, NULL); + + puts("force service name"); + fill_sa_in(&sa_in, ip1_num, port1_num); + test_getnameinfo(sa_in_p, NI_NAMEREQD, true, true, EAI_NONAME, NULL, NULL); + + puts("get node only"); + fill_sa_in(&sa_in, ip1_num, port1_num); + test_getnameinfo(sa_in_p, 0, true, false, 0, ip1_string, NULL); + + puts("get service only"); + fill_sa_in(&sa_in, ip1_num, port1_num); + test_getnameinfo(sa_in_p, 0, false, true, 0, NULL, port1_string); + + puts("get node and service"); + fill_sa_in(&sa_in, ip1_num, port1_num); + test_getnameinfo(sa_in_p, 0, true, true, 0, ip1_string, port1_string); + + puts("get node and service with maximum number of characters for IP"); + fill_sa_in(&sa_in, ip2_num, port2_num); + test_getnameinfo(sa_in_p, 0, true, true, 0, ip2_string, port2_string); +} + +static rtems_task Init(rtems_task_argument argument) +{ + TEST_BEGIN(); + test(); + TEST_END(); + + rtems_test_exit(0); +} + +#define CONFIGURE_INIT + +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS (1) + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT + +#include diff --git a/rtemslwip/test/telnetd01/init.c b/rtemslwip/test/telnetd01/init.c new file mode 100644 index 0000000..f1fe036 --- /dev/null +++ b/rtemslwip/test/telnetd01/init.c @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * Written by Kinsey Moore + * + * 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. + * + * 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. + */ + +#include +#include +#include + +#include + +const char rtems_test_name[] = "TELNETD 1"; + +//struct rtems_bsdnet_config rtems_bsdnet_config; + +rtems_shell_env_t env; + +static void telnet_shell( char *name, void *arg ) +{ + rtems_shell_dup_current_env( &env ); + + env.devname = name; + env.taskname = "TLNT"; + + rtems_shell_main_loop( &env ); +} + +rtems_telnetd_config_table rtems_telnetd_config = { + .command = telnet_shell, + .stack_size = 8 * RTEMS_MINIMUM_STACK_SIZE, +}; + +#define print_ip( tag, ip ) \ + printf( \ + "%s: %" PRId32 ".%" PRId32 ".%" PRId32 ".%" PRId32 "\n", \ + tag, \ + ( ntohl( ip.addr ) >> 24 ) & 0xff, \ + ( ntohl( ip.addr ) >> 16 ) & 0xff, \ + ( ntohl( ip.addr ) >> 8 ) & 0xff, \ + ntohl( ip.addr ) & 0xff \ + ); + +static int shell_main_netinfo( + int argc, + char **argv +) +{ + print_ip( "IP", net_interface.ip_addr.u_addr.ip4 ); + print_ip( "Mask", net_interface.netmask.u_addr.ip4 ); + print_ip( "GW", net_interface.gw.u_addr.ip4 ); + return 0; +} + +rtems_shell_cmd_t shell_NETINFO_Command = { + "netinfo", /* name */ + "netinfo - shows basic network info, no arguments", /* usage */ + "net", /* topic */ + shell_main_netinfo, /* command */ + NULL, /* alias */ + NULL /* next */ +}; + +static rtems_task Init( rtems_task_argument argument ) +{ + rtems_status_code sc; + + TEST_BEGIN(); + + lwip_init(); + + rtems_shell_init_environment(); + + dhcp_start( &net_interface ); + + sc = rtems_telnetd_start( &rtems_telnetd_config ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_shell_init( + "SHLL", /* task name */ + RTEMS_MINIMUM_STACK_SIZE * 4, /* task stack size */ + 100, /* task priority */ + "/dev/console", /* device name */ + false, /* run forever */ + true, /* wait for shell to terminate */ + NULL /* login check function, + use NULL to disable a login check */ + ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + sys_arch_delay( 300000 ); + + TEST_END(); + rtems_test_exit( 0 ); +} + +#define CONFIGURE_INIT + +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK + +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 32 + +#define CONFIGURE_SHELL_COMMANDS_INIT +#define CONFIGURE_SHELL_COMMANDS_ALL +#define CONFIGURE_SHELL_USER_COMMANDS &shell_NETINFO_Command + +#define CONFIGURE_MAXIMUM_TASKS 12 + +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1 +#define CONFIGURE_MAXIMUM_SEMAPHORES 20 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS + +#include + +#include diff --git a/rtemslwip/test/telnetd01/telnetd01.doc b/rtemslwip/test/telnetd01/telnetd01.doc new file mode 100644 index 0000000..fe1a4d3 --- /dev/null +++ b/rtemslwip/test/telnetd01/telnetd01.doc @@ -0,0 +1,24 @@ +# +# Copyright (c) 2018 embedded brains GmbH. All rights reserved. +# +# embedded brains GmbH +# Dornierstr. 4 +# 82178 Puchheim +# Germany +# +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. + +This file describes the directives and concepts tested by this test set. + +test set name: telnetd01 + +directives: + + - rtems_telnetd_start() + +concepts: + ++ Check if Telnet server works. diff --git a/rtemslwip/test/telnetd01/telnetd01.scn b/rtemslwip/test/telnetd01/telnetd01.scn new file mode 100644 index 0000000..3e9cc00 --- /dev/null +++ b/rtemslwip/test/telnetd01/telnetd01.scn @@ -0,0 +1,11 @@ +*** BEGIN OF TEST TELNETD 1 *** +*** TEST VERSION: 5.0.0.dc32b6aa0807fb70f9b26bc0bc6e164ddb49bd3a +*** TEST STATE: EXPECTED_PASS +*** TEST BUILD: RTEMS_NETWORKING +*** TEST TOOLS: 7.3.0 20180125 (RTEMS 5, RSB 9670d7541e0621915e521fe76e7bb33de8cee661, Newlib d13c84eb07e35984bf7a974cd786a6cdac29e6b9) +syslog: telnetd: configuration with invalid command +syslog: telnetd: cannot create session task +syslog: telnetd: started successfully on port 23 +syslog: telnetd: cannot bind server socket + +*** END OF TEST TELNETD 1 *** diff --git a/rtemslwip/test/tmacros.h b/rtemslwip/test/tmacros.h new file mode 100644 index 0000000..8189149 --- /dev/null +++ b/rtemslwip/test/tmacros.h @@ -0,0 +1,283 @@ +/** + * @file + * + * This include file contains macros which are useful in the RTEMS + * test suites. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef __TMACROS_h +#define __TMACROS_h + +#include +#include +#include /* includes */ + +#include +#include +#include +#include +#include +#include +#include + +#include "buffer_test_io.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FOREVER 1 /* infinite loop */ + +#ifdef CONFIGURE_INIT +#define TEST_EXTERN +#else +#define TEST_EXTERN extern +#endif + +/* + * Check that that the dispatch disable level is proper for the + * mode/state of the test. Normally it should be 0 when in task space. + */ +#define check_dispatch_disable_level( _expect ) \ + do { \ + if ( (_expect) != -1 \ + && (((!_Thread_Dispatch_is_enabled()) == false && (_expect) != 0) \ + || ((!_Thread_Dispatch_is_enabled()) && (_expect) == 0)) \ + ) { \ + printf( \ + "\n_Thread_Dispatch_disable_level is (%i)" \ + " not %d detected at %s:%d\n", \ + !_Thread_Dispatch_is_enabled(), (_expect), __FILE__, __LINE__ ); \ + rtems_test_exit( 1 ); \ + } \ + } while ( 0 ) + +/* + * Check that that the allocator mutex is not owned by the executing thread. + */ +#include +#define check_if_allocator_mutex_is_not_owned() \ + do { \ + if ( _RTEMS_Allocator_is_owner() ) { \ + printf( \ + "\nRTEMS Allocator Mutex is owned by executing thread " \ + "and should not be.\n" \ + "Detected at %s:%d\n", \ + __FILE__, \ + __LINE__ \ + ); \ + rtems_test_exit( 1 ); \ + } \ + } while ( 0 ) + +/* + * These macros properly report errors within the Classic API + */ +#define directive_failed( _dirstat, _failmsg ) \ + fatal_directive_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg ) + +#define directive_failed_with_level( _dirstat, _failmsg, _level ) \ + fatal_directive_status_with_level( \ + _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level ) + +#define fatal_directive_status( _stat, _desired, _msg ) \ + fatal_directive_status_with_level( _stat, _desired, _msg, 0 ) + +#define fatal_directive_check_status_only( _stat, _desired, _msg ) \ + do { \ + if ( (_stat) != (_desired) ) { \ + printf( "\n%s FAILED -- expected (%s) got (%s)\n", \ + (_msg), rtems_status_text(_desired), rtems_status_text(_stat) ); \ + rtems_test_exit( _stat ); \ + } \ + } while ( 0 ) + +#define fatal_directive_status_with_level( _stat, _desired, _msg, _level ) \ + do { \ + check_dispatch_disable_level( _level ); \ + check_if_allocator_mutex_is_not_owned(); \ + fatal_directive_check_status_only( _stat, _desired, _msg ); \ + } while ( 0 ) + +/* + * These macros properly report errors from the POSIX API + */ + +#define posix_service_failed( _dirstat, _failmsg ) \ + fatal_posix_service_status( _dirstat, 0, _failmsg ) + +#define posix_service_failed_with_level( _dirstat, _failmsg, _level ) \ + fatal_posix_service_status_with_level( _dirstat, 0, _failmsg, _level ) + +#define fatal_posix_service_status_errno( _stat, _desired, _msg ) \ + if ( (_stat != -1) && (errno) != (_desired) ) { \ + long statx = _stat; \ + check_dispatch_disable_level( 0 ); \ + check_if_allocator_mutex_is_not_owned(); \ + printf( "\n%s FAILED -- expected (%d - %s) got (%ld %d - %s)\n", \ + (_msg), _desired, strerror(_desired), \ + statx, errno, strerror(errno) ); \ + rtems_test_exit( _stat ); \ + } + +#define fatal_posix_service_status( _stat, _desired, _msg ) \ + fatal_posix_service_status_with_level( _stat, _desired, _msg, 0 ) + +#define fatal_posix_service_status_with_level( _stat, _desired, _msg, _level ) \ + do { \ + check_dispatch_disable_level( _level ); \ + check_if_allocator_mutex_is_not_owned(); \ + if ( (_stat) != (_desired) ) { \ + printf( "\n%s FAILED -- expected (%d - %s) got (%d - %s)\n", \ + (_msg), _desired, strerror(_desired), _stat, strerror(_stat) ); \ + printf( "\n FAILED -- errno (%d - %s)\n", \ + errno, strerror(errno) ); \ + rtems_test_exit( _stat ); \ + } \ + } while ( 0 ) + +/* + * This macro evaluates the semaphore id returned. + */ +#define fatal_posix_sem( _ptr, _msg ) \ + if ( (_ptr != SEM_FAILED) ) { \ + check_dispatch_disable_level( 0 ); \ + printf( "\n%s FAILED -- expected (-1) got (%p - %d/%s)\n", \ + (_msg), _ptr, errno, strerror(errno) ); \ + rtems_test_exit( -1 ); \ + } + +/* + * This macro evaluates the message queue id returned. + */ +#define fatal_posix_mqd( _ptr, _msg ) \ + if ( (_ptr != (mqd_t) -1) ) { \ + check_dispatch_disable_level( 0 ); \ + printf( "\n%s FAILED -- expected (-1) got (%" PRId32 " - %d/%s)\n", \ + (_msg), _ptr, errno, strerror(errno) ); \ + rtems_test_exit( -1 ); \ + } + +/* + * Generic integer version of the error reporting + */ + +#define int_service_failed( _dirstat, _failmsg ) \ + fatal_int_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg ) + +#define int_service_failed_with_level( _dirstat, _failmsg, _level ) \ + fatal_int_service_status_with_level( \ + _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level ) + +#define fatal_int_service_status( _stat, _desired, _msg ) \ + fatal_int_service_status_with_level( _stat, _desired, _msg, 0 ) + +#define fatal_int_service_status_with_level( _stat, _desired, _msg, _level ) \ + do { \ + check_dispatch_disable_level( _level ); \ + if ( (_stat) != (_desired) ) { \ + printf( "\n%s FAILED -- expected (%d) got (%d)\n", \ + (_msg), (_desired), (_stat) ); \ + rtems_test_exit( _stat ); \ + } \ + } while ( 0 ) + + +/* + * Print the time + */ + +#define sprint_time(_str, _s1, _tb, _s2) \ + do { \ + sprintf( (_str), "%s%02d:%02d:%02d %02d/%02d/%04d%s", \ + _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \ + (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \ + } while ( 0 ) + +#define print_time(_s1, _tb, _s2) \ + do { \ + printf( "%s%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 " %02" PRIu32 "/%02" PRIu32 "/%04" PRIu32 "%s", \ + _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \ + (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \ + } while ( 0 ) + +#define put_dot( _c ) \ + do { \ + putchar( _c ); \ + } while ( 0 ) + +#define new_line puts( "" ) + +#define puts_nocr printf + +#define put_name( name, crlf ) \ +{ int c0, c1, c2, c3; \ + c0 = (name >> 24) & 0xff; \ + c1 = (name >> 16) & 0xff; \ + c2 = (name >> 8) & 0xff; \ + c3 = name & 0xff; \ + putchar( (isprint(c0)) ? c0 : '*' ); \ + if ( c1 ) putchar( (isprint(c1)) ? c1 : '*' ); \ + if ( c2 ) putchar( (isprint(c2)) ? c2 : '*' ); \ + if ( c3 ) putchar( (isprint(c3)) ? c3 : '*' ); \ + if ( crlf ) \ + putchar( '\n' ); \ +} + +#ifndef build_time +#define build_time( TB, MON, DAY, YR, HR, MIN, SEC, TK ) \ + { (TB)->year = YR; \ + (TB)->month = MON; \ + (TB)->day = DAY; \ + (TB)->hour = HR; \ + (TB)->minute = MIN; \ + (TB)->second = SEC; \ + (TB)->ticks = TK; } +#endif + +#define task_number( tid ) \ + ( rtems_object_id_get_index( tid ) - \ + rtems_configuration_get_rtems_api_configuration()-> \ + number_of_initialization_tasks ) + +#define rtems_test_assert(__exp) \ + do { \ + if (!(__exp)) { \ + printf( "%s: %d %s\n", __FILE__, __LINE__, #__exp ); \ + rtems_test_exit(0); \ + } \ + } while (0) + +/** + * This assists in clearly disabling warnings on GCC in certain very + * specific cases. + * + * + -Wnon-null - If a method is declared as never having a NULL first + * parameter. We need to explicitly disable this compiler warning to make + * the code warning free. + */ +#ifdef __GNUC__ + #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH _Pragma("GCC diagnostic push") + #define COMPILER_DIAGNOSTIC_SETTINGS_POP _Pragma("GCC diagnostic pop") + #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL \ + _Pragma("GCC diagnostic ignored \"-Wnonnull\"") +#else + #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH + #define COMPILER_DIAGNOSTIC_SETTINGS_POP + #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL +#endif + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3