BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / net / ethernet.c

// Related

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);
+}