From 4a5152fc915435b893dfaeab6035962396f5ac94 Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Wed, 21 Oct 2020 14:34:10 +0200 Subject: [PATCH] netutils/netcat: Add netcat tool Check readme for usage and demo: [![weboftwins-osvehicle-2020-rzr]( https://files.mastodon.social/media_attachments/files/105/163/916/892/863/178/original/05468e28b4463f95.png )]( https://mastodon.social/@rzr/105225153152922220#weboftwins-osvehicle-2020-rzr "weboftwins-osvehicle-2020-rzr") Change-Id: I2eac915954ca6cf585f01addb53df581631a7ae6 Bug: https://github.com/apache/incubator-nuttx/pull/1999 Relate-to: https://github.com/rzr/aframe-smart-home/issues/3 Origin: https://github.com/CrossStream/nuttx-apps/tree/sandbox/rzr/review/master/netutils/netcat Forwarded: https://github.com/apache/incubator-nuttx-apps/pull/482 Signed-off-by: Philippe Coval --- netutils/netcat/Kconfig | 51 ++++++++ netutils/netcat/Make.defs | 25 ++++ netutils/netcat/Makefile | 36 ++++++ netutils/netcat/README.md | 75 +++++++++++ netutils/netcat/netcat_main.c | 231 ++++++++++++++++++++++++++++++++++ 5 files changed, 418 insertions(+) create mode 100644 netutils/netcat/Kconfig create mode 100644 netutils/netcat/Make.defs create mode 100644 netutils/netcat/Makefile create mode 100644 netutils/netcat/README.md create mode 100644 netutils/netcat/netcat_main.c diff --git a/netutils/netcat/Kconfig b/netutils/netcat/Kconfig new file mode 100644 index 000000000..78dd30603 --- /dev/null +++ b/netutils/netcat/Kconfig @@ -0,0 +1,51 @@ +############################################################################# +# +# netutils/netcat/Kconfig +# netcat networking application +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################# + +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config NETUTILS_NETCAT + tristate "NetCat tool" + default n + depends on NET_TCP + ---help--- + Enable the NetCat TCP/IP swiss army tool + +if NETUTILS_NETCAT + +config NETUTILS_NETCAT_PROGNAME + string "Program name" + default "netcat" + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config NETUTILS_NETCAT_PRIORITY + int "netcat task priority" + default 100 + +config NETUTILS_NETCAT_STACKSIZE + int "netcat stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/netutils/netcat/Make.defs b/netutils/netcat/Make.defs new file mode 100644 index 000000000..3b92c2f58 --- /dev/null +++ b/netutils/netcat/Make.defs @@ -0,0 +1,25 @@ +############################################################################# +# +# netutils/netcat/Make.defs +# netcat sample networking application +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################# + +ifneq ($(CONFIG_NETUTILS_NETCAT),) +CONFIGURED_APPS += $(APPDIR)/netutils/netcat +endif diff --git a/netutils/netcat/Makefile b/netutils/netcat/Makefile new file mode 100644 index 000000000..4a696025a --- /dev/null +++ b/netutils/netcat/Makefile @@ -0,0 +1,36 @@ +############################################################################# +# +# netutils/netcat/Makefile +# Netcat networking application +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################# + +include $(APPDIR)/Make.defs + +# built-in application info + +MODULE = $(CONFIG_NETUTILS_NETCAT) +PRIORITY = $(CONFIG_NETUTILS_NETCAT_PRIORITY) +PROGNAME = $(CONFIG_NETUTILS_NETCAT_PROGNAME) +STACKSIZE = $(CONFIG_NETUTILS_NETCAT_STACKSIZE) + +# Example + +MAINSRC = netcat_main.c + +include $(APPDIR)/Application.mk diff --git a/netutils/netcat/README.md b/netutils/netcat/README.md new file mode 100644 index 000000000..044a700f7 --- /dev/null +++ b/netutils/netcat/README.md @@ -0,0 +1,75 @@ +# Network Utilities / `netcat` tool + +netcat TCP/IP Swiss army knife + +It was re-implemented from scratch for NuttX + + +## DEMO ## + +[![weboftwins-osvehicle-2020-rzr]( +https://files.mastodon.social/media_attachments/files/105/163/916/892/863/178/original/05468e28b4463f95.png +)]( +https://mastodon.social/@rzr/105225153152922220#weboftwins-osvehicle-2020-rzr +"weboftwins-osvehicle-2020-rzr") + + * https://purl.org/rzr/weboftwins + +## USAGE ## + +Usage is straightforward: + + nsh> help ; netcat + Usage: netcat [-l] [destination] [port] [file] + + nsh> renew eth0 ; ifconfig + + eth0 Link encap:Ethernet HWaddr 52:13:FF:FF:FF:FF at UP + inet addr:192.168.1.42 DRaddr:192.168.1.254 Mask:255.255.255.0 + +In the following examples, following configuration is used: + +- target (nuttx) is 192.168.1.42 +- host (linux) is 192.168.1.55 + +### Server ### + +As a server on NuttX and Linux's netcat as client + + nsh> netcat -l + + sh> cat /proc/version | netcat 192.168.1.42 31337 + Linux ... + +Default port is 31337 but it can changed. + + nsh> renew eth0 ; ifconfig ; netcat -l + log: net: listening on :31337 + Linux ... + +### Client ### + +Start Server on GNU/Linux: + + sh> ip addr show && netcat -l 31337 + +Client side on nuttx, we create + + nsh> help ; renew eth0 ; ifconfig + nsh> netcat 192.168.1.55 31337 /proc/version + +### Using pipes ### + + mkfifo /dev/fifo + netcat 192.168.1.55 31337 /proc/fifo + help > /dev/fifo + + fxos8700cq > /dev/fifo & + fxos8700cq [7:100] + netcat 192.168.1.55 31337 /dev/fifo + +### Resources ### + + * + * + * \ No newline at end of file diff --git a/netutils/netcat/netcat_main.c b/netutils/netcat/netcat_main.c new file mode 100644 index 000000000..575dd51d8 --- /dev/null +++ b/netutils/netcat/netcat_main.c @@ -0,0 +1,231 @@ +/**************************************************************************** + * netutils/netcat/netcat_main.c + * netcat networking application + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef NETCAT_PORT +# define NETCAT_PORT 31337 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int netcat_server(int argc, char * argv[]) +{ + FILE * fout = stdout; + struct sockaddr_in server; + struct sockaddr_in client; + int port = NETCAT_PORT; + + if ((1 < argc) && (0 == strcmp("-l", argv[1]))) + { + if (2 < argc) + { + port = atoi(argv[2]); + } + + if (3 < argc) + { + fout = fopen(argv[3], "w"); + if (0 > fout) + { + perror("error: io: Failed to create file"); + return 1; + } + } + } + + int id; + id = socket(AF_INET , SOCK_STREAM , 0); + if (0 > id) + { + perror("error: net: Failed to create socket"); + return 2; + } + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(port); + if (0 > bind(id, (struct sockaddr *)&server , sizeof(server))) + { + perror("error: net: Failed to bind"); + return 3; + } + + fprintf(stderr, "log: net: listening on :%d\n", port); + listen(id , 3); + int capacity = 256; + char buf[capacity]; + socklen_t addrlen; + int conn; + while ((conn = accept(id, (struct sockaddr *)&client, &addrlen))) + { + int avail = 1; + while (0 < avail) + { + avail = recv(conn, buf, capacity, 0); + buf[avail] = 0; + fprintf(fout, "%s", buf); + int status = fflush(fout); + if (0 != status) + { + perror("error: io: Failed to flush"); + } + } + } + + if (0 > conn) + { + perror("accept failed"); + return 4; + } + + if (stdout != fout) + { + fclose(fout); + } + + return EXIT_SUCCESS; +} + +int netcat_client(int argc, char * argv[]) +{ + FILE *fin = stdin; + char *host = "127.0.0.1"; + int port = NETCAT_PORT; + + if (argc > 1) + { + host = argv[1]; + } + + if (argc > 2) + { + port = atoi(argv[2]); + } + + if (argc > 3) + { + fin = fopen(argv[3], "r"); + if (0 > fin) + { + perror("error: io: Failed to create file"); + return 1; + } + } + + int id; + id = socket(AF_INET , SOCK_STREAM , 0); + if (0 > id) + { + perror("error: net: Failed to create socket"); + return 2; + } + + struct sockaddr_in server; + server.sin_family = AF_INET; + server.sin_port = htons(port); + if (1 != inet_pton(AF_INET, host, &server.sin_addr)) + { + perror("error: net: Invalid host"); + return 3; + } + + if (connect(id, (struct sockaddr *) &server, sizeof(server)) < 0) + { + perror("error: net: Failed to connect"); + return 4; + } + + int capacity = 256; + char buf[capacity]; + int avail; + while (true) + { + avail = -1; + if (fgets(buf, capacity, fin)) + { + avail = strnlen(buf, capacity); + } + + if (avail < 0) + { + exit(EXIT_SUCCESS); + } + + buf[avail] = 0; + avail = write(id, buf, avail); + printf("%s", buf); + if (avail < 0) + { + perror("error: net: writing to socket"); + exit(1); + } + } + + if (stdout != fin) + { + fclose(fin); + } + + return EXIT_SUCCESS; +} + +/**************************************************************************** + * netcat_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + int status = EXIT_SUCCESS; + if (2 > argc) + { + fprintf(stderr, + "Usage: netcat [-l] [destination] [port] [file]\n"); + } + else if ((1 < argc) && (0 == strcmp("-l", argv[1]))) + { + status = netcat_server(argc, argv); + } + else + { + status = netcat_client(argc, argv); + } + + return status; +}