66 lines
1.7 KiB
C++
66 lines
1.7 KiB
C++
/*
|
|
* Ethernet.cpp
|
|
* Ethernet frame layer
|
|
* Copyright (c) 2025 Daniel Hammer
|
|
*/
|
|
|
|
#include "Ethernet.hpp"
|
|
#include <Net/ByteOrder.hpp>
|
|
#include <Net/Arp.hpp>
|
|
#include <Net/Ipv4.hpp>
|
|
#include <Drivers/Net/E1000.hpp>
|
|
#include <Libraries/Memory.hpp>
|
|
#include <Terminal/Terminal.hpp>
|
|
#include <CppLib/Stream.hpp>
|
|
|
|
using namespace Kt;
|
|
|
|
namespace Net::Ethernet {
|
|
|
|
void Initialize() {
|
|
KernelLogStream(OK, "Net") << "Ethernet layer initialized";
|
|
}
|
|
|
|
bool Send(const uint8_t* destMac, uint16_t etherType, const uint8_t* payload, uint16_t payloadLen) {
|
|
if (payload == nullptr || payloadLen == 0 || payloadLen > MAX_PAYLOAD_SIZE) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t frame[MAX_FRAME_SIZE];
|
|
Header* hdr = (Header*)frame;
|
|
|
|
memcpy(hdr->DestMac, destMac, 6);
|
|
memcpy(hdr->SrcMac, Drivers::Net::E1000::GetMacAddress(), 6);
|
|
hdr->EtherType = Htons(etherType);
|
|
|
|
memcpy(frame + HEADER_SIZE, payload, payloadLen);
|
|
|
|
uint16_t totalLen = HEADER_SIZE + payloadLen;
|
|
|
|
return Drivers::Net::E1000::SendPacket(frame, totalLen);
|
|
}
|
|
|
|
void OnFrameReceived(const uint8_t* data, uint16_t length) {
|
|
if (length < HEADER_SIZE) {
|
|
return;
|
|
}
|
|
|
|
const Header* hdr = (const Header*)data;
|
|
uint16_t etherType = Ntohs(hdr->EtherType);
|
|
const uint8_t* payload = data + HEADER_SIZE;
|
|
uint16_t payloadLen = length - HEADER_SIZE;
|
|
|
|
switch (etherType) {
|
|
case ETHERTYPE_ARP:
|
|
Arp::OnPacketReceived(payload, payloadLen);
|
|
break;
|
|
case ETHERTYPE_IPV4:
|
|
Ipv4::OnPacketReceived(payload, payloadLen);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|