From cb2acdaf3d1ee158f41a7e2617ebaaadfeef53da Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 6 Aug 2017 21:41:16 +0200 Subject: some cleanup in ethernet constants sending back an ARP packet rtl8139: started to implement write (work in progress) --- README | 2 +- src/drivers/net/network.c | 8 +++++++- src/drivers/net/network.h | 6 ++++++ src/drivers/net/rtl8139.c | 38 ++++++++++++++++++++++++++++++++------ src/drivers/net/rtl8139.h | 6 ++++++ src/kernel/kernel.c | 18 +++++++++++++++--- src/net/ethernet.h | 7 +++++++ 7 files changed, 74 insertions(+), 11 deletions(-) diff --git a/README b/README index 915ce8a..4ddff4c 100644 --- a/README +++ b/README @@ -64,7 +64,7 @@ set disassemble-next-line on analyze network traffic: -tcpdump -nr network.log +tcpdump -enr network.log links ----- diff --git a/src/drivers/net/network.c b/src/drivers/net/network.c index be8001d..8c2edc1 100644 --- a/src/drivers/net/network.c +++ b/src/drivers/net/network.c @@ -12,7 +12,8 @@ static network_vtable_t const network_vtable = { driver_deinit, driver_print_info }, - network_register_handler + network_register_handler, + network_write }; void network_init( network_t *network, interrupt_t *interrupt, void *context ) @@ -32,3 +33,8 @@ void network_register_handler( void *obj, network_event_handler_t handler ) network->handler = handler; } + +void network_write( void *obj, network_buffer_t buf ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} diff --git a/src/drivers/net/network.h b/src/drivers/net/network.h index 91dbf61..39ae627 100644 --- a/src/drivers/net/network.h +++ b/src/drivers/net/network.h @@ -11,6 +11,10 @@ typedef struct { uint16_t length; uint8_t *data; +} network_buffer_t; + +typedef struct { + network_buffer_t buf; } network_event_t; typedef void (*network_event_handler_t)( network_event_t *event, void *context ); @@ -24,10 +28,12 @@ typedef struct { typedef struct { driver_vtable_t base; void (*register_handler)( void *obj, network_event_handler_t handler ); + void (*write)( void *obj, network_buffer_t buf ); } network_vtable_t; void network_init( network_t *network, interrupt_t *interrupt, void *context ); void network_register_handler( void *obj, network_event_handler_t handler ); +void network_write( void *obj, network_buffer_t buf ); #endif // NETWORK_H diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 5b95042..ad6ccfe 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -15,12 +15,15 @@ static rtl8139_vtable_t const rtl8139_vtable = { rtl8139_print_name, rtl8139_print_info }, - network_register_handler + network_register_handler, + rtl8139_write } }; // registers #define REG_MAC0 0x00 +#define REG_TR_STATUS0 0x10 +#define REG_TR_ADDR0 0x20 #define REG_RBSTART 0x30 #define REG_CMD 0x37 #define REG_CAPR 0x38 @@ -86,8 +89,6 @@ 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 @@ -106,6 +107,11 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip for( int i = 0; i < NOF_MAC_REGISTERS; i++ ) { port8_init( &rtl8139->MAC_port[i], descriptor->port_base + REG_MAC0 + i ); } + for( int i = 0; i < NOF_TRANSMIT_BUFFERS; i++ ) { + port32_init( &rtl8139->TSD_port[i], descriptor->port_base + REG_TR_STATUS0 +i ); + port32_init( &rtl8139->TSAD_port[i], descriptor->port_base + REG_TR_ADDR0 + i ); + } + port8_init( &rtl8139->CMD_port, descriptor->port_base + REG_CMD ); port16_init( &rtl8139->CAPR_port, descriptor->port_base + REG_CAPR ); port32_init( &rtl8139->RBSTART_port, descriptor->port_base + REG_RBSTART ); @@ -184,6 +190,14 @@ void rtl8139_init( rtl8139_t *rtl8139, pci_controller_t *pci, pci_device_descrip port32_write( &rtl8139->RBSTART_port, (uint32_t)rtl8139->receive_buffer ); rtl8139->receive_buffer_pos = 0; + // allocate transmit buffers and set index to first transmit buffer + for( int i = 0; i < NOF_TRANSMIT_BUFFERS; i++ ) { + rtl8139->transmit_buffer[i] = (uint8_t *)aligned_alloc( 16, ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 ); + memset( rtl8139->transmit_buffer[i], 0, ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 ); + port32_write( &rtl8139->TSAD_port[i], (uint32_t)rtl8139->transmit_buffer[i] ); + } + rtl8139->transmit_buffer_idx = 0; + // reset missed packet counter port32_write( &rtl8139->MPC_port, 0 ); @@ -279,9 +293,9 @@ static void handle_receive_packet( rtl8139_t *rtl8139 ) 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 ); + event.buf.length = len; + event.buf.data = (uint8_t *)malloc( len ); + memcpy( event.buf.data, buffer, len ); memset( rtl8139->receive_buffer, 0, len + 2 * sizeof( uint16_t ) ); } else { // make sure we don't have a runt package @@ -353,3 +367,15 @@ void rtl8139_print_info( void *obj ) ( rtl8139->model != NULL ) ? rtl8139->model : buf2, rtl8139->pci_descriptor.port_base, rtl8139->pci_descriptor.interrupt, buf ); } + +void rtl8139_write( void *obj, network_buffer_t buf ) +{ +#ifdef DEBUG + printf( "rtl8139: sending data of length %d\n", buf.length ); + printf( "rtl8139: " ); + for( int i = 0; i < buf.length; i++ ) { + printf( "%X ", ((const uint8_t *)buf.data)[i] ); + } + puts( "" ); +#endif +} diff --git a/src/drivers/net/rtl8139.h b/src/drivers/net/rtl8139.h index 462526a..ec87d23 100644 --- a/src/drivers/net/rtl8139.h +++ b/src/drivers/net/rtl8139.h @@ -6,10 +6,13 @@ #include "port.h" #define NOF_MAC_REGISTERS 6 +#define NOF_TRANSMIT_BUFFERS 4 typedef struct { network_t base; port8_t MAC_port[NOF_MAC_REGISTERS]; + port32_t TSD_port[NOF_TRANSMIT_BUFFERS]; + port32_t TSAD_port[NOF_TRANSMIT_BUFFERS]; port32_t RBSTART_port; port8_t CMD_port; port16_t CAPR_port; @@ -24,6 +27,8 @@ typedef struct { const char *model; uint8_t *receive_buffer; uint16_t receive_buffer_pos; + uint8_t *transmit_buffer[NOF_TRANSMIT_BUFFERS]; + int transmit_buffer_idx; interrupt_handler_t interrupt_handler; } rtl8139_t; @@ -37,6 +42,7 @@ void rtl8139_deactivate( void *obj ); void rtl8139_deinit( void *obj ); void rtl8139_print_name( void *obj ); void rtl8139_print_info( void *obj ); +void rtl8139_write( void *obj, network_buffer_t buf ); uint32_t rtl8139_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 460cb74..0b10f45 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -456,7 +456,8 @@ void __stack_chk_fail( void ) void handle_network_event( network_event_t *event, void *context ) { - network_ethernet_packet_t *packet = (network_ethernet_packet_t *)event->data; + network_ethernet_packet_t *packet = (network_ethernet_packet_t *)event->buf.data; + network_t *network = (network_t *)context; char src_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING]; char dst_mac_addr[NETWORK_ETHERNET_MAC_ADDR_STRING]; @@ -464,7 +465,7 @@ void handle_network_event( network_event_t *event, void *context ) network_mac_address_to_string( packet->header.dst_addr, dst_mac_addr, NETWORK_ETHERNET_MAC_ADDR_STRING ); printf( "NETWORK DATA: src: %s, dst: %s, len: %d, type: %X\n", src_mac_addr, dst_mac_addr, - event->length, + event->buf.length, packet->header.type ); if( packet->header.type == NETWORK_ETHER_PROTOCOL_TYPE_ARP ) { @@ -479,8 +480,19 @@ void handle_network_event( network_event_t *event, void *context ) printf( "ARP: hw src: %s, dst: %s, ip src: %s, dst: %s, oper: %d\n", src_mac_addr, dst_mac_addr, src_ip, dst_ip, arp->operation ); + + // TODO: remember the address mapping + + // send answer + packet->header.dst_addr = arp->source_hardware_address; + packet->header.src_addr = global_context.network->mac_address; + arp->operation = ARP_OPERATION_ANSWER; + arp->destination_hardware_address = arp->source_hardware_address; + arp->source_hardware_address = global_context.network->mac_address; + + ((network_vtable_t *)( global_context.network->base.vtable ))->write( global_context.network, event->buf ); } // we must free the data if we no longer need it - free( event->data ); + free( event->buf.data ); } diff --git a/src/net/ethernet.h b/src/net/ethernet.h index 9ebf58e..3af053d 100644 --- a/src/net/ethernet.h +++ b/src/net/ethernet.h @@ -4,8 +4,15 @@ #include "stdint.h" #include "stddef.h" +// length of a string representation of a MAC address #define NETWORK_ETHERNET_MAC_ADDR_STRING 6 * 3 + 1 +// minimal size of an ethernet packet +#define ETHERNET_MIN_FRAME_SIZE_IEEE_802_3 64 + +// maximal size of an ethernet packet +#define ETHERNET_MAX_FRAME_SIZE_IEEE_802_3 1536 + // hardware_address_len #define NETWORK_HARDWARE_ETHERNET_ADDRESS_LENGTH 6 -- cgit v1.2.3-54-g00ecf