summaryrefslogtreecommitdiff
path: root/network
diff options
context:
space:
mode:
Diffstat (limited to 'network')
-rw-r--r--network/arp.c5
-rw-r--r--network/arp.h2
-rw-r--r--network/ethernet.c8
-rw-r--r--network/ethernet.h2
-rw-r--r--network/ipv4.c27
-rw-r--r--network/ipv4.h3
-rw-r--r--network/udp.c26
-rw-r--r--network/udp.h3
8 files changed, 69 insertions, 7 deletions
diff --git a/network/arp.c b/network/arp.c
index eb8aca3..f86c732 100644
--- a/network/arp.c
+++ b/network/arp.c
@@ -43,7 +43,7 @@ void print_ip(const char *str, uint8_t *ip) {
kprintf("\n");
}
-void handle_arp(uint8_t *payload) {
+void handle_arp(const uint8_t *payload) {
struct ARP_DATA *data = (struct ARP_DATA *)payload;
// Assert that communication is over ethernet
@@ -79,5 +79,6 @@ void handle_arp(uint8_t *payload) {
memcpy(response.dsthw, data->srchw, sizeof(uint8_t[6]));
memcpy(response.dstpr, data->srcpr, sizeof(uint8_t[4]));
- send_ethernet_packet(data->srchw, 0x0806, (uint8_t*)&response, sizeof(response));
+ send_ethernet_packet(data->srchw, 0x0806, (uint8_t *)&response,
+ sizeof(response));
}
diff --git a/network/arp.h b/network/arp.h
index 1e8df1b..8efda97 100644
--- a/network/arp.h
+++ b/network/arp.h
@@ -1,3 +1,3 @@
#include <stdint.h>
-void handle_arp(uint8_t *payload);
+void handle_arp(const uint8_t *payload);
diff --git a/network/ethernet.c b/network/ethernet.c
index ae8e814..11a3876 100644
--- a/network/ethernet.c
+++ b/network/ethernet.c
@@ -4,6 +4,7 @@
#include <network/arp.h>
#include <network/bytes.h>
#include <network/ethernet.h>
+#include <network/ipv4.h>
#include <stdio.h>
struct ETHERNET_HEADER {
@@ -44,10 +45,10 @@ uint32_t crc32(const char *buf, size_t len) {
return ~crc;
}
-void handle_ethernet(uint8_t *packet, uint64_t packet_length) {
+void handle_ethernet(const uint8_t *packet, uint64_t packet_length) {
struct ETHERNET_HEADER *eth_header = (struct ETHERNET_HEADER *)packet;
packet += sizeof(struct ETHERNET_HEADER);
- uint8_t *payload = packet;
+ const uint8_t *payload = packet;
packet += packet_length - sizeof(struct ETHERNET_HEADER);
uint32_t crc = *((uint32_t *)packet - 1);
kprintf("PACKET crc: %x\n", crc);
@@ -70,7 +71,7 @@ void handle_ethernet(uint8_t *packet, uint64_t packet_length) {
handle_arp(payload);
break;
case 0x0800:
- kprintf("IPV4 message\n");
+ handle_ipv4(payload, packet_length - sizeof(struct ETHERNET_HEADER) - 4);
break;
default:
kprintf("Can't handle ethernet type\n");
@@ -97,5 +98,6 @@ void send_ethernet_packet(uint8_t mac_dst[6], uint16_t type, uint8_t *payload,
htonl(crc32((const char *)buffer_start, buffer_size - 4));
assert(rtl8139_send_data(buffer_start, buffer_size));
+ kfree(buffer_start);
kprintf("sent data\n");
}
diff --git a/network/ethernet.h b/network/ethernet.h
index 88a4dc6..0fdcee3 100644
--- a/network/ethernet.h
+++ b/network/ethernet.h
@@ -1,5 +1,5 @@
#include <stdint.h>
-void handle_ethernet(uint8_t *packet, uint64_t packet_length);
+void handle_ethernet(const uint8_t *packet, uint64_t packet_length);
void send_ethernet_packet(uint8_t mac_dst[6], uint16_t type, uint8_t *payload,
uint64_t payload_length);
diff --git a/network/ipv4.c b/network/ipv4.c
new file mode 100644
index 0000000..27b38ec
--- /dev/null
+++ b/network/ipv4.c
@@ -0,0 +1,27 @@
+#include <assert.h>
+#include <network/bytes.h>
+#include <network/ipv4.h>
+#include <network/udp.h>
+
+void handle_ipv4(const uint8_t *payload, uint32_t packet_length) {
+ assert(packet_length > 4);
+ uint8_t version = (*payload & 0xF0) >> 4;
+ uint8_t IHL = (*payload & 0xF);
+ kprintf("version: %x\n", version);
+ assert(4 == version);
+ assert(5 == IHL);
+ uint16_t ipv4_total_length = ntohs(*(uint16_t *)(payload + 2));
+ assert(ipv4_total_length >= 20);
+ // Make sure the ipv4 header is not trying to get uninitalized memory
+ assert(ipv4_total_length <= packet_length);
+
+ uint8_t protocol = *(payload + 9);
+ switch (protocol) {
+ case 0x11:
+ handle_udp(payload + 20, ipv4_total_length - 20);
+ break;
+ default:
+ kprintf("Protocol given in IPv4 header not handeld: %x\n", protocol);
+ break;
+ }
+}
diff --git a/network/ipv4.h b/network/ipv4.h
new file mode 100644
index 0000000..294a0ef
--- /dev/null
+++ b/network/ipv4.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+
+void handle_ipv4(const uint8_t *payload, uint32_t packet_length);
diff --git a/network/udp.c b/network/udp.c
new file mode 100644
index 0000000..fb8ba44
--- /dev/null
+++ b/network/udp.c
@@ -0,0 +1,26 @@
+#include <assert.h>
+#include <network/bytes.h>
+#include <network/udp.h>
+#include <socket.h>
+
+void handle_udp(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;
+ const uint8_t *data = payload + 8;
+
+ // Find the open port
+ OPEN_INET_SOCKET *in_s = find_open_udp_port(htons(dst_port));
+ assert(in_s);
+ SOCKET *s = in_s->s;
+ vfs_fd_t *fifo_file = s->ptr_socket_fd;
+ raw_vfs_pwrite(fifo_file, (char *)data, data_length, 0);
+ for (uint32_t i = 0; i < data_length; i++) {
+ kprintf("%c", data[i]);
+ }
+}
diff --git a/network/udp.h b/network/udp.h
new file mode 100644
index 0000000..c6ac753
--- /dev/null
+++ b/network/udp.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+
+void handle_udp(const uint8_t *payload, uint32_t packet_length);