mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-17 02:01:44 +00:00
Update kernel
This commit is contained in:
@@ -26,220 +26,221 @@
|
||||
|
||||
namespace NetworkARP
|
||||
{
|
||||
DiscoveredAddress *ARP::ManageDiscoveredAddresses(DAType Type, InternetProtocol IP, MediaAccessControl MAC)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case DA_ADD:
|
||||
{
|
||||
DiscoveredAddress *tmp = new DiscoveredAddress;
|
||||
tmp->IP = IP;
|
||||
tmp->MAC = MAC;
|
||||
DiscoveredAddresses.push_back(tmp);
|
||||
netdbg("Added %s to discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return tmp;
|
||||
}
|
||||
case DA_DEL:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
DiscoveredAddress *tmp = DiscoveredAddresses[i];
|
||||
netdbg("Removed %s from discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
delete tmp, tmp = nullptr;
|
||||
DiscoveredAddresses.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_SEARCH:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
netdbg("Found %s in discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return DiscoveredAddresses[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_UPDATE:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
DiscoveredAddresses[i]->MAC = MAC;
|
||||
netdbg("Updated %s in discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return DiscoveredAddresses[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
DiscoveredAddress *ARP::ManageDiscoveredAddresses(DAType Type, InternetProtocol IP, MediaAccessControl MAC)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case DA_ADD:
|
||||
{
|
||||
DiscoveredAddress *tmp = new DiscoveredAddress;
|
||||
tmp->IP = IP;
|
||||
tmp->MAC = MAC;
|
||||
DiscoveredAddresses.push_back(tmp);
|
||||
netdbg("Added %s to discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return tmp;
|
||||
}
|
||||
case DA_DEL:
|
||||
{
|
||||
forItr(itr, DiscoveredAddresses)
|
||||
{
|
||||
if ((*itr)->IP.v4 == IP.v4)
|
||||
{
|
||||
DiscoveredAddress *tmp = *itr;
|
||||
netdbg("Removed %s from discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
delete tmp, tmp = nullptr;
|
||||
DiscoveredAddresses.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ARP::ARP(NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_ARP)
|
||||
{
|
||||
debug("ARP interface %#lx created.", this);
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_SEARCH:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
netdbg("Found %s in discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return DiscoveredAddresses[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_UPDATE:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
DiscoveredAddresses[i]->MAC = MAC;
|
||||
netdbg("Updated %s in discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
return DiscoveredAddresses[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ARP::~ARP()
|
||||
{
|
||||
debug("ARP interface %#lx destroyed.", this);
|
||||
}
|
||||
ARP::ARP(NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_ARP)
|
||||
{
|
||||
debug("ARP interface %#lx created.", this);
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
|
||||
MediaAccessControl InvalidMAC;
|
||||
InternetProtocol InvalidIP;
|
||||
DiscoveredAddress InvalidRet = {.MAC = InvalidMAC, .IP = InvalidIP};
|
||||
ARP::~ARP()
|
||||
{
|
||||
debug("ARP interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
DiscoveredAddress *ARP::Search(InternetProtocol TargetIP)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_SEARCH, TargetIP, MediaAccessControl());
|
||||
if (ret)
|
||||
return ret;
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
MediaAccessControl InvalidMAC;
|
||||
InternetProtocol InvalidIP;
|
||||
DiscoveredAddress InvalidRet = {.MAC = InvalidMAC, .IP = InvalidIP};
|
||||
|
||||
DiscoveredAddress *ARP::Update(InternetProtocol TargetIP, MediaAccessControl TargetMAC)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_UPDATE, TargetIP, TargetMAC);
|
||||
if (ret)
|
||||
return ret;
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
DiscoveredAddress *ARP::Search(InternetProtocol TargetIP)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_SEARCH, TargetIP, MediaAccessControl());
|
||||
if (ret)
|
||||
return ret;
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
uint48_t ARP::Resolve(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Resolving %s", IP.v4.ToStringLittleEndian());
|
||||
if (IP.v4 == 0xFFFFFFFF)
|
||||
return 0xFFFFFFFFFFFF;
|
||||
DiscoveredAddress *ARP::Update(InternetProtocol TargetIP, MediaAccessControl TargetMAC)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_UPDATE, TargetIP, TargetMAC);
|
||||
if (ret)
|
||||
return ret;
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
/* If we can't find the MAC, return the default value which is 0xFFFFFFFFFFFF. */
|
||||
uint48_t ret = this->Search(IP)->MAC.ToHex();
|
||||
netdbg("Resolved %s to %lx", IP.v4.ToStringLittleEndian(), ret);
|
||||
uint48_t ARP::Resolve(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Resolving %s", IP.v4.ToStringLittleEndian());
|
||||
if (IP.v4 == 0xFFFFFFFF)
|
||||
return 0xFFFFFFFFFFFF;
|
||||
|
||||
if (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
netdbg("Sending request");
|
||||
/* If we can't find the MAC, send a request.
|
||||
Because we are going to send this over the network, we need to byteswap first.
|
||||
This is actually very confusing for me. */
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
Header->HardwareSize = b8(6);
|
||||
Header->ProtocolSize = b8(4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->TargetMAC = b48(0xFFFFFFFFFFFF);
|
||||
Header->TargetIP = b32(IP.v4.ToHex());
|
||||
netdbg("SIP: %s; TIP: %s", InternetProtocol().v4.FromHex(Header->SenderIP).ToStringLittleEndian(),
|
||||
InternetProtocol().v4.FromHex(Header->TargetIP).ToStringLittleEndian());
|
||||
/* Send the request to the broadcast MAC address. */
|
||||
Ethernet->Send({.Address = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
delete Header, Header = nullptr;
|
||||
}
|
||||
/* If we can't find the MAC, return the default value which is 0xFFFFFFFFFFFF. */
|
||||
uint48_t ret = this->Search(IP)->MAC.ToHex();
|
||||
netdbg("Resolved %s to %lx", IP.v4.ToStringLittleEndian(), ret);
|
||||
|
||||
int RequestTimeout = 20;
|
||||
debug("Waiting for response");
|
||||
while (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
ret = this->Search(IP)->MAC.ToHex();
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
if (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
netdbg("Sending request");
|
||||
/* If we can't find the MAC, send a request.
|
||||
Because we are going to send this over the network, we need to byteswap first.
|
||||
This is actually very confusing for me. */
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
Header->HardwareSize = b8(6);
|
||||
Header->ProtocolSize = b8(4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->TargetMAC = b48(0xFFFFFFFFFFFF);
|
||||
Header->TargetIP = b32(IP.v4.ToHex());
|
||||
netdbg("SIP: %s; TIP: %s", InternetProtocol().v4.FromHex(Header->SenderIP).ToStringLittleEndian(),
|
||||
InternetProtocol().v4.FromHex(Header->TargetIP).ToStringLittleEndian());
|
||||
/* Send the request to the broadcast MAC address. */
|
||||
Ethernet->Send({.Address = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
delete Header, Header = nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int RequestTimeout = 20;
|
||||
debug("Waiting for response");
|
||||
while (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
ret = this->Search(IP)->MAC.ToHex();
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
|
||||
void ARP::Broadcast(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Sending broadcast");
|
||||
uint48_t ResolvedMAC = this->Resolve(IP);
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
Header->HardwareSize = b8(0x6);
|
||||
Header->ProtocolSize = b8(0x4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->TargetMAC = b48(ResolvedMAC);
|
||||
Header->TargetIP = b32(IP.v4.ToHex());
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ResolvedMAC), NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
delete Header, Header = nullptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ARP::OnEthernetPacketReceived(uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Length);
|
||||
netdbg("Received packet");
|
||||
ARPHeader *Header = (ARPHeader *)Data;
|
||||
void ARP::Broadcast(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Sending broadcast");
|
||||
uint48_t ResolvedMAC = this->Resolve(IP);
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
Header->HardwareSize = b8(0x6);
|
||||
Header->ProtocolSize = b8(0x4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->TargetMAC = b48(ResolvedMAC);
|
||||
Header->TargetIP = b32(IP.v4.ToHex());
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ResolvedMAC), NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
delete Header, Header = nullptr;
|
||||
}
|
||||
|
||||
InternetProtocol SenderIPv4;
|
||||
SenderIPv4.v4 = SenderIPv4.v4.FromHex(b32(Header->SenderIP));
|
||||
bool ARP::OnEthernetPacketReceived(uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Length);
|
||||
netdbg("Received packet");
|
||||
ARPHeader *Header = (ARPHeader *)Data;
|
||||
|
||||
/* We only support Ethernet and IPv4. */
|
||||
if (b16(Header->HardwareType) != ARPHardwareType::HTYPE_ETHERNET || b16(Header->ProtocolType) != NetworkEthernet::FrameType::TYPE_IPV4)
|
||||
{
|
||||
warn("Invalid hardware/protocol type (%d/%d)", b16(Header->HardwareType), b16(Header->ProtocolType));
|
||||
return false;
|
||||
}
|
||||
InternetProtocol SenderIPv4;
|
||||
SenderIPv4.v4 = SenderIPv4.v4.FromHex(b32(Header->SenderIP));
|
||||
|
||||
InternetProtocol TmpIPStruct;
|
||||
InternetProtocol().v4.FromHex(b32(Header->SenderIP));
|
||||
/* We only support Ethernet and IPv4. */
|
||||
if (b16(Header->HardwareType) != ARPHardwareType::HTYPE_ETHERNET || b16(Header->ProtocolType) != NetworkEthernet::FrameType::TYPE_IPV4)
|
||||
{
|
||||
warn("Invalid hardware/protocol type (%d/%d)", b16(Header->HardwareType), b16(Header->ProtocolType));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ManageDiscoveredAddresses(DA_SEARCH, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC))) == nullptr)
|
||||
{
|
||||
netdbg("Discovered new address %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
TmpIPStruct.v4.FromHex(b32(Header->SenderIP));
|
||||
ManageDiscoveredAddresses(DA_ADD, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC)));
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Updated address %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
TmpIPStruct.v4.FromHex(b32(Header->SenderIP));
|
||||
ManageDiscoveredAddresses(DA_UPDATE, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC)));
|
||||
}
|
||||
InternetProtocol TmpIPStruct;
|
||||
InternetProtocol().v4.FromHex(b32(Header->SenderIP));
|
||||
|
||||
switch (b16(Header->Operation))
|
||||
{
|
||||
case ARPOperation::REQUEST:
|
||||
netdbg("Received request from %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
/* We need to byteswap before we send it back. */
|
||||
Header->TargetMAC = b48(Header->SenderMAC);
|
||||
Header->TargetIP = b32(Header->SenderIP);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->Operation = b16(ARPOperation::REPLY);
|
||||
Ethernet->Send(MediaAccessControl().FromHex(Header->TargetMAC), NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
netdbg("Sent request for %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
case ARPOperation::REPLY:
|
||||
fixme("Received reply from %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
default:
|
||||
warn("Invalid operation (%d)", b16(Header->Operation));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (ManageDiscoveredAddresses(DA_SEARCH, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC))) == nullptr)
|
||||
{
|
||||
netdbg("Discovered new address %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
TmpIPStruct.v4.FromHex(b32(Header->SenderIP));
|
||||
ManageDiscoveredAddresses(DA_ADD, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC)));
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Updated address %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
TmpIPStruct.v4.FromHex(b32(Header->SenderIP));
|
||||
ManageDiscoveredAddresses(DA_UPDATE, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC)));
|
||||
}
|
||||
|
||||
switch (b16(Header->Operation))
|
||||
{
|
||||
case ARPOperation::REQUEST:
|
||||
netdbg("Received request from %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
/* We need to byteswap before we send it back. */
|
||||
Header->TargetMAC = b48(Header->SenderMAC);
|
||||
Header->TargetIP = b32(Header->SenderIP);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Header->Operation = b16(ARPOperation::REPLY);
|
||||
Ethernet->Send(MediaAccessControl().FromHex(Header->TargetMAC), NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
netdbg("Sent request for %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
case ARPOperation::REPLY:
|
||||
fixme("Received reply from %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
default:
|
||||
warn("Invalid operation (%d)", b16(Header->Operation));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -25,124 +25,126 @@
|
||||
|
||||
namespace NetworkEthernet
|
||||
{
|
||||
struct EthernetEventHelperStruct
|
||||
{
|
||||
EthernetEvents *Ptr;
|
||||
uint16_t Type;
|
||||
};
|
||||
struct EthernetEventHelperStruct
|
||||
{
|
||||
EthernetEvents *Ptr;
|
||||
uint16_t Type;
|
||||
};
|
||||
|
||||
std::vector<EthernetEventHelperStruct> RegisteredEvents;
|
||||
std::vector<EthernetEventHelperStruct> RegisteredEvents;
|
||||
|
||||
Ethernet::Ethernet(NetworkInterfaceManager::DeviceInterface *Interface) : NetworkInterfaceManager::Events(Interface)
|
||||
{
|
||||
debug("Ethernet interface %#lx created.", this);
|
||||
this->Interface = Interface;
|
||||
}
|
||||
Ethernet::~Ethernet()
|
||||
{
|
||||
debug("Ethernet interface %#lx destroyed.", this);
|
||||
}
|
||||
Ethernet::Ethernet(NetworkInterfaceManager::DeviceInterface *Interface) : NetworkInterfaceManager::Events(Interface)
|
||||
{
|
||||
debug("Ethernet interface %#lx created.", this);
|
||||
this->Interface = Interface;
|
||||
}
|
||||
Ethernet::~Ethernet()
|
||||
{
|
||||
debug("Ethernet interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
void Ethernet::Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Sending frame type %#x to %s", Type, MAC.ToString());
|
||||
size_t PacketLength = sizeof(EthernetHeader) + Length;
|
||||
EthernetPacket *Packet = (EthernetPacket *)kmalloc(PacketLength);
|
||||
void Ethernet::Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Sending frame type %#x to %s", Type, MAC.ToString());
|
||||
size_t PacketLength = sizeof(EthernetHeader) + Length;
|
||||
EthernetPacket *Packet = (EthernetPacket *)kmalloc(PacketLength);
|
||||
|
||||
Packet->Header.DestinationMAC = b48(MAC.ToHex());
|
||||
Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
Packet->Header.Type = b16(Type);
|
||||
Packet->Header.DestinationMAC = b48(MAC.ToHex());
|
||||
Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
Packet->Header.Type = b16(Type);
|
||||
|
||||
memcpy(Packet->Data, Data, Length);
|
||||
/* Network Interface Manager takes care of physical allocation.
|
||||
So basically, we allocate here and then it allocates again but 1:1 mapped. */
|
||||
NIManager->Send(Interface, (uint8_t *)Packet, PacketLength);
|
||||
kfree(Packet);
|
||||
}
|
||||
memcpy(Packet->Data, Data, Length);
|
||||
/* Network Interface Manager takes care of physical allocation.
|
||||
So basically, we allocate here and then it allocates again but 1:1 mapped. */
|
||||
NIManager->Send(Interface, (uint8_t *)Packet, PacketLength);
|
||||
kfree(Packet);
|
||||
}
|
||||
|
||||
void Ethernet::Receive(uint8_t *Data, size_t Length)
|
||||
{
|
||||
EthernetPacket *Packet = (EthernetPacket *)Data;
|
||||
size_t PacketLength = Length - sizeof(EthernetHeader);
|
||||
/* TODO: I have to do checks here to be sure that PacketLength is right */
|
||||
UNUSED(PacketLength);
|
||||
void Ethernet::Receive(uint8_t *Data, size_t Length)
|
||||
{
|
||||
EthernetPacket *Packet = (EthernetPacket *)Data;
|
||||
size_t PacketLength = Length - sizeof(EthernetHeader);
|
||||
/* TODO: I have to do checks here to be sure that PacketLength is right */
|
||||
UNUSED(PacketLength);
|
||||
|
||||
MediaAccessControl SourceMAC;
|
||||
SourceMAC.FromHex(b48(Packet->Header.SourceMAC));
|
||||
MediaAccessControl DestinationMAC;
|
||||
DestinationMAC.FromHex(b48(Packet->Header.DestinationMAC));
|
||||
MediaAccessControl SourceMAC;
|
||||
SourceMAC.FromHex(b48(Packet->Header.SourceMAC));
|
||||
MediaAccessControl DestinationMAC;
|
||||
DestinationMAC.FromHex(b48(Packet->Header.DestinationMAC));
|
||||
|
||||
netdbg("Received frame type %#x from %s to %s", b16(Packet->Header.Type), SourceMAC.ToString(), DestinationMAC.ToString());
|
||||
netdbg("Received frame type %#x from %s to %s", b16(Packet->Header.Type), SourceMAC.ToString(), DestinationMAC.ToString());
|
||||
|
||||
/* Byte-swapped little-endian */
|
||||
if (b48(Packet->Header.DestinationMAC) == 0xFFFFFFFFFFFF ||
|
||||
/* Byte-swapped Driver interface has little-endian order */
|
||||
b48(Packet->Header.DestinationMAC) == this->Interface->MAC.ToHex())
|
||||
/* This is true only if the packet is for us (Interface MAC or broadcast) */
|
||||
{
|
||||
netdbg("Received data from %s [Type %#x]", SourceMAC.ToString(), b16(Packet->Header.Type));
|
||||
bool Reply = false;
|
||||
/* Byte-swapped little-endian */
|
||||
if (b48(Packet->Header.DestinationMAC) == 0xFFFFFFFFFFFF ||
|
||||
/* Byte-swapped Driver interface has little-endian order */
|
||||
b48(Packet->Header.DestinationMAC) == this->Interface->MAC.ToHex())
|
||||
/* This is true only if the packet is for us (Interface MAC or broadcast) */
|
||||
{
|
||||
netdbg("Received data from %s [Type %#x]", SourceMAC.ToString(), b16(Packet->Header.Type));
|
||||
bool Reply = false;
|
||||
|
||||
switch (b16(Packet->Header.Type))
|
||||
{
|
||||
case TYPE_IPV4:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_IPV4)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_ARP:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_ARP)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_RARP:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_RARP)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_IPV6:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_IPV6)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
default:
|
||||
warn("Unknown packet type %#lx", Packet->Header.Type);
|
||||
break;
|
||||
}
|
||||
if (Reply)
|
||||
{
|
||||
/* FIXME: I should reply, right? I have to do more research here... */
|
||||
// Packet->Header.DestinationMAC = Packet->Header.SourceMAC;
|
||||
// Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
fixme("Replying to %s [%s]=>[%s]", SourceMAC.ToString(),
|
||||
this->Interface->MAC.ToString(), DestinationMAC.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Packet not for us [%s]=>[%s]", this->Interface->MAC.ToString(), DestinationMAC.ToString());
|
||||
}
|
||||
}
|
||||
switch (b16(Packet->Header.Type))
|
||||
{
|
||||
case TYPE_IPV4:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_IPV4)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_ARP:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_ARP)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_RARP:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_RARP)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
case TYPE_IPV6:
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_IPV6)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
default:
|
||||
warn("Unknown packet type %#lx", Packet->Header.Type);
|
||||
break;
|
||||
}
|
||||
if (Reply)
|
||||
{
|
||||
/* FIXME: I should reply, right? I have to do more research here... */
|
||||
// Packet->Header.DestinationMAC = Packet->Header.SourceMAC;
|
||||
// Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
fixme("Replying to %s [%s]=>[%s]", SourceMAC.ToString(),
|
||||
this->Interface->MAC.ToString(), DestinationMAC.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Packet not for us [%s]=>[%s]", this->Interface->MAC.ToString(), DestinationMAC.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void Ethernet::OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length)
|
||||
{
|
||||
if (Interface == this->Interface)
|
||||
this->Receive(Data, Length);
|
||||
}
|
||||
void Ethernet::OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length)
|
||||
{
|
||||
if (Interface == this->Interface)
|
||||
this->Receive(Data, Length);
|
||||
}
|
||||
|
||||
EthernetEvents::EthernetEvents(FrameType Type)
|
||||
{
|
||||
this->FType = Type;
|
||||
RegisteredEvents.push_back({.Ptr = this, .Type = (uint16_t)Type});
|
||||
}
|
||||
EthernetEvents::EthernetEvents(FrameType Type)
|
||||
{
|
||||
this->FType = Type;
|
||||
RegisteredEvents.push_back({.Ptr = this, .Type = (uint16_t)Type});
|
||||
}
|
||||
|
||||
EthernetEvents::~EthernetEvents()
|
||||
{
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i].Ptr == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EthernetEvents::~EthernetEvents()
|
||||
{
|
||||
forItr(itr, RegisteredEvents)
|
||||
{
|
||||
if (itr->Ptr == this)
|
||||
{
|
||||
RegisteredEvents.erase(itr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -127,12 +127,14 @@ namespace NetworkIPv4
|
||||
|
||||
IPv4Events::~IPv4Events()
|
||||
{
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i] == this)
|
||||
forItr(itr, RegisteredEvents)
|
||||
{
|
||||
if (*itr == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
RegisteredEvents.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -38,7 +38,7 @@ namespace NetworkInterfaceManager
|
||||
|
||||
NetworkInterface::NetworkInterface()
|
||||
{
|
||||
mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory);
|
||||
mem = new Memory::MemMgr(nullptr, thisProcess->memDirectory);
|
||||
if (DriverManager->GetDrivers().size() > 0)
|
||||
{
|
||||
foreach (auto Driver in DriverManager->GetDrivers())
|
||||
@@ -61,14 +61,8 @@ namespace NetworkInterfaceManager
|
||||
// Unregister all events
|
||||
RegisteredEvents.clear();
|
||||
|
||||
foreach (auto inf in Interfaces)
|
||||
{
|
||||
if (inf)
|
||||
{
|
||||
Interfaces.remove(inf);
|
||||
delete inf, inf = nullptr;
|
||||
}
|
||||
}
|
||||
forItr(itr, Interfaces) delete *itr;
|
||||
Interfaces.clear();
|
||||
|
||||
// Delete all interfaces and their callbacks and free the memory
|
||||
delete mem, mem = nullptr;
|
||||
@@ -77,7 +71,7 @@ namespace NetworkInterfaceManager
|
||||
void NetworkInterface::FetchNetworkCards(unsigned long DriverUID)
|
||||
{
|
||||
KernelCallback cb{};
|
||||
cb.Reason = FetchReason;
|
||||
cb.Reason = QueryReason;
|
||||
DriverManager->IOCB(DriverUID, &cb);
|
||||
|
||||
DeviceInterface *Iface = (DeviceInterface *)mem->RequestPages(TO_PAGES(sizeof(DeviceInterface) + 1));
|
||||
@@ -101,7 +95,7 @@ namespace NetworkInterfaceManager
|
||||
|
||||
void NetworkInterface::StartNetworkStack()
|
||||
{
|
||||
TaskManager->GetCurrentThread()->SetPriority(Tasking::TaskPriority::Critical);
|
||||
thisThread->SetPriority(Tasking::TaskPriority::Critical);
|
||||
DeviceInterface *DefaultDevice = nullptr;
|
||||
foreach (auto inf in Interfaces)
|
||||
if (inf)
|
||||
@@ -121,7 +115,8 @@ namespace NetworkInterfaceManager
|
||||
NetworkUDP::UDP *udp = new NetworkUDP::UDP(ipv4, DefaultDevice);
|
||||
NetworkUDP::Socket *DHCP_Socket = udp->Connect(InternetProtocol() /* Default value is 255.255.255.255 */, 67);
|
||||
NetworkDHCP::DHCP *dhcp = new NetworkDHCP::DHCP(DHCP_Socket, DefaultDevice);
|
||||
debug("eth: %p; arp: %p; ipv4: %p; udp: %p; dhcp: %p", eth, arp, ipv4, udp, dhcp);
|
||||
debug("eth: %p; arp: %p; ipv4: %p; udp: %p; dhcp: %p",
|
||||
eth, arp, ipv4, udp, dhcp);
|
||||
udp->Bind(DHCP_Socket, dhcp);
|
||||
dhcp->Request();
|
||||
|
||||
@@ -159,7 +154,7 @@ namespace NetworkInterfaceManager
|
||||
/* TODO: Store everything in an vector and initialize all network cards */
|
||||
}
|
||||
|
||||
TaskManager->GetCurrentThread()->SetPriority(Tasking::TaskPriority::Idle);
|
||||
thisThread->SetPriority(Tasking::TaskPriority::Idle);
|
||||
CPU::Halt(true);
|
||||
}
|
||||
|
||||
@@ -172,7 +167,7 @@ namespace NetworkInterfaceManager
|
||||
|
||||
void NetworkInterface::StartService()
|
||||
{
|
||||
this->NetSvcThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)CallStartNetworkStackWrapper);
|
||||
this->NetSvcThread = TaskManager->CreateThread(thisProcess, Tasking::IP(CallStartNetworkStackWrapper));
|
||||
this->NetSvcThread->Rename("Network Service");
|
||||
}
|
||||
|
||||
@@ -220,11 +215,13 @@ namespace NetworkInterfaceManager
|
||||
|
||||
Events::~Events()
|
||||
{
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i] == this)
|
||||
forItr(itr, RegisteredEvents)
|
||||
{
|
||||
if (*itr == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
return;
|
||||
RegisteredEvents.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user