mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 07:19:20 +00:00
Updated network related code so now it should work as expected
This commit is contained in:
@ -6,9 +6,8 @@
|
||||
|
||||
namespace NetworkARP
|
||||
{
|
||||
DiscoveredAddress *ARP::ManageDA(DAType Type, InternetProtocol4 IP, MediaAccessControl MAC)
|
||||
DiscoveredAddress *ARP::ManageDiscoveredAddresses(DAType Type, InternetProtocol IP, MediaAccessControl MAC)
|
||||
{
|
||||
// TODO: Compare IPv6 too.
|
||||
switch (Type)
|
||||
{
|
||||
case DA_ADD:
|
||||
@ -17,35 +16,46 @@ namespace NetworkARP
|
||||
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 == IP)
|
||||
{
|
||||
if (DiscoveredAddresses[i]->IP.v4 == IP.v4)
|
||||
{
|
||||
DiscoveredAddress *tmp = DiscoveredAddresses[i];
|
||||
netdbg("Removed %s from discovered addresses", IP.v4.ToStringLittleEndian());
|
||||
delete tmp;
|
||||
DiscoveredAddresses.remove(i);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_SEARCH:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
if (DiscoveredAddresses[i]->IP == IP)
|
||||
{
|
||||
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 == IP)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -54,7 +64,6 @@ namespace NetworkARP
|
||||
|
||||
ARP::ARP(NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_ARP)
|
||||
{
|
||||
netdbg("Initializing.");
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
|
||||
@ -62,55 +71,62 @@ namespace NetworkARP
|
||||
{
|
||||
}
|
||||
|
||||
MediaAccessControl InvalidMAC = {.Address = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
InternetProtocol4 InvalidIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
MediaAccessControl InvalidMAC;
|
||||
InternetProtocol InvalidIP;
|
||||
DiscoveredAddress InvalidRet = {.MAC = InvalidMAC, .IP = InvalidIP};
|
||||
|
||||
DiscoveredAddress *ARP::Search(InternetProtocol4 TargetIP)
|
||||
DiscoveredAddress *ARP::Search(InternetProtocol TargetIP)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDA(DA_SEARCH, TargetIP, MediaAccessControl());
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_SEARCH, TargetIP, MediaAccessControl());
|
||||
if (ret)
|
||||
return ret;
|
||||
netdbg("[DA] No address found for %d.%d.%d.%d", TargetIP.Address[0], TargetIP.Address[1], TargetIP.Address[2], TargetIP.Address[3]);
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
DiscoveredAddress *ARP::Update(InternetProtocol4 TargetIP, MediaAccessControl TargetMAC)
|
||||
DiscoveredAddress *ARP::Update(InternetProtocol TargetIP, MediaAccessControl TargetMAC)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDA(DA_UPDATE, TargetIP, TargetMAC);
|
||||
DiscoveredAddress *ret = ManageDiscoveredAddresses(DA_UPDATE, TargetIP, TargetMAC);
|
||||
if (ret)
|
||||
return ret;
|
||||
warn("[DA] No address found for %d.%d.%d.%d", TargetIP.Address[0], TargetIP.Address[1], TargetIP.Address[2], TargetIP.Address[3]);
|
||||
warn("No address found for %s", TargetIP.v4.ToStringLittleEndian());
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
uint48_t ARP::Resolve(InternetProtocol4 IP)
|
||||
uint48_t ARP::Resolve(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Resolving %d.%d.%d.%d", IP.Address[3], IP.Address[2], IP.Address[1], IP.Address[0]);
|
||||
if (IP == 0xFFFFFFFF)
|
||||
netdbg("Resolving %s", IP.v4.ToStringLittleEndian());
|
||||
if (IP.v4 == 0xFFFFFFFF)
|
||||
return 0xFFFFFFFFFFFF;
|
||||
|
||||
/* If we can't find the MAC, return the default value which is 0xFFFFFFFFFFFF. */
|
||||
uint48_t ret = this->Search(IP)->MAC.ToHex();
|
||||
netdbg("Resolved %d.%d.%d.%d to %x", IP.Address[3], IP.Address[2], IP.Address[1], IP.Address[0], ret);
|
||||
netdbg("Resolved %s to %lx", IP.v4.ToStringLittleEndian(), ret);
|
||||
|
||||
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 = ARPHardwareType::HTYPE_ETHERNET;
|
||||
Header->ProtocolType = NetworkEthernet::FrameType::TYPE_IPV4;
|
||||
Header->HardwareSize = 6;
|
||||
Header->ProtocolSize = 4;
|
||||
Header->Operation = ARPOperation::REQUEST;
|
||||
Header->SenderMAC = Ethernet->GetInterface()->MAC.ToHex();
|
||||
Header->SenderIP = Ethernet->GetInterface()->IP.ToHex();
|
||||
Header->TargetMAC = 0xFFFFFFFFFFFF;
|
||||
Header->TargetIP = IP.ToHex();
|
||||
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;
|
||||
netdbg("Sent request");
|
||||
}
|
||||
|
||||
int RequestTimeout = 10;
|
||||
int RequestTimeout = 20;
|
||||
debug("Waiting for response");
|
||||
while (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
@ -120,16 +136,17 @@ namespace NetworkARP
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
TaskManager->Sleep(5000);
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ARP::Broadcast(InternetProtocol4 IP)
|
||||
void ARP::Broadcast(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Sending broadcast");
|
||||
uint64_t ResolvedMAC = this->Resolve(IP);
|
||||
uint48_t ResolvedMAC = this->Resolve(IP);
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
@ -137,9 +154,9 @@ namespace NetworkARP
|
||||
Header->ProtocolSize = b8(0x4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.ToHex());
|
||||
Header->TargetMAC = ResolvedMAC;
|
||||
Header->TargetIP = IP.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;
|
||||
}
|
||||
@ -149,43 +166,50 @@ namespace NetworkARP
|
||||
netdbg("Received packet");
|
||||
ARPHeader *Header = (ARPHeader *)Data;
|
||||
|
||||
InternetProtocol4 SenderIPv4;
|
||||
SenderIPv4.FromHex(b32(Header->SenderIP));
|
||||
InternetProtocol SenderIPv4;
|
||||
SenderIPv4.v4 = SenderIPv4.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("[DA] Invalid hardware/protocol type (%d/%d)", Header->HardwareType, Header->ProtocolType);
|
||||
warn("Invalid hardware/protocol type (%d/%d)", b16(Header->HardwareType), b16(Header->ProtocolType));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ManageDA(DA_SEARCH, InternetProtocol4().FromHex(Header->SenderIP), MediaAccessControl().FromHex(Header->SenderMAC)) == nullptr)
|
||||
InternetProtocol TmpIPStruct;
|
||||
InternetProtocol().v4.FromHex(b32(Header->SenderIP));
|
||||
|
||||
if (ManageDiscoveredAddresses(DA_SEARCH, TmpIPStruct, MediaAccessControl().FromHex(b48(Header->SenderMAC))) == nullptr)
|
||||
{
|
||||
netdbg("[DA] Discovered new address %d.%d.%d.%d", SenderIPv4.Address[3], SenderIPv4.Address[2], SenderIPv4.Address[1], SenderIPv4.Address[0]);
|
||||
ManageDA(DA_ADD, InternetProtocol4().FromHex(Header->SenderIP), MediaAccessControl().FromHex(Header->SenderMAC));
|
||||
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("[DA] Updated address %d.%d.%d.%d", SenderIPv4.Address[3], SenderIPv4.Address[2], SenderIPv4.Address[1], SenderIPv4.Address[0]);
|
||||
ManageDA(DA_UPDATE, InternetProtocol4().FromHex(Header->SenderIP), MediaAccessControl().FromHex(Header->SenderMAC));
|
||||
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 %d.%d.%d.%d", SenderIPv4.Address[3], SenderIPv4.Address[2], SenderIPv4.Address[1], SenderIPv4.Address[0]);
|
||||
Header->TargetMAC = Header->SenderMAC;
|
||||
Header->TargetIP = Header->SenderIP;
|
||||
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.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 %d.%d.%d.%d", SenderIPv4.Address[0], SenderIPv4.Address[1], SenderIPv4.Address[2], SenderIPv4.Address[3]);
|
||||
netdbg("Sent request for %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
case ARPOperation::REPLY:
|
||||
fixme("Received reply from %d.%d.%d.%d", SenderIPv4.Address[0], SenderIPv4.Address[1], SenderIPv4.Address[2], SenderIPv4.Address[3]);
|
||||
fixme("Received reply from %s", SenderIPv4.v4.ToStringLittleEndian());
|
||||
break;
|
||||
default:
|
||||
warn("Invalid operation (%d)", Header->Operation);
|
||||
warn("Invalid operation (%d)", b16(Header->Operation));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
16
Network/DomainNameSystem.cpp
Normal file
16
Network/DomainNameSystem.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include <net/dns.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkDNS
|
||||
{
|
||||
DNS::DNS(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
this->UDPSocket = Socket;
|
||||
}
|
||||
|
||||
DNS::~DNS()
|
||||
{
|
||||
}
|
||||
}
|
@ -7,10 +7,24 @@ namespace NetworkDHCP
|
||||
{
|
||||
DHCP::DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
netdbg("Initializing.");
|
||||
this->UDPSocket = Socket;
|
||||
this->Interface = Interface;
|
||||
Socket->LocalPort = b16(68);
|
||||
|
||||
InternetProtocol::Version4 DefaultIPv4 = {.Address = {0x0, 0x0, 0x0, 0x0}};
|
||||
InternetProtocol::Version6 DefaultIPv6 = {.Address = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
|
||||
|
||||
this->IP.v4 = DefaultIPv4;
|
||||
this->IP.v6 = DefaultIPv6;
|
||||
|
||||
this->Gateway.v4 = DefaultIPv4;
|
||||
this->Gateway.v6 = DefaultIPv6;
|
||||
|
||||
this->SubNetworkMask.v4 = DefaultIPv4;
|
||||
this->SubNetworkMask.v6 = DefaultIPv6;
|
||||
|
||||
this->DomainNameSystem.v4 = DefaultIPv4;
|
||||
this->DomainNameSystem.v6 = DefaultIPv6;
|
||||
}
|
||||
|
||||
DHCP::~DHCP()
|
||||
@ -29,7 +43,7 @@ namespace NetworkDHCP
|
||||
memcpy(Packet->ClientHardwareAddress, &InterfaceMAC, sizeof(InterfaceMAC));
|
||||
|
||||
uint8_t *Ptr = Packet->Options;
|
||||
*((uint32_t *)(Ptr)) = b32(0x63825363); // magic cookie
|
||||
*((uint32_t *)(Ptr)) = b32(0x63825363); // Magic Cookie
|
||||
Ptr += 4;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_MESSAGE_TYPE;
|
||||
@ -80,7 +94,7 @@ namespace NetworkDHCP
|
||||
this->UDPSocket->SocketUDP->Send(this->UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 10;
|
||||
int RequestTimeout = 20;
|
||||
while (!Received)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
@ -88,17 +102,19 @@ namespace NetworkDHCP
|
||||
warn("Request timeout.");
|
||||
break;
|
||||
}
|
||||
TaskManager->Sleep(5000);
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void DHCP::Request(InternetProtocol4 IP)
|
||||
void DHCP::Request(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Requesting IP address %d.%d.%d.%d", IP.Address[0], IP.Address[1], IP.Address[2], IP.Address[3]);
|
||||
netdbg("Requesting IP address %s", IP.v4.ToStringLittleEndian());
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_REQUEST, IP.ToHex());
|
||||
/* CreatePacket() accepts IP as MSB */
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_REQUEST, b32(IP.v4.ToHex()));
|
||||
UDPSocket->SocketUDP->Send(UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
}
|
||||
|
||||
@ -106,7 +122,7 @@ namespace NetworkDHCP
|
||||
{
|
||||
uint8_t *Option = Packet->Options + 4;
|
||||
uint8_t Current = *Option;
|
||||
while (Current != 0xff)
|
||||
while (Current != 0xFF)
|
||||
{
|
||||
uint8_t OptionLength = *(Option + 1);
|
||||
if (Current == Type)
|
||||
@ -126,17 +142,23 @@ namespace NetworkDHCP
|
||||
switch (*MessageType)
|
||||
{
|
||||
case DHCP_OPTION_TIME_OFFSET:
|
||||
this->Request(InternetProtocol4().FromHex(Packet->YourIP));
|
||||
{
|
||||
InternetProtocol ReqIP;
|
||||
ReqIP.v4.FromHex(b32(Packet->YourIP));
|
||||
netdbg("Received DHCP offer for IP %s", ReqIP.v4.ToStringLittleEndian());
|
||||
this->Request(ReqIP);
|
||||
break;
|
||||
}
|
||||
case DHCP_OPTION_NAME_SERVER:
|
||||
this->IP.FromHex(Packet->YourIP);
|
||||
this->Gateway.FromHex(*(uint32_t *)GetOption(Packet, DHCP_OPTION_ROUTER));
|
||||
this->DomainNameSystem.FromHex(*(uint32_t *)GetOption(Packet, DHCP_OPTION_DOMAIN_NAME_SERVER));
|
||||
this->SubNetworkMask.FromHex((*(uint32_t *)GetOption(Packet, DHCP_OPTION_SUBNETMASK)));
|
||||
this->IP.v4.FromHex(b32(Packet->YourIP));
|
||||
this->Gateway.v4.FromHex(b32((uint32_t)(*(uintptr_t *)GetOption(Packet, DHCP_OPTION_ROUTER))));
|
||||
this->DomainNameSystem.v4.FromHex(b32((uint32_t)(*(uintptr_t *)GetOption(Packet, DHCP_OPTION_DOMAIN_NAME_SERVER))));
|
||||
this->SubNetworkMask.v4.FromHex(b32((uint32_t)(*(uintptr_t *)GetOption(Packet, DHCP_OPTION_SUBNETMASK))));
|
||||
this->Received = true;
|
||||
netdbg("Received DHCP ACK for IP %s", this->IP.v4.ToStringLittleEndian());
|
||||
break;
|
||||
default:
|
||||
netdbg("Received unknown message type %#x", *MessageType);
|
||||
warn("Received unknown message type %#x", *MessageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5,26 +5,6 @@
|
||||
|
||||
namespace NetworkEthernet
|
||||
{
|
||||
Ethernet::Ethernet(NetworkInterfaceManager::DeviceInterface *Interface) : NetworkInterfaceManager::Events(Interface) { this->Interface = Interface; }
|
||||
Ethernet::~Ethernet() {}
|
||||
|
||||
void Ethernet::Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("ETH: Sending frame type %#x to %02x:%02x:%02x:%02x:%02x:%02x", Type,
|
||||
MAC.Address[0], MAC.Address[1], MAC.Address[2],
|
||||
MAC.Address[3], MAC.Address[4], MAC.Address[5]);
|
||||
uint64_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);
|
||||
|
||||
memcpy(Packet->Data, Data, Length);
|
||||
NIManager->Send(Interface, (uint8_t *)Packet, PacketLength);
|
||||
kfree(Packet);
|
||||
}
|
||||
|
||||
struct EthernetEventHelperStruct
|
||||
{
|
||||
EthernetEvents *Ptr;
|
||||
@ -33,62 +13,87 @@ namespace NetworkEthernet
|
||||
|
||||
Vector<EthernetEventHelperStruct> RegisteredEvents;
|
||||
|
||||
Ethernet::Ethernet(NetworkInterfaceManager::DeviceInterface *Interface) : NetworkInterfaceManager::Events(Interface) { this->Interface = Interface; }
|
||||
Ethernet::~Ethernet() {}
|
||||
|
||||
void Ethernet::Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, uint64_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);
|
||||
|
||||
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, uint64_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));
|
||||
|
||||
if (b48(Packet->Header.DestinationMAC) == 0xFFFFFFFFFFFF ||
|
||||
b48(Packet->Header.DestinationMAC) == this->Interface->MAC.ToHex())
|
||||
{
|
||||
netdbg("ETH: Received data from %02x:%02x:%02x:%02x:%02x:%02x [Type %#x]",
|
||||
SourceMAC.Address[0], SourceMAC.Address[1], SourceMAC.Address[2],
|
||||
SourceMAC.Address[3], SourceMAC.Address[4], SourceMAC.Address[5], b16(Packet->Header.Type));
|
||||
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;
|
||||
|
||||
switch (b16(Packet->Header.Type))
|
||||
{
|
||||
case TYPE_IPV4:
|
||||
foreach (auto var in RegisteredEvents)
|
||||
if (var.Type == TYPE_IPV4)
|
||||
Reply = var.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
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 var in RegisteredEvents)
|
||||
if (var.Type == TYPE_ARP)
|
||||
Reply = var.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
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 var in RegisteredEvents)
|
||||
if (var.Type == TYPE_RARP)
|
||||
Reply = var.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
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 var in RegisteredEvents)
|
||||
if (var.Type == TYPE_IPV6)
|
||||
Reply = var.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e.Type == TYPE_IPV6)
|
||||
Reply = e.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
default:
|
||||
warn("ETH: Unknown packet type %#lx", Packet->Header.Type);
|
||||
warn("Unknown packet type %#lx", Packet->Header.Type);
|
||||
break;
|
||||
}
|
||||
if (Reply)
|
||||
{
|
||||
Packet->Header.DestinationMAC = Packet->Header.SourceMAC;
|
||||
Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
/* 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("ETH: Type: [%#x] [%02x:%02x:%02x:%02x:%02x:%02x]=>[%02x:%02x:%02x:%02x:%02x:%02x]", b16(Packet->Header.Type),
|
||||
SourceMAC.Address[0], SourceMAC.Address[1], SourceMAC.Address[2],
|
||||
SourceMAC.Address[3], SourceMAC.Address[4], SourceMAC.Address[5],
|
||||
DestinationMAC.Address[0], DestinationMAC.Address[1], DestinationMAC.Address[2],
|
||||
DestinationMAC.Address[3], DestinationMAC.Address[4], DestinationMAC.Address[5]);
|
||||
netdbg("Packet not for us [%s]=>[%s]", this->Interface->MAC.ToString(), DestinationMAC.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,13 +105,13 @@ namespace NetworkEthernet
|
||||
|
||||
EthernetEvents::EthernetEvents(FrameType Type)
|
||||
{
|
||||
FType = Type;
|
||||
this->FType = Type;
|
||||
RegisteredEvents.push_back({.Ptr = this, .Type = (uint16_t)Type});
|
||||
}
|
||||
|
||||
EthernetEvents::~EthernetEvents()
|
||||
{
|
||||
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i].Ptr == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
|
@ -19,7 +19,7 @@ namespace NetworkICMPv4
|
||||
if (Packet->Header.Type == ICMPv4Type::TYPE_ECHO)
|
||||
{
|
||||
// TODO: This probably doesn't work
|
||||
netdbg("ICMPv4: Echo Request");
|
||||
netdbg("Echo Request");
|
||||
Packet->Header.Type = ICMPv4Type::TYPE_ECHO_REPLY;
|
||||
Packet->Header.Code = 0x0;
|
||||
Packet->Header.Checksum = CalculateChecksum((uint16_t *)Packet, sizeof(ICMPHeader));
|
||||
@ -27,7 +27,7 @@ namespace NetworkICMPv4
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("ICMPv4: Unknown type %d", Packet->Header.Type);
|
||||
netdbg("Unknown type %d", Packet->Header.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ namespace NetworkIPv4
|
||||
{
|
||||
IPv4::IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_IPV4)
|
||||
{
|
||||
netdbg("IPv4: Initializing.");
|
||||
this->ARP = ARP;
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
@ -16,30 +15,32 @@ namespace NetworkIPv4
|
||||
{
|
||||
}
|
||||
|
||||
void IPv4::Send(uint8_t *Data, uint64_t Length, uint8_t Protocol, InternetProtocol4 DestinationIP)
|
||||
void IPv4::Send(uint8_t *Data, uint64_t Length, uint8_t Protocol, InternetProtocol DestinationIP)
|
||||
{
|
||||
netdbg("IPv4: Sending %ld bytes to %d.%d.%d.%d", Length, DestinationIP.Address[0], DestinationIP.Address[1], DestinationIP.Address[2], DestinationIP.Address[3]);
|
||||
netdbg("Sending %ld bytes to %s", Length, DestinationIP.v4.ToStringLittleEndian());
|
||||
IPv4Packet *Packet = (IPv4Packet *)kmalloc(Length + sizeof(IPv4Header));
|
||||
|
||||
Packet->Header.Version = 4;
|
||||
Packet->Header.IHL = sizeof(IPv4Header) / 4;
|
||||
Packet->Header.TypeOfService = 0;
|
||||
/* This part is the most confusing one for me. */
|
||||
Packet->Header.Version = b8(4);
|
||||
Packet->Header.IHL = b8(sizeof(IPv4Header) / 4);
|
||||
Packet->Header.TypeOfService = b8(0);
|
||||
/* We don't byteswap. */
|
||||
Packet->Header.TotalLength = Length + sizeof(IPv4Header);
|
||||
Packet->Header.TotalLength = ((Packet->Header.TotalLength & 0xFF00) >> 8) | ((Packet->Header.TotalLength & 0x00FF) << 8);
|
||||
Packet->Header.Identification = 0;
|
||||
// Packet->Header.Flags = 0x0;
|
||||
// Packet->Header.FragmentOffset = 0x0;
|
||||
Packet->Header.FlagsAndFragmentOffset = 0x0;
|
||||
Packet->Header.TimeToLive = 64;
|
||||
Packet->Header.Protocol = Protocol;
|
||||
Packet->Header.DestinationIP = b32(DestinationIP.ToHex());
|
||||
Packet->Header.SourceIP = b32(Ethernet->GetInterface()->IP.ToHex());
|
||||
Packet->Header.HeaderChecksum = 0x0;
|
||||
|
||||
Packet->Header.Identification = b16(0x0000);
|
||||
Packet->Header.Flags = b8(0x0);
|
||||
Packet->Header.FragmentOffset = b8(0x0);
|
||||
Packet->Header.TimeToLive = b8(64);
|
||||
Packet->Header.Protocol = b8(Protocol);
|
||||
Packet->Header.DestinationIP = b32(DestinationIP.v4.ToHex());
|
||||
Packet->Header.SourceIP = b32(Ethernet->GetInterface()->IP.v4.ToHex());
|
||||
Packet->Header.HeaderChecksum = b16(0x0);
|
||||
Packet->Header.HeaderChecksum = CalculateChecksum((uint16_t *)Packet, sizeof(IPv4Header));
|
||||
|
||||
memcpy(Packet->Data, Data, Length);
|
||||
InternetProtocol4 DestinationRoute = DestinationIP;
|
||||
if ((b32(DestinationIP.ToHex()) & SubNetworkMaskIP.ToHex()) != (Packet->Header.SourceIP & SubNetworkMaskIP.ToHex()))
|
||||
InternetProtocol DestinationRoute = DestinationIP;
|
||||
if ((DestinationIP.v4.ToHex() & SubNetworkMaskIP.v4.ToHex()) != (b32(Packet->Header.SourceIP) & SubNetworkMaskIP.v4.ToHex()))
|
||||
DestinationRoute = SubNetworkMaskIP;
|
||||
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ARP->Resolve(DestinationRoute)), this->GetFrameType(), (uint8_t *)Packet, Length + sizeof(IPv4Header));
|
||||
@ -51,16 +52,16 @@ namespace NetworkIPv4
|
||||
bool IPv4::OnEthernetPacketReceived(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
IPv4Packet *Packet = (IPv4Packet *)Data;
|
||||
netdbg("IPv4: Received %d bytes [Protocol %ld]", Length, Packet->Header.Protocol);
|
||||
netdbg("Received %d bytes [Protocol %ld]", Length, Packet->Header.Protocol);
|
||||
if (Length < sizeof(IPv4Header))
|
||||
{
|
||||
warn("IPv4: Packet too short");
|
||||
warn("Packet too short");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Reply = false;
|
||||
|
||||
if (Packet->Header.DestinationIP == Ethernet->GetInterface()->IP.ToHex() || Packet->Header.DestinationIP == 0xFFFFFFFF || Ethernet->GetInterface()->IP.ToHex() == 0)
|
||||
if (b32(Packet->Header.DestinationIP) == Ethernet->GetInterface()->IP.v4.ToHex() || b32(Packet->Header.DestinationIP) == 0xFFFFFFFF || Ethernet->GetInterface()->IP.v4.ToHex() == 0)
|
||||
{
|
||||
uint64_t TotalLength = Packet->Header.TotalLength;
|
||||
if (TotalLength > Length)
|
||||
@ -68,8 +69,22 @@ namespace NetworkIPv4
|
||||
|
||||
foreach (auto Event in RegisteredEvents)
|
||||
if (Packet->Header.Protocol == Event->GetProtocol())
|
||||
if (Event->OnIPv4PacketReceived(InternetProtocol4().FromHex(b32(Packet->Header.SourceIP)), InternetProtocol4().FromHex(b32(Packet->Header.DestinationIP)), (uint8_t *)((uint64_t)Data + 4 * Packet->Header.IHL), TotalLength - 4 * Packet->Header.IHL))
|
||||
{
|
||||
InternetProtocol SourceIP;
|
||||
InternetProtocol DestinationIP;
|
||||
|
||||
SourceIP.v4 = SourceIP.v4.FromHex(b32(Packet->Header.SourceIP));
|
||||
DestinationIP.v4 = DestinationIP.v4.FromHex(b32(Packet->Header.DestinationIP));
|
||||
|
||||
if (Event->OnIPv4PacketReceived(SourceIP, DestinationIP, (uint8_t *)((uint64_t)Data + 4 * Packet->Header.IHL), TotalLength - 4 * Packet->Header.IHL))
|
||||
Reply = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Not for us. We are %s but this is for %s",
|
||||
Ethernet->GetInterface()->IP.v4.ToHex(),
|
||||
Packet->Header.DestinationIP);
|
||||
}
|
||||
|
||||
if (Reply)
|
||||
|
@ -1,13 +1,15 @@
|
||||
#include <net/nc.hpp>
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/dhcp.hpp>
|
||||
#include <net/eth.hpp>
|
||||
#include <net/arp.hpp>
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/ntp.hpp>
|
||||
#include <net/dns.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/dhcp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
#include "../DAPI.hpp"
|
||||
#include "../Fex.hpp"
|
||||
|
||||
@ -37,7 +39,7 @@ namespace NetworkInterfaceManager
|
||||
|
||||
// Unregister all events
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
RegisteredEvents.remove(i);
|
||||
RegisteredEvents.remove(i);
|
||||
|
||||
// Delete all interfaces and their callbacks and free the memory
|
||||
delete mem;
|
||||
@ -64,6 +66,12 @@ namespace NetworkInterfaceManager
|
||||
debug("Network Card: %s; MAC: %#lx", Iface->Name, Iface->MAC.ToHex());
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NETWORK
|
||||
#define DbgWriteScreen(x, ...) KPrint(x, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DbgWriteScreen(x, ...) debug(x, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
void NetworkInterface::StartNetworkStack()
|
||||
{
|
||||
TaskManager->GetCurrentThread()->SetPriority(100);
|
||||
@ -79,22 +87,46 @@ namespace NetworkInterfaceManager
|
||||
error("No network device found!");
|
||||
else
|
||||
{
|
||||
DbgWriteScreen("Using %s (%s) as the default network device", DefaultDevice->Name, DefaultDevice->MAC.ToString());
|
||||
NetworkEthernet::Ethernet *eth = new NetworkEthernet::Ethernet(DefaultDevice); // Use the first device found as the ethernet device
|
||||
NetworkARP::ARP *arp = new NetworkARP::ARP(eth);
|
||||
NetworkIPv4::IPv4 *ipv4 = new NetworkIPv4::IPv4(arp, eth);
|
||||
NetworkUDP::UDP *udp = new NetworkUDP::UDP(ipv4, DefaultDevice);
|
||||
NetworkUDP::Socket *DHCP_Socket = udp->Connect({.Address = {0xFF, 0xFF, 0xFF, 0xFF}}, 67);
|
||||
NetworkUDP::Socket *DHCP_Socket = udp->Connect(InternetProtocol() /* Default value is 255.255.255.255 */, 67);
|
||||
NetworkDHCP::DHCP *dhcp = new NetworkDHCP::DHCP(DHCP_Socket, DefaultDevice);
|
||||
udp->Bind(DHCP_Socket, dhcp);
|
||||
dhcp->Request();
|
||||
DefaultDevice->IP = InternetProtocol4().FromHex(b32(dhcp->IP.ToHex()));
|
||||
|
||||
DefaultDevice->IP.v4.FromHex(dhcp->IP.v4.ToHex());
|
||||
ipv4->SubNetworkMaskIP = dhcp->SubNetworkMask;
|
||||
ipv4->GatewayIP = dhcp->Gateway;
|
||||
arp->Broadcast(dhcp->Gateway);
|
||||
trace("IP: %d.%d.%d.%d", dhcp->IP.Address[3], dhcp->IP.Address[2], dhcp->IP.Address[1], dhcp->IP.Address[0]);
|
||||
trace("SubNetwork Mask: %d.%d.%d.%d", dhcp->SubNetworkMask.Address[3], dhcp->SubNetworkMask.Address[2], dhcp->SubNetworkMask.Address[1], dhcp->SubNetworkMask.Address[0]);
|
||||
trace("Gateway: %d.%d.%d.%d", dhcp->Gateway.Address[3], dhcp->Gateway.Address[2], dhcp->Gateway.Address[1], dhcp->Gateway.Address[0]);
|
||||
trace("DNS: %d.%d.%d.%d", dhcp->DomainNameSystem.Address[3], dhcp->DomainNameSystem.Address[2], dhcp->DomainNameSystem.Address[1], dhcp->DomainNameSystem.Address[0]);
|
||||
TaskManager->Sleep(200);
|
||||
DbgWriteScreen("IP: %s", dhcp->IP.v4.ToStringLittleEndian());
|
||||
DbgWriteScreen("SubNetwork Mask: %s", dhcp->SubNetworkMask.v4.ToStringLittleEndian());
|
||||
DbgWriteScreen("Gateway: %s", dhcp->Gateway.v4.ToStringLittleEndian());
|
||||
DbgWriteScreen("DNS: %s", dhcp->DomainNameSystem.v4.ToStringLittleEndian());
|
||||
TaskManager->Sleep(200);
|
||||
|
||||
/*
|
||||
I HAVE TO REWRITE THE ENTIRE NETWORK STACK BECAUSE IT'S A MESS. I HATE BYTE SWAPPING!!!!!
|
||||
|
||||
Rules to follow:
|
||||
- The functions MUST have little endian parameters and return values.
|
||||
*/
|
||||
|
||||
/* TODO: This is a quick workaround we need DNS resolver asap. IP is time-a-g.nist.gov; https://tf.nist.gov/tf-cgi/servers.cgi */
|
||||
InternetProtocol ip = {.v4 = {.Address = {129, 6, 15, 28}},
|
||||
.v6 = {.Address = {}}};
|
||||
NetworkUDP::Socket *NTP_Socket = udp->Connect(ip, 123);
|
||||
NetworkNTP::NTP *ntp = new NetworkNTP::NTP(NTP_Socket);
|
||||
udp->Bind(NTP_Socket, ntp);
|
||||
int UnixTimestamp = ntp->ReadTime();
|
||||
Time::Clock time = Time::ConvertFromUnix(UnixTimestamp);
|
||||
DbgWriteScreen("NTP: %d - %d.%d.%d %d:%d:%d", UnixTimestamp,
|
||||
time.Day, time.Month, time.Year,
|
||||
time.Hour, time.Minute, time.Second);
|
||||
TaskManager->Sleep(200);
|
||||
|
||||
/* TODO: Store everything in an vector and initialize all network cards */
|
||||
}
|
||||
|
@ -6,16 +6,20 @@ TODO: This code is a mess. It needs to be cleaned up.
|
||||
|
||||
#ifdef DEBUG_NETWORK
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <uart.hpp>
|
||||
#include <printf.h>
|
||||
#include "../drivers/serial.h"
|
||||
#include <lock.hpp>
|
||||
|
||||
using namespace UniversalAsynchronousReceiverTransmitter;
|
||||
|
||||
NewLock(netdbg_lock);
|
||||
|
||||
namespace NetDbg
|
||||
{
|
||||
class NETWORK_DEBUG : public NetworkInterfaceManager::Events
|
||||
{
|
||||
public:
|
||||
static inline void print_wrapper(char c, void *unused) { write_serial(COM1, c); }
|
||||
static inline void print_wrapper(char c, void *unused) { UART(COM1).Write(c); }
|
||||
int vprintf(const char *format, va_list list) { return vfctprintf(print_wrapper, NULL, format, list); }
|
||||
void WriteRaw(const char *format, ...)
|
||||
{
|
||||
@ -27,6 +31,7 @@ namespace NetDbg
|
||||
|
||||
void DumpData(const char *Description, void *Address, unsigned long Length)
|
||||
{
|
||||
SmartLock(netdbg_lock);
|
||||
WriteRaw("-------------------------------------------------------------------------\n");
|
||||
unsigned char *AddressChar = (unsigned char *)Address;
|
||||
unsigned char Buffer[17];
|
||||
|
@ -5,17 +5,44 @@
|
||||
|
||||
namespace NetworkNTP
|
||||
{
|
||||
NTP::NTP(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
void NTP::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
this->Socket = Socket;
|
||||
this->NTPPacket = *(NTPHeader *)Data;
|
||||
this->TimeReceived = true;
|
||||
netdbg("Received UDP packet for NTP.");
|
||||
}
|
||||
|
||||
NTP::~NTP()
|
||||
{
|
||||
}
|
||||
NTP::NTP(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents() { this->UDPSocket = Socket; }
|
||||
NTP::~NTP() {}
|
||||
|
||||
void ReadTime()
|
||||
int NTP::ReadTime()
|
||||
{
|
||||
fixme("ReadTime()");
|
||||
netdbg("Requesting time");
|
||||
this->TimeReceived = false;
|
||||
|
||||
NTPHeader ReqPacket; // This may require phyiscal memory allocation but Ethernet already has this job.
|
||||
memset(&ReqPacket, 0, sizeof(NTPHeader)); // Zero out the packet
|
||||
*((char *)&ReqPacket) = 0x1b; // byteswap nightmare, this is the code below but in little endian
|
||||
// ReqPacket.LeapIndicator = 0;
|
||||
// ReqPacket.VersionNumber = 3;
|
||||
// ReqPacket.Mode = 3;
|
||||
UDPSocket->SocketUDP->Send(UDPSocket, (uint8_t *)&ReqPacket, sizeof(NTPHeader));
|
||||
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 20;
|
||||
while (!this->TimeReceived)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
|
||||
int UnixTimestamp = b32(this->NTPPacket.TransmitTimestamp[0]) - 2208988800;
|
||||
debug("Unix time: %d", UnixTimestamp);
|
||||
return UnixTimestamp;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ namespace NetworkUDP
|
||||
|
||||
UDP::UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface) : NetworkIPv4::IPv4Events(NetworkIPv4::PROTOCOL_UDP)
|
||||
{
|
||||
netdbg("UDP: Initializing.");
|
||||
this->ipv4 = ipv4;
|
||||
this->Interface = Interface;
|
||||
}
|
||||
@ -29,16 +28,16 @@ namespace NetworkUDP
|
||||
|
||||
uint16_t UsablePort = 0x200;
|
||||
|
||||
Socket *UDP::Connect(InternetProtocol4 IP, uint16_t Port)
|
||||
Socket *UDP::Connect(InternetProtocol IP, uint16_t Port)
|
||||
{
|
||||
netdbg("UDP: Connecting to %d.%d.%d.%d:%d", IP.Address[0], IP.Address[1], IP.Address[2], IP.Address[3], Port);
|
||||
netdbg("Connecting to %s", IP.v4.ToStringLittleEndian(), Port);
|
||||
Socket *socket = new Socket(this);
|
||||
socket->RemoteIP = IP;
|
||||
socket->RemotePort = Port;
|
||||
socket->LocalPort = UsablePort++; // TODO: track ports
|
||||
socket->LocalIP = Interface->IP;
|
||||
socket->LocalPort = __builtin_bswap16(socket->LocalPort);
|
||||
socket->RemotePort = __builtin_bswap16(socket->RemotePort);
|
||||
socket->LocalPort = b16(socket->LocalPort);
|
||||
socket->RemotePort = b16(socket->RemotePort);
|
||||
RegisteredEvents.push_back({.UDPSocket = socket, .Port = socket->LocalPort});
|
||||
return socket;
|
||||
}
|
||||
@ -56,7 +55,7 @@ namespace NetworkUDP
|
||||
|
||||
void UDP::Send(Socket *Socket, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("UDP: Sending %d bytes to %d.%d.%d.%d:%d", Length, Socket->RemoteIP.Address[0], Socket->RemoteIP.Address[1], Socket->RemoteIP.Address[2], Socket->RemoteIP.Address[3], Socket->RemotePort);
|
||||
netdbg("Sending %d bytes to %s", Length, Socket->RemoteIP.v4.ToStringLittleEndian(), Socket->RemotePort);
|
||||
uint16_t TotalLength = Length + sizeof(UDPHeader);
|
||||
UDPPacket *packet = (UDPPacket *)kmalloc(TotalLength);
|
||||
packet->Header.SourcePort = Socket->LocalPort;
|
||||
@ -69,36 +68,40 @@ namespace NetworkUDP
|
||||
kfree(packet);
|
||||
}
|
||||
|
||||
void UDP::Bind(Socket *Socket, UDPEvents *EventHandler) { Socket->EventHandler = EventHandler; }
|
||||
|
||||
bool UDP::OnIPv4PacketReceived(InternetProtocol4 SourceIP, InternetProtocol4 DestinationIP, uint8_t *Data, uint64_t Length)
|
||||
void UDP::Bind(Socket *Socket, UDPEvents *EventHandler)
|
||||
{
|
||||
netdbg("UDP: Received %d bytes from %d.%d.%d.%d", Length, SourceIP.Address[0], SourceIP.Address[1], SourceIP.Address[2], SourceIP.Address[3]);
|
||||
netdbg("Binding socket to %s", Socket->LocalIP.v4.ToStringLittleEndian(), Socket->LocalPort);
|
||||
Socket->EventHandler = EventHandler;
|
||||
}
|
||||
|
||||
bool UDP::OnIPv4PacketReceived(InternetProtocol SourceIP, InternetProtocol DestinationIP, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("Received %d bytes from %s", Length, SourceIP.v4.ToStringLittleEndian());
|
||||
if (Length < sizeof(UDPHeader))
|
||||
return false;
|
||||
|
||||
UDPHeader *udp = (UDPHeader *)Data;
|
||||
|
||||
netdbg("UDP: SP:%d | DP:%d | L:%d | CHK:%#x", b16(udp->SourcePort), b16(udp->DestinationPort), b16(udp->Length), b16(udp->Checksum));
|
||||
netdbg("SP:%d | DP:%d | L:%d | CHK:%#x", b16(udp->SourcePort), b16(udp->DestinationPort), b16(udp->Length), b16(udp->Checksum));
|
||||
|
||||
Socket *GoodSocket = nullptr;
|
||||
|
||||
foreach (auto var in RegisteredEvents)
|
||||
{
|
||||
netdbg("UDP->SKT[]: LP:%d | LIP:%d.%d.%d.%d | RP:%d | RIP:%d.%d.%d.%d | LST:%d",
|
||||
netdbg("UDP->SKT[]: LP:%d | LIP:%s | RP:%d | RIP:%s | LST:%d",
|
||||
b16(var.UDPSocket->LocalPort),
|
||||
var.UDPSocket->LocalIP.Address[0], var.UDPSocket->LocalIP.Address[1], var.UDPSocket->LocalIP.Address[2], var.UDPSocket->LocalIP.Address[3],
|
||||
var.UDPSocket->LocalIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->RemotePort),
|
||||
var.UDPSocket->RemoteIP.Address[0], var.UDPSocket->RemoteIP.Address[1], var.UDPSocket->RemoteIP.Address[2], var.UDPSocket->RemoteIP.Address[3],
|
||||
var.UDPSocket->RemoteIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->Listening));
|
||||
if (var.UDPSocket->LocalPort == udp->DestinationPort &&
|
||||
var.UDPSocket->LocalIP == DestinationIP &&
|
||||
var.UDPSocket->LocalIP.v4 == DestinationIP.v4 &&
|
||||
var.UDPSocket->Listening == true)
|
||||
{
|
||||
var.UDPSocket->Listening = false;
|
||||
var.UDPSocket->RemotePort = b16(udp->SourcePort);
|
||||
var.UDPSocket->RemoteIP = SourceIP;
|
||||
netdbg("UDP: E1");
|
||||
netdbg("E1");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -107,7 +110,7 @@ namespace NetworkUDP
|
||||
if (GoodSocket)
|
||||
GoodSocket->EventHandler->OnUDPPacketReceived(GoodSocket, ((UDPPacket *)Data)->Data, Length);
|
||||
|
||||
netdbg("UDP: E0 (Success)");
|
||||
netdbg("E0 (Success)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user