Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)diff --git a/net/ethernet.c b/net/ethernet.c new file mode 100644 index 0000000..98d6692 --- /dev/null +++ b/net/ethernet.c @@ -0,0 +1,63 @@ +/* + * 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); +}