diff options
Diffstat (limited to 'network')
-rw-r--r-- | network/arp.c | 5 | ||||
-rw-r--r-- | network/arp.h | 2 | ||||
-rw-r--r-- | network/ethernet.c | 8 | ||||
-rw-r--r-- | network/ethernet.h | 2 | ||||
-rw-r--r-- | network/ipv4.c | 27 | ||||
-rw-r--r-- | network/ipv4.h | 3 | ||||
-rw-r--r-- | network/udp.c | 26 | ||||
-rw-r--r-- | network/udp.h | 3 |
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); |