From 7d40548496f4d3cdfce828fc8e4f0fd4286e873a Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 2 Aug 2017 11:24:26 +0200 Subject: introduced a network library, added ethernet structure, moved generic stuff out of the network driver, kernel now sees ARP messages and prints src and dst MAC addresses --- README | 1 + doc/LINKS.TODO | 1 + src/Makefile | 8 ++++-- src/README | 7 +++++ src/drivers/net/network.c | 10 ------- src/drivers/net/network.h | 6 +--- src/drivers/net/rtl8139.c | 70 ++++++++++++----------------------------------- src/kernel/kernel.c | 16 ++++++++++- src/net/ethernet.c | 13 +++++++++ src/net/ethernet.h | 38 +++++++++++++++++++++++++ 10 files changed, 100 insertions(+), 70 deletions(-) create mode 100644 src/net/ethernet.c create mode 100644 src/net/ethernet.h diff --git a/README b/README index aa75fbd..915ce8a 100644 --- a/README +++ b/README @@ -101,3 +101,4 @@ http://prettyos.de http://www.jbox.dk/sanos/index.htm https://github.com/omarrx024/xos/ http://minirighi.sourceforge.net +http://contiki-os.org/ diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO index 4824e48..cc77456 100644 --- a/doc/LINKS.TODO +++ b/doc/LINKS.TODO @@ -118,6 +118,7 @@ http://linuxgazette.net/156/jangir.html http://blog.elastocloud.org/2015/07/qemukvm-bridged-network-with-tap.html Ethernet: +https://en.wikipedia.org/wiki/Ethernet_frame https://en.wikipedia.org/wiki/EtherType ARP: diff --git a/src/Makefile b/src/Makefile index c71cfa8..32e98e6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CC := gcc DEFINES = -DOS_ABAOS OPT := -O0 -INCLUDES = -I. -Ilibc -Ihardware -Idrivers -Idrivers/hdi -Idrivers/hdi/ps2 -Idrivers/video -Idrivers/net -Ikernel -Igui +INCLUDES = -I. -Ilibc -Ihardware -Idrivers -Idrivers/hdi -Idrivers/hdi/ps2 -Idrivers/video -Inet -Idrivers/net -Ikernel -Igui CFLAGS := -std=c99 -m32 -march=i486 -ffreestanding $(OPT) -g -Werror $(INCLUDES) $(DEFINES) LD := ld LDFLAGS := -lgcc @@ -36,7 +36,7 @@ kernel.bin: kernel.elf kernel.sym: kernel.elf $(OBJCOPY) --only-keep-debug kernel.elf kernel.sym -kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/memorymanagement.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/mouse.o drivers/hdi/keyboard.o drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2mouse.o drivers/video/video.o drivers/video/vga.o drivers/video/vga_font.o drivers/net/network.o drivers/net/rtl8139.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o +kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/memorymanagement.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/mouse.o drivers/hdi/keyboard.o drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2mouse.o drivers/video/video.o drivers/video/vga.o drivers/video/vga_font.o net/ethernet.o drivers/net/network.o drivers/net/rtl8139.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o $(LD) -o kernel.elf -N -n -Ttext 0x8800 -e kernel_entry --oformat elf32-i386 \ kernel/entry.o \ kernel/kernel.o kernel/kernel_asm.o \ @@ -45,6 +45,7 @@ kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o hardware/port.o hardware/port_asm.o \ hardware/interrupts.o hardware/interrupts_asm.o \ hardware/pci.o \ + net/ethernet.o \ drivers/driver.o \ drivers/hdi/mouse.o drivers/hdi/keyboard.o \ drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2mouse.o \ @@ -98,6 +99,9 @@ hardware/interrupts_asm.o: hardware/interrupts.asm hardware/pci.o: hardware/pci.c hardware/pci.h $(CC) $(CFLAGS) -c -o hardware/pci.o hardware/pci.c +network/ethernet.o: network/ethernet.c network/ethernet.h + $(CC) $(CFLAGS) -c -o network/ethernet.o network/ethernet.c + drivers/driver.o: drivers/driver.c drivers/driver.h $(CC) $(CFLAGS) -c -o drivers/driver.o drivers/driver.c diff --git a/src/README b/src/README index c2e9065..43abced 100644 --- a/src/README +++ b/src/README @@ -75,3 +75,10 @@ C library routines * stdlib.c - UNIX standard library functions * stdio.c - I/O functions, printing * setjmp.asm - setjmp/longjmp implementation (in assembly) + +net +--- + +Network library, currently IPv4 only. + +* arp.c - implementation of the ARP protocol diff --git a/src/drivers/net/network.c b/src/drivers/net/network.c index 85bfdf2..be8001d 100644 --- a/src/drivers/net/network.c +++ b/src/drivers/net/network.c @@ -32,13 +32,3 @@ void network_register_handler( void *obj, network_event_handler_t handler ) network->handler = handler; } - -char *network_mac_to_string( network_mac_address_t mac, char *buf, size_t buflen ) -{ - snprintf( buf, buflen, "%X:%X:%X:%X:%X:%X", - mac.byte[0], mac.byte[1], mac.byte[2], - mac.byte[3], mac.byte[4], mac.byte[5] ); - - return buf; -} - diff --git a/src/drivers/net/network.h b/src/drivers/net/network.h index a4ffca0..91dbf61 100644 --- a/src/drivers/net/network.h +++ b/src/drivers/net/network.h @@ -6,9 +6,7 @@ #include "stdint.h" #include "stddef.h" -typedef struct { - uint8_t byte[6]; -} network_mac_address_t; +#include "ethernet.h" typedef struct { uint16_t length; @@ -32,6 +30,4 @@ void network_init( network_t *network, interrupt_t *interrupt, void *context ); void network_register_handler( void *obj, network_event_handler_t handler ); -char *network_mac_to_string( network_mac_address_t mac, char *buf, size_t buflen ); - #endif // NETWORK_H diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 08c2b1a..c119112 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -86,6 +86,8 @@ static rtl8139_vtable_t const rtl8139_vtable = { // header #define PACKET_HEADER_ROK 0x0001 +#define ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 64 + // receive buffer, set to 8k + header (16) + wrap (2k) #define RECEIVE_BUFFER_SIZE 8192 #define RECEIVE_TOTAL_BUFFER_SIZE RECEIVE_BUFFER_SIZE + 16 + 2048 @@ -270,14 +272,21 @@ static void handle_receive_packet( rtl8139_t *rtl8139 ) for( int i = len; i < len + 4; i++ ) { printf( "%X ", rtl8139->receive_buffer[rtl8139->receive_buffer_pos+i] ); } + puts( "" ); #endif - // copy data for the handler of the network event network_event_t event; - event.length = len; - event.data = (uint8_t *)malloc( len ); - memcpy( event.data, buffer, len ); - memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) ); + + if( len >= ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 ) { + // copy data for the handler of the network event + event.length = len; + event.data = (uint8_t *)malloc( len ); + memcpy( event.data, buffer, len ); + memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) ); + } else { + // make sure we don't have a runt package + puts( "rtl8139: too small frame seen. packet ignored." ); + } // adjust buffer pos rtl8139->receive_buffer_pos += 2 * sizeof( uint16_t ); @@ -292,53 +301,10 @@ static void handle_receive_packet( rtl8139_t *rtl8139 ) // documentation of the card!) port16_write( &rtl8139->CAPR_port, rtl8139->receive_buffer_pos - 16 ); - rtl8139->base.handler( &event, rtl8139 ); + if( len >= ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 ) { + rtl8139->base.handler( &event, rtl8139 ); + } } - -#if 0 - - while (1) - { - netcard->rx_buffer_offset += 4; - - if (length >= sizeof(struct eth_packet_header)) - { - uint8_t data[length - 4]; - if ((netcard->rx_buffer_offset + length - 4) >= RX_BUFFER_SIZE) { - // FIXME Beim Umbruch gehen Daten kaputt - memcpy(data, buffer, RX_BUFFER_SIZE - netcard->rx_buffer_offset); - memcpy( - data + RX_BUFFER_SIZE - netcard->rx_buffer_offset, - netcard->rx_buffer, - (length - 4) - (RX_BUFFER_SIZE - netcard->rx_buffer_offset) - ); - } else { - memcpy(data, buffer, length - 4); - } - - cdi_net_receive( - (struct cdi_net_device*) netcard, - data, - length - 4); - } - --- - - // Den aktuellen Offset im Lesepuffer anpassen. Jedes Paket ist - // dword-aligned, daher anschließend Aufrundung. - netcard->rx_buffer_offset += length + 4; - netcard->rx_buffer_offset = (netcard->rx_buffer_offset + 3) & ~0x3; - - // Überläufe abfangen - netcard->rx_buffer_offset %= 0x2000; - - write_register_word(netcard, REG_CUR_READ_ADDR, - netcard->rx_buffer_offset - 0x10); - - - - } -#endif } uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) @@ -377,7 +343,7 @@ void rtl8139_print_info( void *obj ) { rtl8139_t *rtl8139 = (rtl8139_t *)obj; - char buf[20]; + char buf[NETWORK_ETHERNET_MAC_ADDR_STRING]; char buf2[30]; if( rtl8139->model == NULL ) { snprintf( buf2, 30, "unknown submodel 0x%X", rtl8139->model_id ); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 4b2990d..7cef578 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -16,7 +16,10 @@ #include "video.h" #include "pci.h" #include "memorymanagement.h" + +// TODO: move away from main! #include "network.h" +#include "ethernet.h" #include "setjmp.h" @@ -452,7 +455,18 @@ void __stack_chk_fail( void ) void handle_network_event( network_event_t *event, void *context ) { - printf( "NETWORK DATA: len: %d\n", event->length ); + network_ethernet_packet_t *packet = (network_ethernet_packet_t *)event->data; + + printf( "NETWORK DATA: len: %d, type: %X\n", event->length, + packet->header.type ); + + if( packet->header.type == NETWORK_ETHER_TYPE_ARP ) { + char src[NETWORK_ETHERNET_MAC_ADDR_STRING]; + char dst[NETWORK_ETHERNET_MAC_ADDR_STRING]; + network_mac_to_string( packet->header.src_addr, src, NETWORK_ETHERNET_MAC_ADDR_STRING ); + network_mac_to_string( packet->header.dst_addr, dst, NETWORK_ETHERNET_MAC_ADDR_STRING ); + printf( "ARP: src: %s dst: %s\n", src, dst ); + } // we must free if data if we no longer need it free( event->data ); diff --git a/src/net/ethernet.c b/src/net/ethernet.c new file mode 100644 index 0000000..48db20c --- /dev/null +++ b/src/net/ethernet.c @@ -0,0 +1,13 @@ +#include "ethernet.h" + +#include "stdio.h" + +char *network_mac_to_string( network_mac_address_t mac, char *buf, size_t buflen ) +{ + snprintf( buf, buflen, "%X:%X:%X:%X:%X:%X", + mac.byte[0], mac.byte[1], mac.byte[2], + mac.byte[3], mac.byte[4], mac.byte[5] ); + + return buf; +} + diff --git a/src/net/ethernet.h b/src/net/ethernet.h new file mode 100644 index 0000000..a2726e7 --- /dev/null +++ b/src/net/ethernet.h @@ -0,0 +1,38 @@ +#ifndef ETHERNET_H +#define ETHERNET_H + +#include "stddef.h" + +#define NETWORK_ETHERNET_MAC_ADDR_STRING 6 * 3 + 1 + +typedef struct { + uint8_t byte[6]; +} network_mac_address_t; + +typedef uint16_t ether_type_t; + +// TODO: network order not host oder, so for now swap it +#define NETWORK_ETHER_TYPE_ARP 0x0608 + +#if defined( __TINYC__ ) +#pragma pack(1) +#endif + +typedef struct { + network_mac_address_t dst_addr; + network_mac_address_t src_addr; + ether_type_t type; +} __attribute__( ( packed ) ) network_ethernet_packet_header_t; + +typedef struct { + network_ethernet_packet_header_t header; + uint8_t *data; +} __attribute__( ( packed ) ) network_ethernet_packet_t; + +#if defined( __TINYC__ ) +#pragma pack() +#endif + +char *network_mac_to_string( network_mac_address_t mac, char *buf, size_t buflen ); + +#endif // ETHERNET_H -- cgit v1.2.3-54-g00ecf