Skip to content

Commit 7aba68d

Browse files
committed
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().
1 parent c588653 commit 7aba68d

File tree

6 files changed

+91
-0
lines changed

6 files changed

+91
-0
lines changed

Kernel/sync.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ cp -v ../Userland/env mnt/bin/env
7676
cp -v ../Userland/stat mnt/bin/stat
7777
cp -v ../Userland/ping mnt/bin/ping
7878
cp -v ../Userland/uc mnt/bin/uc
79+
cp -v ../Userland/tc mnt/bin/tc
7980
chmod 4755 mnt/bin/su
8081
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
8182
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor

LibC/sys/socket.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,23 @@ ssize_t sendto(int sockfd, const void* data, size_t data_length, int flags, cons
4141
__RETURN_WITH_ERRNO(rc, rc, -1);
4242
}
4343

44+
ssize_t send(int sockfd, const void* data, size_t data_length, int flags)
45+
{
46+
return sendto(sockfd, data, data_length, flags, nullptr, 0);
47+
}
48+
4449
ssize_t recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* addr, socklen_t* addr_length)
4550
{
4651
Syscall::SC_recvfrom_params params { sockfd, buffer, buffer_length, flags, addr, addr_length };
4752
int rc = syscall(SC_recvfrom, &params);
4853
__RETURN_WITH_ERRNO(rc, rc, -1);
4954
}
5055

56+
ssize_t recv(int sockfd, void* buffer, size_t buffer_length, int flags)
57+
{
58+
return recvfrom(sockfd, buffer, buffer_length, flags, nullptr, nullptr);
59+
}
60+
5161
int getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size)
5262
{
5363
Syscall::SC_getsockopt_params params { sockfd, level, option, value, value_size };

LibC/sys/socket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ int bind(int sockfd, const sockaddr* addr, socklen_t);
5656
int listen(int sockfd, int backlog);
5757
int accept(int sockfd, sockaddr*, socklen_t*);
5858
int connect(int sockfd, const sockaddr*, socklen_t);
59+
ssize_t send(int sockfd, const void*, size_t, int flags);
5960
ssize_t sendto(int sockfd, const void*, size_t, int flags, const struct sockaddr*, socklen_t);
61+
ssize_t recv(int sockfd, void*, size_t, int flags);
6062
ssize_t recvfrom(int sockfd, void*, size_t, int flags, struct sockaddr*, socklen_t*);
6163
int getsockopt(int sockfd, int level, int option, void*, socklen_t*);
6264
int setsockopt(int sockfd, int level, int option, const void*, socklen_t);

Userland/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ chown
3939
stat
4040
ping
4141
uc
42+
tc

Userland/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OBJS = \
3535
stat.o \
3636
ping.o \
3737
uc.o \
38+
tc.o \
3839
rm.o
3940

4041
APPS = \
@@ -75,6 +76,7 @@ APPS = \
7576
stat \
7677
ping \
7778
uc \
79+
tc \
7880
rm
7981

8082
ARCH_FLAGS =
@@ -208,6 +210,8 @@ ping: ping.o
208210
uc: uc.o
209211
$(LD) -o $@ $(LDFLAGS) $< -lc
210212

213+
tc: tc.o
214+
$(LD) -o $@ $(LDFLAGS) $< -lc
211215

212216
.cpp.o:
213217
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<

Userland/tc.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <string.h>
5+
#include <sys/types.h>
6+
#include <sys/socket.h>
7+
#include <arpa/inet.h>
8+
#include <netinet/in.h>
9+
10+
int main(int argc, char** argv)
11+
{
12+
const char* addr_str = "127.0.0.1";
13+
if (argc > 1)
14+
addr_str = argv[1];
15+
16+
int fd = socket(AF_INET, SOCK_STREAM, 0);
17+
if (fd < 0) {
18+
perror("socket");
19+
return 1;
20+
}
21+
22+
struct timeval timeout { 3, 0 };
23+
int rc = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
24+
if (rc < 0) {
25+
perror("setsockopt");
26+
return 1;
27+
}
28+
rc = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
29+
if (rc < 0) {
30+
perror("setsockopt");
31+
return 1;
32+
}
33+
34+
struct sockaddr_in dst_addr;
35+
memset(&dst_addr, 0, sizeof(dst_addr));
36+
37+
dst_addr.sin_family = AF_INET;
38+
dst_addr.sin_port = htons(8080);
39+
rc = inet_pton(AF_INET, addr_str, &dst_addr.sin_addr);
40+
if (rc < 0) {
41+
perror("inet_pton");
42+
return 1;
43+
}
44+
45+
rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
46+
if (rc < 0) {
47+
perror("connect");
48+
return 1;
49+
}
50+
51+
char buffer[BUFSIZ];
52+
const char* msg = "Test message";
53+
54+
send(fd, (const char*)msg, strlen(msg), 0);
55+
printf("Message sent.\n");
56+
57+
struct sockaddr_in src_addr;
58+
socklen_t src_addr_len = sizeof(src_addr);
59+
ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0);
60+
if (nrecv < 0) {
61+
perror("recvfrom");
62+
return 1;
63+
}
64+
buffer[nrecv] = '\0';
65+
printf("Server: %s\n", buffer);
66+
67+
rc = close(fd);
68+
if (rc < 0) {
69+
perror("close");
70+
return 1;
71+
}
72+
return 0;
73+
}

0 commit comments

Comments
 (0)