summaryrefslogtreecommitdiff
path: root/network/udp.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-27 19:41:26 +0200
committerAnton Kling <anton@kling.gg>2023-10-30 21:49:48 +0100
commit4f9ed7087cb58683d9423ab771ad76b31dac5514 (patch)
tree5364217b7d491c4321830025020ab13513067cb1 /network/udp.c
parent715274d3a77c58510b97c3f87cd604dde9de7a4f (diff)
Kernel: Expose source information of incoming UDP packets
Diffstat (limited to 'network/udp.c')
-rw-r--r--network/udp.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/network/udp.c b/network/udp.c
index fb8ba44..29f17e1 100644
--- a/network/udp.c
+++ b/network/udp.c
@@ -3,24 +3,47 @@
#include <network/udp.h>
#include <socket.h>
-void handle_udp(const uint8_t *payload, uint32_t packet_length) {
+void handle_udp(uint8_t src_ip[4], const uint8_t *payload,
+ uint32_t packet_length) {
assert(packet_length >= 8);
- uint16_t source_port = ntohs(*(uint16_t *)payload);
- uint16_t dst_port = ntohs(*(uint16_t *)(payload + 2));
- uint16_t length = ntohs(*(uint16_t *)(payload + 4));
- assert(length == packet_length);
- kprintf("source_port: %d\n", source_port);
- kprintf("dst_port: %d\n", dst_port);
- uint32_t data_length = length - 8;
+ // n_.* means network format(big endian)
+ // h_.* means host format((probably) little endian)
+ uint16_t n_source_port = *(uint16_t *)payload;
+ uint16_t h_source_port = ntohs(n_source_port);
+ uint16_t h_dst_port = ntohs(*(uint16_t *)(payload + 2));
+ uint16_t h_length = ntohs(*(uint16_t *)(payload + 4));
+ assert(h_length == packet_length);
+ kprintf("source_port: %d\n", h_source_port);
+ kprintf("dst_port: %d\n", h_dst_port);
+ uint16_t data_length = h_length - 8;
const uint8_t *data = payload + 8;
// Find the open port
- OPEN_INET_SOCKET *in_s = find_open_udp_port(htons(dst_port));
+ OPEN_INET_SOCKET *in_s = find_open_udp_port(htons(h_dst_port));
assert(in_s);
SOCKET *s = in_s->s;
vfs_fd_t *fifo_file = s->ptr_socket_fd;
+
+ // Write the sockaddr struct such that it can later be
+ // given to userland if asked.
+ struct sockaddr_in /*{
+ sa_family_t sin_family;
+ union {
+ uint32_t s_addr;
+ } sin_addr;
+ uint16_t sin_port;
+ }*/ in;
+ in.sin_family = AF_INET;
+ memcpy(&in.sin_addr.s_addr, src_ip, sizeof(uint32_t));
+ in.sin_port = n_source_port;
+ socklen_t sock_length = sizeof(struct sockaddr_in);
+
+ raw_vfs_pwrite(fifo_file, &sock_length, sizeof(sock_length), 0);
+ raw_vfs_pwrite(fifo_file, &in, sizeof(in), 0);
+
+ // Write the UDP payload length(not including header)
+ raw_vfs_pwrite(fifo_file, &data_length, sizeof(uint16_t), 0);
+
+ // Write the UDP payload
raw_vfs_pwrite(fifo_file, (char *)data, data_length, 0);
- for (uint32_t i = 0; i < data_length; i++) {
- kprintf("%c", data[i]);
- }
}