From 8a9208612eec8ddae4c418485d848ecfa0613699 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 30 Oct 2023 22:12:14 +0100 Subject: Meta: Move kernel and userland to their own folders. This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear. --- network/arp.c | 153 ----------------------------------------------------- network/arp.h | 4 -- network/bytes.c | 10 ---- network/bytes.h | 5 -- network/ethernet.c | 93 -------------------------------- network/ethernet.h | 5 -- network/ipv4.c | 98 ---------------------------------- network/ipv4.h | 5 -- network/udp.c | 64 ---------------------- network/udp.h | 7 --- 10 files changed, 444 deletions(-) delete mode 100644 network/arp.c delete mode 100644 network/arp.h delete mode 100644 network/bytes.c delete mode 100644 network/bytes.h delete mode 100644 network/ethernet.c delete mode 100644 network/ethernet.h delete mode 100644 network/ipv4.c delete mode 100644 network/ipv4.h delete mode 100644 network/udp.c delete mode 100644 network/udp.h (limited to 'network') diff --git a/network/arp.c b/network/arp.c deleted file mode 100644 index de6d898..0000000 --- a/network/arp.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -struct ARP_DATA { - uint16_t htype; // Hardware type - uint16_t ptype; // Protocol type - uint8_t hlen; // Hardware address length (Ethernet = 6) - uint8_t plen; // Protocol address length (IPv4 = 4) - uint16_t opcode; // ARP Operation Code - uint8_t srchw[6]; // Source hardware address - hlen bytes (see above) - uint8_t srcpr[4]; // Source protocol address - plen bytes (see above). - // If IPv4 can just be a "u32" type. - uint8_t dsthw[6]; // Destination hardware address - hlen bytes (see above) - uint8_t dstpr[4]; // Destination protocol address - plen bytes (see - // above). If IPv4 can just be a "u32" type. -}; - -struct ARP_TABLE_ENTRY { - uint8_t is_used; - uint8_t mac[6]; - uint8_t ip[4]; -}; - -struct ARP_TABLE_ENTRY arp_table[10] = {0}; - -// FIXME: This is hardcoded, don't do this. -uint8_t ip_address[4] = {10, 0, 2, 15}; - -struct ARP_TABLE_ENTRY *find_arp_entry_to_use(void) { - // This does not need to find a "free" entry as a ARP table is - // just a cache, it just has to pick a entry efficently. - for (int i = 0; i < 10; i++) { - if (!arp_table[i].is_used) { - return &arp_table[i]; - } - } - return &arp_table[0]; -} - -void print_mac(const char *str, uint8_t *mac) { - kprintf("%s: ", str); - for (int i = 0; i < 6; i++) { - kprintf("%x", mac[i]); - if (5 != i) - kprintf(":"); - } - kprintf("\n"); -} - -void print_ip(const char *str, const uint8_t *ip) { - kprintf("%s: ", str); - for (int i = 0; i < 4; i++) { - kprintf("%d", ip[i]); - if (3 != i) - kprintf("."); - } - kprintf("\n"); -} - -void send_arp_request(const uint8_t ip[4]) { - struct ARP_DATA data; - data.htype = htons(1); - data.ptype = htons(0x0800); - - data.hlen = 6; - data.plen = 4; - - data.opcode = htons(0x0001); - get_mac_address(data.srchw); - memcpy(data.srcpr, ip_address, sizeof(uint8_t[4])); - - memset(data.dsthw, 0, sizeof(uint8_t[6])); - memcpy(data.dstpr, ip, sizeof(uint8_t[4])); - - uint8_t broadcast[6]; - memset(broadcast, 0xFF, sizeof(broadcast)); - send_ethernet_packet(broadcast, 0x0806, (uint8_t *)&data, sizeof(data)); -} - -int get_mac_from_ip(const uint8_t ip[4], uint8_t mac[6]) { - print_ip("ARP GETTING MAC FROM IP: ", ip); - for (int i = 0; i < 10; i++) { - if (0 != memcmp(arp_table[i].ip, ip, sizeof(uint8_t[4]))) - continue; - memcpy(mac, arp_table[i].mac, sizeof(uint8_t[6])); - return 1; - } - klog("ARP cache miss", LOG_NOTE); - asm("sti"); - send_arp_request(ip); - // TODO: Maybe wait a bit? - for (int i = 0; i < 10; i++) { - if (0 != memcmp(arp_table[i].ip, ip, sizeof(uint8_t[4]))) - continue; - memcpy(mac, arp_table[i].mac, sizeof(uint8_t[6])); - return 1; - } - assert(0); - return 0; -} - -void handle_arp(const uint8_t *payload) { - struct ARP_DATA *data = (struct ARP_DATA *)payload; - - // Assert that communication is over ethernet - assert(1 == ntohs(data->htype)); - // Assert that request uses IP - assert(0x0800 == ntohs(data->ptype)); - - assert(6 == data->hlen); - assert(4 == data->plen); - // Assert it is a request - if (0x0001 /*arp_request*/ == ntohs(data->opcode)) { - print_mac("srchw: ", data->srchw); - print_ip("srcpr: ", data->srcpr); - - print_mac("dsthw: ", data->dsthw); - print_ip("dstpr: ", data->dstpr); - - assert(0 == memcmp(data->dstpr, ip_address, sizeof(uint8_t[4]))); - - // Now we have to construct a ARP response - struct ARP_DATA response; - response.htype = htons(1); - response.ptype = htons(0x0800); - response.opcode = htons(0x00002); - response.hlen = 6; - response.plen = 4; - get_mac_address(response.srchw); - memcpy(response.srcpr, ip_address, sizeof(uint8_t[4])); - - 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)); - } else if (0x0002 /*arp_response*/ == ntohs(data->opcode)) { - // Find a entry to fill - struct ARP_TABLE_ENTRY *entry = find_arp_entry_to_use(); - entry->is_used = 1; - memcpy(entry->mac, data->srchw, sizeof(uint8_t[6])); - memcpy(entry->ip, data->srcpr, sizeof(uint8_t[4])); - print_ip("Added ip: ", entry->ip); - } else { - kprintf("GOT A ARP REQEUST WITH TYPE: %x\n", ntohs(data->opcode)); - assert(0); - } -} diff --git a/network/arp.h b/network/arp.h deleted file mode 100644 index c2beb94..0000000 --- a/network/arp.h +++ /dev/null @@ -1,4 +0,0 @@ -#include - -int get_mac_from_ip(const uint8_t ip[4], uint8_t mac[6]); -void handle_arp(const uint8_t *payload); diff --git a/network/bytes.c b/network/bytes.c deleted file mode 100644 index 94afa73..0000000 --- a/network/bytes.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -uint16_t ntohs(uint16_t net) { return (net >> 8) | (net << 8); } - -uint16_t htons(uint16_t net) { return (net >> 8) | (net << 8); } - -uint32_t htonl(uint32_t net) { - return (((net & 0x000000FF) << 24) | ((net & 0x0000FF00) << 8) | - ((net & 0x00FF0000) >> 8) | ((net & 0xFF000000) >> 24)); -} diff --git a/network/bytes.h b/network/bytes.h deleted file mode 100644 index c291589..0000000 --- a/network/bytes.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -uint16_t ntohs(uint16_t net); -uint16_t htons(uint16_t net); -uint32_t htonl(uint32_t net); diff --git a/network/ethernet.c b/network/ethernet.c deleted file mode 100644 index e97ccbd..0000000 --- a/network/ethernet.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -struct ETHERNET_HEADER { - uint8_t mac_dst[6]; - uint8_t mac_src[6]; - uint16_t type; -}; - -uint32_t crc32(const char *buf, size_t len) { - static uint32_t table[256]; - static int have_table = 0; - uint32_t rem; - uint8_t octet; - int i, j; - const char *p, *q; - - if (have_table == 0) { - for (i = 0; i < 256; i++) { - rem = i; - for (j = 0; j < 8; j++) { - if (rem & 1) { - rem >>= 1; - rem ^= 0xedb88320; - } else - rem >>= 1; - } - table[i] = rem; - } - have_table = 1; - } - - uint32_t crc = 0xFFFFFFFF; - q = buf + len; - for (p = buf; p < q; p++) { - octet = *p; - crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet]; - } - return ~crc; -} - -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); - 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); - kprintf("OUR OWN CALCULATED crc: %x\n", - crc32((const char *)eth_header, (packet_length - 4))); - - uint16_t type = ntohs(eth_header->type); - switch (type) { - case 0x0806: - handle_arp(payload); - break; - case 0x0800: - handle_ipv4(payload, packet_length - sizeof(struct ETHERNET_HEADER) - 4); - break; - default: - kprintf("Can't handle ethernet type\n"); - break; - } -} - -void send_ethernet_packet(uint8_t mac_dst[6], uint16_t type, uint8_t *payload, - uint64_t payload_length) { - // FIXME: Janky allocation, do this better - uint64_t buffer_size = - sizeof(struct ETHERNET_HEADER) + payload_length + sizeof(uint32_t); - uint8_t *buffer = kmalloc(buffer_size); - uint8_t *buffer_start = buffer; - struct ETHERNET_HEADER *eth_header = (struct ETHERNET_HEADER *)buffer; - buffer += sizeof(struct ETHERNET_HEADER); - memcpy(buffer, payload, payload_length); - buffer += payload_length; - - memcpy(eth_header->mac_dst, mac_dst, sizeof(uint8_t[6])); - get_mac_address(eth_header->mac_src); - eth_header->type = htons(type); - *(uint32_t *)(buffer) = - 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 deleted file mode 100644 index 0fdcee3..0000000 --- a/network/ethernet.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -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 deleted file mode 100644 index 099aa0d..0000000 --- a/network/ipv4.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -uint16_t ip_checksum(void *vdata, size_t length) { - // Cast the data pointer to one that can be indexed. - char *data = (char *)vdata; - - // Initialise the accumulator. - uint32_t acc = 0xffff; - - // Handle complete 16-bit blocks. - for (size_t i = 0; i + 1 < length; i += 2) { - uint16_t word; - memcpy(&word, data + i, 2); - acc += ntohs(word); - if (acc > 0xffff) { - acc -= 0xffff; - } - } - - // Handle any partial block at the end of the data. - if (length & 1) { - uint16_t word = 0; - memcpy(&word, data + length - 1, 1); - acc += ntohs(word); - if (acc > 0xffff) { - acc -= 0xffff; - } - } - - // Return the checksum in network byte order. - return htons(~acc); -} - -extern uint8_t ip_address[4]; -void send_ipv4_packet(uint32_t ip, uint8_t protocol, const uint8_t *payload, - uint16_t length) { - uint8_t header[20] = {0}; - header[0] = (4 /*version*/ << 4) | (5 /*IHL*/); - *((uint16_t *)(header + 2)) = htons(length + 20); - header[8 /*TTL*/] = 0xF8; - header[9] = protocol; - - memcpy(header + 12 /*src_ip*/, ip_address, sizeof(uint8_t[4])); - memcpy(header + 16, &ip, sizeof(uint8_t[4])); - - *((uint16_t *)(header + 10 /*checksum*/)) = ip_checksum(header, 20); - uint16_t packet_length = length + 20; - uint8_t *packet = kmalloc(packet_length); - memcpy(packet, header, 20); - memcpy(packet + 20, payload, length); - - uint8_t mac[6]; - uint8_t ip_copy[4]; // TODO: Do I need to do this? - memcpy(ip_copy, &ip, sizeof(uint8_t[4])); - get_mac_from_ip(ip_copy, mac); - send_ethernet_packet(mac, 0x0800, packet, packet_length); - kfree(packet); -} - -void handle_ipv4(const uint8_t *payload, uint32_t packet_length) { - assert(packet_length > 4); - - uint16_t saved_checksum = *(uint16_t *)(payload + 10); - *(uint16_t *)(payload + 10) = 0; - uint16_t calc_checksum = ip_checksum((uint8_t *)payload, 20); - *(uint16_t *)(payload + 10) = saved_checksum; - assert(calc_checksum == saved_checksum); - - 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 src_ip[4]; - memcpy(src_ip, payload + 12, sizeof(uint8_t[4])); - - uint8_t protocol = *(payload + 9); - switch (protocol) { - case 0x11: - handle_udp(src_ip, 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 deleted file mode 100644 index f578202..0000000 --- a/network/ipv4.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -void handle_ipv4(const uint8_t *payload, uint32_t packet_length); -void send_ipv4_packet(uint32_t ip, uint8_t protocol, const uint8_t *payload, - uint16_t length); diff --git a/network/udp.c b/network/udp.c deleted file mode 100644 index 23411da..0000000 --- a/network/udp.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include - -void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, - const uint8_t *payload, uint16_t payload_length) { - uint16_t header[4] = {0}; - header[0] = src->sin_port; - header[1] = dst->sin_port; - header[2] = htons(payload_length + 8); - - uint16_t packet_length = sizeof(header) + payload_length; - uint8_t *packet = kmalloc(packet_length); - memcpy(packet, header, sizeof(header)); - memcpy(packet + sizeof(header), payload, payload_length); - send_ipv4_packet(dst->sin_addr.s_addr, 0x11, packet, packet_length); - kfree(packet); -} - -void handle_udp(uint8_t src_ip[4], const uint8_t *payload, - uint32_t packet_length) { - assert(packet_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); - (void)h_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); - 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(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); -} diff --git a/network/udp.h b/network/udp.h deleted file mode 100644 index c30b8c8..0000000 --- a/network/udp.h +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -void handle_udp(uint8_t src_ip[4], const uint8_t *payload, - uint32_t packet_length); -void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, - const uint8_t *payload, uint16_t payload_length); -- cgit v1.2.3