Ver código fonte

Userland+LibC: Add a new little "tc" program for testing TCP.

Also added send() and recv() to LibC in support of this. They are just
wrappers around sendto() and recvfrom().
Andreas Kling 6 anos atrás
pai
commit
7aba68d51c
6 arquivos alterados com 91 adições e 0 exclusões
  1. 1 0
      Kernel/sync.sh
  2. 10 0
      LibC/sys/socket.cpp
  3. 2 0
      LibC/sys/socket.h
  4. 1 0
      Userland/.gitignore
  5. 4 0
      Userland/Makefile
  6. 73 0
      Userland/tc.cpp

+ 1 - 0
Kernel/sync.sh

@@ -76,6 +76,7 @@ cp -v ../Userland/env mnt/bin/env
 cp -v ../Userland/stat mnt/bin/stat
 cp -v ../Userland/ping mnt/bin/ping
 cp -v ../Userland/uc mnt/bin/uc
+cp -v ../Userland/tc mnt/bin/tc
 chmod 4755 mnt/bin/su
 cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
 cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor

+ 10 - 0
LibC/sys/socket.cpp

@@ -41,6 +41,11 @@ ssize_t sendto(int sockfd, const void* data, size_t data_length, int flags, cons
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }
 
+ssize_t send(int sockfd, const void* data, size_t data_length, int flags)
+{
+    return sendto(sockfd, data, data_length, flags, nullptr, 0);
+}
+
 ssize_t recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* addr, socklen_t* addr_length)
 {
     Syscall::SC_recvfrom_params params { sockfd, buffer, buffer_length, flags, addr, addr_length };
@@ -48,6 +53,11 @@ ssize_t recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, stru
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }
 
+ssize_t recv(int sockfd, void* buffer, size_t buffer_length, int flags)
+{
+    return recvfrom(sockfd, buffer, buffer_length, flags, nullptr, nullptr);
+}
+
 int getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size)
 {
     Syscall::SC_getsockopt_params params { sockfd, level, option, value, value_size };

+ 2 - 0
LibC/sys/socket.h

@@ -56,7 +56,9 @@ int bind(int sockfd, const sockaddr* addr, socklen_t);
 int listen(int sockfd, int backlog);
 int accept(int sockfd, sockaddr*, socklen_t*);
 int connect(int sockfd, const sockaddr*, socklen_t);
+ssize_t send(int sockfd, const void*, size_t, int flags);
 ssize_t sendto(int sockfd, const void*, size_t, int flags, const struct sockaddr*, socklen_t);
+ssize_t recv(int sockfd, void*, size_t, int flags);
 ssize_t recvfrom(int sockfd, void*, size_t, int flags, struct sockaddr*, socklen_t*);
 int getsockopt(int sockfd, int level, int option, void*, socklen_t*);
 int setsockopt(int sockfd, int level, int option, const void*, socklen_t);

+ 1 - 0
Userland/.gitignore

@@ -39,3 +39,4 @@ chown
 stat
 ping
 uc
+tc

+ 4 - 0
Userland/Makefile

@@ -35,6 +35,7 @@ OBJS = \
        stat.o \
        ping.o \
        uc.o \
+       tc.o \
        rm.o
 
 APPS = \
@@ -75,6 +76,7 @@ APPS = \
        stat \
        ping \
        uc \
+       tc \
        rm
 
 ARCH_FLAGS =
@@ -208,6 +210,8 @@ ping: ping.o
 uc: uc.o
 	$(LD) -o $@ $(LDFLAGS) $< -lc
 
+tc: tc.o
+	$(LD) -o $@ $(LDFLAGS) $< -lc
 
 .cpp.o:
 	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<

+ 73 - 0
Userland/tc.cpp

@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+int main(int argc, char** argv)
+{
+    const char* addr_str = "127.0.0.1";
+    if (argc > 1)
+        addr_str = argv[1];
+
+    int fd = socket(AF_INET, SOCK_STREAM, 0);
+    if (fd < 0) {
+        perror("socket");
+        return 1;
+    } 
+
+    struct timeval timeout { 3, 0 };
+    int rc = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+    if (rc < 0) {
+        perror("setsockopt");
+        return 1;
+    }
+    rc = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
+    if (rc < 0) {
+        perror("setsockopt");
+        return 1;
+    }
+
+    struct sockaddr_in dst_addr;
+    memset(&dst_addr, 0, sizeof(dst_addr));
+
+    dst_addr.sin_family = AF_INET;
+    dst_addr.sin_port = htons(8080);
+    rc = inet_pton(AF_INET, addr_str, &dst_addr.sin_addr);
+    if (rc < 0) {
+        perror("inet_pton");
+        return 1;
+    }
+
+    rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
+    if (rc < 0) {
+        perror("connect");
+        return 1;
+    }
+
+    char buffer[BUFSIZ];
+    const char* msg = "Test message";
+
+    send(fd, (const char*)msg, strlen(msg), 0);
+    printf("Message sent.\n");
+
+    struct sockaddr_in src_addr;
+    socklen_t src_addr_len = sizeof(src_addr);
+    ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0);
+    if (nrecv < 0) {
+        perror("recvfrom");
+        return 1;
+    }
+    buffer[nrecv] = '\0';
+    printf("Server: %s\n", buffer);
+
+    rc = close(fd);
+    if (rc < 0) {
+        perror("close");
+        return 1;
+    }
+    return 0;
+}