aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-09-26 16:29:49 +0200
committerMarvin Borner2020-09-26 16:29:49 +0200
commitcac7c352a1ece2744de42128a9c69df16f05d26a (patch)
tree667d9b817f77df30468c63af735de0790f59acac
parent038722e045684a1a04f0fd6a51da2a6ea9dc9bb5 (diff)
Very simple icmp ping handling
-rw-r--r--.gitignore2
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/drivers/rtl8139.c4
-rw-r--r--kernel/features/net.c79
-rw-r--r--kernel/inc/net.h13
-rwxr-xr-xrun2
6 files changed, 67 insertions, 35 deletions
diff --git a/.gitignore b/.gitignore
index 3ff5e8e..b2e2972 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@ compile_commands.json
*.o
*.elf
*.bin
+*.log
+*.pcap
.clangd/
build/
diff --git a/kernel/Makefile b/kernel/Makefile
index e415454..1fc024f 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -23,7 +23,7 @@ LD = ../cross/opt/bin/i686-elf-ld
OC = ../cross/opt/bin/i686-elf-objcopy
AS = nasm
-CFLAGS = -Wall -Wextra -nostdlib -nostdinc -ffreestanding -fno-builtin -mno-red-zone -mgeneral-regs-only -std=c99 -m32 -pedantic-errors -Wl,-ekernel_main -I../libc/inc/ -Iinc/ -Dkernel -O0
+CFLAGS = -Wall -Wextra -Wno-address-of-packed-member -nostdlib -nostdinc -ffreestanding -fno-builtin -mno-red-zone -mgeneral-regs-only -std=c99 -m32 -pedantic-errors -Wl,-ekernel_main -I../libc/inc/ -Iinc/ -Dkernel -Ofast
ASFLAGS = -f elf32
diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c
index 6487eca..2fc8f07 100644
--- a/kernel/drivers/rtl8139.c
+++ b/kernel/drivers/rtl8139.c
@@ -25,6 +25,7 @@ u8 *rtl8139_get_mac()
void rtl8139_receive_packet()
{
+ printf("%x\n", current_packet_ptr);
u16 *t = (u16 *)(rx_buffer + current_packet_ptr);
u16 length = *(t + 1);
t += 2;
@@ -35,7 +36,7 @@ void rtl8139_receive_packet()
current_packet_ptr = (current_packet_ptr + length + 4 + 3) & (~3);
- if (current_packet_ptr > RX_BUF_SIZE)
+ if (current_packet_ptr >= RX_BUF_SIZE)
current_packet_ptr -= RX_BUF_SIZE;
outw(rtl_iobase + RTL_PORT_RXPTR, current_packet_ptr - 0x10);
@@ -46,6 +47,7 @@ static u8 tsd_array[4] = { 0x10, 0x14, 0x18, 0x1C };
static u8 tx_current = 0;
void rtl8139_send_packet(void *data, u32 len)
{
+ printf("Sending packet %d\n", len);
outl(rtl_iobase + tsad_array[tx_current], (u32)data);
outl(rtl_iobase + tsd_array[tx_current++], len);
if (tx_current > 3)
diff --git a/kernel/features/net.c b/kernel/features/net.c
index 7806504..1ebccb5 100644
--- a/kernel/features/net.c
+++ b/kernel/features/net.c
@@ -7,55 +7,74 @@
#include <print.h>
#include <rtl8139.h>
-int ethernet_send_packet(u8 *dst_mac_addr, u8 *data, int len, int prot)
+/**
+ * Checksums
+ */
+
+u16 ip_calculate_checksum(struct ip_packet *packet)
+{
+ u32 sum = 0;
+ u16 *s = (u16 *)packet;
+
+ for (int i = 0; i < 10; ++i)
+ sum += ntohs(s[i]);
+
+ if (sum > 0xFFFF)
+ sum = (sum >> 16) + (sum & 0xFFFF);
+
+ return sum;
+}
+
+/**
+ * Requests
+ */
+
+int ethernet_send_packet(u8 *dst, u8 *data, int len, int prot)
{
struct ethernet_packet *packet = malloc(sizeof(*packet) + len);
- void *packet_data = (u32 *)packet + sizeof(*packet);
- memcpy(packet->src_mac_addr, rtl8139_get_mac(), 6);
- memcpy(packet->dst_mac_addr, dst_mac_addr, 6);
- memcpy(packet_data, data, len);
+ memcpy(packet->src, rtl8139_get_mac(), 6);
+ memcpy(packet->dst, dst, 6);
+ memcpy(packet->data, data, len);
packet->type = htons(prot);
rtl8139_send_packet(packet, sizeof(*packet) + len);
free(packet);
return len;
}
-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++) {
- u32 first_byte = *((u8 *)(&array[i]));
- u32 second_byte = *((u8 *)(&array[i]) + 1);
- sum += (first_byte << 8) | (second_byte);
- }
- u32 carry = sum >> 16;
- sum = sum & 0x0000ffff;
- sum = sum + carry;
- u16 ret = ~sum;
- return ret;
-}
-
void ip_send_packet(u32 dst, void *data, int len, int prot)
{
struct ip_packet *packet = malloc(sizeof(*packet) + len);
memset(packet, 0, sizeof(*packet));
- packet->version = 4;
- packet->ihl = 5; // 5 * 4 = 20B
+ packet->version_ihl = ((0x4 << 4) | (0x5 << 0));
packet->length = sizeof(*packet) + len;
packet->id = 0; // TODO: IP fragmentation
packet->ttl = 64;
packet->protocol = prot;
- packet->src = 0;
+ packet->src = htonl(0x0a00022a);
packet->dst = dst;
- void *packet_data = (u32 *)packet + packet->ihl * 4;
- memcpy(packet_data, data, len);
+ /* void *packet_data = (u32 *)packet + 0x5 * 4; */
+ memcpy(packet->data, data, len);
packet->length = htons(sizeof(*packet) + len);
packet->checksum = htons(ip_calculate_checksum(packet));
// TODO: arp destination lookup
ethernet_send_packet((u8 *)0x424242424242, (u8 *)packet, htons(packet->length),
ETHERNET_TYPE_IP4);
+ free(packet);
+}
+
+/**
+ * Responses
+ */
+
+void icmp_handle_packet(u32 dst, int len)
+{
+ struct icmp_packet *packet = malloc(sizeof(*packet) + len);
+ memset(packet, 0, sizeof(*packet));
+ packet->type = 0; // Ping reponse
+ packet->version = 0;
+ packet->checksum = 0;
+ ip_send_packet(dst, packet, sizeof(*packet) + len, IP_PROT_ICMP);
+ free(packet);
}
void ip_handle_packet(struct ip_packet *packet, int len)
@@ -63,7 +82,7 @@ void ip_handle_packet(struct ip_packet *packet, int len)
switch (packet->protocol) {
case IP_PROT_ICMP:
print("ICMP Packet!\n");
- ip_send_packet(packet->src, packet->data, len, IP_PROT_ICMP);
+ icmp_handle_packet(packet->src, len);
break;
case IP_PROT_TCP:
print("TCP Packet!\n");
@@ -93,6 +112,10 @@ void ethernet_handle_packet(struct ethernet_packet *packet, int len)
}
}
+/**
+ * Install
+ */
+
void net_install()
{
rtl8139_install();
diff --git a/kernel/inc/net.h b/kernel/inc/net.h
index 300c0bd..943583a 100644
--- a/kernel/inc/net.h
+++ b/kernel/inc/net.h
@@ -21,15 +21,14 @@
#define IP_PROT_UDP 0x11
struct ethernet_packet {
- u8 dst_mac_addr[6];
- u8 src_mac_addr[6];
+ u8 dst[6];
+ u8 src[6];
u16 type;
u8 data[];
} __attribute__((packed));
struct ip_packet {
- u8 version : 4;
- u8 ihl : 4;
+ u8 version_ihl;
u8 dscp_ecn;
u16 length;
u16 id;
@@ -42,6 +41,12 @@ struct ip_packet {
u8 data[];
} __attribute__((packed));
+struct icmp_packet {
+ u8 type;
+ u8 version;
+ u16 checksum;
+} __attribute__((packed));
+
void ethernet_handle_packet(struct ethernet_packet *packet, int len);
void net_install();
diff --git a/run b/run
index 284a07e..7ce006b 100755
--- a/run
+++ b/run
@@ -12,7 +12,7 @@ no_ask="${2}"
qemu_with_flags() {
if [ -z "$network" ]; then network="rtl8139"; fi
if [ "$network" != "false" ] && [ "$mode" = "net" ]; then
- qemu-system-i386 -cpu max -no-reboot -vga std -rtc base=localtime -m 256M -smp 4 -netdev tap,helper=/usr/lib/qemu/qemu-bridge-helper,id=melvix_net -device $network,netdev=melvix_net,id=melvix_nic "$@"
+ qemu-system-i386 -cpu max -no-reboot -vga std -rtc base=localtime -m 256M -smp 4 -netdev tap,helper=/usr/lib/qemu/qemu-bridge-helper,id=melvix_net -device $network,netdev=melvix_net,id=melvix_nic -object filter-dump,id=melvix_nic,netdev=melvix_net,file=dump.pcap "$@"
else
qemu-system-i386 -cpu max -no-reboot -vga std -rtc base=localtime -m 256M -smp 4 "$@"
fi