Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)/* * This file implements the Ethernet layer of the Network Stack. It wraps any * packet sent to it with the Ethernet Header. Equally, it unwraps any packets * before passing them to the next layer, determined by the EtherType in the * header. */ #include <stdint.h> #include <stddef.h> #include <string.h> #include "net.h" #include "../mem/heap.h" #include "../screen.h" /* Structure for an Ethernet Header */ typedef struct Header { uint8_t dst[6]; uint8_t src[6]; uint16_t ethertype; } __attribute__((packed)) Header; /* Receive a frame of data */ void ethernet_receive_frame(NetIF *netif, void *data, size_t len) { Header header; memcpy(&header, data, sizeof(Header)); header.ethertype = ntohs(header.ethertype); /* Handle appropriately */ switch (header.ethertype) { case 0x0800: /* IPv4 */ ipv4_receive_packet(netif, data + sizeof(Header), len - sizeof(Header)); break; case 0x0806: /* ARP */ arp_receive_packet(netif, data + sizeof(Header), len - sizeof(Header)); break; // default: // kprintf("Unhandled type (%04x)", header.ethertype); } } /* Send a frame of data */ void ethernet_send_frame(NetIF *netif, uint8_t dst[6], uint16_t type, void *data, size_t len) { Header header; header.ethertype = htons(type); memcpy(header.src, netif->mac, 6); memcpy(header.dst, dst, 6); size_t frameLen = sizeof(Header) + len; if (frameLen < 64) frameLen = 64; char *frame = kmalloc(frameLen); memcpy(frame, &header, sizeof(Header)); memcpy(frame + sizeof(Header), data, len); netif->transmit(frame, frameLen); kfree(frame); }