1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 13:27:35 +00:00

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().
This commit is contained in:
Andreas Kling 2019-03-13 17:33:40 +01:00
parent c588653f76
commit 7aba68d51c
6 changed files with 91 additions and 0 deletions

View file

@ -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

View file

@ -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 };

View file

@ -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
Userland/.gitignore vendored
View file

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

View file

@ -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
Userland/tc.cpp Normal file
View file

@ -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;
}