diff options
| author | Nakidai <nakidai@disroot.org> | 2025-05-20 00:33:49 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2025-05-20 00:33:49 +0300 |
| commit | eba7daeebc79080ede43d440ee075b0ef7ca96eb (patch) | |
| tree | 283b9e10652648e8fa5ba5af982c7dcd48f48053 | |
| download | smalltcp-eba7daeebc79080ede43d440ee075b0ef7ca96eb.tar.gz smalltcp-eba7daeebc79080ede43d440ee075b0ef7ca96eb.zip | |
Add code
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | LICENSE | 10 | ||||
| -rw-r--r-- | Makefile | 19 | ||||
| -rw-r--r-- | README | 11 | ||||
| -rw-r--r-- | buc.c | 20 | ||||
| -rw-r--r-- | bus.c | 67 |
6 files changed, 129 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a577849 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +buc +bus diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7ae8865 --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE +FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5fd5245 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +RM ?= rm -f +PREFIX ?= /usr/local/ +BINDIR ?= ${PREFIX}/bin + +CFLAGS += -ansi + +.PHONY: all +all: buc bus + +install: all + install -d ${BINDIR} + install -m755 buc bus ${BINDIR} + +uninstall: + ${RM} ${BINDIR}/buc ${BINDIR}/bus + +.PHONY: clean +clean: + ${RM} buc bus diff --git a/README b/README new file mode 100644 index 0000000..1930e75 --- /dev/null +++ b/README @@ -0,0 +1,11 @@ +SmallTCP +======== +these are small scripts for TCP client (buc) and server (bus). buc connects to a +server and works like netcat. bus broadcasts messages between peers. + +usages: +buc [ip [port]] +bus [port [ip]] + +default port in 8604 +default ip is (client == buc ? 127.0.0.1 : 0.0.0.0) diff --git a/buc.c b/buc.c new file mode 100644 index 0000000..d54d0d1 --- /dev/null +++ b/buc.c @@ -0,0 +1,20 @@ +#include <arpa/inet.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <poll.h> + +char buf[512]; progress, all; +atoi(), err(), exit(), read(), write(); + +#define readbuf(sock) ((((progress = read((sock), buf, sizeof(buf))) == -1) && err(1, "read()") || !progress && exit(0)), progress) +#define sendbuf(sock, size) (write(sock, buf, size) == -1 && err(1, "write()")) + +main(argc, argv) char **argv; { + struct sockaddr_in addr = {AF_INET, htons(argc > 2 ? atoi(argv[1]) : 8604), inet_addr(argc > 1 ? argv[1] : "127.0.0.1")}; + struct pollfd fds[2] = {{0, POLLIN}, {0, POLLIN}}; + for ( (fds[1].fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 && err(1, "socket()"), + connect(fds[1].fd, (void *)&addr, sizeof(addr)) == -1 && err(1, "connect()"); + ;) poll(fds, 2, -1) == -1 && err(1, "poll()"), + fds[0].revents & POLLIN && sendbuf(fds[1].fd, readbuf(0)), + fds[1].revents & POLLIN && sendbuf(1, readbuf(fds[1].fd)); +} diff --git a/bus.c b/bus.c new file mode 100644 index 0000000..7b4d01d --- /dev/null +++ b/bus.c @@ -0,0 +1,67 @@ +#include <signal.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <poll.h> + +err(), warn(), warnx(), read(), write(), close(); + +#define SOCKETS_MAX 128 +#define BUFFER_SIZE 512 + +#define lengthof(X) (sizeof(X) / sizeof(*(X))) + +main(argc, argv) char **argv; +{ + struct sockaddr_in addr = {AF_INET, htons(8604), htonl(INADDR_ANY)}; + struct pollfd ppeers[SOCKETS_MAX] = {0}; + int peers[SOCKETS_MAX] = {0}, client, i, j, written, readed; + char buf[BUFFER_SIZE] = {0}; + + for ( + argc > 1 && (addr.sin_port = htons(atoi(argv[1]))), + argc > 2 && inet_pton(AF_INET, argv[1], &addr.sin_addr) == -1 && err(1, "inet_pton()"), + (peers[0] = socket(AF_INET, SOCK_STREAM, 0)) == -1 && err(1, "socket()"), + setsockopt(peers[0], SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) == -1 && err(1, "setsockopt()"), + bind(peers[0], (void *)&addr, sizeof(addr)) == -1 && err(1, "bind()"), + listen(peers[0], 16) == -1 && err(1, "listen()"), + signal(SIGPIPE, SIG_IGN); + ;) + { + for (written = i = 0; i < lengthof(peers) ? (peers[i] && ((ppeers[written++] = (struct pollfd){peers[i], POLLIN}), 0), 1) : 0; ++i) + if (i + 1 == lengthof(peers)) + for ( + client = 0, j = 1, poll(ppeers, written, -1) == -1 && err(1, "poll"); + ppeers[0].revents & POLLIN && + (client ? client : (client = accept(peers[0], 0, 0))) == -1 + ? (warn("accept()"), 0) + : ( + j < lengthof(peers) + ? (!peers[j] ? ((peers[j] = client), 0) : 1) + : 1 + ); + ++j + ) + if (j + 1 == lengthof(peers)) + warnx("dropping %d as peer list is full", client), + close(client); + for (i = 1; i < written; ++i) + if (ppeers[i].revents & POLLIN) + for ( + readed = read(ppeers[i].fd, buf, sizeof(buf)), + j = 1; + j < lengthof(peers) + ? ( + readed == -1 || !readed + ? ( + ppeers[i].fd == peers[j] + ? (close(peers[j]), peers[j] = 0) + : 1 + ) + : (peers[j] && ppeers[i].fd != peers[j] && write(peers[j], buf, readed), 1) + ) + : 0; + ++j + ); + } +} |