diff --git a/kernel-src/include/kernel/eth.h b/kernel-src/include/kernel/eth.h index 1a5bb0bb..d3af646e 100644 --- a/kernel-src/include/kernel/eth.h +++ b/kernel-src/include/kernel/eth.h @@ -1,6 +1,7 @@ #ifndef _ETH_H #define _ETH_H +#include #include #include @@ -13,6 +14,6 @@ typedef struct { #define ETH_PROTO_IP 0x0800 #define ETH_PROTO_ARP 0x0806 -void eth_process(netdev_t *netdev, void *buffer); +void eth_process(netdev_t *netdev, void *buffer, size_t size); #endif diff --git a/kernel-src/io/net/eth.c b/kernel-src/io/net/eth.c index 7e183595..0afe5b43 100644 --- a/kernel-src/io/net/eth.c +++ b/kernel-src/io/net/eth.c @@ -3,7 +3,10 @@ #include // runs on dpc context, called by the individual driver dpcs on a receive. -void eth_process(netdev_t *netdev, void *buffer) { +void eth_process(netdev_t *netdev, void *buffer, size_t size) { + if (size < sizeof(ethframe_t)) + return; + ethframe_t *frame = buffer; mac_t dst, src; diff --git a/kernel-src/io/net/loopback.c b/kernel-src/io/net/loopback.c index 1ff6305e..05868f89 100644 --- a/kernel-src/io/net/loopback.c +++ b/kernel-src/io/net/loopback.c @@ -40,7 +40,7 @@ static int loopback_sendpacket(netdev_t *netdev, netdesc_t desc, mac_t targetmac memcpy(desc.address, ðframe, sizeof(ethframe_t)); long ipl = interrupt_raiseipl(IPL_DPC); - eth_process(netdev, desc.address); + eth_process(netdev, desc.address, desc.size); interrupt_loweripl(ipl); return netdev->freedesc(netdev, &desc); diff --git a/kernel-src/io/net/rtl8169.c b/kernel-src/io/net/rtl8169.c index 5aa1238f..d03f9611 100644 --- a/kernel-src/io/net/rtl8169.c +++ b/kernel-src/io/net/rtl8169.c @@ -54,6 +54,7 @@ #define RX_DESCRIPTOR_COUNT 1024 #define TX_DESCRIPTOR_COUNT 1024 #define RX_BUFFER_SIZE 1524 +#define RX_FCS_SIZE 4 #define DESCRIPTOR_OWN (1 << 15) #define DESCRIPTOR_EOR (1 << 14) @@ -133,7 +134,8 @@ static void rtl8169_dpc_rx(context_t *, dpcarg_t arg) { volatile descriptor_t *descriptor = &dev->rx_ring[dev->rx_next]; void *buffer = MAKE_HHDM((void *)(descriptor->addr_low | ((uint64_t)descriptor->addr_high << 32))); - eth_process(&dev->netdev, buffer); + if (descriptor->length >= RX_FCS_SIZE) + eth_process(&dev->netdev, buffer, descriptor->length - RX_FCS_SIZE); uint16_t eor = descriptor->flags & DESCRIPTOR_EOR; descriptor->length = RX_BUFFER_SIZE; diff --git a/kernel-src/io/net/u80211/kernel_interface.c b/kernel-src/io/net/u80211/kernel_interface.c index b3fd42e9..6636799b 100644 --- a/kernel-src/io/net/u80211/kernel_interface.c +++ b/kernel-src/io/net/u80211/kernel_interface.c @@ -299,6 +299,5 @@ static void u80211_kernel_interface_init(void) { INIT_ROUTINE_DEFINE(u80211, INIT_ROUTINE_FLAGS_NONE, u80211_kernel_interface_init, work_queue); void u80211_kernel_receive_callback(u80211_device_t *device, void *buffer, size_t size) { - (void)size; - eth_process(device->driver_data, buffer); + eth_process(device->driver_data, buffer, size); } diff --git a/kernel-src/io/net/vionet.c b/kernel-src/io/net/vionet.c index b78fcebc..1c48fe76 100644 --- a/kernel-src/io/net/vionet.c +++ b/kernel-src/io/net/vionet.c @@ -45,8 +45,11 @@ static void rx_dpc(context_t *context, dpcarg_t arg) { while (netdev->rxqueue.lastusedindex != VIO_QUEUE_DEV_IDX(&netdev->rxqueue)) { int idx = netdev->rxqueue.lastusedindex++ % netdev->rxqueue.size; int buffidx = VIO_QUEUE_DEV_RING(&netdev->rxqueue)[idx].index; - void *ethbufferphys = (void *)(buffers[buffidx].address + sizeof(vioframe_t)); - eth_process((netdev_t *)netdev, MAKE_HHDM(ethbufferphys)); + size_t size = VIO_QUEUE_DEV_RING(&netdev->rxqueue)[idx].length; + if (size >= sizeof(vioframe_t)) { + void *phys = (void *)(buffers[buffidx].address + sizeof(vioframe_t)); + eth_process((netdev_t *)netdev, MAKE_HHDM(phys), size - sizeof(vioframe_t)); + } VIO_QUEUE_DRV_RING(&netdev->rxqueue)[VIO_QUEUE_DRV_IDX(&netdev->rxqueue)++ % netdev->rxqueue.size] = buffidx; *netdev->rxqueue.notify = 0; }