mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Update kernel
This commit is contained in:
@ -21,7 +21,7 @@
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
/* conversion from ‘uint48_t’ {aka ‘long unsigned int’} to ‘long unsigned int:48’ may change value */
|
||||
/* conversion from 'uint48_t' {aka 'long unsigned int'} to 'long unsigned int:48' may change value */
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
|
||||
namespace NetworkARP
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
uint16_t CalculateChecksum(uint16_t *Data, size_t Length)
|
||||
{
|
||||
uint16_t *Data16 = (uint16_t *)Data;
|
||||
uint64_t Checksum = 0;
|
||||
for (uint64_t i = 0; i < Length / 2; i++)
|
||||
Checksum += ((Data16[i] & 0xFF00) >> 8) | ((Data16[i] & 0x00FF) << 8);
|
||||
if (Length % 2)
|
||||
Checksum += ((uint16_t)((char *)Data16)[Length - 1]) << 8;
|
||||
while (Checksum & 0xFFFF0000)
|
||||
Checksum = (Checksum & 0xFFFF) + (Checksum >> 16);
|
||||
return (uint16_t)(((~Checksum & 0xFF00) >> 8) | ((~Checksum & 0x00FF) << 8));
|
||||
uint16_t *Data16 = (uint16_t *)Data;
|
||||
uint64_t Checksum = 0;
|
||||
for (uint64_t i = 0; i < Length / 2; i++)
|
||||
Checksum += ((Data16[i] & 0xFF00) >> 8) | ((Data16[i] & 0x00FF) << 8);
|
||||
if (Length % 2)
|
||||
Checksum += ((uint16_t)((char *)Data16)[Length - 1]) << 8;
|
||||
while (Checksum & 0xFFFF0000)
|
||||
Checksum = (Checksum & 0xFFFF) + (Checksum >> 16);
|
||||
return (uint16_t)(((~Checksum & 0xFF00) >> 8) | ((~Checksum & 0x00FF) << 8));
|
||||
}
|
||||
|
276
network/dhcp.cpp
276
network/dhcp.cpp
@ -22,165 +22,165 @@
|
||||
|
||||
namespace NetworkDHCP
|
||||
{
|
||||
DHCP::DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
debug("DHCP interface %#lx created.", this);
|
||||
this->UDPSocket = Socket;
|
||||
this->Interface = Interface;
|
||||
Socket->LocalPort = b16(68);
|
||||
DHCP::DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
debug("DHCP interface %#lx created.", this);
|
||||
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}};
|
||||
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->IP.v4 = DefaultIPv4;
|
||||
this->IP.v6 = DefaultIPv6;
|
||||
|
||||
this->Gateway.v4 = DefaultIPv4;
|
||||
this->Gateway.v6 = DefaultIPv6;
|
||||
this->Gateway.v4 = DefaultIPv4;
|
||||
this->Gateway.v6 = DefaultIPv6;
|
||||
|
||||
this->SubNetworkMask.v4 = DefaultIPv4;
|
||||
this->SubNetworkMask.v6 = DefaultIPv6;
|
||||
this->SubNetworkMask.v4 = DefaultIPv4;
|
||||
this->SubNetworkMask.v6 = DefaultIPv6;
|
||||
|
||||
this->DomainNameSystem.v4 = DefaultIPv4;
|
||||
this->DomainNameSystem.v6 = DefaultIPv6;
|
||||
}
|
||||
this->DomainNameSystem.v4 = DefaultIPv4;
|
||||
this->DomainNameSystem.v6 = DefaultIPv6;
|
||||
}
|
||||
|
||||
DHCP::~DHCP()
|
||||
{
|
||||
debug("DHCP interface %#lx destroyed.", this);
|
||||
}
|
||||
DHCP::~DHCP()
|
||||
{
|
||||
debug("DHCP interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
__no_sanitize("alignment") void DHCP::CreatePacket(DHCPHeader *Packet, uint8_t MessageType, uint32_t RequestIP)
|
||||
{
|
||||
Packet->Opcode = b8(DHCP_OP_BOOTREQUEST);
|
||||
Packet->HardwareType = b8(1);
|
||||
Packet->HardwareAddressLength = b8(6);
|
||||
Packet->Hops = b8(0);
|
||||
Packet->TransactionID = b32(DHCP_TRANSACTION_ID);
|
||||
Packet->Flags = b16(0x40);
|
||||
uint48_t InterfaceMAC = b48(Interface->MAC.ToHex());
|
||||
memcpy(Packet->ClientHardwareAddress, &InterfaceMAC, sizeof(InterfaceMAC));
|
||||
__no_sanitize("alignment") void DHCP::CreatePacket(DHCPHeader *Packet, uint8_t MessageType, uint32_t RequestIP)
|
||||
{
|
||||
Packet->Opcode = b8(DHCP_OP_BOOTREQUEST);
|
||||
Packet->HardwareType = b8(1);
|
||||
Packet->HardwareAddressLength = b8(6);
|
||||
Packet->Hops = b8(0);
|
||||
Packet->TransactionID = b32(DHCP_TRANSACTION_ID);
|
||||
Packet->Flags = b16(0x40);
|
||||
uint48_t InterfaceMAC = b48(Interface->MAC.ToHex());
|
||||
memcpy(Packet->ClientHardwareAddress, &InterfaceMAC, sizeof(InterfaceMAC));
|
||||
|
||||
uint8_t *Ptr = Packet->Options;
|
||||
*((uint32_t *)(Ptr)) = b32(0x63825363); // Magic Cookie
|
||||
Ptr += 4;
|
||||
uint8_t *Ptr = Packet->Options;
|
||||
*((uint32_t *)(Ptr)) = b32(0x63825363); // Magic Cookie
|
||||
Ptr += 4;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_MESSAGE_TYPE;
|
||||
*(Ptr++) = DHCP_MESSAGE_TYPE_DISCOVER;
|
||||
*(Ptr++) = MessageType;
|
||||
*(Ptr++) = DHCP_OPTION_MESSAGE_TYPE;
|
||||
*(Ptr++) = DHCP_MESSAGE_TYPE_DISCOVER;
|
||||
*(Ptr++) = MessageType;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_CLIENT_IDENTIFIER;
|
||||
*(Ptr++) = 0x07;
|
||||
*(Ptr++) = 0x01;
|
||||
memcpy(Ptr, &InterfaceMAC, sizeof(InterfaceMAC));
|
||||
Ptr += 6;
|
||||
*(Ptr++) = DHCP_OPTION_CLIENT_IDENTIFIER;
|
||||
*(Ptr++) = 0x07;
|
||||
*(Ptr++) = 0x01;
|
||||
memcpy(Ptr, &InterfaceMAC, sizeof(InterfaceMAC));
|
||||
Ptr += 6;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_REQUESTED_IP;
|
||||
*(Ptr++) = 0x04;
|
||||
*((uint32_t *)(Ptr)) = b32(0x0a00020e);
|
||||
memcpy((uint32_t *)(Ptr), &RequestIP, 4);
|
||||
Ptr += 4;
|
||||
*(Ptr++) = DHCP_OPTION_REQUESTED_IP;
|
||||
*(Ptr++) = 0x04;
|
||||
*((uint32_t *)(Ptr)) = b32(0x0a00020e);
|
||||
memcpy((uint32_t *)(Ptr), &RequestIP, 4);
|
||||
Ptr += 4;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_HOST_NAME;
|
||||
char *HostName = (char *)KERNEL_NAME;
|
||||
*(Ptr++) = s_cst(uint8_t, 1 + strlen(HostName));
|
||||
memcpy(Ptr, HostName, strlen(HostName));
|
||||
Ptr += strlen(HostName);
|
||||
*(Ptr++) = DHCP_OPTION_HOST_NAME;
|
||||
char *HostName = (char *)KERNEL_NAME;
|
||||
*(Ptr++) = s_cst(uint8_t, 1 + strlen(HostName));
|
||||
memcpy(Ptr, HostName, strlen(HostName));
|
||||
Ptr += strlen(HostName);
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_PAD;
|
||||
*(Ptr++) = DHCP_OPTION_PAD;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_PARAMETER_REQUEST_LIST;
|
||||
*(Ptr++) = DHCP_OPTION_COOKIE_SERVER;
|
||||
*(Ptr++) = DHCP_OPTION_SUBNETMASK;
|
||||
*(Ptr++) = DHCP_OPTION_ROUTER;
|
||||
*(Ptr++) = DHCP_OPTION_DOMAIN_NAME_SERVER;
|
||||
*(Ptr++) = DHCP_OPTION_DOMAIN_NAME;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_NAME_SERVERS;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_NODE_TYPE;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_SCOPE;
|
||||
*(Ptr++) = DHCP_OPTION_MAX_MESSAGE_SIZE;
|
||||
*(Ptr++) = DHCP_OPTION_PARAMETER_REQUEST_LIST;
|
||||
*(Ptr++) = DHCP_OPTION_COOKIE_SERVER;
|
||||
*(Ptr++) = DHCP_OPTION_SUBNETMASK;
|
||||
*(Ptr++) = DHCP_OPTION_ROUTER;
|
||||
*(Ptr++) = DHCP_OPTION_DOMAIN_NAME_SERVER;
|
||||
*(Ptr++) = DHCP_OPTION_DOMAIN_NAME;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_NAME_SERVERS;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_NODE_TYPE;
|
||||
*(Ptr++) = DHCP_OPTION_NETBIOS_SCOPE;
|
||||
*(Ptr++) = DHCP_OPTION_MAX_MESSAGE_SIZE;
|
||||
|
||||
*(Ptr++) = DHCP_OPTION_END;
|
||||
}
|
||||
*(Ptr++) = DHCP_OPTION_END;
|
||||
}
|
||||
|
||||
void DHCP::Request()
|
||||
{
|
||||
netdbg("Requesting IP address");
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
void DHCP::Request()
|
||||
{
|
||||
netdbg("Requesting IP address");
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_DISCOVER, 0x00000000);
|
||||
this->UDPSocket->SocketUDP->Send(this->UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_DISCOVER, 0x00000000);
|
||||
this->UDPSocket->SocketUDP->Send(this->UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 20;
|
||||
while (!Received)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
break;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
}
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 20;
|
||||
while (!Received)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
break;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void DHCP::Request(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Requesting IP address %s", IP.v4.ToStringLittleEndian());
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
void DHCP::Request(InternetProtocol IP)
|
||||
{
|
||||
netdbg("Requesting IP address %s", IP.v4.ToStringLittleEndian());
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
|
||||
/* CreatePacket() accepts IP as MSB */
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_REQUEST, b32(IP.v4.ToHex()));
|
||||
UDPSocket->SocketUDP->Send(UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
}
|
||||
/* CreatePacket() accepts IP as MSB */
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_REQUEST, b32(IP.v4.ToHex()));
|
||||
UDPSocket->SocketUDP->Send(UDPSocket, (uint8_t *)&packet, sizeof(DHCPHeader));
|
||||
}
|
||||
|
||||
void *DHCP::GetOption(DHCPHeader *Packet, uint8_t Type)
|
||||
{
|
||||
uint8_t *Option = Packet->Options + 4;
|
||||
uint8_t Current = *Option;
|
||||
while (Current != 0xFF)
|
||||
{
|
||||
uint8_t OptionLength = *(Option + 1);
|
||||
if (Current == Type)
|
||||
return Option + 2;
|
||||
Option += (2 + OptionLength);
|
||||
Current = *Option;
|
||||
}
|
||||
warn("Option %#x not found", Type);
|
||||
return nullptr;
|
||||
}
|
||||
void *DHCP::GetOption(DHCPHeader *Packet, uint8_t Type)
|
||||
{
|
||||
uint8_t *Option = Packet->Options + 4;
|
||||
uint8_t Current = *Option;
|
||||
while (Current != 0xFF)
|
||||
{
|
||||
uint8_t OptionLength = *(Option + 1);
|
||||
if (Current == Type)
|
||||
return Option + 2;
|
||||
Option += (2 + OptionLength);
|
||||
Current = *Option;
|
||||
}
|
||||
warn("Option %#x not found", Type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
__no_sanitize("alignment") void DHCP::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
UNUSED(Length);
|
||||
DHCPHeader *Packet = (DHCPHeader *)Data;
|
||||
uint8_t *MessageType = (uint8_t *)GetOption(Packet, DHCP_OPTION_MESSAGE_TYPE);
|
||||
__no_sanitize("alignment") void DHCP::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
UNUSED(Length);
|
||||
DHCPHeader *Packet = (DHCPHeader *)Data;
|
||||
uint8_t *MessageType = (uint8_t *)GetOption(Packet, DHCP_OPTION_MESSAGE_TYPE);
|
||||
|
||||
switch (*MessageType)
|
||||
{
|
||||
case DHCP_OPTION_TIME_OFFSET:
|
||||
{
|
||||
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.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:
|
||||
warn("Received unknown message type %#x", *MessageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (*MessageType)
|
||||
{
|
||||
case DHCP_OPTION_TIME_OFFSET:
|
||||
{
|
||||
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.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:
|
||||
warn("Received unknown message type %#x", *MessageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,14 @@
|
||||
|
||||
namespace NetworkDNS
|
||||
{
|
||||
DNS::DNS(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
debug("DNS interface %#lx created.", this);
|
||||
this->UDPSocket = Socket;
|
||||
}
|
||||
DNS::DNS(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
debug("DNS interface %#lx created.", this);
|
||||
this->UDPSocket = Socket;
|
||||
}
|
||||
|
||||
DNS::~DNS()
|
||||
{
|
||||
debug("DNS interface %#lx destroyed.", this);
|
||||
}
|
||||
DNS::~DNS()
|
||||
{
|
||||
debug("DNS interface %#lx destroyed.", this);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
/* conversion from ‘uint48_t’ {aka ‘long unsigned int’} to ‘long unsigned int:48’ may change value */
|
||||
/* conversion from 'uint48_t' {aka 'long unsigned int'} to 'long unsigned int:48' may change value */
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
|
||||
namespace NetworkEthernet
|
||||
@ -77,7 +77,7 @@ namespace NetworkEthernet
|
||||
|
||||
/* Byte-swapped little-endian */
|
||||
if (b48(Packet->Header.DestinationMAC) == 0xFFFFFFFFFFFF ||
|
||||
/* Byte-swapped Module interface has little-endian order */
|
||||
/* 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) */
|
||||
{
|
||||
|
@ -23,55 +23,55 @@
|
||||
|
||||
namespace NetworkICMPv4
|
||||
{
|
||||
ICMPv4::ICMPv4(NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
debug("ICMPv4 interface %#lx created.", this);
|
||||
this->Interface = Interface;
|
||||
}
|
||||
ICMPv4::ICMPv4(NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
debug("ICMPv4 interface %#lx created.", this);
|
||||
this->Interface = Interface;
|
||||
}
|
||||
|
||||
ICMPv4::~ICMPv4()
|
||||
{
|
||||
debug("ICMPv4 interface %#lx destroyed.", this);
|
||||
}
|
||||
ICMPv4::~ICMPv4()
|
||||
{
|
||||
debug("ICMPv4 interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
void ICMPv4::Send(/* ???? */)
|
||||
{
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
void ICMPv4::Send(/* ???? */)
|
||||
{
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
|
||||
void ICMPv4::Receive(ICMPPacket *Packet)
|
||||
{
|
||||
if (Packet->Header.Type == ICMPv4Type::TYPE_ECHO)
|
||||
{
|
||||
// TODO: This probably doesn't work
|
||||
netdbg("Echo Request");
|
||||
Packet->Header.Type = ICMPv4Type::TYPE_ECHO_REPLY;
|
||||
Packet->Header.Code = 0x0;
|
||||
Packet->Header.Checksum = CalculateChecksum((uint16_t *)Packet, sizeof(ICMPHeader));
|
||||
NIManager->Send(this->Interface, (uint8_t *)Packet, sizeof(ICMPHeader) + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Unknown type %d", Packet->Header.Type);
|
||||
}
|
||||
}
|
||||
void ICMPv4::Receive(ICMPPacket *Packet)
|
||||
{
|
||||
if (Packet->Header.Type == ICMPv4Type::TYPE_ECHO)
|
||||
{
|
||||
// TODO: This probably doesn't work
|
||||
netdbg("Echo Request");
|
||||
Packet->Header.Type = ICMPv4Type::TYPE_ECHO_REPLY;
|
||||
Packet->Header.Code = 0x0;
|
||||
Packet->Header.Checksum = CalculateChecksum((uint16_t *)Packet, sizeof(ICMPHeader));
|
||||
NIManager->Send(this->Interface, (uint8_t *)Packet, sizeof(ICMPHeader) + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
netdbg("Unknown type %d", Packet->Header.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace NetworkICMPv6
|
||||
{
|
||||
ICMPv6::ICMPv6(NetworkInterfaceManager::DeviceInterface *Interface) { this->Interface = Interface; }
|
||||
ICMPv6::~ICMPv6() {}
|
||||
ICMPv6::ICMPv6(NetworkInterfaceManager::DeviceInterface *Interface) { this->Interface = Interface; }
|
||||
ICMPv6::~ICMPv6() {}
|
||||
|
||||
void ICMPv6::Send(uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
void ICMPv6::Send(uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
|
||||
void ICMPv6::Receive(uint8_t *Data)
|
||||
{
|
||||
UNUSED(Data);
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
void ICMPv6::Receive(uint8_t *Data)
|
||||
{
|
||||
UNUSED(Data);
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
}
|
||||
|
196
network/ip.cpp
196
network/ip.cpp
@ -22,120 +22,120 @@
|
||||
|
||||
namespace NetworkIPv4
|
||||
{
|
||||
IPv4::IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_IPV4)
|
||||
{
|
||||
debug("IPv4 interface %#lx created.", this);
|
||||
this->ARP = ARP;
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
IPv4::IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_IPV4)
|
||||
{
|
||||
debug("IPv4 interface %#lx created.", this);
|
||||
this->ARP = ARP;
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
|
||||
IPv4::~IPv4()
|
||||
{
|
||||
debug("IPv4 interface %#lx destroyed.", this);
|
||||
}
|
||||
IPv4::~IPv4()
|
||||
{
|
||||
debug("IPv4 interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
void IPv4::Send(uint8_t *Data, size_t Length, uint8_t Protocol, InternetProtocol DestinationIP)
|
||||
{
|
||||
netdbg("Sending %ld bytes to %s", Length, DestinationIP.v4.ToStringLittleEndian());
|
||||
IPv4Packet *Packet = (IPv4Packet *)kmalloc(Length + sizeof(IPv4Header));
|
||||
void IPv4::Send(uint8_t *Data, size_t Length, uint8_t Protocol, InternetProtocol DestinationIP)
|
||||
{
|
||||
netdbg("Sending %ld bytes to %s", Length, DestinationIP.v4.ToStringLittleEndian());
|
||||
IPv4Packet *Packet = (IPv4Packet *)kmalloc(Length + sizeof(IPv4Header));
|
||||
|
||||
/* 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 = s_cst(uint16_t, Length + sizeof(IPv4Header));
|
||||
Packet->Header.TotalLength = s_cst(uint16_t, ((Packet->Header.TotalLength & 0xFF00) >> 8) | ((Packet->Header.TotalLength & 0x00FF) << 8));
|
||||
/* 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 = s_cst(uint16_t, Length + sizeof(IPv4Header));
|
||||
Packet->Header.TotalLength = s_cst(uint16_t, ((Packet->Header.TotalLength & 0xFF00) >> 8) | ((Packet->Header.TotalLength & 0x00FF) << 8));
|
||||
|
||||
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));
|
||||
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);
|
||||
InternetProtocol DestinationRoute = DestinationIP;
|
||||
if ((DestinationIP.v4.ToHex() & SubNetworkMaskIP.v4.ToHex()) != (b32(Packet->Header.SourceIP) & SubNetworkMaskIP.v4.ToHex()))
|
||||
DestinationRoute = SubNetworkMaskIP;
|
||||
memcpy(Packet->Data, Data, Length);
|
||||
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));
|
||||
kfree(Packet);
|
||||
}
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ARP->Resolve(DestinationRoute)), this->GetFrameType(), (uint8_t *)Packet, Length + sizeof(IPv4Header));
|
||||
kfree(Packet);
|
||||
}
|
||||
|
||||
std::vector<IPv4Events *> RegisteredEvents;
|
||||
std::vector<IPv4Events *> RegisteredEvents;
|
||||
|
||||
__no_sanitize("alignment") bool IPv4::OnEthernetPacketReceived(uint8_t *Data, size_t Length)
|
||||
{
|
||||
IPv4Packet *Packet = (IPv4Packet *)Data;
|
||||
netdbg("Received %d bytes [Protocol %ld]", Length, Packet->Header.Protocol);
|
||||
if (Length < sizeof(IPv4Header))
|
||||
{
|
||||
warn("Packet too short");
|
||||
return false;
|
||||
}
|
||||
__no_sanitize("alignment") bool IPv4::OnEthernetPacketReceived(uint8_t *Data, size_t Length)
|
||||
{
|
||||
IPv4Packet *Packet = (IPv4Packet *)Data;
|
||||
netdbg("Received %d bytes [Protocol %ld]", Length, Packet->Header.Protocol);
|
||||
if (Length < sizeof(IPv4Header))
|
||||
{
|
||||
warn("Packet too short");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Reply = false;
|
||||
bool Reply = false;
|
||||
|
||||
if (b32(Packet->Header.DestinationIP) == Ethernet->GetInterface()->IP.v4.ToHex() || b32(Packet->Header.DestinationIP) == 0xFFFFFFFF || Ethernet->GetInterface()->IP.v4.ToHex() == 0)
|
||||
{
|
||||
size_t TotalLength = Packet->Header.TotalLength;
|
||||
if (TotalLength > Length)
|
||||
TotalLength = Length;
|
||||
if (b32(Packet->Header.DestinationIP) == Ethernet->GetInterface()->IP.v4.ToHex() || b32(Packet->Header.DestinationIP) == 0xFFFFFFFF || Ethernet->GetInterface()->IP.v4.ToHex() == 0)
|
||||
{
|
||||
size_t TotalLength = Packet->Header.TotalLength;
|
||||
if (TotalLength > Length)
|
||||
TotalLength = Length;
|
||||
|
||||
foreach (auto Event in RegisteredEvents)
|
||||
if (Packet->Header.Protocol == Event->GetProtocol())
|
||||
{
|
||||
InternetProtocol SourceIP;
|
||||
InternetProtocol DestinationIP;
|
||||
foreach (auto Event in RegisteredEvents)
|
||||
if (Packet->Header.Protocol == Event->GetProtocol())
|
||||
{
|
||||
InternetProtocol SourceIP;
|
||||
InternetProtocol DestinationIP;
|
||||
|
||||
SourceIP.v4 = SourceIP.v4.FromHex(b32(Packet->Header.SourceIP));
|
||||
DestinationIP.v4 = DestinationIP.v4.FromHex(b32(Packet->Header.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 (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)
|
||||
{
|
||||
uint32_t SwapIP = Packet->Header.DestinationIP;
|
||||
Packet->Header.DestinationIP = Packet->Header.SourceIP;
|
||||
Packet->Header.SourceIP = SwapIP;
|
||||
Packet->Header.TimeToLive = 0x40;
|
||||
Packet->Header.HeaderChecksum = 0x0;
|
||||
Packet->Header.HeaderChecksum = CalculateChecksum((uint16_t *)Data, 4 * Packet->Header.TotalLength);
|
||||
NIManager->Send(Ethernet->GetInterface(), (uint8_t *)Data, Length);
|
||||
}
|
||||
return Reply;
|
||||
}
|
||||
if (Reply)
|
||||
{
|
||||
uint32_t SwapIP = Packet->Header.DestinationIP;
|
||||
Packet->Header.DestinationIP = Packet->Header.SourceIP;
|
||||
Packet->Header.SourceIP = SwapIP;
|
||||
Packet->Header.TimeToLive = 0x40;
|
||||
Packet->Header.HeaderChecksum = 0x0;
|
||||
Packet->Header.HeaderChecksum = CalculateChecksum((uint16_t *)Data, 4 * Packet->Header.TotalLength);
|
||||
NIManager->Send(Ethernet->GetInterface(), (uint8_t *)Data, Length);
|
||||
}
|
||||
return Reply;
|
||||
}
|
||||
|
||||
IPv4Events::IPv4Events(IPv4Protocols Protocol)
|
||||
{
|
||||
this->Protocol = (uint8_t)Protocol;
|
||||
RegisteredEvents.push_back(this);
|
||||
}
|
||||
IPv4Events::IPv4Events(IPv4Protocols Protocol)
|
||||
{
|
||||
this->Protocol = (uint8_t)Protocol;
|
||||
RegisteredEvents.push_back(this);
|
||||
}
|
||||
|
||||
IPv4Events::~IPv4Events()
|
||||
{
|
||||
forItr(itr, RegisteredEvents)
|
||||
{
|
||||
if (*itr == this)
|
||||
{
|
||||
RegisteredEvents.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
IPv4Events::~IPv4Events()
|
||||
{
|
||||
forItr(itr, RegisteredEvents)
|
||||
{
|
||||
if (*itr == this)
|
||||
{
|
||||
RegisteredEvents.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace NetworkIPv6
|
||||
|
@ -33,64 +33,64 @@ NewLock(netdbg_lock);
|
||||
|
||||
namespace NetDbg
|
||||
{
|
||||
class NETWORK_DEBUG : public NetworkInterfaceManager::Events
|
||||
{
|
||||
public:
|
||||
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, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
class NETWORK_DEBUG : public NetworkInterfaceManager::Events
|
||||
{
|
||||
public:
|
||||
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, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
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];
|
||||
unsigned long Iterate;
|
||||
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];
|
||||
unsigned long Iterate;
|
||||
|
||||
if (Description != nullptr)
|
||||
WriteRaw("%s:\n", Description);
|
||||
if (Description != nullptr)
|
||||
WriteRaw("%s:\n", Description);
|
||||
|
||||
for (Iterate = 0; Iterate < Length; Iterate++)
|
||||
{
|
||||
if ((Iterate % 16) == 0)
|
||||
{
|
||||
if (Iterate != 0)
|
||||
WriteRaw(" %s\n", Buffer);
|
||||
WriteRaw(" %04x ", Iterate);
|
||||
}
|
||||
for (Iterate = 0; Iterate < Length; Iterate++)
|
||||
{
|
||||
if ((Iterate % 16) == 0)
|
||||
{
|
||||
if (Iterate != 0)
|
||||
WriteRaw(" %s\n", Buffer);
|
||||
WriteRaw(" %04x ", Iterate);
|
||||
}
|
||||
|
||||
WriteRaw(" %02x", AddressChar[Iterate]);
|
||||
WriteRaw(" %02x", AddressChar[Iterate]);
|
||||
|
||||
if ((AddressChar[Iterate] < 0x20) || (AddressChar[Iterate] > 0x7e))
|
||||
Buffer[Iterate % 16] = '.';
|
||||
else
|
||||
Buffer[Iterate % 16] = AddressChar[Iterate];
|
||||
if ((AddressChar[Iterate] < 0x20) || (AddressChar[Iterate] > 0x7e))
|
||||
Buffer[Iterate % 16] = '.';
|
||||
else
|
||||
Buffer[Iterate % 16] = AddressChar[Iterate];
|
||||
|
||||
Buffer[(Iterate % 16) + 1] = '\0';
|
||||
}
|
||||
Buffer[(Iterate % 16) + 1] = '\0';
|
||||
}
|
||||
|
||||
while ((Iterate % 16) != 0)
|
||||
{
|
||||
WriteRaw(" ");
|
||||
Iterate++;
|
||||
}
|
||||
while ((Iterate % 16) != 0)
|
||||
{
|
||||
WriteRaw(" ");
|
||||
Iterate++;
|
||||
}
|
||||
|
||||
WriteRaw(" %s\n", Buffer);
|
||||
WriteRaw("-------------------------------------------------------------------------\n");
|
||||
}
|
||||
WriteRaw(" %s\n", Buffer);
|
||||
WriteRaw("-------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
NETWORK_DEBUG() : NetworkInterfaceManager::Events(nullptr) { netdbg("NetworkDebugger initialized."); }
|
||||
~NETWORK_DEBUG() { netdbg("NetworkDebugger destroyed."); }
|
||||
void OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length) { DumpData("Received", Data, Length); }
|
||||
void OnInterfaceSent(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length) { DumpData("Sent", Data, Length); }
|
||||
};
|
||||
NETWORK_DEBUG() : NetworkInterfaceManager::Events(nullptr) { netdbg("NetworkDebugger initialized."); }
|
||||
~NETWORK_DEBUG() { netdbg("NetworkDebugger destroyed."); }
|
||||
void OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length) { DumpData("Received", Data, Length); }
|
||||
void OnInterfaceSent(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, size_t Length) { DumpData("Sent", Data, Length); }
|
||||
};
|
||||
}
|
||||
|
||||
NetDbg::NETWORK_DEBUG *N;
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
#include "../mapi.hpp"
|
||||
#include "../Fex.hpp"
|
||||
|
||||
/* FIXME: The functions MUST have little endian parameters and return values. */
|
||||
|
||||
@ -39,14 +37,15 @@ namespace NetworkInterfaceManager
|
||||
NetworkInterface::NetworkInterface()
|
||||
{
|
||||
this->vma = new Memory::VirtualMemoryArea(nullptr);
|
||||
if (ModuleManager->GetModules().size() > 0)
|
||||
{
|
||||
foreach (auto Module in ModuleManager->GetModules())
|
||||
if (((FexExtended *)Module.ExtendedHeaderAddress)->Module.Type == FexModuleType::FexModuleType_Network)
|
||||
this->FetchNetworkCards(Module.modUniqueID);
|
||||
}
|
||||
else
|
||||
KPrint("\eE85230No network drivers found! Cannot fetch network cards!");
|
||||
/* KernelCallback */
|
||||
// if (DriverManager->GetModules().size() > 0)
|
||||
// {
|
||||
// foreach (auto Driver in DriverManager->GetModules())
|
||||
// if (((FexExtended *)Driver.ExtendedHeaderAddress)->Driver.Type == FexDriverType::FexDriverType_Network)
|
||||
// this->FetchNetworkCards(Driver.modUniqueID);
|
||||
// }
|
||||
// else
|
||||
// KPrint("\eE85230No network drivers found! Cannot fetch network cards!");
|
||||
|
||||
DbgNetwork();
|
||||
}
|
||||
@ -70,14 +69,15 @@ namespace NetworkInterfaceManager
|
||||
|
||||
void NetworkInterface::FetchNetworkCards(unsigned long modUniqueID)
|
||||
{
|
||||
KernelCallback cb{};
|
||||
cb.Reason = QueryReason;
|
||||
ModuleManager->IOCB(modUniqueID, &cb);
|
||||
// KernelCallback cb{};
|
||||
// cb.Reason = QueryReason;
|
||||
// DriverManager->IOCB(modUniqueID, &cb);
|
||||
/* KernelCallback */
|
||||
|
||||
DeviceInterface *Iface = (DeviceInterface *)vma->RequestPages(TO_PAGES(sizeof(DeviceInterface) + 1));
|
||||
strcpy(Iface->Name, cb.NetworkCallback.Fetch.Name);
|
||||
// strcpy(Iface->Name, cb.NetworkCallback.Fetch.Name);
|
||||
Iface->ID = this->CardIDs++;
|
||||
Iface->MAC.FromHex(cb.NetworkCallback.Fetch.MAC);
|
||||
// Iface->MAC.FromHex(cb.NetworkCallback.Fetch.MAC);
|
||||
Iface->DriverID = modUniqueID;
|
||||
Interfaces.push_back(Iface);
|
||||
|
||||
@ -98,62 +98,68 @@ namespace NetworkInterfaceManager
|
||||
thisThread->SetPriority(Tasking::TaskPriority::Critical);
|
||||
DeviceInterface *DefaultDevice = nullptr;
|
||||
foreach (auto inf in Interfaces)
|
||||
{
|
||||
if (inf)
|
||||
{
|
||||
DefaultDevice = inf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DefaultDevice)
|
||||
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(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);
|
||||
udp->Bind(DHCP_Socket, dhcp);
|
||||
dhcp->Request();
|
||||
|
||||
DefaultDevice->IP.v4.FromHex(dhcp->IP.v4.ToHex());
|
||||
ipv4->SubNetworkMaskIP = dhcp->SubNetworkMask;
|
||||
ipv4->GatewayIP = dhcp->Gateway;
|
||||
arp->Broadcast(dhcp->Gateway);
|
||||
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);
|
||||
|
||||
/* TODO: This is a quick workaround we need DNS resolver asap.
|
||||
|
||||
https://tf.nist.gov/tf-cgi/servers.cgi
|
||||
https://www.ntppool.org
|
||||
|
||||
- 0.ro.pool.ntp.org ( {86, 127, 71, 168} )
|
||||
- time-a-g.nist.gov ( {129, 6, 15, 28} )
|
||||
*/
|
||||
// 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", time.Counter,
|
||||
// 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 */
|
||||
error("No network device found!");
|
||||
KPrint("\eE85230No network device found!");
|
||||
thisThread->SetPriority(Tasking::TaskPriority::Idle);
|
||||
CPU::Halt(true);
|
||||
}
|
||||
|
||||
KPrint("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(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);
|
||||
udp->Bind(DHCP_Socket, dhcp);
|
||||
dhcp->Request();
|
||||
|
||||
DefaultDevice->IP.v4.FromHex(dhcp->IP.v4.ToHex());
|
||||
ipv4->SubNetworkMaskIP = dhcp->SubNetworkMask;
|
||||
ipv4->GatewayIP = dhcp->Gateway;
|
||||
arp->Broadcast(dhcp->Gateway);
|
||||
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);
|
||||
|
||||
/* TODO: This is a quick workaround we need DNS resolver asap.
|
||||
|
||||
https://tf.nist.gov/tf-cgi/servers.cgi
|
||||
https://www.ntppool.org
|
||||
|
||||
- 0.ro.pool.ntp.org ( {86, 127, 71, 168} )
|
||||
- time-a-g.nist.gov ( {129, 6, 15, 28} )
|
||||
*/
|
||||
// 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", time.Counter,
|
||||
// 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 */
|
||||
|
||||
thisThread->SetPriority(Tasking::TaskPriority::Idle);
|
||||
CPU::Halt(true);
|
||||
}
|
||||
@ -190,11 +196,12 @@ namespace NetworkInterfaceManager
|
||||
void *DataToBeSent = vma->RequestPages(TO_PAGES(Length + 1));
|
||||
memcpy(DataToBeSent, Data, Length);
|
||||
|
||||
KernelCallback cb{};
|
||||
cb.Reason = SendReason;
|
||||
cb.NetworkCallback.Send.Data = (uint8_t *)DataToBeSent;
|
||||
cb.NetworkCallback.Send.Length = Length;
|
||||
ModuleManager->IOCB(Interface->DriverID, &cb);
|
||||
/* KernelCallback */
|
||||
// KernelCallback cb{};
|
||||
// cb.Reason = SendReason;
|
||||
// cb.NetworkCallback.Send.Data = (uint8_t *)DataToBeSent;
|
||||
// cb.NetworkCallback.Send.Length = Length;
|
||||
// DriverManager->IOCB(Interface->DriverID, &cb);
|
||||
|
||||
vma->FreePages(DataToBeSent, TO_PAGES(Length + 1));
|
||||
foreach (auto ev in RegisteredEvents)
|
||||
|
@ -22,54 +22,54 @@
|
||||
|
||||
namespace NetworkNTP
|
||||
{
|
||||
void NTP::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
UNUSED(Length);
|
||||
this->NTPPacket = *(NTPHeader *)Data;
|
||||
this->TimeReceived = true;
|
||||
netdbg("Received UDP packet for NTP.");
|
||||
}
|
||||
void NTP::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
UNUSED(Length);
|
||||
this->NTPPacket = *(NTPHeader *)Data;
|
||||
this->TimeReceived = true;
|
||||
netdbg("Received UDP packet for NTP.");
|
||||
}
|
||||
|
||||
NTP::NTP(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
debug("NTP interface %#lx created.", this);
|
||||
this->UDPSocket = Socket;
|
||||
}
|
||||
NTP::NTP(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
debug("NTP interface %#lx created.", this);
|
||||
this->UDPSocket = Socket;
|
||||
}
|
||||
|
||||
NTP::~NTP()
|
||||
{
|
||||
debug("NTP interface %#lx destroyed.", this);
|
||||
}
|
||||
NTP::~NTP()
|
||||
{
|
||||
debug("NTP interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
int NTP::ReadTime()
|
||||
{
|
||||
netdbg("Requesting time");
|
||||
this->TimeReceived = false;
|
||||
int NTP::ReadTime()
|
||||
{
|
||||
netdbg("Requesting time");
|
||||
this->TimeReceived = false;
|
||||
|
||||
NTPHeader ReqPacket; // This may require physical 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));
|
||||
NTPHeader ReqPacket; // This may require physical 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);
|
||||
}
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 20;
|
||||
while (!this->TimeReceived)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
netdbg("Still waiting...");
|
||||
TaskManager->Sleep(1000);
|
||||
}
|
||||
|
||||
uint64_t UnixTimestamp = (b32(this->NTPPacket.TransmitTimestamp[0])) - 2208988800;
|
||||
debug("Unix time: %d", UnixTimestamp);
|
||||
return s_cst(int, UnixTimestamp);
|
||||
}
|
||||
uint64_t UnixTimestamp = (b32(this->NTPPacket.TransmitTimestamp[0])) - 2208988800;
|
||||
debug("Unix time: %d", UnixTimestamp);
|
||||
return s_cst(int, UnixTimestamp);
|
||||
}
|
||||
}
|
||||
|
198
network/udp.cpp
198
network/udp.cpp
@ -22,124 +22,124 @@
|
||||
|
||||
namespace NetworkUDP
|
||||
{
|
||||
struct EventInfo
|
||||
{
|
||||
Socket *UDPSocket;
|
||||
uint16_t Port;
|
||||
};
|
||||
std::vector<EventInfo> RegisteredEvents;
|
||||
struct EventInfo
|
||||
{
|
||||
Socket *UDPSocket;
|
||||
uint16_t Port;
|
||||
};
|
||||
std::vector<EventInfo> RegisteredEvents;
|
||||
|
||||
UDPEvents::UDPEvents() {}
|
||||
UDPEvents::UDPEvents() {}
|
||||
|
||||
UDPEvents::~UDPEvents() {}
|
||||
UDPEvents::~UDPEvents() {}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
UDP::UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface) : NetworkIPv4::IPv4Events(NetworkIPv4::PROTOCOL_UDP)
|
||||
{
|
||||
debug("UDP interface %#lx created.", this);
|
||||
this->ipv4 = ipv4;
|
||||
this->Interface = Interface;
|
||||
}
|
||||
UDP::UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface) : NetworkIPv4::IPv4Events(NetworkIPv4::PROTOCOL_UDP)
|
||||
{
|
||||
debug("UDP interface %#lx created.", this);
|
||||
this->ipv4 = ipv4;
|
||||
this->Interface = Interface;
|
||||
}
|
||||
|
||||
UDP::~UDP()
|
||||
{
|
||||
debug("UDP interface %#lx destroyed.", this);
|
||||
}
|
||||
UDP::~UDP()
|
||||
{
|
||||
debug("UDP interface %#lx destroyed.", this);
|
||||
}
|
||||
|
||||
uint16_t UsablePort = 0x200;
|
||||
uint16_t UsablePort = 0x200;
|
||||
|
||||
Socket *UDP::Connect(InternetProtocol IP, uint16_t 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 = b16(socket->LocalPort);
|
||||
socket->RemotePort = b16(socket->RemotePort);
|
||||
RegisteredEvents.push_back({.UDPSocket = socket, .Port = socket->LocalPort});
|
||||
return socket;
|
||||
}
|
||||
Socket *UDP::Connect(InternetProtocol IP, uint16_t 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 = b16(socket->LocalPort);
|
||||
socket->RemotePort = b16(socket->RemotePort);
|
||||
RegisteredEvents.push_back({.UDPSocket = socket, .Port = socket->LocalPort});
|
||||
return socket;
|
||||
}
|
||||
|
||||
Socket *UDP::Listen(uint16_t Port)
|
||||
{
|
||||
UNUSED(Port);
|
||||
fixme("Not implemented.");
|
||||
return nullptr;
|
||||
}
|
||||
Socket *UDP::Listen(uint16_t Port)
|
||||
{
|
||||
UNUSED(Port);
|
||||
fixme("Not implemented.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UDP::Disconnect(Socket *Socket)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
fixme("Not implemented.");
|
||||
}
|
||||
void UDP::Disconnect(Socket *Socket)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
fixme("Not implemented.");
|
||||
}
|
||||
|
||||
void UDP::Send(Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Sending %d bytes to %s", Length, Socket->RemoteIP.v4.ToStringLittleEndian(), Socket->RemotePort);
|
||||
uint16_t TotalLength = s_cst(uint16_t, Length + sizeof(UDPHeader));
|
||||
UDPPacket *packet = (UDPPacket *)kmalloc(TotalLength);
|
||||
packet->Header.SourcePort = Socket->LocalPort;
|
||||
packet->Header.DestinationPort = Socket->RemotePort;
|
||||
packet->Header.Length = b16(TotalLength);
|
||||
memcpy(packet->Data, Data, Length);
|
||||
packet->Header.Checksum = 0; // I totally should do this. Some devices may require it.
|
||||
// packet->Header.Checksum = CalculateChecksum((uint16_t *)packet, TotalLength);
|
||||
this->ipv4->Send((uint8_t *)packet, TotalLength, 0x11, Socket->RemoteIP);
|
||||
kfree(packet);
|
||||
}
|
||||
void UDP::Send(Socket *Socket, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Sending %d bytes to %s", Length, Socket->RemoteIP.v4.ToStringLittleEndian(), Socket->RemotePort);
|
||||
uint16_t TotalLength = s_cst(uint16_t, Length + sizeof(UDPHeader));
|
||||
UDPPacket *packet = (UDPPacket *)kmalloc(TotalLength);
|
||||
packet->Header.SourcePort = Socket->LocalPort;
|
||||
packet->Header.DestinationPort = Socket->RemotePort;
|
||||
packet->Header.Length = b16(TotalLength);
|
||||
memcpy(packet->Data, Data, Length);
|
||||
packet->Header.Checksum = 0; // I totally should do this. Some devices may require it.
|
||||
// packet->Header.Checksum = CalculateChecksum((uint16_t *)packet, TotalLength);
|
||||
this->ipv4->Send((uint8_t *)packet, TotalLength, 0x11, Socket->RemoteIP);
|
||||
kfree(packet);
|
||||
}
|
||||
|
||||
void UDP::Bind(Socket *Socket, UDPEvents *EventHandler)
|
||||
{
|
||||
netdbg("Binding socket to %s", Socket->LocalIP.v4.ToStringLittleEndian(), Socket->LocalPort);
|
||||
Socket->EventHandler = EventHandler;
|
||||
}
|
||||
void UDP::Bind(Socket *Socket, UDPEvents *EventHandler)
|
||||
{
|
||||
netdbg("Binding socket to %s", Socket->LocalIP.v4.ToStringLittleEndian(), Socket->LocalPort);
|
||||
Socket->EventHandler = EventHandler;
|
||||
}
|
||||
|
||||
bool UDP::OnIPv4PacketReceived(InternetProtocol SourceIP, InternetProtocol DestinationIP, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Received %d bytes from %s", Length, SourceIP.v4.ToStringLittleEndian());
|
||||
if (Length < sizeof(UDPHeader))
|
||||
return false;
|
||||
bool UDP::OnIPv4PacketReceived(InternetProtocol SourceIP, InternetProtocol DestinationIP, uint8_t *Data, size_t Length)
|
||||
{
|
||||
netdbg("Received %d bytes from %s", Length, SourceIP.v4.ToStringLittleEndian());
|
||||
if (Length < sizeof(UDPHeader))
|
||||
return false;
|
||||
|
||||
UDPHeader *udp = (UDPHeader *)Data;
|
||||
UDPHeader *udp = (UDPHeader *)Data;
|
||||
|
||||
netdbg("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;
|
||||
Socket *GoodSocket = nullptr;
|
||||
|
||||
foreach (auto &var in RegisteredEvents)
|
||||
{
|
||||
netdbg("UDP->SKT[]: LP:%d | LIP:%s | RP:%d | RIP:%s | LST:%d",
|
||||
b16(var.UDPSocket->LocalPort),
|
||||
var.UDPSocket->LocalIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->RemotePort),
|
||||
var.UDPSocket->RemoteIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->Listening));
|
||||
if (var.UDPSocket->LocalPort == udp->DestinationPort &&
|
||||
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("E1");
|
||||
return true;
|
||||
}
|
||||
foreach (auto &var in RegisteredEvents)
|
||||
{
|
||||
netdbg("UDP->SKT[]: LP:%d | LIP:%s | RP:%d | RIP:%s | LST:%d",
|
||||
b16(var.UDPSocket->LocalPort),
|
||||
var.UDPSocket->LocalIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->RemotePort),
|
||||
var.UDPSocket->RemoteIP.v4.ToStringLittleEndian(),
|
||||
b16(var.UDPSocket->Listening));
|
||||
if (var.UDPSocket->LocalPort == udp->DestinationPort &&
|
||||
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("E1");
|
||||
return true;
|
||||
}
|
||||
|
||||
GoodSocket = var.UDPSocket;
|
||||
}
|
||||
if (GoodSocket)
|
||||
GoodSocket->EventHandler->OnUDPPacketReceived(GoodSocket, ((UDPPacket *)Data)->Data, Length);
|
||||
GoodSocket = var.UDPSocket;
|
||||
}
|
||||
if (GoodSocket)
|
||||
GoodSocket->EventHandler->OnUDPPacketReceived(GoodSocket, ((UDPPacket *)Data)->Data, Length);
|
||||
|
||||
netdbg("E0 (Success)");
|
||||
return false;
|
||||
}
|
||||
netdbg("E0 (Success)");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
Socket::Socket(UDP *_UDP) { this->SocketUDP = _UDP; }
|
||||
Socket::Socket(UDP *_UDP) { this->SocketUDP = _UDP; }
|
||||
|
||||
Socket::~Socket() {}
|
||||
Socket::~Socket() {}
|
||||
}
|
||||
|
Reference in New Issue
Block a user