diff --git a/userspace/CMakeLists.txt b/userspace/CMakeLists.txt index 29f6c707..cb4a6542 100644 --- a/userspace/CMakeLists.txt +++ b/userspace/CMakeLists.txt @@ -35,6 +35,7 @@ set(USERSPACE_PROJECTS test-mouse test-sort test-tcp + test-udp test-unix-socket touch u8sum diff --git a/userspace/test-udp/CMakeLists.txt b/userspace/test-udp/CMakeLists.txt new file mode 100644 index 00000000..3294e6cc --- /dev/null +++ b/userspace/test-udp/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.26) + +project(test-udp CXX) + +set(SOURCES + main.cpp +) + +add_executable(test-udp ${SOURCES}) +target_compile_options(test-udp PUBLIC -O2 -g) +target_link_libraries(test-udp PUBLIC libc) + +add_custom_target(test-udp-install + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test-udp ${BANAN_BIN}/ + DEPENDS test-udp +) diff --git a/userspace/test-udp/main.cpp b/userspace/test-udp/main.cpp new file mode 100644 index 00000000..8e159a19 --- /dev/null +++ b/userspace/test-udp/main.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include + +int usage(const char* argv0) +{ + fprintf(stderr, "usage: %s [-s|-c] [-a addr] [-p port]\n", argv0); + return 1; +} + +int main(int argc, char** argv) +{ + bool server = false; + uint32_t addr = 0; + uint16_t port = 0; + + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-s") == 0) + server = true; + else if (strcmp(argv[i], "-c") == 0) + server = false; + else if (strcmp(argv[i], "-a") == 0) + addr = inet_addr(argv[++i]); + else if (strcmp(argv[i], "-p") == 0) + sscanf(argv[++i], "%hu", &port); + else + return usage(argv[0]); + } + + int socket = ::socket(AF_INET, SOCK_DGRAM, 0); + if (socket == -1) + { + perror("socket"); + return 1; + } + + if (server) + { + sockaddr_in bind_addr; + bind_addr.sin_family = AF_INET; + bind_addr.sin_port = htons(port); + bind_addr.sin_addr.s_addr = addr; + + if (bind(socket, (sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) + { + perror("bind"); + return 1; + } + + printf("listening on %s:%hu\n", inet_ntoa(bind_addr.sin_addr), ntohs(bind_addr.sin_port)); + + char buffer[1024]; + sockaddr_in sender; + socklen_t sender_len = sizeof(sender); + + if (recvfrom(socket, buffer, sizeof(buffer), 0, (sockaddr*)&sender, &sender_len) == -1) + { + perror("recvfrom"); + return 1; + } + + printf("received from %s:%hu\n", inet_ntoa(sender.sin_addr), ntohs(sender.sin_port)); + printf(" %s\n", buffer); + } + else + { + const char buffer[] = "Hello from banan-os!"; + + sockaddr_in server_addr; + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = addr; + + printf("sending to %s:%hu\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); + if (sendto(socket, buffer, sizeof(buffer), 0, (sockaddr*)&server_addr, sizeof(server_addr)) == -1) + { + perror("sendto"); + return 1; + } + } + + close(socket); + return 0; +}