From ef04aeaeadfe43d26217b7709a147641cd6a2356 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Tue, 4 Jul 2017 10:13:26 +0900 Subject: [PATCH 01/12] NSH library: Fix build break in nsh_command.c with IPv4/IPv6 dual stack. --- nshlib/nsh_command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index cca237151..4f51ca813 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -474,7 +474,7 @@ static const struct cmdmap_s g_cmdmap[] = #if defined(CONFIG_NSH_TELNET) && !defined(CONFIG_NSH_DISABLE_TELNETD) #if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) - {"telnetd", cmd_telnetd, 2, 2, [ipv4|ipv6] }, + {"telnetd", cmd_telnetd, 2, 2, "[ipv4|ipv6]" }, #else {"telnetd", cmd_telnetd, 1, 1, NULL }, #endif From abc01c0e5be27fa0474bd3c9b5f7262e874fa5de Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 4 Jul 2017 15:56:55 -0600 Subject: [PATCH 02/12] =?UTF-8?q?apps/examples/keypadtest:=20REMOVED=20and?= =?UTF-8?q?=20warehoused=20in=20the=20Obsoleted=20repository.=20=20This=20?= =?UTF-8?q?was=20just=20a=20bad=20clone=20of=20apps/examples/hidkbd=20for?= =?UTF-8?q?=20a=20keypad=20driver=20that=20was=20removed=20years=20ago.?= =?UTF-8?q?=E2=80=82=E2=80=82It=20also=20uses=20illegal=20function=20calls?= =?UTF-8?q?=20into=20the=20OS.=E2=80=82=E2=80=82So=20it=20has=20no=20purps?= =?UTF-8?q?e:=E2=80=82=E2=80=82It=20is=20redundant,=20it=20uses=20illegal?= =?UTF-8?q?=20interfaces,=20and=20is=20a=20test=20for=20non-existent=20cod?= =?UTF-8?q?e.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/README.txt | 13 -- examples/keypadtest/.gitignore | 11 -- examples/keypadtest/Kconfig | 29 --- examples/keypadtest/Make.defs | 39 ---- examples/keypadtest/Makefile | 53 ------ examples/keypadtest/keypadtest_main.c | 259 -------------------------- 6 files changed, 404 deletions(-) delete mode 100644 examples/keypadtest/.gitignore delete mode 100644 examples/keypadtest/Kconfig delete mode 100644 examples/keypadtest/Make.defs delete mode 100644 examples/keypadtest/Makefile delete mode 100644 examples/keypadtest/keypadtest_main.c diff --git a/examples/README.txt b/examples/README.txt index a0de89082..00e973be3 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -694,19 +694,6 @@ examples/json on 2011-10-10 so I presume that the code is stable and there is no risk of maintaining duplicate logic in the NuttX repository. -examples/keypadtest -^^^^^^^^^^^^^^^^^^^ - - This is a generic keypad test example. It is similar to the USB hidkbd - example, but makes no assumptions about the underlying keyboard interface. - It uses the interfaces of include/nuttx/input/keypad.h. - - CONFIG_EXAMPLES_KEYPADTEST - Selects the keypadtest example (only need - if the mconf/Kconfig tool is used. - - CONFIG_EXAMPLES_KEYPAD_DEVNAME - The name of the keypad device that will - be opened in order to perform the keypad test. Default: "/dev/keypad" - examples/lcdrw ^^^^^^^^^^^^^^ diff --git a/examples/keypadtest/.gitignore b/examples/keypadtest/.gitignore deleted file mode 100644 index fa1ec7579..000000000 --- a/examples/keypadtest/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Make.dep -/.depend -/.built -/*.asm -/*.obj -/*.rel -/*.lst -/*.sym -/*.adb -/*.lib -/*.src diff --git a/examples/keypadtest/Kconfig b/examples/keypadtest/Kconfig deleted file mode 100644 index 08408ae56..000000000 --- a/examples/keypadtest/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config EXAMPLES_KEYPADTEST - bool "Keypad test example program" - default n - ---help--- - Enable the Keypad test example programe - -if EXAMPLES_KEYPADTEST - - config EXAMPLES_KEYPAD_DEVNAME - string "Keypad Device Name" - default "/dev/keypad" - ---help--- - The name of the keypad device that will be opened in order to perform - the keypad test. Default: "/dev/keypad" - -config EXAMPLES_KEYPADTEST_ENCODED - bool "Use Keyboard CODEC" - default n - ---help--- - Use the keyboard encoded/decoder to pass control information from - the keypad driver to the keypad test. This is the keyboard CODEC - defined in nuttx/input/kbd_codec.h. - -endif diff --git a/examples/keypadtest/Make.defs b/examples/keypadtest/Make.defs deleted file mode 100644 index 74d1fdccd..000000000 --- a/examples/keypadtest/Make.defs +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################ -# apps/examples/keypadtest/Make.defs -# Adds selected applications to apps/ build -# -# Copyright (C) 2015 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# -# 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. -# -############################################################################ - -ifeq ($(CONFIG_EXAMPLES_KEYPADTEST),y) -CONFIGURED_APPS += examples/keypadtest -endif diff --git a/examples/keypadtest/Makefile b/examples/keypadtest/Makefile deleted file mode 100644 index 8faaf7341..000000000 --- a/examples/keypadtest/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -############################################################################ -# apps/examples/keypadtest/Makefile -# -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# -# 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. -# -############################################################################ - --include $(TOPDIR)/Make.defs - -# Keypad Test Example - -ASRCS = -CSRCS = -MAINSRC = keypadtest_main.c - -# helloxx built-in application info - -APPNAME = keypadtest -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 - -CONFIG_XYZ_PROGNAME ?= keypadtest$(EXEEXT) -PROGNAME = $(CONFIG_XYZ_PROGNAME) - -include $(APPDIR)/Application.mk diff --git a/examples/keypadtest/keypadtest_main.c b/examples/keypadtest/keypadtest_main.c deleted file mode 100644 index ea8863755..000000000 --- a/examples/keypadtest/keypadtest_main.c +++ /dev/null @@ -1,259 +0,0 @@ -/**************************************************************************** - * examples/keypadtest/keypadtest_main.c - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifdef CONFIG_EXAMPLES_KEYPADTEST_ENCODED -# include -# include -# include -# include -#endif - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Configuration ************************************************************/ - -/* Sanity checking */ - -/* Provide some default values for other configuration settings */ - -#ifndef CONFIG_EXAMPLES_KEYPAD_DEVNAME -# define CONFIG_EXAMPLES_KEYPAD_DEVNAME "/dev/keypad" -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_KEYPADTEST_ENCODED -struct keypad_instream_s -{ - struct lib_instream_s stream; - FAR char *buffer; - ssize_t nbytes; -}; -#endif - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: keypad_getstream - * - * Description: - * Get one character from the keyboard. - * - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_KEYPADTEST_ENCODED -static int keypad_getstream(FAR struct lib_instream_s *this) -{ - FAR struct keypad_instream_s *kbdstream = (FAR struct keypad_instream_s *)this; - - DEBUGASSERT(kbdstream && kbdstream->buffer); - if (kbdstream->nbytes > 0) - { - kbdstream->nbytes--; - kbdstream->stream.nget++; - return (int)*kbdstream->buffer++; - } - - return EOF; -} -#endif - -/**************************************************************************** - * Name: keypad_decode - * - * Description: - * Decode encoded keyboard input - * - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_KEYPADTEST_ENCODED -static void keypad_decode(FAR char *buffer, ssize_t nbytes) -{ - struct keypad_instream_s kbdstream; - struct kbd_getstate_s state; - uint8_t ch; - int ret; - - /* Initialize */ - - memset(&state, 0, sizeof(struct kbd_getstate_s)); - kbdstream.stream.get = keypad_getstream; - kbdstream.stream.nget = 0; - kbdstream.buffer = buffer; - kbdstream.nbytes = nbytes; - - /* Loop until all of the bytes have been consumed. We implicitly assume - * that the escaped sequences do not cross buffer boundaries. That - * might be true if the read buffer were small or the data rates high. - */ - - for (;;) - { - /* Decode the next thing from the buffer */ - - ret = kbd_decode((FAR struct lib_instream_s *)&kbdstream, &state, &ch); - if (ret == KBD_ERROR) - { - break; - } - - /* Normal data? Or special key? */ - - switch (ret) - { - case KBD_PRESS: /* Key press event */ - printf("Normal Press: %c [%02x]\n", isprint(ch) ? ch : '.', ch); - break; - - case KBD_RELEASE: /* Key release event */ - printf("Normal Release: %c [%02x]\n", isprint(ch) ? ch : '.', ch); - break; - - case KBD_SPECPRESS: /* Special key press event */ - printf("Special Press: %d\n", ch); - break; - - case KBD_SPECREL: /* Special key release event */ - printf("Special Release: %d\n", ch); - break; - - case KBD_ERROR: /* Error or end-of-file */ - printf("EOF: %d\n", ret); - break; - - default: - printf("Unexpected: %d\n", ret); - break; - } - } - - fflush(stdout); -} -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: keypadtest_main - ****************************************************************************/ - -#ifdef CONFIG_BUILD_KERNEL -int main(int argc, FAR char *argv[]) -#else -int keypadtest_main(int argc, char *argv[]) -#endif -{ - char buffer[256]; - ssize_t nbytes; - int fd; - int ret; - - /* First, register the keyboard device(s) */ - - printf("keypadtest_main: Register keyboard device\n"); - ret = keypad_kbdinit(); - if (ret != OK) - { - printf("keypadtest_main: Failed to register the KBD class\n"); - fflush(stdout); - return 1; - } - - /* Open the configured keyboard device. */ - - printf("keypadtest_main: Opening device %s\n", CONFIG_EXAMPLES_KEYPAD_DEVNAME); - fd = open(CONFIG_EXAMPLES_KEYPAD_DEVNAME, O_RDONLY); - if (fd < 0) - { - printf("keypadtest_main: open() failed: %d\n", errno); - fflush(stdout); - return 1; - } - - printf("keypadtest_main: Device %s opened\n", CONFIG_EXAMPLES_KEYPAD_DEVNAME); - fflush(stdout); - - /* Loop until there is a read failure */ - - do - { - /* Read a buffer of data */ - - nbytes = read(fd, buffer, 256); - if (nbytes > 0) - { - /* On success, echo the buffer to stdout */ -#ifdef CONFIG_EXAMPLES_KEYPADTEST_ENCODED - keypad_decode(buffer, nbytes); -#else - (void)write(1, buffer, nbytes); -#endif - } - } - while (nbytes >= 0); - - printf("keypadtest_main: Closing device %s: %d\n", CONFIG_EXAMPLES_KEYPAD_DEVNAME, (int)nbytes); - fflush(stdout); - close(fd); - return 0; -} From c322b7739588711b1204d01f8dddd074244ecb97 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 5 Jul 2017 11:33:58 -0600 Subject: [PATCH 03/12] tools/mkkconfig.bat: Use %cd% instead of %~dp0 for usage of APPSDIR in this batch file. --- tools/mkkconfig.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkkconfig.bat b/tools/mkkconfig.bat index e7865cca2..0bcb04b31 100755 --- a/tools/mkkconfig.bat +++ b/tools/mkkconfig.bat @@ -76,7 +76,7 @@ REM ) ) REM Get the current directory -SET APPSDIR=%~dp0 +SET APPSDIR=%cd% Echo # > %kconfig% Echo # For a description of the syntax of this configuration file, >> %kconfig% From 1829e252f2ef027627a55cf7099cf9a444e331b5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 5 Jul 2017 12:45:03 -0600 Subject: [PATCH 04/12] system/dhcpc: Fix warning about renew_main.o appear twice in rule. --- system/dhcpc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/dhcpc/Makefile b/system/dhcpc/Makefile index 52e937d6e..25c5bafde 100644 --- a/system/dhcpc/Makefile +++ b/system/dhcpc/Makefile @@ -91,7 +91,7 @@ VPATH = all: .built .PHONY: clean depend distclean -$(OBJS) $(RENEW_MAINOBJ): %$(OBJEXT): %.c +$(RENEW_OBJS) $(RENEW_MAINOBJ): %$(OBJEXT): %.c $(call COMPILE, $<, $@) .built: $(OBJS) From 3e37dbc4ab9e97d59c1bda1c0e4df1f039bc1525 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 5 Jul 2017 12:52:46 -0600 Subject: [PATCH 05/12] apps/examples/nettest: Fix incorrectly named file. --- examples/nettest/{nettest_initinit.c => nettest_netinit.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/nettest/{nettest_initinit.c => nettest_netinit.c} (100%) diff --git a/examples/nettest/nettest_initinit.c b/examples/nettest/nettest_netinit.c similarity index 100% rename from examples/nettest/nettest_initinit.c rename to examples/nettest/nettest_netinit.c From 3f644f418438e1c7330dd19512bc18a898cdeb85 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 5 Jul 2017 13:36:24 -0600 Subject: [PATCH 06/12] tools/mkkconfig.bat: Remove quotes in echo. These were begin Echo'ed and generating double quots in the output. --- tools/mkkconfig.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkkconfig.bat b/tools/mkkconfig.bat index 0bcb04b31..a42b12372 100755 --- a/tools/mkkconfig.bat +++ b/tools/mkkconfig.bat @@ -87,7 +87,7 @@ Echo # >> %kconfig% Echo[ >> %kconfig% IF %menu% NEQ "" ( - Echo menu "%menu%" >> %kconfig% + Echo menu %menu% >> %kconfig% ) DIR /B /A:D >_tmp_.dat From 4143c8a985e94e6e959f3cec49c5b06026585ea9 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 6 Jul 2017 14:07:17 -0600 Subject: [PATCH 07/12] Windows build fixes: tools/mkkconfig.bat - switch APPSDIR path to use forward slashes for kconfig-frontends. interpreters/ficl - Reorder some targets that causes GNUwin32 make to behave badly. --- interpreters/ficl/Makefile | 6 +++--- tools/mkkconfig.bat | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interpreters/ficl/Makefile b/interpreters/ficl/Makefile index bc3ae7c43..e99f39816 100644 --- a/interpreters/ficl/Makefile +++ b/interpreters/ficl/Makefile @@ -78,7 +78,7 @@ SRC_DEPPATH = --dep-path src VPATH = src:$(FICL_SUBDIR) all: .built -.PHONY: debug context depend clean distclean +.PHONY: debug context depend clean distclean preconfig $(AOBJS): %$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) @@ -113,6 +113,6 @@ distclean: clean $(call DELFILE, Make.dep) $(call DELFILE, .depend) --include Make.dep -.PHONY: preconfig preconfig: + +-include Make.dep diff --git a/tools/mkkconfig.bat b/tools/mkkconfig.bat index a42b12372..fca5597f7 100755 --- a/tools/mkkconfig.bat +++ b/tools/mkkconfig.bat @@ -77,6 +77,7 @@ REM ) REM Get the current directory SET APPSDIR=%cd% +SET APPSDIR=%APPSDIR:\=/% Echo # > %kconfig% Echo # For a description of the syntax of this configuration file, >> %kconfig% From 175610de486d514dff12f521726ae587d56faeee Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 6 Jul 2017 14:27:16 -0600 Subject: [PATCH 08/12] Windows build fixes: Backslash as a delimiter causes problems in pattern subsitutions --- platform/Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/platform/Makefile b/platform/Makefile index 8f562f779..dc22f3218 100644 --- a/platform/Makefile +++ b/platform/Makefile @@ -37,7 +37,10 @@ -include $(TOPDIR)/Make.defs CONFIG_ARCH_BOARD ?= dummy -DELIM ?= $(strip /) + +# REVISIT: Backslash causes problems in $(COBJS) target +# DELIM ?= $(strip /) +DELIM := $(strip /) include $(APPDIR)$(DELIM)Make.defs @@ -46,11 +49,11 @@ include $(APPDIR)$(DELIM)Make.defs ifeq ($(DIRLINK),) ifeq ($(CONFIG_WINDOWS_NATIVE),y) -DIRLINK = $(TOPDIR)/tools/link.bat -DIRUNLINK = $(TOPDIR)/tools/unlink.bat +DIRLINK = $(TOPDIR)$(DELIM)tools$(DELIM)link.bat +DIRUNLINK = $(TOPDIR)$(DELIM)tools$(DELIM)unlink.bat else -DIRLINK = $(TOPDIR)/tools/link.sh -DIRUNLINK = $(TOPDIR)/tools/unlink.sh +DIRLINK = $(TOPDIR)$(DELIM)tools$(DELIM)link.sh +DIRUNLINK = $(TOPDIR)$(DELIM)tools$(DELIM)unlink.sh endif endif From 013a8a0774a60fd83455a87ed4127d4559b812dc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Jul 2017 20:17:56 -0600 Subject: [PATCH 09/12] platform/Makefile: More attempts to fix for Windows native build. --- platform/Makefile | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/platform/Makefile b/platform/Makefile index dc22f3218..cc85b4833 100644 --- a/platform/Makefile +++ b/platform/Makefile @@ -37,10 +37,7 @@ -include $(TOPDIR)/Make.defs CONFIG_ARCH_BOARD ?= dummy - -# REVISIT: Backslash causes problems in $(COBJS) target -# DELIM ?= $(strip /) -DELIM := $(strip /) +DELIM ?= $(strip /) include $(APPDIR)$(DELIM)Make.defs @@ -85,8 +82,11 @@ CSRCS = -include $(GNUDIR)$(DELIM)Make.defs -include $(PLATFORMDIR)$(DELIM)Make.defs -AOBJS = $(patsubst %.S, bin$(DELIM)%$(OBJEXT), $(ASRCS)) -COBJS = $(patsubst %.c, bin$(DELIM)%$(OBJEXT), $(CSRCS)) +# REVISIT: Backslash causes problems in $(A/COBJS) patsubst +# AOBJS = $(patsubst %.S, bin$(DELIM)%$(OBJEXT), $(ASRCS)) +# COBJS = $(patsubst %.c, bin$(DELIM)%$(OBJEXT), $(CSRCS)) +AOBJS = $(patsubst %.S, bin/%$(OBJEXT), $(ASRCS)) +COBJS = $(patsubst %.c, bin/%$(OBJEXT), $(CSRCS)) SRCS = $(ASRCS) $(CSRCS) OBJS = $(AOBJS) $(COBJS) @@ -107,12 +107,16 @@ all: .built .PHONY: context .depend depend clean distclean ifneq ($(ASRCS),) -$(AOBJS): bin$(DELIM)%$(OBJEXT): %.S +# REVISIT: Backslash causes problems in $(AOBJS) target +# $(AOBJS): bin$(DELIM)%$(OBJEXT): %.S +$(AOBJS): bin/%$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) endif ifneq ($(CSRCS),) -$(COBJS): bin$(DELIM)%$(OBJEXT): %.c +# REVISIT: Backslash causes problems in $(COBJS) target +# $(COBJS): bin$(DELIM)%$(OBJEXT): %.c +$(COBJS): bin/%$(OBJEXT): %.c $(call COMPILE, $<, $@) endif From 47a42852e5e952afc11c615cd787c2c78660737d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 7 Jul 2017 13:07:21 -0600 Subject: [PATCH 10/12] apps/examples/ipforward: Add beginning of an IP forwarding example using only TUN devices. --- examples/README.txt | 7 + examples/ipforward/.gitignore | 11 ++ examples/ipforward/Kconfig | 31 ++++ examples/ipforward/Make.defs | 39 +++++ examples/ipforward/Makefile | 56 +++++++ examples/ipforward/ipforward.c | 298 +++++++++++++++++++++++++++++++++ 6 files changed, 442 insertions(+) create mode 100644 examples/ipforward/.gitignore create mode 100644 examples/ipforward/Kconfig create mode 100644 examples/ipforward/Make.defs create mode 100644 examples/ipforward/Makefile create mode 100644 examples/ipforward/ipforward.c diff --git a/examples/README.txt b/examples/README.txt index 00e973be3..3ddeaa8f7 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -681,6 +681,13 @@ examples/i2cchar each time that this test executes. Not available in the kernel build mode. +examples/ipforward +^^^^^^^^^^^^^^^^^^ + + A simple test of IP forwarding using TUN devices. This can be used on any + platform, but was intended for use on the simulation platform because it + performs a test of IP forwarding without the use of hardware. + examples/json ^^^^^^^^^^^^^ diff --git a/examples/ipforward/.gitignore b/examples/ipforward/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/examples/ipforward/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/examples/ipforward/Kconfig b/examples/ipforward/Kconfig new file mode 100644 index 000000000..148dac1f2 --- /dev/null +++ b/examples/ipforward/Kconfig @@ -0,0 +1,31 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_IPFORWARD + bool "IP forwarding example" + default n + depends on NET_TUN && NET_TCP + ---help--- + Enable the IP forwarding example + +if EXAMPLES_IPFORWARD + +config EXAMPLES_IPFORWARD_PROGNAME + string "IP forwarding rogram name" + default "ipfwd" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config EXAMPLES_IPFORWARD_PRIORITY + int "IP forwarding task priority" + default 100 + +config EXAMPLES_IPFORWARD_STACKSIZE + int "IP forwarding stack size" + default 2048 + +endif diff --git a/examples/ipforward/Make.defs b/examples/ipforward/Make.defs new file mode 100644 index 000000000..3cfe21de0 --- /dev/null +++ b/examples/ipforward/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/ipforward/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_IPFORWARD),y) +CONFIGURED_APPS += examples/ipforward +endif diff --git a/examples/ipforward/Makefile b/examples/ipforward/Makefile new file mode 100644 index 000000000..f2450ddba --- /dev/null +++ b/examples/ipforward/Makefile @@ -0,0 +1,56 @@ +############################################################################ +# apps/examples/ipforward/Makefile +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +# Hello, World! built-in application info + +CONFIG_EXAMPLES_IPFORWARD_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_IPFORWARD_STACKSIZE ?= 2048 + +APPNAME = ipfwd +PRIORITY = $(CONFIG_EXAMPLES_IPFORWARD_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_IPFORWARD_STACKSIZE) + +# Hello, World! Example + +ASRCS = +CSRCS = +MAINSRC = ipforward.c + +CONFIG_EXAMPLES_IPFORWARD_PROGNAME ?= ipfwd$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_IPFORWARD_PROGNAME) + +include $(APPDIR)/Application.mk diff --git a/examples/ipforward/ipforward.c b/examples/ipforward/ipforward.c new file mode 100644 index 000000000..3f6487f72 --- /dev/null +++ b/examples/ipforward/ipforward.c @@ -0,0 +1,298 @@ +/**************************************************************************** + * examplex/ipforward/ipforward.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "netutils/netlib.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MAX_DEVNAME 8 + +#ifdef CONFIG_NET_IPv6 +# define IPADDR_TYPE FAR const uint16_t * +#else +# define IPADDR_TYPE uint32_t +#endif + +/**************************************************************************** + * Name: Private Types + ****************************************************************************/ + +struct ipfwd_tun_s +{ + int it_fd; + char it_devname[MAX_DEVNAME]; +}; + +struct ipfwd_state_s +{ + struct ipfwd_tun_s if_tun0; + struct ipfwd_tun_s if_tun1; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +static const uint16_t g_tun0_ipaddr[8] = +{ + HTONS(0x7c00), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0x0097), +}; + +static const uint16_t g_tun1_ipaddr[8] = +{ + HTONS(0x7c00), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0x0139), +}; + +static const uint16_t g_netmask[8] = +{ + HTONS(0xffff), + HTONS(0xffff), + HTONS(0xffff), + HTONS(0xffff), + HTONS(0xffff), + HTONS(0xffff), + HTONS(0xffff), + HTONS(0), +}; +#else +static const uint32_t g_tun0_ipaddr = HTONL(0x0a000097); +static const uint32_t g_tun1_ipaddr = HTONL(0x0a000039); +static const uint32_t g_netmask = HTONL(0xffffff00); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipfwd_tun_configure + ****************************************************************************/ + +static int ipfwd_tun_configure(FAR struct ipfwd_tun_s *tun) +{ + struct ifreq ifr; + int errcode; + int ret; + + tun->it_fd = open("/dev/tun", O_RDWR); + if (tun->it_fd < 0) + { + errcode = errno; + fprintf(stderr, "ERROR: Failed to open /dev/tun: %d\n", errcode); + return -errcode; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TUN; + + ret = ioctl(tun->it_fd, TUNSETIFF, (unsigned long)&ifr); + if (ret < 0) + { + errcode = errno; + fprintf(stderr, "ERROR: ioctl TUNSETIFF failed: %d\n", errcode); + close(tun->it_fd); + return -errcode; + } + + strncpy(tun->it_devname, ifr.ifr_name, MAX_DEVNAME); + printf("Created TUN device: %s\n", tun->it_devname); + return 0; +} + +/**************************************************************************** + * Name: ipfwd_netconfig + ****************************************************************************/ + +static int ipfwd_netconfig(FAR struct ipfwd_tun_s *tun, IPADDR_TYPE ipaddr, + IPADDR_TYPE netmask) +{ + int ret; + +#ifdef CONFIG_NET_IPv6 + + struct in6_addr addr; + + memcpy(addr.s6_addr16, ipaddr, 8 * sizeof(uint16_t)); + ret = netlib_set_ipv6addr(tun->it_devname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: netlib_set_ipv6addr() failed\n", ret); + return ret; + } + + memcpy(addr.s6_addr16, netmask, 8 * sizeof(uint16_t)); + ret = netlib_set_ipv6netmask(tun->it_devname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: netlib_set_ipv6netmask() failed\n", ret); + return ret; + } + +#else /* CONFIG_NET_IPv4 */ + + struct in_addr addr; + + addr.s_addr = ipaddr; + ret = netlib_set_ipv4addr(tun->it_devname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: netlib_set_ipv4addr() failed\n", ret); + return ret; + } + + addr.s_addr = netmask; + ret = netlib_set_ipv4netmask(tun->it_devname, &addr); + if (ret < 0) + { + fprintf(stderr, "ERROR: netlib_set_ipv4netmask() failed\n", ret); + return ret; + } +#endif + + netlib_ifup(tun->it_devname); + return 0; +} + +/**************************************************************************** + * Name: ipfwd_receiver + ****************************************************************************/ + +/**************************************************************************** + * Name: ipfwd_sender + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fstest_main + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int ipfwd_main(int argc, char *argv[]) +#endif +{ + struct ipfwd_state_s fwd; + int errcode = EXIT_SUCCESS; + int ret; + + /* Initialize the first TUN device */ + + ret = ipfwd_tun_configure(&fwd.if_tun0); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to create tun0: %d\n", ret); + goto errout; + } + + ret = ipfwd_netconfig(&fwd.if_tun0, g_tun0_ipaddr, g_netmask); + if (ret < 0) + { + fprintf(stderr, "ERROR: ipfwd_netconfig failed: %d\n", ret); + goto errout_with_tun0; + } + + /* Initialize the second TUN device */ + + ret = ipfwd_tun_configure(&fwd.if_tun1); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to create tun1: %d\n", ret); + goto errout_with_tun0; + } + + ret = ipfwd_netconfig(&fwd.if_tun0, g_tun0_ipaddr, g_netmask); + if (ret < 0) + { + fprintf(stderr, "ERROR: ipfwd_netconfig failed: %d\n", ret); + errcode = EXIT_FAILURE; + goto errout_with_tun1; + } + + /* Start receiver thread */ + + /* Start sender thread */ + + /* Wait for sender thread to terminate */ + +errout_with_receiver: + /* Wait for receiver thread to terminate */ + +errout_with_tun1: + close(fwd.if_tun1.it_fd); +errout_with_tun0: + close(fwd.if_tun0.it_fd); +errout: + return errcode; +} From 37bb767089a4894e57bc26c628d08011300d3f1e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 7 Jul 2017 14:59:45 -0600 Subject: [PATCH 11/12] Completes code for apps/examples/ipforward. Still untested. --- examples/ipforward/ipforward.c | 418 ++++++++++++++++++++++++++++++++- 1 file changed, 411 insertions(+), 7 deletions(-) diff --git a/examples/ipforward/ipforward.c b/examples/ipforward/ipforward.c index 3f6487f72..be2782bae 100644 --- a/examples/ipforward/ipforward.c +++ b/examples/ipforward/ipforward.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,8 @@ #include #include +#include +#include #include #include "netutils/netlib.h" @@ -58,12 +61,17 @@ * Pre-processor Definitions ****************************************************************************/ -#define MAX_DEVNAME 8 +#define MAX_DEVNAME 8 +#define IPFWD_BUFSIZE CONFIG_NET_TUN_MTU +#define NBYTES_PER_LINE 32 +#define IPFWD_NPACKETS 3 #ifdef CONFIG_NET_IPv6 -# define IPADDR_TYPE FAR const uint16_t * +# define IPADDR_TYPE FAR const uint16_t * +# define IP_HDRLEN IPv6_HDRLEN #else -# define IPADDR_TYPE uint32_t +# define IPADDR_TYPE uint32_t +# define IP_HDRLEN IPv4_HDRLEN #endif /**************************************************************************** @@ -72,14 +80,24 @@ struct ipfwd_tun_s { - int it_fd; - char it_devname[MAX_DEVNAME]; + int it_fd; + char it_devname[MAX_DEVNAME]; }; struct ipfwd_state_s { struct ipfwd_tun_s if_tun0; struct ipfwd_tun_s if_tun1; + pthread_t if_receiver; + pthread_t if_sender; +}; + +struct ipfwd_arg_s +{ + int ia_fd; + IPADDR_TYPE ia_srcipaddr; + IPADDR_TYPE ia_destipaddr; + uint8_t ia_buffer[IPFWD_BUFSIZE]; }; /**************************************************************************** @@ -128,6 +146,11 @@ static const uint32_t g_tun1_ipaddr = HTONL(0x0a000039); static const uint32_t g_netmask = HTONL(0xffffff00); #endif +static const char g_payload[] = "Hi there, TUN receiver!"; +#ifdef CONFIG_NET_IPv4 +static uint16_t g_ipid; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -221,14 +244,355 @@ static int ipfwd_netconfig(FAR struct ipfwd_tun_s *tun, IPADDR_TYPE ipaddr, return 0; } +/**************************************************************************** + * Name: Checksums + ****************************************************************************/ + +static uint16_t chksum(uint16_t sum, FAR const uint8_t *data, uint16_t len) +{ + FAR const uint8_t *dataptr; + FAR const uint8_t *last_byte; + uint16_t t; + + dataptr = data; + last_byte = data + len - 1; + + while (dataptr < last_byte) + { + /* At least two more bytes */ + + t = ((uint16_t)dataptr[0] << 8) + dataptr[1]; + sum += t; + if (sum < t) + { + sum++; /* carry */ + } + + dataptr += 2; + } + + if (dataptr == last_byte) + { + t = (dataptr[0] << 8) + 0; + sum += t; + if (sum < t) + { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + + return sum; +} + +#ifdef CONFIG_NET_IPv4 +static uint16_t ipv4_chksum(FAR const uint8_t *buffer) +{ + uint16_t sum; + + sum = chksum(0, buffer, IPv4_HDRLEN); + return (sum == 0) ? 0xffff : htons(sum); +} +#endif + +uint16_t tcp_chksum(FAR uint8_t *buffer) +{ +#ifdef CONFIG_NET_IPv6 + FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)buffer; + uint16_t upperlen; + uint16_t sum; + + /* The length reported in the IPv6 header is the length of the payload + * that follows the header. + */ + + upperlen = ((uint16_t)ipv6->len[0] << 8) + ipv6->len[1]; + + /* The checksum is calculated starting with a pseudo-header of IPv6 header + * fields according to the IPv6 standard, which consists of the source + * and destination addresses, the packet length and the next header field. + */ + + sum = upperlen + IP_PROTO_TCP; + + /* Sum IP source and destination addresses. */ + + sum = chksum(sum, (FAR uint8_t *)&ipv6->srcipaddr, 2 * sizeof(net_ipv6addr_t)); + + /* Sum IP payload data. */ + + sum = chksum(sum, &buffer[IPv6_HDRLEN], upperlen); + return (sum == 0) ? 0xffff : htons(sum); +#else + FAR struct ipv4_hdr_s *ipv4 = (FAR struct ipv4_hdr_s *)buffer; + uint16_t upperlen; + uint16_t sum; + + /* The length reported in the IPv4 header is the length of both the IPv4 + * header and the payload that follows the header. We need to subtract + * the size of the IPv4 header to get the size of the payload. + */ + + upperlen = (((uint16_t)(ipv4->len[0]) << 8) + ipv4->len[1]) - IPv4_HDRLEN; + + /* First sum pseudo-header. */ + /* IP protocol and length fields. This addition cannot carry. */ + + sum = upperlen + IP_PROTO_TCP; + + /* Sum IP source and destination addresses. */ + + sum = chksum(sum, (FAR uint8_t *)&ipv4->srcipaddr, 2 * sizeof(in_addr_t)); + + /* Sum IP payload data. */ + + sum = chksum(sum, &buffer[IPv4_HDRLEN], upperlen); + return (sum == 0) ? 0xffff : htons(sum); +#endif +} + +/**************************************************************************** + * Name: ipfwd_dumppkt (and friends) + ****************************************************************************/ + +static char lib_nibble(unsigned char nibble) +{ + if (nibble < 10) + { + return '0' + nibble; + } + else + { + return 'a' + nibble - 10; + } +} + +static void ipfwd_dumpbuffer(FAR uint8_t *buffer, size_t buflen) +{ + unsigned int i; + unsigned int j; + unsigned int k; + + for (i = 0; i < buflen; i += NBYTES_PER_LINE) + { + /* Generate hex values: 2 * NBYTES_PER_LINE + 1 bytes */ + + for (j = 0; j < NBYTES_PER_LINE; j++) + { + k = i + j; + + putchar(' '); + putchar(' '); + + if (j == (NBYTES_PER_LINE / 2)) + { + putchar(' '); + } + + if (k < buflen) + { + putchar(lib_nibble((buffer[k] >> 4) & 0xf)); + putchar(lib_nibble(buffer[k] & 0xf)); + } + else + { + putchar(' '); + putchar(' '); + } + } + + putchar('\n'); + } +} + +static void ipfwd_dumppkt(FAR uint8_t *buffer, size_t buflen) +{ + size_t dumpsize; + + if (buflen <= 0) + { + return; + } + + dumpsize = IP_HDRLEN; + if (dumpsize > buflen) + { + dumpsize = buflen; + } + + printf("IP Header:\n"); + ipfwd_dumpbuffer(buffer, dumpsize); + + buffer += dumpsize; + buflen -= dumpsize; + if (buflen <= 0) + { + return; + } + + dumpsize = TCP_HDRLEN; + if (dumpsize > buflen) + { + dumpsize = buflen; + } + + printf("TCP Header:\n"); + ipfwd_dumpbuffer(buffer, dumpsize); + + buffer += dumpsize; + buflen -= dumpsize; + if (buflen <= 0) + { + return; + } + + printf("Payload:\n"); + ipfwd_dumpbuffer(buffer, buflen); +} + /**************************************************************************** * Name: ipfwd_receiver ****************************************************************************/ +static FAR void *ipfwd_receiver(FAR void *arg) +{ + FAR struct ipfwd_arg_s *fwd = (FAR struct ipfwd_arg_s *)arg; + ssize_t nread; + int errcode; + int i; + + for (i = 0; i < IPFWD_NPACKETS; i++) + { + nread = read(fwd->ia_fd, fwd->ia_buffer, IPFWD_BUFSIZE); + if (nread < 0) + { + errcode = errno; + fprintf(stderr, "ERROR: read() failed: %d\n", errcode); + break; + } + + printf("Received packet %d: size=%lu\n", i+1, (unsigned long)nread); + ipfwd_dumppkt(fwd->ia_buffer, nread); + } + + return NULL; +} + /**************************************************************************** * Name: ipfwd_sender ****************************************************************************/ +static FAR void *ipfwd_sender(FAR void *arg) +{ + FAR struct ipfwd_arg_s *fwd = (FAR struct ipfwd_arg_s *)arg; +#ifdef CONFIG_NET_IPv6 + FAR struct ipv6_hdr_s *ipv6; +#else + FAR struct ipv4_hdr_s *ipv4; +#endif + FAR struct tcp_hdr_s *tcp; + FAR char *payload; + size_t paysize; + size_t pktlen; + ssize_t nwritten; + int errcode; + int i; + + paysize = sizeof(g_payload); + + for (i = 0; i < IPFWD_NPACKETS; i++) + { +#ifdef CONFIG_NET_IPv6 + ipv6 = (FAR struct ipv6_hdr_s *)fwd->ia_buffer; + + /* Set up the IPv6 header */ + + ipv6->vtc = 0x60; /* Version/traffic class (MS) */ + ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */ + ipv6->flow = 0; /* Flow label (LS) */ + + /* Length excludes the IPv6 header */ + + pktlen = TCP_HDRLEN + paysize; + ipv6->len[0] = (pktlen >> 8); + ipv6->len[1] = (pktlen & 0xff); + + ipv6->proto = IP_PROTO_TCP; /* Next header */ + ipv6->ttl = 255; /* Hop limit */ + + /* Set source and destination address */ + + net_ipv6addr_copy(ipv6->srcipaddr, fwd->ia_srcipaddr); + net_ipv6addr_copy(ipv6->destipaddr, fwd->ia_destipaddr); + + pktlen = IPv6_HDRLEN + TCP_HDRLEN + paysize; + tcp = (FAR struct tcp_hdr_s *)&fwd->ia_buffer[IPv6_HDRLEN]; +#else + ipv4 = (FAR struct ipv4_hdr_s *)fwd->ia_buffer; + + /* Set up the IPv4 header */ + + ipv4->vhl = 0x45; + ipv4->tos = 0; + + pktlen = IPv4_HDRLEN + TCP_HDRLEN + paysize; + ipv4->len[0] = (pktlen >> 8); + ipv4->len[1] = (pktlen & 0xff); + + ++g_ipid; + ipv4->ipid[0] = g_ipid >> 8; + ipv4->ipid[1] = g_ipid & 0xff; + + ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8; + ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff; + ipv4->ttl = IP_TTL; + ipv4->proto = IP_PROTO_TCP; + + net_ipv4addr_hdrcopy(ipv4->srcipaddr, fwd->ia_srcipaddr); + net_ipv4addr_hdrcopy(ipv4->destipaddr, fwd->ia_srcipaddr); + + /* Calculate IP checksum. */ + + ipv4->ipchksum = 0; + ipv4->ipchksum = ~(ipv4_chksum(fwd->ia_buffer)); + + tcp = (FAR struct tcp_hdr_s *)&fwd->ia_buffer[IPv4_HDRLEN]; +#endif + + /* Set up the TCP header. NOTE: Most of the elements are irrelevant + * in this test. The forwarding is L2 layer only and the L3 header + * content is not used in the forwarding. + */ + + memset(tcp, 0, sizeof(struct tcp_hdr_s)); + + tcp->srcport = HTONS(0x1234); + tcp->destport = HTONS(0xabcd); + tcp->tcpoffset = (TCP_HDRLEN / 4) << 4; + + payload = (FAR char *)tcp + TCP_HDRLEN; + memcpy(payload, g_payload, paysize); + + tcp->tcpchksum = ~tcp_chksum(fwd->ia_buffer); + + printf("Sending packet %d: size=%lu\n", i+1, (unsigned long)pktlen); + ipfwd_dumppkt(fwd->ia_buffer, pktlen); + + nwritten = write(fwd->ia_fd, fwd->ia_buffer, pktlen); + if (nwritten < 0) + { + errcode = errno; + fprintf(stderr, "ERROR: write() failed: %d\n", errcode); + break; + } + + printf(" %lu bytes sent\n", (unsigned long)nwritten); + } + + return NULL; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -244,6 +608,9 @@ int ipfwd_main(int argc, char *argv[]) #endif { struct ipfwd_state_s fwd; + struct ipfwd_arg_s tun0arg; + struct ipfwd_arg_s tun1arg; + FAR void *value; int errcode = EXIT_SUCCESS; int ret; @@ -280,15 +647,52 @@ int ipfwd_main(int argc, char *argv[]) goto errout_with_tun1; } - /* Start receiver thread */ + /* Start receiver thread on tun0 */ - /* Start sender thread */ + tun0arg.ia_fd = fwd.if_tun0.it_fd; + tun0arg.ia_srcipaddr = g_tun0_ipaddr; + tun0arg.ia_destipaddr = g_tun1_ipaddr; + + ret = pthread_create(&fwd.if_receiver, NULL, ipfwd_receiver, &tun0arg); + if (ret != 0) + { + fprintf(stderr, "ERROR: pthread_create() failed for receiver: %d\n", ret); + errcode = EXIT_FAILURE; + goto errout_with_tun1; + } + + /* Start sender thread on tun1 */ + + tun1arg.ia_fd = fwd.if_tun1.it_fd; + tun1arg.ia_srcipaddr = g_tun1_ipaddr; + tun1arg.ia_destipaddr = g_tun0_ipaddr; + + ret = pthread_create(&fwd.if_sender, NULL, ipfwd_sender, &tun1arg); + if (ret != 0) + { + fprintf(stderr, "ERROR: pthread_create() failed for sender: %d\n", ret); + errcode = EXIT_FAILURE; + goto errout_with_receiver; + } /* Wait for sender thread to terminate */ + ret = pthread_join(fwd.if_sender, &value); + if (ret != OK) + { + fprintf(stderr, "ERROR: pthread_join() failed for sender: %d\n", ret); + } + errout_with_receiver: /* Wait for receiver thread to terminate */ + pthread_kill(fwd.if_receiver, 9); + ret = pthread_join(fwd.if_receiver, &value); + if (ret != OK) + { + fprintf(stderr, "ERROR: pthread_join() failed for receiver: %d\n", ret); + } + errout_with_tun1: close(fwd.if_tun1.it_fd); errout_with_tun0: From 1657d1fff5f0749d794967951d405f98f1fab527 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 7 Jul 2017 17:32:37 -0600 Subject: [PATCH 12/12] apps/examples/ipforward: A few fixes, but still no cigar. --- examples/ipforward/ipforward.c | 89 +++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/examples/ipforward/ipforward.c b/examples/ipforward/ipforward.c index be2782bae..36b484ffe 100644 --- a/examples/ipforward/ipforward.c +++ b/examples/ipforward/ipforward.c @@ -103,9 +103,24 @@ struct ipfwd_arg_s /**************************************************************************** * Private Data ****************************************************************************/ +/* Network addresses: + * + * g_tun0_laddr is the address assigned to the tun0 device. g_tun1_laddr + * is the address assigned to tun1 device. Both are loal addresses can the + * target can received addresses on. + * + * g_netmask is the network mask that defines the networks: tun0 is on + * network 0; tun1 is on network 1. + * + * g_tun0_raddr and g_tun1_raddr are addresses that are not local to the + * target, but should instead be forwarded via the correct network device. + * g_tun0_raddr lies on network 0 and g_tun1_raddr lies on network 1 and so + * should be forwarded from network 0 to network1 by the NuttX IP forwarding + * logic. + */ #ifdef CONFIG_NET_IPv6 -static const uint16_t g_tun0_ipaddr[8] = +static const uint16_t g_tun0_laddr[8] = { HTONS(0x7c00), HTONS(0), @@ -113,11 +128,11 @@ static const uint16_t g_tun0_ipaddr[8] = HTONS(0), HTONS(0), HTONS(0), - HTONS(0), + HTONS(0), /* Netork 0 */ HTONS(0x0097), }; -static const uint16_t g_tun1_ipaddr[8] = +static const uint16_t g_tun1_laddr[8] = { HTONS(0x7c00), HTONS(0), @@ -125,10 +140,34 @@ static const uint16_t g_tun1_ipaddr[8] = HTONS(0), HTONS(0), HTONS(0), - HTONS(0), + HTONS(0x0001), /* Netork 1 */ HTONS(0x0139), }; +static const uint16_t g_tun0_raddr[8] = +{ + HTONS(0x7c00), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), /* Netork 0 */ + HTONS(0x0062), +}; + +static const uint16_t g_tun1_raddr[8] = +{ + HTONS(0x7c00), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0), + HTONS(0x0001), /* Netork 1 */ + HTONS(0x0147), +}; + static const uint16_t g_netmask[8] = { HTONS(0xffff), @@ -141,9 +180,11 @@ static const uint16_t g_netmask[8] = HTONS(0), }; #else -static const uint32_t g_tun0_ipaddr = HTONL(0x0a000097); -static const uint32_t g_tun1_ipaddr = HTONL(0x0a000039); -static const uint32_t g_netmask = HTONL(0xffffff00); +static const uint32_t g_tun0_laddr = HTONL(0x0a000097); /* Netork 0 */ +static const uint32_t g_tun1_laddr = HTONL(0x0a000139); /* Netork 1 */ +static const uint32_t g_tun0_raddr = HTONL(0x0a000062); /* Netork 0 */ +static const uint32_t g_tun1_raddr = HTONL(0x0a000147); /* Netork 1 */ +static const uint32_t g_netmask = HTONL(0xffffff00); #endif static const char g_payload[] = "Hi there, TUN receiver!"; @@ -376,15 +417,15 @@ static void ipfwd_dumpbuffer(FAR uint8_t *buffer, size_t buflen) for (i = 0; i < buflen; i += NBYTES_PER_LINE) { + putchar(' '); + putchar(' '); + /* Generate hex values: 2 * NBYTES_PER_LINE + 1 bytes */ for (j = 0; j < NBYTES_PER_LINE; j++) { k = i + j; - putchar(' '); - putchar(' '); - if (j == (NBYTES_PER_LINE / 2)) { putchar(' '); @@ -623,10 +664,10 @@ int ipfwd_main(int argc, char *argv[]) goto errout; } - ret = ipfwd_netconfig(&fwd.if_tun0, g_tun0_ipaddr, g_netmask); + ret = ipfwd_netconfig(&fwd.if_tun0, g_tun0_laddr, g_netmask); if (ret < 0) { - fprintf(stderr, "ERROR: ipfwd_netconfig failed: %d\n", ret); + fprintf(stderr, "ERROR: ipfwd_netconfig for tun0 failed: %d\n", ret); goto errout_with_tun0; } @@ -639,21 +680,21 @@ int ipfwd_main(int argc, char *argv[]) goto errout_with_tun0; } - ret = ipfwd_netconfig(&fwd.if_tun0, g_tun0_ipaddr, g_netmask); + ret = ipfwd_netconfig(&fwd.if_tun1, g_tun1_laddr, g_netmask); if (ret < 0) { - fprintf(stderr, "ERROR: ipfwd_netconfig failed: %d\n", ret); + fprintf(stderr, "ERROR: ipfwd_netconfig tun1 failed: %d\n", ret); errcode = EXIT_FAILURE; goto errout_with_tun1; } - /* Start receiver thread on tun0 */ + /* Start receiver thread on tun1 */ - tun0arg.ia_fd = fwd.if_tun0.it_fd; - tun0arg.ia_srcipaddr = g_tun0_ipaddr; - tun0arg.ia_destipaddr = g_tun1_ipaddr; + tun1arg.ia_fd = fwd.if_tun1.it_fd; + tun1arg.ia_srcipaddr = g_tun1_raddr; + tun1arg.ia_destipaddr = g_tun0_raddr; - ret = pthread_create(&fwd.if_receiver, NULL, ipfwd_receiver, &tun0arg); + ret = pthread_create(&fwd.if_receiver, NULL, ipfwd_receiver, &tun1arg); if (ret != 0) { fprintf(stderr, "ERROR: pthread_create() failed for receiver: %d\n", ret); @@ -661,13 +702,13 @@ int ipfwd_main(int argc, char *argv[]) goto errout_with_tun1; } - /* Start sender thread on tun1 */ + /* Start sender thread on tun0 */ - tun1arg.ia_fd = fwd.if_tun1.it_fd; - tun1arg.ia_srcipaddr = g_tun1_ipaddr; - tun1arg.ia_destipaddr = g_tun0_ipaddr; + tun0arg.ia_fd = fwd.if_tun0.it_fd; + tun0arg.ia_srcipaddr = g_tun0_raddr; + tun0arg.ia_destipaddr = g_tun1_raddr; - ret = pthread_create(&fwd.if_sender, NULL, ipfwd_sender, &tun1arg); + ret = pthread_create(&fwd.if_sender, NULL, ipfwd_sender, &tun0arg); if (ret != 0) { fprintf(stderr, "ERROR: pthread_create() failed for sender: %d\n", ret);