diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/drivers/rtl8139.c | 4 | ||||
-rw-r--r-- | kernel/features/net.c | 79 | ||||
-rw-r--r-- | kernel/inc/net.h | 13 | ||||
-rwxr-xr-x | run | 2 |
6 files changed, 67 insertions, 35 deletions
@@ -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(); @@ -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 |