aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml (renamed from .github/workflows/build.yml)20
-rw-r--r--Makefile2
-rw-r--r--kernel/drivers/acpi.c12
-rw-r--r--kernel/drivers/cpu.c2
-rw-r--r--kernel/drivers/interrupts.c4
-rw-r--r--kernel/drivers/mbr.c2
-rw-r--r--kernel/drivers/pci.c4
-rw-r--r--kernel/drivers/ps2/keyboard.c6
-rw-r--r--kernel/drivers/ps2/mouse.c4
-rw-r--r--kernel/drivers/ps2/ps2.c4
-rw-r--r--kernel/drivers/rtc.c6
-rw-r--r--kernel/drivers/rtl8139.c177
-rw-r--r--kernel/drivers/serial.c2
-rw-r--r--kernel/drivers/timer.c6
-rw-r--r--kernel/drivers/vmware.c4
-rw-r--r--kernel/features/bus.c2
-rw-r--r--kernel/features/fs.c6
-rw-r--r--kernel/features/logger.c4
-rw-r--r--kernel/features/net.c865
-rw-r--r--kernel/features/proc.c4
-rw-r--r--kernel/features/syscall.c5
-rw-r--r--kernel/inc/drivers/cpu.h2
-rw-r--r--kernel/inc/drivers/pci.h4
-rw-r--r--kernel/inc/drivers/rtl8139.h36
-rw-r--r--kernel/inc/mm.h2
-rw-r--r--kernel/inc/net.h168
-rw-r--r--kernel/main.c9
-rw-r--r--libs/libc/print.c2
-rw-r--r--libs/libgui/png.c1
-rw-r--r--libs/libnet/Makefile17
-rw-r--r--libs/libnet/dns.c116
-rw-r--r--libs/libnet/dns.h21
-rw-r--r--libs/libnet/http.c134
-rw-r--r--libs/libnet/http.h82
-rw-r--r--libs/libnet/ip.c48
-rw-r--r--libs/libnet/ip.h12
-rw-r--r--libs/libnet/net.h73
-rw-r--r--libs/libtxt/xml.c514
-rw-r--r--libs/libtxt/xml.h51
-rw-r--r--res/test.c5
-rwxr-xr-xrun23
41 files changed, 88 insertions, 2373 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/main.yml
index cb9660e..3984c6e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/main.yml
@@ -1,9 +1,23 @@
-name: Project build and test
+name: lint, build, test, release
on: push
jobs:
- build-and-test:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install
+ run: sudo apt-get update && sudo apt-get install -y build-essential ctags ccache clang-tidy-11 clang-format-11
+ - name: Generate linting instructions
+ run: sh run sync
+ - name: Lint
+ run: sh run lint
+
+ build-test-release:
+ needs: [lint]
runs-on: ubuntu-latest
steps:
@@ -16,7 +30,7 @@ jobs:
uses: actions/cache@v1
with:
path: cross
- key: toolchain
+ key: cached-toolchain
- name: Build cross compiler
if: steps.cache-cross.outputs.cache-hit != 'true'
run: sh run cross -y
diff --git a/Makefile b/Makefile
index b6813a0..d585f7e 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ endef
PREPROCESSOR_FLAGS = $(foreach flag, $(ALL_PREPROCESSOR_FLAGS), $(call PREPROCESSOR_FLAG_TEMPLATE,$(flag)))
-CFLAGS_WARNINGS = -Wall -Wextra -Werror -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wlogical-op -Wunreachable-code -Wundef -Wold-style-definition -Wvla -Winline -pedantic-errors
+CFLAGS_WARNINGS = -Wall -Wextra -Werror -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wunreachable-code -Wundef -Wold-style-definition -Wvla -Winline -pedantic-errors
CFLAGS_DEFAULT = $(CFLAGS_WARNINGS) -std=c99 -m32 -nostdlib -nostdinc -fno-builtin -fno-profile-generate -fno-omit-frame-pointer -fno-common -fno-asynchronous-unwind-tables -mno-red-zone -mno-80387 -mno-mmx -mno-sse -mno-sse2 $(CONFIG_OPTIMIZATION) $(CONFIG_EXTRA_CFLAGS) $(PREPROCESSOR_FLAGS)
CC = $(CONFIG_CACHE) $(PWD)/cross/opt/bin/i686-elf-gcc
diff --git a/kernel/drivers/acpi.c b/kernel/drivers/acpi.c
index 6860a43..13c132c 100644
--- a/kernel/drivers/acpi.c
+++ b/kernel/drivers/acpi.c
@@ -1,13 +1,13 @@
// MIT License, Copyright (c) 2020 Marvin Borner
-#include <drivers/acpi.h>
#include <assert.h>
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/acpi.h>
+#include <drivers/cpu.h>
#include <mem.h>
#include <print.h>
-int check_sdt(struct sdt_header *header)
+static int check_sdt(struct sdt_header *header)
{
u8 sum = 0;
@@ -17,7 +17,7 @@ int check_sdt(struct sdt_header *header)
return sum == 0;
}
-int check_sdp(struct sdp_header *header)
+static int check_sdp(struct sdp_header *header)
{
u8 sum = 0;
@@ -27,7 +27,7 @@ int check_sdp(struct sdp_header *header)
return sum == 0;
}
-struct rsdp *find_rsdp(void)
+static struct rsdp *find_rsdp(void)
{
// Main BIOS area
for (int i = 0xe0000; i < 0xfffff; i++) {
@@ -45,7 +45,7 @@ struct rsdp *find_rsdp(void)
return NULL;
}
-void *find_sdt(struct rsdt *rsdt, const char *signature)
+static void *find_sdt(struct rsdt *rsdt, const char *signature)
{
u32 entries = (rsdt->header.length - sizeof(rsdt->header)) / 4;
diff --git a/kernel/drivers/cpu.c b/kernel/drivers/cpu.c
index 8927d1d..8694fc2 100644
--- a/kernel/drivers/cpu.c
+++ b/kernel/drivers/cpu.c
@@ -2,8 +2,8 @@
// This file is a wrapper around some CPU asm calls
#include <assert.h>
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
#include <mem.h>
#include <print.h>
diff --git a/kernel/drivers/interrupts.c b/kernel/drivers/interrupts.c
index e9ab0ce..39a59a0 100644
--- a/kernel/drivers/interrupts.c
+++ b/kernel/drivers/interrupts.c
@@ -2,14 +2,14 @@
// TODO: Remove some magic numbers
#include <assert.h>
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
#include <drivers/interrupts.h>
+#include <drivers/serial.h>
#include <mem.h>
#include <mm.h>
#include <print.h>
#include <proc.h>
-#include <drivers/serial.h>
/**
* IDT
diff --git a/kernel/drivers/mbr.c b/kernel/drivers/mbr.c
index c9eba15..d5f7a40 100644
--- a/kernel/drivers/mbr.c
+++ b/kernel/drivers/mbr.c
@@ -1,9 +1,9 @@
// MIT License, Copyright (c) 2021 Marvin Borner
#include <def.h>
-#include <fs.h>
#include <drivers/ide.h>
#include <drivers/mbr.h>
+#include <fs.h>
#include <mem.h>
#include <print.h>
#include <str.h>
diff --git a/kernel/drivers/pci.c b/kernel/drivers/pci.c
index 55806c2..0aab8e5 100644
--- a/kernel/drivers/pci.c
+++ b/kernel/drivers/pci.c
@@ -2,10 +2,10 @@
// Uses parts of the ToAruOS Project, released under the terms of the NCSA
// Copyright (C) 2011-2018 K. Lange
-#include <drivers/cpu.h>
#include <def.h>
-#include <mem.h>
+#include <drivers/cpu.h>
#include <drivers/pci.h>
+#include <mem.h>
CLEAR void pci_write_field(u32 device, int field, u32 value)
{
diff --git a/kernel/drivers/ps2/keyboard.c b/kernel/drivers/ps2/keyboard.c
index bddb280..bf1a520 100644
--- a/kernel/drivers/ps2/keyboard.c
+++ b/kernel/drivers/ps2/keyboard.c
@@ -1,14 +1,14 @@
// MIT License, Copyright (c) 2020 Marvin Borner
-#include <drivers/cpu.h>
#include <def.h>
-#include <errno.h>
+#include <drivers/cpu.h>
#include <drivers/interrupts.h>
+#include <drivers/ps2.h>
+#include <errno.h>
#include <io.h>
#include <mem.h>
#include <print.h>
#include <proc.h>
-#include <drivers/ps2.h>
#include <stack.h>
#include <str.h>
#include <sys.h>
diff --git a/kernel/drivers/ps2/mouse.c b/kernel/drivers/ps2/mouse.c
index 2942e34..680183d 100644
--- a/kernel/drivers/ps2/mouse.c
+++ b/kernel/drivers/ps2/mouse.c
@@ -2,13 +2,13 @@
#include <assert.h>
#include <drivers/cpu.h>
-#include <errno.h>
#include <drivers/interrupts.h>
+#include <drivers/ps2.h>
+#include <errno.h>
#include <io.h>
#include <mem.h>
#include <print.h>
#include <proc.h>
-#include <drivers/ps2.h>
#include <stack.h>
#include <str.h>
#include <sys.h>
diff --git a/kernel/drivers/ps2/ps2.c b/kernel/drivers/ps2/ps2.c
index f8d849b..0206892 100644
--- a/kernel/drivers/ps2/ps2.c
+++ b/kernel/drivers/ps2/ps2.c
@@ -1,10 +1,10 @@
// MIT License, Copyright (c) 2021 Marvin Borner
#include <assert.h>
-#include <drivers/cpu.h>
#include <def.h>
-#include <print.h>
+#include <drivers/cpu.h>
#include <drivers/ps2.h>
+#include <print.h>
#define PS2_TIMEOUT 100
diff --git a/kernel/drivers/rtc.c b/kernel/drivers/rtc.c
index 63d9461..b67829e 100644
--- a/kernel/drivers/rtc.c
+++ b/kernel/drivers/rtc.c
@@ -1,12 +1,12 @@
// MIT License, Copyright (c) 2021 Marvin Borner
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
+#include <drivers/rtc.h>
+#include <drivers/timer.h>
#include <fs.h>
#include <mem.h>
-#include <drivers/rtc.h>
#include <str.h>
-#include <drivers/timer.h>
static u8 rtc_busy(void)
{
diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c
deleted file mode 100644
index 8e7bc88..0000000
--- a/kernel/drivers/rtl8139.c
+++ /dev/null
@@ -1,177 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// Uses parts of the ToAruOS Project, released under the terms of the NCSA
-// Copyright (C) 2011-2018 K. Lange
-
-#include <def.h>
-#include <drivers/cpu.h>
-#include <drivers/interrupts.h>
-#include <drivers/pci.h>
-#include <drivers/rtl8139.h>
-#include <mem.h>
-#include <net.h>
-#include <print.h>
-
-static int rtl_irq = 0;
-static u8 mac[6] = { 0 };
-static u8 *last_packet = NULL;
-static u8 *rtl_rx_buffer = NULL;
-static u32 rtl_device_pci = 0;
-static u32 rtl_iobase = 0;
-static u32 cur_rx = 0;
-
-u8 *rtl8139_get_mac(void)
-{
- if (!rtl_device_pci)
- return NULL;
-
- return mac;
-}
-
-static void rtl8139_receive_packet(void)
-{
- while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) {
- int offset = cur_rx % 0x2000;
-
- u32 *buf_start = (u32 *)((u32)rtl_rx_buffer + offset);
- u32 rx_status = buf_start[0];
- u32 rx_size = rx_status >> 16;
-
- if (rx_status & (0x0020 | 0x0010 | 0x0004 | 0x0002)) {
- print("RX Error\n");
- } else {
- u8 *buf_8 = (u8 *)&(buf_start[1]);
-
- last_packet = malloc(rx_size);
-
- u32 packet_end = (u32)buf_8 + rx_size;
- if (packet_end > (u32)rtl_rx_buffer + 0x2000) {
- u32 s = ((u32)rtl_rx_buffer + 0x2000) - (u32)buf_8;
- memcpy(last_packet, buf_8, s);
- memcpy((void *)((u32)last_packet + s), rtl_rx_buffer, rx_size - s);
- } else {
- memcpy(last_packet, buf_8, rx_size);
- }
-
- u16 *t = (u16 *)(rtl_rx_buffer + cur_rx);
- ethernet_handle_packet((struct ethernet_packet *)last_packet, *(t + 1));
- }
-
- cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
- outw(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16);
- }
-}
-
-static u8 tsad_array[4] = { 0x20, 0x24, 0x28, 0x2C };
-static u8 tsd_array[4] = { 0x10, 0x14, 0x18, 0x1C };
-static u8 tx_current = 0;
-void rtl8139_send_packet(void *data, u32 len)
-{
- if (!rtl_device_pci)
- return;
-
- outl(rtl_iobase + tsad_array[tx_current], (u32)data);
- outl(rtl_iobase + tsd_array[tx_current++], len);
- if (tx_current > 3)
- tx_current = 0;
-}
-
-static void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra)
-{
- if ((vendor_id == 0x10ec) && (device_id == 0x8139))
- *((u32 *)extra) = device;
-}
-
-static void rtl8139_irq_handler(struct regs *r)
-{
- UNUSED(r);
- u16 status = inw(rtl_iobase + RTL_PORT_ISR);
- if (!status)
- return;
- outw(rtl_iobase + RTL_PORT_ISR, status);
-
- if (status & 0x01 || status & 0x02)
- rtl8139_receive_packet();
-}
-
-static void rtl8139_init(void)
-{
- if (!rtl_device_pci)
- return;
-
- u16 command_reg = (u16)pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
- if ((command_reg & (1 << 2)) == 0) {
- command_reg |= (1 << 2);
- pci_write_field(rtl_device_pci, PCI_COMMAND, command_reg);
- }
-
- rtl_irq = pci_get_interrupt(rtl_device_pci);
- irq_install_handler(rtl_irq, rtl8139_irq_handler);
-
- u32 rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
- /* u32 rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4); */
- rtl_iobase = 0;
-
- if (rtl_bar0 & 0x00000001)
- rtl_iobase = rtl_bar0 & 0xFFFFFFFC;
-
- // Get mac address
- for (int i = 0; i < 6; ++i)
- mac[i] = inb(rtl_iobase + RTL_PORT_MAC + i);
- printf("Mac address: %x:%x:%x:%x:%x:%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
- // Activate
- outb(rtl_iobase + RTL_PORT_CONFIG, 0x0);
-
- // Reset
- outb((u16)(rtl_iobase + RTL_PORT_CMD), 0x10);
- while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x10) != 0)
- ;
-
- // Set receive buffer
- rtl_rx_buffer = (u8 *)malloc(0x3000);
- memset(rtl_rx_buffer, 0, 0x3000);
- outl(rtl_iobase + RTL_PORT_RBSTART, (u32)rtl_rx_buffer);
-
- // Enable IRQs
- outw(rtl_iobase + RTL_PORT_IMR, 0x8000 | /* PCI error */
- 0x4000 | /* PCS timeout */
- 0x40 | /* Rx FIFO over */
- 0x20 | /* Rx underrun */
- 0x10 | /* Rx overflow */
- 0x08 | /* Tx error */
- 0x04 | /* Tx okay */
- 0x02 | /* Rx error */
- 0x01 /* Rx okay */
- );
-
- // Configure transmit
- outl(rtl_iobase + RTL_PORT_TCR, 0);
-
- // Configure receive
- outl(rtl_iobase + RTL_PORT_RCR, (0) | /* 8K receive */
- 0x08 | /* broadcast */
- 0x01 /* all physical */
- );
-
- // Enable receive and transmit
- outb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04);
-
- // Reset rx statistics
- outl(rtl_iobase + RTL_PORT_RXMISS, 0);
-}
-
-int rtl8139_installed(void)
-{
- return rtl_device_pci != 0;
-}
-
-int rtl8139_install(void)
-{
- pci_scan(&rtl8139_find, -1, &rtl_device_pci);
-
- if (rtl_device_pci) {
- print("Found rtl8139 card\n");
- rtl8139_init();
- }
- return rtl_device_pci;
-}
diff --git a/kernel/drivers/serial.c b/kernel/drivers/serial.c
index 95ac02d..281772d 100644
--- a/kernel/drivers/serial.c
+++ b/kernel/drivers/serial.c
@@ -1,8 +1,8 @@
// MIT License, Copyright (c) 2020 Marvin Borner
#include <assert.h>
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
#include <drivers/serial.h>
#include <str.h>
diff --git a/kernel/drivers/timer.c b/kernel/drivers/timer.c
index c586088..3ddc229 100644
--- a/kernel/drivers/timer.c
+++ b/kernel/drivers/timer.c
@@ -1,13 +1,13 @@
// MIT License, Copyright (c) 2020 Marvin Borner
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
#include <drivers/interrupts.h>
+#include <drivers/rtc.h>
+#include <drivers/timer.h>
#include <io.h>
#include <mem.h>
#include <proc.h>
-#include <drivers/rtc.h>
-#include <drivers/timer.h>
static u32 timer_ticks = 0;
PROTECTED static u8 call_scheduler = 0;
diff --git a/kernel/drivers/vmware.c b/kernel/drivers/vmware.c
index 6f95d02..169865f 100644
--- a/kernel/drivers/vmware.c
+++ b/kernel/drivers/vmware.c
@@ -3,12 +3,12 @@
#include <def.h>
#include <drivers/interrupts.h>
+#include <drivers/ps2.h>
+#include <drivers/vmware.h>
#include <io.h>
#include <mem.h>
#include <print.h>
-#include <drivers/ps2.h>
#include <stack.h>
-#include <drivers/vmware.h>
#define VMWARE_CMD_VERSION 0x0a
diff --git a/kernel/features/bus.c b/kernel/features/bus.c
index d58cee3..3757a3a 100644
--- a/kernel/features/bus.c
+++ b/kernel/features/bus.c
@@ -2,9 +2,9 @@
#include <assert.h>
#include <bus.h>
-#include <drivers/cpu.h>
#include <crypto.h>
#include <def.h>
+#include <drivers/cpu.h>
#include <errno.h>
#include <io.h>
#include <list.h>
diff --git a/kernel/features/fs.c b/kernel/features/fs.c
index c5ebfcd..7e79a42 100644
--- a/kernel/features/fs.c
+++ b/kernel/features/fs.c
@@ -1,13 +1,13 @@
// MIT License, Copyright (c) 2020 Marvin Borner
#include <assert.h>
-#include <drivers/cpu.h>
#include <crypto.h>
#include <def.h>
-#include <errno.h>
-#include <fs.h>
+#include <drivers/cpu.h>
#include <drivers/ide.h>
#include <drivers/mbr.h>
+#include <errno.h>
+#include <fs.h>
#include <mem.h>
#include <mm.h>
#include <print.h>
diff --git a/kernel/features/logger.c b/kernel/features/logger.c
index 23efa93..fd5d730 100644
--- a/kernel/features/logger.c
+++ b/kernel/features/logger.c
@@ -1,13 +1,13 @@
// MIT License, Copyright (c) 2021 Marvin Borner
-#include <drivers/cpu.h>
#include <def.h>
+#include <drivers/cpu.h>
+#include <drivers/serial.h>
#include <errno.h>
#include <io.h>
#include <logger.h>
#include <mem.h>
#include <print.h>
-#include <drivers/serial.h>
static res logger_write(const void *buf, u32 offset, u32 count)
{
diff --git a/kernel/features/net.c b/kernel/features/net.c
deleted file mode 100644
index 9e40ea6..0000000
--- a/kernel/features/net.c
+++ /dev/null
@@ -1,865 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <assert.h>
-#include <drivers/cpu.h>
-#include <def.h>
-#include <list.h>
-#include <mem.h>
-#include <net.h>
-#include <drivers/pci.h>
-#include <print.h>
-#include <rand.h>
-#include <drivers/rtl8139.h>
-#include <socket.h>
-#include <str.h>
-#include <drivers/timer.h>
-
-static u32 current_ip_addr = 0;
-static u32 gateway_addr = 0;
-static u32 subnet_mask = 0;
-static u8 gateway_mac[6] = { 0 };
-
-static struct list *tcp_sockets = NULL;
-static struct list *udp_sockets = NULL;
-
-/**
- * Socket functions
- */
-
-static struct list *socket_list(enum socket_type type)
-{
- struct list *list = NULL;
- if (type == S_TCP)
- list = tcp_sockets;
- else if (type == S_UDP)
- list = udp_sockets;
- return list;
-}
-
-static struct socket *socket_get(enum socket_type type, u32 port)
-{
- struct list *list = socket_list(type);
-
- if (!list || !list->head || !port)
- return NULL;
-
- struct node *iterator = list->head;
- while (iterator != NULL && iterator->data != NULL) {
- if (((struct socket *)iterator->data)->src_port == port)
- return iterator->data;
- iterator = iterator->next;
- }
-
- return NULL;
-}
-
-static struct socket *socket_new(enum socket_type type)
-{
- struct list *list = socket_list(type);
-
- if (!list)
- return NULL;
-
- struct socket *socket = malloc(sizeof(*socket));
- memset(socket, 0, sizeof(*socket));
- if (!list_add(list, socket))
- return NULL;
-
- return socket;
-}
-
-static int socket_close(struct socket *socket)
-{
- if (!socket)
- return 0;
-
- struct list *list = socket_list(socket->type);
-
- if (!list)
- return 0;
-
- struct node *iterator = list->head;
- while (iterator != NULL && iterator->data != NULL) {
- if (iterator->data == socket)
- list_remove(list, iterator);
- iterator = iterator->next;
- }
-
- socket->state = S_CLOSED;
- free(socket);
-
- return 1;
-}
-
-/**
- * Helper functions
- */
-
-static u16 next_port(void)
-{
- static u16 port = 49152;
- return port++;
-}
-
-static int same_net(u32 ip_addr)
-{
- if (gateway_addr && ip_addr > 1)
- return (ip_addr & subnet_mask) == (gateway_addr & subnet_mask);
- else
- return 0;
-}
-
-static u16 ip_calculate_checksum(struct ip_packet *packet)
-{
- int array_size = sizeof(*packet) / 2;
- u16 *array = (u16 *)packet;
- u32 sum = 0;
- for (int i = 0; i < array_size; i++) {
- sum += (u32)htons(array[i]);
- }
- u32 carry = sum >> 16;
- sum = sum & 0x0000ffff;
- sum = sum + carry;
- u16 ret = (u16)~sum;
- return ret;
-}
-
-static u16 tcp_calculate_checksum(struct tcp_packet *packet, struct tcp_pseudo_header *header,
- void *data, u32 len)
-{
- u32 sum = 0;
- u16 *s = (u16 *)header;
-
- // TODO: Checksums for options?
- for (int i = 0; i < 6; i++) {
- sum += (u32)ntohs(s[i]);
- if (sum > 0xffff) {
- sum = (sum >> 16) + (sum & 0xffff);
- }
- }
-
- s = (u16 *)packet;
- for (int i = 0; i < 10; i++) {
- sum += (u32)ntohs(s[i]);
- if (sum > 0xffff) {
- sum = (sum >> 16) + (sum & 0xffff);
- }
- }
-
- u16 d_words = (u16)(len / 2);
-
- s = (u16 *)data;
- for (u32 i = 0; i < d_words; ++i) {
- sum += (u32)ntohs(s[i]);
- if (sum > 0xffff) {
- sum = (sum >> 16) + (sum & 0xffff);
- }
- }
-
- if (d_words * 2 != len) {
- u8 *t = (u8 *)data;
- u8 tmp[2];
- tmp[0] = t[d_words * sizeof(u16)];
- tmp[1] = 0;
-
- u16 *f = (u16 *)tmp;
-
- sum += (u32)ntohs(f[0]);
- if (sum > 0xffff) {
- sum = (sum >> 16) + (sum & 0xffff);
- }
- }
-
- return ~(sum & 0xffff) & 0xffff;
-}
-
-static u16 icmp_calculate_checksum(struct icmp_packet *packet)
-{
- u32 sum = 0;
- u16 *s = (u16 *)packet;
-
- for (int i = 0; i < 5; i++)
- sum += s[i];
-
- if (sum > 0xffff)
- sum = (sum >> 16) + (sum & 0xffff);
-
- return (u16)~sum;
-}
-
-static void *dhcp_get_options(struct dhcp_packet *packet, u8 type)
-{
- u8 *options = packet->options + 4;
- u8 curr_type = 0;
- while ((curr_type = *options) != 0xff) {
- u8 len = *(options + 1);
- if (curr_type == type) {
- void *ret = malloc(len);
- memcpy(ret, options + 2, len);
- return ret;
- }
- options += (2 + len);
- }
- return NULL;
-}
-
-/**
- * Requests
- */
-
-static void ethernet_send_packet(u8 *dst, u8 *data, int len, int prot)
-{
- print("Ethernet send packet\n");
- struct ethernet_packet *packet = malloc(sizeof(*packet) + (u32)len);
- memcpy(packet->src, rtl8139_get_mac(), 6);
- memcpy(packet->dst, dst, 6);
- memcpy(packet->data, data, (u32)len);
- packet->type = (u16)htons(prot);
- rtl8139_send_packet(packet, sizeof(*packet) + (u32)len);
- free(packet);
-}
-
-static u8 broadcast_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-static void arp_send_packet(u8 *dst_mac, u32 dst_protocol_addr, u8 opcode)
-{
- print("ARP send packet\n");
- struct arp_packet *packet = malloc(sizeof(*packet));
-
- memcpy(packet->src_mac, rtl8139_get_mac(), 6);
- packet->src_protocol_addr = htonl(current_ip_addr);
- memcpy(packet->dst_mac, dst_mac, 6);
- packet->dst_protocol_addr = htonl(dst_protocol_addr);
- packet->opcode = (u16)htons(opcode);
- packet->hardware_addr_len = 6;
- packet->protocol_addr_len = 4;
- packet->hardware_type = htons(HARDWARE_TYPE_ETHERNET);
- packet->protocol = htons(ETHERNET_TYPE_IP4);
-
- ethernet_send_packet(broadcast_mac, (u8 *)packet, sizeof(*packet), ETHERNET_TYPE_ARP);
- free(packet);
-}
-
-static int arp_lookup(u8 *ret_hardware_addr, u32 ip_addr);
-static void ip_send_packet(u32 dst, void *data, int len, u8 prot)
-{
- print("IP send packet\n");
- struct ip_packet *packet = malloc(sizeof(*packet) + (u32)len);
- memset(packet, 0, sizeof(*packet));
- packet->version_ihl = ((0x4 << 4) | (0x5 << 0));
- packet->length = (u16)sizeof(*packet) + (u16)len;
- packet->id = htons(1); // TODO: IP fragmentation
- /* packet->flags_fragment = htons(1); */
- packet->ttl = 64;
- packet->protocol = prot;
- packet->src = htonl(current_ip_addr);
- packet->dst = htonl(dst);
- packet->length = (u16)htons(sizeof(*packet) + (u32)len);
- packet->checksum = (u16)htons(ip_calculate_checksum(packet));
-
- if (data)
- memcpy(packet->data, data, (u32)len);
-
- u8 zero_hardware_addr[] = { 0, 0, 0, 0, 0, 0 };
- u8 dst_mac[6];
- if (same_net(dst)) {
- scheduler_disable();
- sti();
- int arp_sent = 3;
- while (!arp_lookup(dst_mac, dst)) {
- if (arp_sent) {
- arp_sent--;
- arp_send_packet(zero_hardware_addr, dst, ARP_REQUEST);
- } else {
- break;
- }
- }
- cli();
- scheduler_enable();
- } else {
- memcpy(dst_mac, gateway_mac, 6);
- }
-
- printf("Destination: %x:%x:%x:%x:%x:%x\n", dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3],
- dst_mac[4], dst_mac[5]);
- ethernet_send_packet(dst_mac, (u8 *)packet, htons(packet->length), ETHERNET_TYPE_IP4);
-
- free(packet);
-}
-
-static void udp_send_packet(struct socket *socket, void *data, int len)
-{
- print("UDP send packet\n");
- if (!socket || socket->state == S_FAILED)
- return;
-
- u32 length = sizeof(struct udp_packet) + (u32)len;
- struct udp_packet *packet = malloc(length);
- memset(packet, 0, sizeof(*packet));
- packet->src_port = (u16)htons(socket->src_port);
- packet->dst_port = (u16)htons(socket->dst_port);
- packet->length = (u16)htons(length);
- packet->checksum = 0; // Optional
-
- if (data)
- memcpy(packet->data, data, (u32)len);
-
- ip_send_packet(socket->ip_addr, packet, (int)length, IP_PROT_UDP);
- free(packet);
-}
-
-//void tcp_send_packet(u32 dst, u16 src_port, u16 dst_port, u16 flags, void *data, int len)
-static void tcp_send_packet(struct socket *socket, u16 flags, void *data, int len)
-{
- print("TCP send packet\n");
-
- if (!socket || socket->state == S_FAILED)
- return;
-
- u32 length = sizeof(struct tcp_packet) + (u32)len;
- struct tcp_packet *packet = malloc(length);
- memset(packet, 0, sizeof(*packet));
- packet->src_port = (u16)htons(socket->src_port);
- packet->dst_port = (u16)htons(socket->dst_port);
- packet->seq_number = htonl(socket->prot.tcp.seq_no);
- packet->ack_number = (flags & TCP_FLAG_ACK) ? htonl(socket->prot.tcp.ack_no) : 0;
- packet->flags = (u16)htons(0x5000 ^ (flags & 0xff));
- packet->window_size = htons(U16_MAX); // TODO: Support TCP windows
- packet->urgent = 0;
- packet->checksum = 0; // Later
-
- if (data)
- memcpy(packet->data, data, (u32)len);
-
- struct tcp_pseudo_header checksum_hd = {
- .src = htonl(current_ip_addr),
- .dst = htonl(socket->ip_addr),
- .zeros = 0,
- .protocol = 6,
- .tcp_len = (u16)htons(length),
- };
- u16 checksum = tcp_calculate_checksum(packet, &checksum_hd, data,
- length - ((u32)htons(packet->flags) >> 12) * 4);
- packet->checksum = (u16)htons(checksum);
-
- ip_send_packet(socket->ip_addr, packet, (int)length, IP_PROT_TCP);
- free(packet);
-}
-
-static void dhcp_make_packet(struct dhcp_packet *packet, u8 msg_type);
-static void dhcp_request(void)
-{
- struct socket *socket = net_open(S_UDP);
- if (!socket || !net_connect(socket, 0xffffffff, 67))
- return;
-
- struct dhcp_packet *packet = malloc(sizeof(*packet));
- memset(packet, 0, sizeof(*packet));
- dhcp_make_packet(packet, 3);
- net_send(socket, packet, sizeof(*packet));
- free(packet);
-}
-
-/**
- * Responses
- */
-
-static void icmp_handle_packet(struct icmp_packet *request_packet, u32 dst)
-{
- struct icmp_packet *packet = malloc(sizeof(*packet));
- memset(packet, 0, sizeof(*packet));
- packet->type = 0; // Ping reponse
- packet->version = 0;
- packet->checksum = 0;
- packet->identifier = request_packet->identifier;
- packet->sequence = request_packet->sequence;
- packet->checksum = icmp_calculate_checksum(packet);
- ip_send_packet(dst, packet, sizeof(*packet), IP_PROT_ICMP);
- free(packet);
-}
-
-static void dhcp_handle_packet(struct dhcp_packet *packet)
-{
- print("DHCP!\n");
- if (packet->op == DHCP_REPLY && htonl(packet->xid) == DHCP_TRANSACTION_IDENTIFIER) {
- u8 *type = dhcp_get_options(packet, 53);
- if (*type == 2) { // Offer
- print("DHCP offer\n");
- dhcp_request();
- } else if (*type == 5) { // ACK
- current_ip_addr = htonl(packet->your_ip);
-
- memcpy(&subnet_mask, dhcp_get_options(packet, 1), 4);
- memcpy(&gateway_addr, dhcp_get_options(packet, 3), 4);
- memcpy(gateway_mac, dhcp_get_options(packet, 3), 4);
- subnet_mask = htonl(subnet_mask);
- gateway_addr = htonl(gateway_addr);
-
- u8 zero_hardware_addr[] = { 0, 0, 0, 0, 0, 0 };
- printf("New IP: %x\n", current_ip_addr);
- printf("Gateway: %x\n", gateway_addr);
- if (same_net(current_ip_addr))
- arp_send_packet(zero_hardware_addr, gateway_addr, ARP_REQUEST);
- /* sti(); */
- /* while (!arp_lookup(gateway_mac, gateway_addr)) */
- /* hlt(); */
- }
- free(type);
- }
-}
-
-// enum tcp_state { TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECIEVED, TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSE_WAIT, TCP_CLOSING, TCP_LAST_ACK, TCP_TIME_WAIT, TCP_CLOSED };
-static void tcp_handle_packet(struct tcp_packet *packet, u32 dst, int len)
-{
- printf("TCP Port: %d\n", ntohs(packet->dst_port));
-
- struct socket *socket = NULL;
- if (!(socket = socket_get(S_TCP, ntohs(packet->dst_port))) || socket->state == S_CLOSED ||
- socket->state == S_FAILED) {
- print("Port isn't mapped!\n");
- return;
- }
- struct tcp_socket *tcp = &socket->prot.tcp;
-
- u32 data_length = (u32)len - (ntohs(packet->flags) >> 12) * 4;
- u16 flags = (u16)ntohs(packet->flags);
-
- u32 recv_ack = ntohl(packet->ack_number);
- u32 recv_seq = ntohl(packet->seq_number);
-
- // TODO: Verify checksum first, then send ACK
-
- if (flags & TCP_FLAG_RST) {
- proc_from_pid(socket->pid)->state = PROC_RUNNING;
- socket->state = S_FAILED;
- tcp->state = 0;
- return;
- }
-
- // Serve
- if (tcp->state == 0 && (flags & 0xff) == TCP_FLAG_SYN) {
- socket->ip_addr = ntohl(dst);
- socket->dst_port = ntohs(packet->src_port);
- tcp->ack_no = recv_seq + 1;
- tcp->seq_no = 1000;
- tcp_send_packet(socket, TCP_FLAG_SYN | TCP_FLAG_ACK, NULL, 0);
- tcp->state++;
- return;
- } else if (tcp->state == 1 && (flags & 0xff) == TCP_FLAG_ACK) {
- tcp->state++;
- return;
- } else if (tcp->state == 2 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_PSH)) {
- struct socket_data *sdata = malloc(sizeof(*sdata));
- sdata->length = data_length;
- if (sdata->length) {
- sdata->data = malloc(data_length);
- memcpy(sdata->data, packet->data, data_length);
- } else {
- sdata->data = NULL;
- }
- list_add(socket->packets, sdata);
- proc_from_pid(socket->pid)->state = PROC_RUNNING;
-
- tcp->ack_no += data_length;
- tcp->seq_no++;
-
- tcp_send_packet(socket, TCP_FLAG_ACK, NULL, 0);
-
- socket->state = S_CONNECTED;
- tcp->state++;
- return;
- } else if (tcp->state == 3 && (flags & 0xff) == TCP_FLAG_ACK) {
- tcp->ack_no = recv_seq + 1;
- tcp->seq_no = recv_ack;
-
- socket->state = S_CONNECTED;
- tcp->state++; // ?
- return;
- } else if (tcp->state == 4 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_FIN)) {
- tcp->ack_no = recv_seq + 1;
- tcp->seq_no = recv_ack;
-
- tcp_send_packet(socket, TCP_FLAG_FIN | TCP_FLAG_ACK, NULL, 0);
-
- socket->state = S_CONNECTED;
- tcp->state++;
- return;
- } else if (tcp->state == 5 && (flags & 0xff) == TCP_FLAG_ACK) {
- proc_from_pid(socket->pid)->state = PROC_RUNNING;
-
- socket->state = S_CLOSED;
- tcp->state = 0;
- }
-
- // Receive
- if (tcp->state == 0 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_SYN)) {
- tcp->ack_no = recv_seq + 1;
- tcp->seq_no = recv_ack;
-
- tcp_send_packet(socket, TCP_FLAG_ACK, NULL, 0);
-
- socket->state = S_CONNECTED;
- tcp->state = 6; // TODO: TCP enum state machine
- return;
- } else if (tcp->state == 6 && (flags & 0xff) == TCP_FLAG_ACK) {
- tcp->ack_no = recv_seq;
- tcp->seq_no = recv_ack;
-
- socket->state = S_CONNECTED;
- tcp->state++;
- return;
- } else if (tcp->state == 7 && flags & TCP_FLAG_ACK) {
- struct socket_data *sdata = malloc(sizeof(*sdata));
- sdata->length = data_length;
- if (sdata->length) {
- sdata->data = malloc(data_length);
- memcpy(sdata->data, packet->data, data_length);
- } else {
- sdata->data = NULL;
- }
- list_add(socket->packets, sdata);
-
- tcp->ack_no += data_length;
- tcp->seq_no = recv_ack;
-
- tcp_send_packet(socket, TCP_FLAG_ACK, NULL, 0);
-
- socket->state = S_CONNECTED;
- return;
- } else if (tcp->state == 8 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_FIN)) {
- tcp->ack_no = recv_seq + 1;
- tcp->seq_no = recv_ack;
-
- tcp_send_packet(socket, TCP_FLAG_ACK, NULL, 0);
-
- socket->state = S_CLOSED;
- tcp->state = 0;
- return;
- }
-}
-
-static void udp_handle_packet(struct udp_packet *packet)
-{
- printf("UDP Port: %d\n", ntohs(packet->dst_port));
-
- void *data_ptr = packet->data;
-
- if (ntohs(packet->dst_port) == DHCP_PORT) {
- dhcp_handle_packet(data_ptr);
- return;
- }
-
- struct socket *socket = NULL;
- if (!(socket = socket_get(S_UDP, ntohs(packet->dst_port))) || socket->state == S_CLOSED ||
- socket->state == S_FAILED) {
- print("Port isn't mapped!\n");
- return;
- }
-
- struct socket_data *sdata = malloc(sizeof(*sdata));
- sdata->length = ntohs(packet->length);
- if (sdata->length) {
- sdata->data = malloc(sdata->length);
- memcpy(sdata->data, packet->data, sdata->length);
- } else {
- sdata->data = NULL;
- }
- list_add(socket->packets, sdata);
-}
-
-static void ip_handle_packet(struct ip_packet *packet, int len)
-{
- (void)len;
- switch (packet->protocol) {
- case IP_PROT_ICMP:
- print("ICMP Packet!\n");
- icmp_handle_packet((struct icmp_packet *)packet->data, packet->src);
- break;
- case IP_PROT_TCP:
- print("TCP Packet!\n");
- tcp_handle_packet((struct tcp_packet *)packet->data, packet->src,
- ntohs(packet->length) - sizeof(*packet));
- break;
- case IP_PROT_UDP:
- print("UDP Packet!\n");
- udp_handle_packet((struct udp_packet *)packet->data);
- break;
- default:
- break;
- }
-}
-
-static struct arp_table_entry arp_table[512] = { 0 };
-static int arp_table_size = 0;
-static void arp_handle_packet(struct arp_packet *packet, int len)
-{
- (void)len;
- u8 dst_mac[6];
- memcpy(dst_mac, packet->src_mac, 6);
- u32 dst_protocol_addr = htonl(packet->src_protocol_addr);
- if (ntohs(packet->opcode) == ARP_REQUEST) {
- print("Got ARP request\n");
- if (htonl(packet->dst_protocol_addr) == current_ip_addr) {
- print("Returning ARP request\n");
- arp_send_packet(dst_mac, dst_protocol_addr, ARP_REPLY);
- }
- return;
- } else if (ntohs(packet->opcode) == ARP_REPLY) {
- print("Got ARP reply\n");
- } else {
- printf("Got unknown ARP, opcode = %d\n", packet->opcode);
- return;
- }
-
- // Store
- arp_table[arp_table_size].ip_addr = dst_protocol_addr;
- memcpy(&arp_table[arp_table_size].mac_addr, dst_mac, 6);
- if (arp_table_size < 512)
- arp_table_size++;
- else
- arp_table_size = 0;
-
- if (dst_protocol_addr == gateway_addr)
- memcpy(gateway_mac, dst_mac, 6);
-}
-
-void ethernet_handle_packet(struct ethernet_packet *packet, int len)
-{
- void *data = packet->data;
- int data_len = len - (int)sizeof(*packet);
- if (ntohs(packet->type) == ETHERNET_TYPE_ARP) {
- print("ARP PACKET\n");
- arp_handle_packet(data, data_len);
- } else if (ntohs(packet->type) == ETHERNET_TYPE_IP4) {
- print("IP4 PACKET\n");
- ip_handle_packet(data, data_len);
- } else if (ntohs(packet->type) == ETHERNET_TYPE_IP6) {
- print("IP6 PACKET\n");
- /* ip_handle_packet(data, data_len); */
- } else {
- /* printf("Unknown packet %x\n", ntohs(packet->type)); */
- }
-}
-
-/**
- * DHCP
- */
-
-static void dhcp_make_packet(struct dhcp_packet *packet, u8 msg_type)
-{
- packet->op = DHCP_REQUEST;
- packet->hardware_type = HARDWARE_TYPE_ETHERNET;
- packet->mac_len = 6;
- packet->hops = 0;
- packet->xid = htonl(DHCP_TRANSACTION_IDENTIFIER);
- packet->flags = htons(0x0001);
- memcpy(packet->client_mac, rtl8139_get_mac(), 6);
-
- // Magic Cookie
- u8 *options = packet->options;
- *((u32 *)(options)) = htonl(0x63825363);
- options += 4;
-
- // First option, message type = DHCP_DISCOVER/DHCP_REQUEST
- *(options++) = 53;
- *(options++) = 1;
- *(options++) = msg_type;
-
- // End
- *(options++) = 0xff;
-}
-
-static int dhcp_discover(void)
-{
- print("DHCP discover\n");
- struct socket *socket = net_open(S_UDP);
- if (socket)
- socket->src_port = DHCP_PORT;
- if (!socket || !net_connect(socket, 0xffffffff, 67))
- return 0;
-
- struct dhcp_packet *packet = malloc(sizeof(*packet));
- memset(packet, 0, sizeof(*packet));
- dhcp_make_packet(packet, 1);
- net_send(socket, packet, sizeof(*packet));
- free(packet);
- return 1;
-}
-
-/**
- * ARP
- */
-
-static void arp_lookup_add(u8 *ret_hardware_addr, u32 ip_addr)
-{
- arp_table[arp_table_size].ip_addr = ip_addr;
- memcpy(&arp_table[arp_table_size].mac_addr, ret_hardware_addr, 6);
- if (arp_table_size < 512)
- arp_table_size++;
- else
- arp_table_size = 0;
-}
-
-static int arp_lookup(u8 *ret_hardware_addr, u32 ip_addr)
-{
- for (int i = 0; i < arp_table_size; i++) {
- if (arp_table[i].ip_addr == ip_addr) {
- memcpy(ret_hardware_addr, &arp_table[i].mac_addr, 6);
- return 1;
- }
- }
- return 0;
-}
-
-/**
- * Wrappers
- */
-
-struct socket *net_open(enum socket_type type)
-{
- if (!net_installed())
- return NULL;
-
- struct socket *socket = socket_new(type);
- if (!socket)
- return NULL;
-
- socket->type = type;
- socket->state = S_OPEN;
- socket->packets = list_new();
- socket->pid = proc_current()->pid;
- return socket;
-}
-
-int net_close(struct socket *socket)
-{
- if (!net_installed())
- return 1;
-
- if (socket->state == S_CLOSING)
- return 0;
-
- if (socket->type == S_TCP && socket->state != S_CLOSED) {
- tcp_send_packet(socket, TCP_FLAG_FIN | TCP_FLAG_ACK, NULL, 0);
- socket->state = S_CLOSING;
- socket->prot.tcp.state++;
- return 0;
- }
-
- return socket_close(socket);
-}
-
-int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port)
-{
- if (!net_installed() || socket->state != S_OPEN || !ip_addr || !dst_port)
- return 0;
-
- socket->ip_addr = ip_addr;
- socket->dst_port = dst_port;
- if (!socket->src_port)
- socket->src_port = next_port();
-
- if (socket->type == S_TCP) {
- srand(timer_get());
- socket->prot.tcp.seq_no = rand();
- socket->prot.tcp.ack_no = 0;
- socket->prot.tcp.state = 0;
- socket->state = S_CONNECTING;
- tcp_send_packet(socket, TCP_FLAG_SYN, NULL, 0);
- return 0;
- } else if (socket->type == S_UDP) {
- socket->state = S_CONNECTED;
- return 1;
- } else {
- socket->state = S_FAILED;
- return 0;
- }
-}
-
-void net_send(struct socket *socket, void *data, u32 len)
-{
- if (!net_installed() || socket->state != S_CONNECTED)
- return;
-
- if (socket->type == S_TCP) {
- tcp_send_packet(socket, TCP_FLAG_PSH | TCP_FLAG_ACK, data, len);
- socket->prot.tcp.ack_no += len;
- } else if (socket->type == S_UDP) {
- udp_send_packet(socket, data, len);
- } else {
- print("Unknown socket type!\n");
- }
-}
-
-int net_receive(struct socket *socket, void *buf, u32 len)
-{
- if (!net_installed() || !socket->packets)
- return 0;
-
- u32 offset = 0;
- struct node *iterator = socket->packets->head;
- while (iterator != NULL) {
- struct socket_data *sdata = iterator->data;
- u32 length = sdata->length;
- // TODO: Fix underflow breaking
- if (offset + length < len) {
- memcpy((u8 *)buf + offset, sdata->data, length);
- offset += length;
- } else {
- break;
- };
- iterator = iterator->next;
- }
-
- return offset;
-}
-
-/**
- * Install
- */
-
-int net_installed(void)
-{
- return rtl8139_installed() != 0;
-}
-
-void net_install(void)
-{
- if (!rtl8139_install())
- return;
-
- sti();
-
- tcp_sockets = list_new();
- udp_sockets = list_new();
-
- arp_lookup_add(broadcast_mac, 0xffffffff);
- if (!dhcp_discover()) {
- print("DHCP discover failed\n");
- loop();
- return;
- }
-
- // DHCP timeout (no gateway address)
- sti();
- u32 time = timer_get();
- while (!gateway_addr && timer_get() - time < 1000)
- ;
-
- if (timer_get() - time >= 1000) {
- print("DHCP timeout\n");
- loop();
- return;
- }
-
- // ARP lookup timeout
- sti();
- time = timer_get();
- while (!arp_lookup(gateway_mac, gateway_addr) && timer_get() - time < 1000)
- ;
-
- if (timer_get() - time >= 1000) {
- printf("Gateway ARP timeout at address %x\n", gateway_addr);
- loop();
- return;
- }
-}
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 019b0ed..8fc922e 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -2,9 +2,10 @@
#include <assert.h>
#include <drivers/cpu.h>
+#include <drivers/gdt.h>
+#include <drivers/timer.h>
#include <errno.h>
#include <fs.h>
-#include <drivers/gdt.h>
#include <load.h>
#include <mem.h>
#include <mm.h>
@@ -12,7 +13,6 @@
#include <proc.h>
#include <stack.h>
#include <str.h>
-#include <drivers/timer.h>
#define PROC(node) ((struct proc *)node->data)
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index b376a13..9efb849 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -1,20 +1,19 @@
// MIT License, Copyright (c) 2020 Marvin Borner
#include <drivers/cpu.h>
+#include <drivers/interrupts.h>
+#include <drivers/timer.h>
#include <errno.h>
#include <fs.h>
-#include <drivers/interrupts.h>
#include <io.h>
#include <load.h>
#include <mem.h>
#include <mm.h>
-#include <net.h>
#include <print.h>
#include <proc.h>
#include <str.h>
#include <sys.h>
#include <syscall.h>
-#include <drivers/timer.h>
static void syscall_handler(struct regs *r)
{
diff --git a/kernel/inc/drivers/cpu.h b/kernel/inc/drivers/cpu.h
index 7ac6074..75e0495 100644
--- a/kernel/inc/drivers/cpu.h
+++ b/kernel/inc/drivers/cpu.h
@@ -5,7 +5,7 @@
#include <def.h>
-static inline void spinlock(u32 *ptr)
+UNUSED_FUNC static inline void spinlock(u32 *ptr)
{
u32 prev;
do
diff --git a/kernel/inc/drivers/pci.h b/kernel/inc/drivers/pci.h
index 9429f29..ac288c6 100644
--- a/kernel/inc/drivers/pci.h
+++ b/kernel/inc/drivers/pci.h
@@ -76,14 +76,14 @@ static inline u8 pci_extract_func(u32 device)
return (u8)(device);
}
-static inline u32 pci_get_addr(u32 device, int field)
+UNUSED_FUNC static inline u32 pci_get_addr(u32 device, int field)
{
return 0x80000000 | (u32)(pci_extract_bus(device) << 16) |
(u32)(pci_extract_slot(device) << 11) | (u32)(pci_extract_func(device) << 8) |
((field)&0xFC);
}
-static inline u32 pci_box_device(int bus, int slot, int func)
+UNUSED_FUNC static inline u32 pci_box_device(int bus, int slot, int func)
{
return (u32)((bus << 16) | (slot << 8) | func);
}
diff --git a/kernel/inc/drivers/rtl8139.h b/kernel/inc/drivers/rtl8139.h
deleted file mode 100644
index 0d748af..0000000
--- a/kernel/inc/drivers/rtl8139.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef RTL8139_H
-#define RTL8139_H
-
-#include <def.h>
-
-#define RX_BUF_SIZE 0x2000
-
-#define RTL8139_VENDOR_ID 0x10ec
-#define RTL8139_DEVICE_ID 0x8139
-
-#define RTL_ROK (1 << 0)
-#define RTL_TOK (1 << 2)
-
-#define RTL_PORT_MAC 0x00
-#define RTL_PORT_MAR 0x08
-#define RTL_PORT_TXSTAT 0x10
-#define RTL_PORT_TXBUF 0x20
-#define RTL_PORT_RBSTART 0x30
-#define RTL_PORT_CMD 0x37
-#define RTL_PORT_RXPTR 0x38
-#define RTL_PORT_RXADDR 0x3A
-#define RTL_PORT_IMR 0x3C
-#define RTL_PORT_ISR 0x3E
-#define RTL_PORT_TCR 0x40
-#define RTL_PORT_RCR 0x44
-#define RTL_PORT_RXMISS 0x4C
-#define RTL_PORT_CONFIG 0x52
-
-int rtl8139_install(void);
-int rtl8139_installed(void);
-void rtl8139_send_packet(void *data, u32 len) NONNULL;
-u8 *rtl8139_get_mac(void);
-
-#endif
diff --git a/kernel/inc/mm.h b/kernel/inc/mm.h
index 8f6f06a..0a2bb81 100644
--- a/kernel/inc/mm.h
+++ b/kernel/inc/mm.h
@@ -4,8 +4,8 @@
#define PAGING_H
#include <def.h>
-#include <errno.h>
#include <drivers/interrupts.h>
+#include <errno.h>
struct memory_range {
u32 base;
diff --git a/kernel/inc/net.h b/kernel/inc/net.h
deleted file mode 100644
index 62ff5e5..0000000
--- a/kernel/inc/net.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef NET_H
-#define NET_H
-
-#include <def.h>
-#include <socket.h>
-
-#define htonl(l) \
- ((((l)&0xff) << 24) | (((l)&0xff00) << 8) | (((l)&0xff0000) >> 8) | \
- (((l)&0xff000000) >> 24))
-#define htons(s) ((((s)&0xff) << 8) | (((s)&0xff00) >> 8))
-#define ntohl(l) htonl((l))
-#define ntohs(s) htons((s))
-#define ip(a, b, c, d) \
- ((((a)&0xff) << 24) | (((b)&0xff) << 16) | (((c)&0xff) << 8) | (((d)&0xff) << 0))
-
-#define ETHERNET_TYPE_IP4 0x0800
-#define ETHERNET_TYPE_IP6 0x86dd
-#define ETHERNET_TYPE_ARP 0x0806
-
-#define IP_PROT_ICMP 0x01
-#define IP_PROT_TCP 0x06
-#define IP_PROT_UDP 0x11
-
-#define TCP_FLAG_FIN (1 << 0)
-#define TCP_FLAG_SYN (1 << 1)
-#define TCP_FLAG_RST (1 << 2)
-#define TCP_FLAG_PSH (1 << 3)
-#define TCP_FLAG_ACK (1 << 4)
-#define TCP_FLAG_URG (1 << 5)
-#define TCP_FLAG_ECE (1 << 6)
-#define TCP_FLAG_CWR (1 << 7)
-#define TCP_FLAG_NS (1 << 8)
-
-#define ARP_REQUEST 1
-#define ARP_REPLY 2
-
-#define DHCP_REQUEST 1
-#define DHCP_REPLY 2
-#define DHCP_TRANSACTION_IDENTIFIER 0x18122002
-
-#define HARDWARE_TYPE_ETHERNET 0x01
-
-// Hardcoded ports - TODO!
-#define DHCP_PORT 68
-#define DNS_PORT 50053
-
-// Protocol structs
-
-struct ethernet_packet {
- u8 dst[6];
- u8 src[6];
- u16 type;
- u8 data[];
-} PACKED;
-
-struct arp_packet {
- u16 hardware_type;
- u16 protocol;
- u8 hardware_addr_len;
- u8 protocol_addr_len;
- u16 opcode;
- u8 src_mac[6];
- u32 src_protocol_addr;
- u8 dst_mac[6];
- u32 dst_protocol_addr;
-} PACKED;
-
-struct ip_packet {
- u8 version_ihl;
- u8 dscp_ecn;
- u16 length;
- u16 id;
- u16 flags_fragment;
- u8 ttl;
- u8 protocol;
- u16 checksum;
- u32 src;
- u32 dst;
- u8 data[];
-} PACKED;
-
-struct dhcp_packet {
- u8 op;
- u8 hardware_type;
- u8 mac_len;
- u8 hops;
- u32 xid;
- u16 seconds;
- u16 flags;
- u32 client_ip;
- u32 your_ip;
- u32 server_ip;
- u32 gateway_ip;
- u8 client_mac[6];
- u8 reserved[10];
- u8 server_name[64];
- u8 file[128];
- u8 options[64];
-} PACKED;
-
-struct dns_packet {
- u16 qid;
- u16 flags;
- u16 questions;
- u16 answers;
- u16 authorities;
- u16 additional;
- u8 data[];
-} PACKED;
-
-struct udp_packet {
- u16 src_port;
- u16 dst_port;
- u16 length;
- u16 checksum;
- u8 data[];
-} PACKED;
-
-struct tcp_packet {
- u16 src_port;
- u16 dst_port;
- u32 seq_number;
- u32 ack_number;
- u16 flags;
- u16 window_size;
- u16 checksum;
- u16 urgent;
- u8 data[];
-} PACKED;
-
-struct tcp_pseudo_header {
- u32 src;
- u32 dst;
- u8 zeros;
- u8 protocol;
- u16 tcp_len;
- u8 tcp_packet[];
-};
-
-struct icmp_packet {
- u8 type;
- u8 version;
- u16 checksum;
- u16 identifier;
- u16 sequence;
-} PACKED;
-
-// Other structs
-
-struct arp_table_entry {
- u32 ip_addr;
- u64 mac_addr;
-};
-
-void ethernet_handle_packet(struct ethernet_packet *packet, int len) NONNULL;
-
-struct socket *net_open(enum socket_type type);
-int net_close(struct socket *socket) NONNULL;
-int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port) NONNULL;
-void net_send(struct socket *socket, void *data, u32 len) NONNULL;
-int net_receive(struct socket *socket, void *buf, u32 len) NONNULL;
-
-int net_installed(void);
-void net_install(void);
-
-#endif
diff --git a/kernel/main.c b/kernel/main.c
index 76d8412..44198e4 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -1,20 +1,19 @@
// MIT License, Copyright (c) 2020 Marvin Borner
#include <drivers/cpu.h>
-#include <fs.h>
#include <drivers/gdt.h>
#include <drivers/ide.h>
#include <drivers/interrupts.h>
+#include <drivers/pci.h>
+#include <drivers/rtc.h>
+#include <drivers/serial.h>
+#include <fs.h>
#include <io.h>
#include <load.h>
#include <mem.h>
#include <mm.h>
#include <multiboot.h>
-#include <net.h>
-#include <drivers/pci.h>
#include <rand.h>
-#include <drivers/rtc.h>
-#include <drivers/serial.h>
#include <syscall.h>
PROTECTED extern u32 __stack_chk_guard;
diff --git a/libs/libc/print.c b/libs/libc/print.c
index 46483cd..2eb119a 100644
--- a/libs/libc/print.c
+++ b/libs/libc/print.c
@@ -188,9 +188,9 @@ int print(const char *str)
// The kernel prints everything into the serial console
#include <drivers/cpu.h>
+#include <drivers/serial.h>
#include <mm.h>
#include <proc.h>
-#include <drivers/serial.h>
static void print_kernel(const char *str)
{
diff --git a/libs/libgui/png.c b/libs/libgui/png.c
index c405c3c..d2053ca 100644
--- a/libs/libgui/png.c
+++ b/libs/libgui/png.c
@@ -408,7 +408,6 @@ u32 png_load_file(u8 **out, u32 *outsize, const char *filename)
/*write given buffer to the file, overwriting the file, it doesn't append to it.*/
u32 png_save_file(const u8 *buffer, u32 buffersize, const char *filename)
{
- err(1, "Not implemented!\n");
if (write(filename, buffer, 0, buffersize) <= 0)
return 79;
return 0;
diff --git a/libs/libnet/Makefile b/libs/libnet/Makefile
deleted file mode 100644
index 53cb7a9..0000000
--- a/libs/libnet/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# MIT License, Copyright (c) 2020 Marvin Borner
-
-COBJS = dns.o http.o ip.o
-
-CFLAGS = $(CFLAGS_DEFAULT) -I$(LIBS) -I$(LIBS)/libc/inc/ -pie -fPIE -fPIC -DUSER
-
-all: libtxt
-
-%.o: %.c
- @$(CC) -c $(CFLAGS) $< -o $@
-
-libtxt: $(COBJS)
- @mkdir -p $(BUILD)
- @$(AR) rcs $(BUILD)/libnet.a $+
-
-clean:
- @find . -name "*.o" -type f -delete
diff --git a/libs/libnet/dns.c b/libs/libnet/dns.c
deleted file mode 100644
index e179bd6..0000000
--- a/libs/libnet/dns.c
+++ /dev/null
@@ -1,116 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// TODO: Less magic, auto xld splitting
-// TODO: DNS cache
-
-#include <def.h>
-#include <libnet/net.h>
-#include <libnet/socket.h>
-#include <mem.h>
-#include <print.h>
-#include <random.h>
-#include <str.h>
-
-static u32 dns_ip_addr = ip(1, 1, 1, 1);
-
-struct dns_packet {
- u16 qid;
- u16 flags;
- u16 questions;
- u16 answers;
- u16 authorities;
- u16 additional;
- u8 data[];
-} PACKED;
-
-static u32 part_count(const char *name)
-{
- u32 cnt = 0;
- for (u32 i = 0; i < strlen(name); i++) {
- if (name[i] == '.')
- cnt++;
- }
- return cnt + 1;
-}
-
-static u32 part_len(const char *name, u32 index)
-{
- const char *data = name;
-
- u32 cnt = 0;
- for (u32 i = 0; i < strlen(name); i++) {
- if (cnt == index) {
- data += i;
- break;
- }
-
- if (name[i] == '.')
- cnt++;
- }
-
- for (cnt = 0; cnt < strlen(data); cnt++) {
- if (data[cnt] == '.' || data[cnt] == '\0')
- break;
- }
-
- return cnt;
-}
-
-static void dns_make_packet(struct dns_packet *packet, const char *name)
-{
- packet->qid = htons(rand());
- packet->flags = htons(0x0100); // Standard query
- packet->questions = htons(1);
- packet->answers = htons(0);
- packet->authorities = htons(0);
- packet->additional = htons(0);
-
- u8 *data = packet->data;
- u32 cnt = 0;
- for (u32 i = 0; i < part_count(name) * 2; i += 2) {
- data[cnt] = part_len(name, i / 2);
- memcpy(&data[cnt + 1], &name[cnt], data[cnt]);
- cnt += data[cnt] + 1;
- }
-
- packet->data[cnt + 0] = 0x00; // Name end
- packet->data[cnt + 2] = 0x01; // A
- packet->data[cnt + 4] = 0x01; // IN
-}
-
-static u32 dns_handle_packet(struct dns_packet *packet)
-{
- u16 flags = htons(packet->flags);
- u8 reply_code = flags & 0xf;
- if (reply_code != DNS_NOERROR) {
- printf("DNS error: %d\n", reply_code);
- return 0;
- }
-
- u8 *start = &packet->data[1] + strlen((char *)&packet->data[1]);
- printf("TTL of %s: %ds\n", &packet->data[1], (u32)start[14]);
- u8 *ip = &start[17];
- printf("IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
- return ip(ip[0], ip[1], ip[2], ip[3]);
-}
-
-u32 dns_request(const char *name)
-{
- struct socket *socket = net_open(S_UDP);
- if (!socket || !net_connect(socket, dns_ip_addr, 53, NET_TIMEOUT) || part_count(name) == 1)
- return 0;
-
- u32 length = sizeof(struct dns_packet) + strlen(name) + part_count(name) + 4;
- struct dns_packet *packet = malloc(length);
- memset(packet, 0, length);
- dns_make_packet(packet, name);
- net_send(socket, packet, length);
- free(packet);
-
- u8 buf[1024] = { 0 };
- int l = net_receive(socket, buf, 1024, NET_TIMEOUT);
- net_close(socket);
- if (l > 0)
- return dns_handle_packet((void *)buf);
- else
- return 0;
-}
diff --git a/libs/libnet/dns.h b/libs/libnet/dns.h
deleted file mode 100644
index d6673e6..0000000
--- a/libs/libnet/dns.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef DNS_H
-#define DNS_H
-
-#include <def.h>
-
-#define DNS_NOERROR 0
-#define DNS_FORMERR 1
-#define DNS_SERVFAIL 2
-#define DNS_NXDOMAIN 3
-#define DNS_NOTIMP 4
-#define DNS_REFUSED 5
-#define DNS_YXDOMAIN 6
-#define DNS_XRRSET 7
-#define DNS_NOTAUTH 8
-#define DNS_NOTZONE 9
-
-u32 dns_request(const char *name);
-
-#endif
diff --git a/libs/libnet/http.c b/libs/libnet/http.c
deleted file mode 100644
index 808d4c2..0000000
--- a/libs/libnet/http.c
+++ /dev/null
@@ -1,134 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <assert.h>
-#include <conv.h>
-#include <def.h>
-#include <libnet/http.h>
-#include <libnet/net.h>
-#include <libnet/socket.h>
-#include <mem.h>
-#include <print.h>
-#include <str.h>
-
-char *http_data(char *r)
-{
- char *h = NULL;
- for (u32 i = 0; i < strlen(r); ++i) {
- if (r[i] == '\r' && r[i + 1] == '\n' && r[i + 2] == '\r' && r[i + 3] == '\n') {
- h = &r[i + 4];
- break;
- }
- }
- return h;
-}
-
-char *http_header_key(char *r, const char *key)
-{
- char *res = NULL;
- for (char *p = r; *p; p++) {
- /* printf("'%c%c%c' vs '%c%c%c'\n", p[0], p[1], p[2], key[0], key[1], key[2]); */
- if (strlen(p) >= strlen(key) && !memcmp(p, key, strlen(key))) {
- char *start = p + strlen(key) + 2;
- char *end = start;
- for (; *end != '\n'; end++)
- ;
- res = malloc(end - start);
- memcpy(res, start, end - start - 1);
- res[end - start] = '\0';
- break;
- }
- }
- return res;
-}
-
-u32 http_content_length(char *r)
-{
- char *value = http_header_key(r, "Content-Length");
- int length = value ? atoi(value) : 0;
- free(value);
- return length;
-}
-
-char *http_code(char *r)
-{
- char *code = malloc(4);
- char tmp = r[12];
- r[12] = '\0';
- memcpy(code, r + 9, 3);
- code[3] = '\0';
- r[12] = tmp;
- return code;
-}
-
-u32 http_response(const char *http_code, u32 content_length, const char *data, char *resp)
-{
- char buf[16] = { 0 };
-
- resp[0] = '\0';
- strcat(resp, "HTTP/1.1 ");
- strcat(resp, buf);
- strcat(resp, http_code);
- strcat(resp, "\r\n");
- strcat(resp, "Content-Length: ");
- strcat(resp, conv_base(content_length, buf, 10, 0));
- strcat(resp, "\r\n");
- strcat(resp, "Server: Melvix\r\n");
- strcat(resp, "Content-Type: text/html\r\n");
- strcat(resp, "Connection: close\r\n\r\n");
- u32 len = strlen(resp);
- memcpy(&resp[len], data, content_length);
-
- return len + content_length;
-}
-
-char *http_query_get(const char *url, const char *path)
-{
- char *query = malloc(27 + strlen(url)); // TODO: Dynamic http length etc
- query[0] = '\0';
- strcat(query, "GET ");
- if (path[0] != '/')
- strcat(query, "/");
- strcat(query, path);
- strcat(query, " HTTP/1.1\r\nHost: ");
- strcat(query, url);
- strcat(query, "\r\n\r\n");
- return query;
-}
-
-char *http_query_path(const char *query, char *path)
-{
- u8 b = 0;
- u32 s = 0;
- u32 e = 0;
-
- while (1) {
- if (!b && query[e] == ' ' && query[++e]) {
- s = e;
- b = 1;
- } else if (b && query[e] == ' ') {
- strncat(path, &query[s], e - s);
- break;
- } else if (query[e] == '\0') {
- return NULL;
- }
- e++;
- }
-
- return path;
-}
-
-char *http_receive(struct socket *socket)
-{
- char buf[4096] = { 0 };
- if (!net_receive(socket, buf, 4096, NET_TIMEOUT))
- return NULL;
-
- u32 length = http_content_length(buf);
- char *data = malloc(strlen(buf) + length);
- memcpy(data, buf, strlen(buf));
- while (strlen(http_data(data)) != length) {
- if (!net_receive(socket, data, length, NET_TIMEOUT))
- break;
- }
- return data;
-}
diff --git a/libs/libnet/http.h b/libs/libnet/http.h
deleted file mode 100644
index b9160ad..0000000
--- a/libs/libnet/http.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef HTTP_H
-#define HTTP_H
-
-#include <def.h>
-#include <libnet/socket.h>
-
-char *http_data(char *response);
-char *http_header_key(char *r, const char *key);
-u32 http_content_length(char *r);
-char *http_code(char *r);
-u32 http_response(const char *http_code, u32 content_length, const char *data, char *resp);
-char *http_query_get(const char *url, const char *path);
-char *http_query_path(const char *query, char *path);
-char *http_receive(struct socket *socket);
-
-#define HTTP_100 "100 Continue"
-#define HTTP_101 "101 Switching Protocol"
-#define HTTP_102 "102 Processing"
-#define HTTP_103 "103 Early Hints"
-#define HTTP_200 "200 OK"
-#define HTTP_201 "201 Created"
-#define HTTP_202 "202 Accepted"
-#define HTTP_203 "203 Non-Authoritative Information"
-#define HTTP_204 "204 No Content"
-#define HTTP_205 "205 Reset Content"
-#define HTTP_206 "206 Partial Content"
-#define HTTP_207 "207 Multi-Status"
-#define HTTP_208 "208 Already Reported"
-#define HTTP_226 "226 IM Used"
-#define HTTP_300 "300 Multiple Choice"
-#define HTTP_301 "301 Moved Permanently"
-#define HTTP_302 "302 Found"
-#define HTTP_303 "303 See Other"
-#define HTTP_304 "304 Not Modified"
-#define HTTP_305 "305 Use Proxy"
-#define HTTP_306 "306 Unused"
-#define HTTP_307 "307 Temporary Redirect"
-#define HTTP_308 "308 Permanent Redirect"
-#define HTTP_400 "400 Bad Request"
-#define HTTP_401 "401 Unauthorized"
-#define HTTP_402 "402 Payment Required"
-#define HTTP_403 "403 Forbidden"
-#define HTTP_404 "404 Not Found"
-#define HTTP_405 "405 Method Not Allowed"
-#define HTTP_406 "406 Not Acceptable"
-#define HTTP_407 "407 Proxy Authentication Required"
-#define HTTP_408 "408 Request Timeout"
-#define HTTP_409 "409 Conflict"
-#define HTTP_410 "410 Gone"
-#define HTTP_411 "411 Length Required"
-#define HTTP_412 "412 Precondition Failed"
-#define HTTP_413 "413 Payload Too Large"
-#define HTTP_414 "414 URI Too Long"
-#define HTTP_415 "415 Unsupported Media Type"
-#define HTTP_416 "416 Range Not Satisfiable"
-#define HTTP_417 "417 Expectation Failed"
-#define HTTP_418 "418 I'm a teapot"
-#define HTTP_421 "421 Misdirected Request"
-#define HTTP_422 "422 Unprocessable Entity"
-#define HTTP_423 "423 Locked"
-#define HTTP_424 "424 Failed Dependency"
-#define HTTP_425 "425 Too Early"
-#define HTTP_426 "426 Upgrade Required"
-#define HTTP_428 "428 Precondition Required"
-#define HTTP_429 "429 Too Many Request"
-#define HTTP_431 "431 Request Header Fields Too Large"
-#define HTTP_451 "451 Unavailable For Legal Reasons"
-#define HTTP_500 "500 Internal Server Error"
-#define HTTP_501 "501 Not Implemented"
-#define HTTP_502 "502 Bad Gateway"
-#define HTTP_503 "503 Service Unavailable"
-#define HTTP_504 "504 Gateway Timeout"
-#define HTTP_505 "505 HTTP Version Not Supported"
-#define HTTP_506 "506 Variant Also Negotiates"
-#define HTTP_507 "507 Insufficient Storage"
-#define HTTP_508 "508 Loop Detected"
-#define HTTP_510 "510 Not Extended"
-#define HTTP_511 "511 Network Authentication Required"
-
-#endif
diff --git a/libs/libnet/ip.c b/libs/libnet/ip.c
deleted file mode 100644
index 66fd8eb..0000000
--- a/libs/libnet/ip.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// Most net/ip handlers are in the kernel space
-// This is a userspace wrapper for some things
-
-#include <def.h>
-#include <libnet/net.h>
-#include <mem.h>
-#include <str.h>
-
-// Inspired by Paul Vixie, 1996
-int ip_pton(const char *src, u32 *dst)
-{
- const char *end = src + strlen(src);
- u8 tmp[4], *tp;
- int saw_digit = 0;
- int octets = 0;
- *(tp = tmp) = 0;
-
- while (src < end) {
- int ch = *src++;
- if (ch >= '0' && ch <= '9') {
- u32 new = *tp * 10 + (ch - '0');
-
- if ((saw_digit && *tp == 0) || new > 255)
- return 0;
-
- *tp = new;
- if (!saw_digit) {
- if (++octets > 4)
- return 0;
- saw_digit = 1;
- }
- } else if (ch == '.' && saw_digit) {
- if (octets == 4)
- return 0;
- *++tp = 0;
- saw_digit = 0;
- } else {
- return 0;
- }
- }
-
- if (octets < 4)
- return 0;
-
- *dst = htonl(*(u32 *)tmp);
- return 1;
-}
diff --git a/libs/libnet/ip.h b/libs/libnet/ip.h
deleted file mode 100644
index e06aba2..0000000
--- a/libs/libnet/ip.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// Most net/ip handlers are in the kernel space
-// This is a userspace wrapper for some things
-
-#ifndef IP_H
-#define IP_H
-
-#include <def.h>
-
-int ip_pton(const char *src, u32 *dst);
-
-#endif
diff --git a/libs/libnet/net.h b/libs/libnet/net.h
deleted file mode 100644
index 4bfda2b..0000000
--- a/libs/libnet/net.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef NET_H
-#define NET_H
-
-#include <libnet/dns.h>
-#include <libnet/ip.h>
-#include <libnet/socket.h>
-#include <print.h>
-#include <sys.h>
-
-#define htonl(l) \
- ((((l)&0xff) << 24) | (((l)&0xff00) << 8) | (((l)&0xff0000) >> 8) | \
- (((l)&0xff000000) >> 24))
-#define htons(s) ((((s)&0xff) << 8) | (((s)&0xff00) >> 8))
-#define ntohl(l) htonl((l))
-#define ntohs(s) htons((s))
-#define ip(a, b, c, d) \
- ((((a)&0xff) << 24) | (((b)&0xff) << 16) | (((c)&0xff) << 8) | (((d)&0xff) << 0))
-
-#define NET_TIMEOUT 2000
-#define NET_NO_TIMEOUT 0
-
-static inline int net_data_available(struct socket *socket)
-{
- return (socket && socket->packets && socket->packets->head && socket->packets->head->data &&
- ((struct socket_data *)socket->packets->head->data)->length > 0);
-}
-
-#define net_open(type) (void *)sys1(SYS_NET_OPEN, (int)(type))
-#define net_send(socket, data, len) (void)sys3(SYS_NET_SEND, (int)(socket), (int)(data), (int)(len))
-
-static inline int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port, u32 timeout)
-{
- if (!socket || !ip_addr || !dst_port)
- return 0;
- sys3(SYS_NET_CONNECT, (int)(socket), (int)(ip_addr), (int)(dst_port));
- int time = time();
- while (socket->state != S_CONNECTED) {
- if (socket->state == S_FAILED || (timeout && time() - time >= timeout))
- return 0;
- yield();
- }
- return 1;
-}
-
-static inline int net_close(struct socket *socket)
-{
- if (!socket)
- return 0;
- int res = 0;
- while (socket->state == S_CLOSING || !(res = (int)sys1(SYS_NET_CLOSE, (int)(socket))))
- yield();
- return res;
-}
-
-static inline int net_receive(struct socket *socket, void *buf, u32 len, u32 timeout)
-{
- if (!socket || !buf || !len)
- return 0;
-
- int time = time();
- while (!net_data_available(socket)) {
- if (socket->state == S_FAILED || (timeout && time() - time >= timeout))
- return 0;
- yield();
- }
-
- // TODO: Only return once all segments are received?
- return (int)sys3(SYS_NET_RECEIVE, (int)(socket), (int)(buf), (int)(len));
-}
-
-#endif
diff --git a/libs/libtxt/xml.c b/libs/libtxt/xml.c
deleted file mode 100644
index 9a5fd76..0000000
--- a/libs/libtxt/xml.c
+++ /dev/null
@@ -1,514 +0,0 @@
-// Inspired by sxml (capmar)
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <assert.h>
-#include <libtxt/xml.h>
-#include <mem.h>
-#include <str.h>
-
-static const char *str_findchr(const char *start, const char *end, int c)
-{
- const char *it;
-
- assert(start <= end);
- assert(0 <= c && c <= 127);
-
- it = (const char *)memchr((void *)start, c, end - start);
- return (it != NULL) ? it : end;
-}
-
-static const char *str_findstr(const char *start, const char *end, const char *needle)
-{
- u32 needlelen;
- int first;
- assert(start <= end);
-
- needlelen = strlen(needle);
- assert(0 < needlelen);
- first = (u8)needle[0];
-
- while (start + needlelen <= end) {
- const char *it =
- (const char *)memchr((void *)start, first, (end - start) - (needlelen - 1));
- if (it == NULL)
- break;
-
- if (memcmp(it, needle, needlelen) == 0)
- return it;
-
- start = it + 1;
- }
-
- return end;
-}
-
-static int str_starts_with(const char *start, const char *end, const char *prefix)
-{
- long nbytes;
- assert(start <= end);
-
- nbytes = strlen(prefix);
- if (end - start < nbytes)
- return 0;
-
- return memcmp(prefix, start, nbytes) == 0;
-}
-
-static int white_space(int c)
-{
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- return 1;
- }
-
- return 0;
-}
-
-static int name_start_char(int c)
-{
- if (0x80 <= c)
- return 1;
-
- return c == ':' || ('A' <= c && c <= 'Z') || c == '_' || ('a' <= c && c <= 'z');
-}
-
-static int name_char(int c)
-{
- return name_start_char(c) || c == '-' || c == '.' || ('0' <= c && c <= '9') || c == 0xB7 ||
- (0x0300 <= c && c <= 0x036F) || (0x203F <= c && c <= 0x2040);
-}
-
-#define is_space(c) (white_space(((u8)(c))))
-#define is_alpha(c) (name_start_char(((u8)(c))))
-#define is_alnum(c) (name_char(((u8)(c))))
-
-static const char *str_ltrim(const char *start, const char *end)
-{
- const char *it;
- assert(start <= end);
-
- for (it = start; it != end && is_space(*it); it++)
- ;
-
- return it;
-}
-
-static const char *str_rtrim(const char *start, const char *end)
-{
- const char *it, *prev;
- assert(start <= end);
-
- for (it = end; start != it; it = prev) {
- prev = it - 1;
- if (!is_space(*prev))
- return it;
- }
-
- return start;
-}
-
-static const char *str_find_notalnum(const char *start, const char *end)
-{
- const char *it;
- assert(start <= end);
-
- for (it = start; it != end && is_alnum(*it); it++)
- ;
-
- return it;
-}
-
-#define buffer_from_offset(args, i) ((args)->buffer + (i))
-#define buffer_tooffset(args, ptr) (unsigned)((ptr) - (args)->buffer)
-#define buffer_getend(args) ((args)->buffer + (args)->buffer_length)
-
-static int state_push_token(struct xml *state, struct xml_args *args, enum xml_type type,
- const char *start, const char *end)
-{
- struct xml_token *token;
- u32 i;
- if (args->num_tokens <= state->ntokens)
- return 0;
-
- i = state->ntokens++;
- token = &args->tokens[i];
- token->type = type;
- token->start_pos = buffer_tooffset(args, start);
- token->end_pos = buffer_tooffset(args, end);
- token->size = 0;
-
- switch (type) {
- case XML_START_TAG:
- state->tag_level++;
- break;
-
- case XML_END_TAG:
- assert(0 < state->tag_level);
- state->tag_level--;
- break;
-
- default:
- break;
- }
-
- return 1;
-}
-
-static enum xml_error state_set_pos(struct xml *state, const struct xml_args *args, const char *ptr)
-{
- state->buffer_pos = buffer_tooffset(args, ptr);
- return (state->ntokens <= args->num_tokens) ? XML_SUCCESS : XML_ERROR_TOKENSFULL;
-}
-
-#define state_commit(dest, src) memcpy((dest), (src), sizeof(struct xml))
-
-#define XML_ERROR_STRICT XML_ERROR_INVALID
-#define ENTITY_MAXLEN 8
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-static enum xml_error parse_characters(struct xml *state, struct xml_args *args, const char *end)
-{
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *limit, *colon, *ampr = str_findchr(start, end, '&');
- assert(end <= buffer_getend(args));
-
- if (ampr != start)
- state_push_token(state, args, XML_CHARACTER, start, ampr);
-
- if (ampr == end)
- return state_set_pos(state, args, ampr);
-
- limit = MIN(ampr + ENTITY_MAXLEN, end);
- colon = str_findchr(ampr, limit, ';');
- if (colon == limit)
- return (limit == end) ? XML_ERROR_BUFFERDRY : XML_ERROR_INVALID;
-
- start = colon + 1;
- state_push_token(state, args, XML_CHARACTER, ampr, start);
- return state_set_pos(state, args, start);
-}
-
-static enum xml_error parse_attrvalue(struct xml *state, struct xml_args *args, const char *end)
-{
- while (buffer_from_offset(args, state->buffer_pos) != end) {
- enum xml_error error = parse_characters(state, args, end);
- if (error != XML_SUCCESS)
- return error;
- }
-
- return XML_SUCCESS;
-}
-
-static enum xml_error parse_attributes(struct xml *state, struct xml_args *args)
-{
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- const char *name = str_ltrim(start, end);
-
- u32 ntokens = state->ntokens;
- assert(0 < ntokens);
-
- while (name != end && is_alpha(*name)) {
- const char *eq, *space, *quot, *value;
- enum xml_error error;
-
- eq = str_findchr(name, end, '=');
- if (eq == end)
- return XML_ERROR_BUFFERDRY;
-
- space = str_rtrim(name, eq);
- state_push_token(state, args, XML_CDATA, name, space);
-
- quot = str_ltrim(eq + 1, end);
- if (quot == end)
- return XML_ERROR_BUFFERDRY;
- else if (*quot != '\'' && *quot != '"')
- return XML_ERROR_INVALID;
-
- value = quot + 1;
- quot = str_findchr(value, end, *quot);
- if (quot == end)
- return XML_ERROR_BUFFERDRY;
-
- state_set_pos(state, args, value);
- error = parse_attrvalue(state, args, quot);
- if (error != XML_SUCCESS)
- return error;
-
- name = str_ltrim(quot + 1, end);
- }
-
- {
- struct xml_token *token = args->tokens + (ntokens - 1);
- token->size = (u16)(state->ntokens - ntokens);
- }
-
- return state_set_pos(state, args, name);
-}
-
-#define TAG_LEN(str) (sizeof(str) - 1)
-#define TAG_MINSIZE 1
-
-static enum xml_error parse_comment(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<!--";
- static const char END_TAG[] = "-->";
-
- const char *dash;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- dash = str_findstr(start, end, END_TAG);
- if (dash == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_COMMENT, start, dash);
- return state_set_pos(state, args, dash + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_instruction(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<?";
- static const char END_TAG[] = "?>";
-
- enum xml_error error;
- const char *quest, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- space = str_find_notalnum(start, end);
- if (space == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_INSTRUCTION, start, space);
-
- state_set_pos(state, args, space);
- error = parse_attributes(state, args);
- if (error != XML_SUCCESS)
- return error;
-
- quest = buffer_from_offset(args, state->buffer_pos);
- if (end - quest < (int)TAG_LEN(END_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(quest, end, END_TAG))
- return XML_ERROR_INVALID;
-
- return state_set_pos(state, args, quest + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_doctype(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<!DOCTYPE";
- static const char END_TAG[] = ">";
-
- const char *bracket;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- start += TAG_LEN(START_TAG);
- bracket = str_findstr(start, end, END_TAG);
- if (bracket == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_DOCTYPE, start, bracket);
- return state_set_pos(state, args, bracket + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_start(struct xml *state, struct xml_args *args)
-{
- enum xml_error error;
- const char *gt, *name, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!(start[0] == '<' && is_alpha(start[1])))
- return XML_ERROR_INVALID;
-
- name = start + 1;
- space = str_find_notalnum(name, end);
- if (space == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_START_TAG, name, space);
-
- state_set_pos(state, args, space);
- error = parse_attributes(state, args);
- if (error != XML_SUCCESS)
- return error;
-
- gt = buffer_from_offset(args, state->buffer_pos);
-
- if (gt != end && *gt == '/') {
- state_push_token(state, args, XML_END_TAG, name, space);
- gt++;
- }
-
- if (gt == end)
- return XML_ERROR_BUFFERDRY;
-
- if (*gt != '>')
- return XML_ERROR_INVALID;
-
- return state_set_pos(state, args, gt + 1);
-}
-
-static enum xml_error parse_end(struct xml *state, struct xml_args *args)
-{
- const char *gt, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!(str_starts_with(start, end, "</") && is_alpha(start[2])))
- return XML_ERROR_INVALID;
-
- start += 2;
- gt = str_findchr(start, end, '>');
- if (gt == end)
- return XML_ERROR_BUFFERDRY;
-
- space = str_find_notalnum(start, gt);
- if (str_ltrim(space, gt) != gt)
- return XML_ERROR_STRICT;
-
- state_push_token(state, args, XML_END_TAG, start, space);
- return state_set_pos(state, args, gt + 1);
-}
-
-static enum xml_error parse_cdata(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<![CDATA[";
- static const char END_TAG[] = "]]>";
-
- const char *bracket;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- bracket = str_findstr(start, end, END_TAG);
- if (bracket == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_CDATA, start, bracket);
- return state_set_pos(state, args, bracket + TAG_LEN(END_TAG));
-}
-
-void xml_init(struct xml *state)
-{
- state->buffer_pos = 0;
- state->ntokens = 0;
- state->tag_level = 0;
-}
-
-#define ROOT_FOUND(state) (0 < (state)->tag_level)
-#define ROOT_PARSED(state) ((state)->tag_level == 0)
-
-enum xml_error xml_parse(struct xml *state, const char *buffer, u32 buffer_length,
- struct xml_token tokens[], u32 num_tokens)
-{
- struct xml temp = *state;
- const char *end = buffer + buffer_length;
-
- struct xml_args args;
- args.buffer = buffer;
- args.buffer_length = buffer_length;
- args.tokens = tokens;
- args.num_tokens = num_tokens;
-
- while (!ROOT_FOUND(&temp)) {
- enum xml_error error;
- const char *start = buffer_from_offset(&args, temp.buffer_pos);
- const char *lt = str_ltrim(start, end);
- state_set_pos(&temp, &args, lt);
- state_commit(state, &temp);
-
- if (end - lt < TAG_MINSIZE)
- return XML_ERROR_BUFFERDRY;
-
- if (*lt != '<')
- return XML_ERROR_INVALID;
-
- switch (lt[1]) {
- case '?':
- error = parse_instruction(&temp, &args);
- break;
- case '!':
- error = (lt[2] == '-') ? parse_comment(&temp, &args) :
- parse_doctype(&temp, &args);
- break;
- default:
- error = parse_start(&temp, &args);
- break;
- }
-
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- while (!ROOT_PARSED(&temp)) {
- enum xml_error error;
- const char *start = buffer_from_offset(&args, temp.buffer_pos);
- const char *lt = str_findchr(start, end, '<');
- while (buffer_from_offset(&args, temp.buffer_pos) != lt) {
- error = parse_characters(&temp, &args, lt);
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- if (end - lt < TAG_MINSIZE)
- return XML_ERROR_BUFFERDRY;
-
- switch (lt[1]) {
- case '?':
- error = parse_instruction(&temp, &args);
- break;
- case '/':
- error = parse_end(&temp, &args);
- break;
- case '!':
- error = (lt[2] == '-') ? parse_comment(&temp, &args) :
- parse_cdata(&temp, &args);
- break;
- default:
- error = parse_start(&temp, &args);
- break;
- }
-
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- return XML_SUCCESS;
-}
diff --git a/libs/libtxt/xml.h b/libs/libtxt/xml.h
deleted file mode 100644
index 3f5c74d..0000000
--- a/libs/libtxt/xml.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Inspired by sxml (capmar)
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef XML_H
-#define XML_H
-
-#include <def.h>
-
-enum xml_error {
- XML_ERROR_INVALID = -1,
- XML_SUCCESS = 0,
- XML_ERROR_BUFFERDRY = 1,
- XML_ERROR_TOKENSFULL = 2
-};
-
-struct xml_token {
- u16 type;
- u16 size;
- u32 start_pos;
- u32 end_pos;
-};
-
-struct xml_args {
- const char *buffer;
- u32 buffer_length;
- struct xml_token *tokens;
- u32 num_tokens;
-};
-
-enum xml_type {
- XML_START_TAG,
- XML_END_TAG,
- XML_CHARACTER,
- XML_CDATA,
- XML_INSTRUCTION,
- XML_DOCTYPE,
- XML_COMMENT
-};
-
-struct xml {
- u32 buffer_pos;
- u32 ntokens;
- u32 tag_level;
-};
-
-enum xml_error xml_parse(struct xml *parser, const char *buffer, u32 buffer_length,
- struct xml_token *tokens, u32 num_tokens) NONNULL;
-
-void xml_init(struct xml *parser) NONNULL;
-
-#endif
diff --git a/res/test.c b/res/test.c
deleted file mode 100644
index ead84da..0000000
--- a/res/test.c
+++ /dev/null
@@ -1,5 +0,0 @@
-int main()
-{
- printf("Hello, world!\n");
- return 0;
-}
diff --git a/run b/run
index 8f882e0..980a6d3 100755
--- a/run
+++ b/run
@@ -270,6 +270,23 @@ make_sync() {
mv tmp compile_commands.json
}
+make_lint() {
+ format=$({ find . -path ./cross -prune -false -o -iname *.h -o -iname *.c -exec clang-format-11 -n --Werror {} \;; } 2>&1)
+ if [ $(echo -n "$format" | head -c1 | wc -c) -ne 0 ]; then
+ echo "$format"
+ exit 1
+ fi
+
+ # TODO: Implement clang-tidy linting
+ # find . -path ./cross -prune -o -iname *.h -o -iname *.c | xargs clang-tidy-11 --checks=-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
+
+ echo "No errors!"
+}
+
+make_format() {
+ find . -path ./cross -prune -false -o -iname *.h -o -iname *.c -exec clang-format-11 -i {} \;
+}
+
make_clean() {
#rm -rf build/
$MAKE clean
@@ -283,6 +300,10 @@ elif [ "${mode}" = "build" ]; then
make_build
elif [ "${mode}" = "clean" ]; then
make_clean
+elif [ "${mode}" = "lint" ]; then
+ make_lint
+elif [ "${mode}" = "format" ]; then
+ make_format
elif [ "${mode}" = "again" ]; then
make_test
elif [ "${mode}" = "disasm" ]; then
@@ -313,6 +334,8 @@ else
printf "\nDescription of options:\n"
printf "cross\t\tBuilds the cross compiler\n"
printf "clean\t\tRemoves the compiled files\n"
+ printf "lint\t\tLint the entire project using clang-tidy\n"
+ printf "format\t\tFormat the entire project using clang-format\n"
printf "build\t\tBuilds the whole project (cross+clean)\n"
printf "test\t\tRuns the Melvix unit tests with QEMU (cross+clean+build)\n"
printf "debug\t\tEmulates Melvix with QEMU and debug options (cross+clean+build)\n"