mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
🎉Implemented networking🎉
This commit is contained in:
parent
0942fb4cd3
commit
ba425e59ca
@ -13,6 +13,7 @@
|
||||
|
||||
Driver::Driver *DriverManager = nullptr;
|
||||
Disk::Manager *DiskManager = nullptr;
|
||||
NetworkInterfaceManager::NetworkInterface *NIManager = nullptr;
|
||||
|
||||
void KernelMainThread()
|
||||
{
|
||||
@ -42,6 +43,11 @@ void KernelMainThread()
|
||||
else
|
||||
KPrint("\eE85230No disk drivers found! Cannot fetch disks!");
|
||||
|
||||
KPrint("Initializing Network Interface Manager...");
|
||||
NIManager = new NetworkInterfaceManager::NetworkInterface;
|
||||
KPrint("Starting Network Interface Manager...");
|
||||
NIManager->StartService();
|
||||
|
||||
KPrint("Setting up userspace...");
|
||||
|
||||
const char *envp[9] = {
|
||||
@ -82,6 +88,8 @@ Exit:
|
||||
|
||||
void KernelShutdownThread(bool Reboot)
|
||||
{
|
||||
delete NIManager;
|
||||
|
||||
if (DriverManager)
|
||||
DriverManager->UnloadAllDrivers();
|
||||
|
||||
|
193
Network/AddressResolutionProtocol.cpp
Normal file
193
Network/AddressResolutionProtocol.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
#include <net/arp.hpp>
|
||||
#include <debug.h>
|
||||
#include <smartptr.hpp>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkARP
|
||||
{
|
||||
DiscoveredAddress *ARP::ManageDA(DAType Type, InternetProtocol4 IP, MediaAccessControl MAC)
|
||||
{
|
||||
// TODO: Compare IPv6 too.
|
||||
switch (Type)
|
||||
{
|
||||
case DA_ADD:
|
||||
{
|
||||
DiscoveredAddress *tmp = new DiscoveredAddress;
|
||||
tmp->IP = IP;
|
||||
tmp->MAC = MAC;
|
||||
DiscoveredAddresses.push_back(tmp);
|
||||
return tmp;
|
||||
}
|
||||
case DA_DEL:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
if (DiscoveredAddresses[i]->IP == IP)
|
||||
{
|
||||
DiscoveredAddress *tmp = DiscoveredAddresses[i];
|
||||
delete tmp;
|
||||
DiscoveredAddresses.remove(i);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case DA_SEARCH:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
if (DiscoveredAddresses[i]->IP == IP)
|
||||
return DiscoveredAddresses[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
case DA_UPDATE:
|
||||
{
|
||||
for (size_t i = 0; i < DiscoveredAddresses.size(); i++)
|
||||
if (DiscoveredAddresses[i]->IP == IP)
|
||||
{
|
||||
DiscoveredAddresses[i]->MAC = MAC;
|
||||
return DiscoveredAddresses[i];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ARP::ARP(NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_ARP)
|
||||
{
|
||||
netdbg("Initializing.");
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
|
||||
ARP::~ARP()
|
||||
{
|
||||
}
|
||||
|
||||
MediaAccessControl InvalidMAC = {.Address = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
InternetProtocol4 InvalidIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
DiscoveredAddress InvalidRet = {.MAC = InvalidMAC, .IP = InvalidIP};
|
||||
|
||||
DiscoveredAddress *ARP::Search(InternetProtocol4 TargetIP)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDA(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]);
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
DiscoveredAddress *ARP::Update(InternetProtocol4 TargetIP, MediaAccessControl TargetMAC)
|
||||
{
|
||||
DiscoveredAddress *ret = ManageDA(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]);
|
||||
return &InvalidRet;
|
||||
}
|
||||
|
||||
uint48_t ARP::Resolve(InternetProtocol4 IP)
|
||||
{
|
||||
netdbg("Resolving %d.%d.%d.%d", IP.Address[3], IP.Address[2], IP.Address[1], IP.Address[0]);
|
||||
if (IP == 0xFFFFFFFF)
|
||||
return 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);
|
||||
|
||||
if (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
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();
|
||||
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;
|
||||
debug("Waiting for response");
|
||||
while (ret == 0xFFFFFFFFFFFF)
|
||||
{
|
||||
ret = this->Search(IP)->MAC.ToHex();
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
return 0;
|
||||
}
|
||||
TaskManager->Sleep(5000);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ARP::Broadcast(InternetProtocol4 IP)
|
||||
{
|
||||
netdbg("Sending broadcast");
|
||||
uint64_t ResolvedMAC = this->Resolve(IP);
|
||||
ARPHeader *Header = new ARPHeader;
|
||||
Header->HardwareType = b16(ARPHardwareType::HTYPE_ETHERNET);
|
||||
Header->ProtocolType = b16(NetworkEthernet::FrameType::TYPE_IPV4);
|
||||
Header->HardwareSize = b8(0x6);
|
||||
Header->ProtocolSize = b8(0x4);
|
||||
Header->Operation = b16(ARPOperation::REQUEST);
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.ToHex());
|
||||
Header->TargetMAC = ResolvedMAC;
|
||||
Header->TargetIP = IP.ToHex();
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ResolvedMAC), NetworkEthernet::FrameType::TYPE_ARP, (uint8_t *)Header, sizeof(ARPHeader));
|
||||
delete Header;
|
||||
}
|
||||
|
||||
bool ARP::OnEthernetPacketReceived(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("Received packet");
|
||||
ARPHeader *Header = (ARPHeader *)Data;
|
||||
|
||||
InternetProtocol4 SenderIPv4;
|
||||
SenderIPv4.FromHex(b32(Header->SenderIP));
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ManageDA(DA_SEARCH, InternetProtocol4().FromHex(Header->SenderIP), MediaAccessControl().FromHex(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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
Header->SenderMAC = b48(Ethernet->GetInterface()->MAC.ToHex());
|
||||
Header->SenderIP = b32(Ethernet->GetInterface()->IP.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]);
|
||||
break;
|
||||
case ARPOperation::REPLY:
|
||||
fixme("Received reply from %d.%d.%d.%d", SenderIPv4.Address[0], SenderIPv4.Address[1], SenderIPv4.Address[2], SenderIPv4.Address[3]);
|
||||
break;
|
||||
default:
|
||||
warn("Invalid operation (%d)", Header->Operation);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
14
Network/Checksum.cpp
Normal file
14
Network/Checksum.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include <net/net.hpp>
|
||||
|
||||
uint16_t CalculateChecksum(uint16_t *Data, uint64_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));
|
||||
}
|
143
Network/DynamicHostConfigurationProtocol.cpp
Normal file
143
Network/DynamicHostConfigurationProtocol.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include <net/dhcp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkDHCP
|
||||
{
|
||||
DHCP::DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface)
|
||||
{
|
||||
netdbg("Initializing.");
|
||||
this->UDPSocket = Socket;
|
||||
this->Interface = Interface;
|
||||
Socket->LocalPort = b16(68);
|
||||
}
|
||||
|
||||
DHCP::~DHCP()
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
*(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_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++) = 1 + strlen(HostName);
|
||||
memcpy(Ptr, HostName, strlen(HostName));
|
||||
Ptr += strlen(HostName);
|
||||
|
||||
*(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_END;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
debug("Waiting for response...");
|
||||
int RequestTimeout = 10;
|
||||
while (!Received)
|
||||
{
|
||||
if (--RequestTimeout == 0)
|
||||
{
|
||||
warn("Request timeout.");
|
||||
break;
|
||||
}
|
||||
TaskManager->Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
void DHCP::Request(InternetProtocol4 IP)
|
||||
{
|
||||
netdbg("Requesting IP address %d.%d.%d.%d", IP.Address[0], IP.Address[1], IP.Address[2], IP.Address[3]);
|
||||
DHCPHeader packet;
|
||||
memset(&packet, 0, sizeof(DHCPHeader));
|
||||
|
||||
CreatePacket(&packet, DHCP_MESSAGE_TYPE_REQUEST, IP.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::OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
DHCPHeader *Packet = (DHCPHeader *)Data;
|
||||
uint8_t *MessageType = (uint8_t *)GetOption(Packet, DHCP_OPTION_MESSAGE_TYPE);
|
||||
|
||||
switch (*MessageType)
|
||||
{
|
||||
case DHCP_OPTION_TIME_OFFSET:
|
||||
this->Request(InternetProtocol4().FromHex(Packet->YourIP));
|
||||
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->Received = true;
|
||||
break;
|
||||
default:
|
||||
netdbg("Received unknown message type %#x", *MessageType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
116
Network/Ethernet.cpp
Normal file
116
Network/Ethernet.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include <net/eth.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
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;
|
||||
uint16_t Type;
|
||||
};
|
||||
|
||||
Vector<EthernetEventHelperStruct> RegisteredEvents;
|
||||
|
||||
void Ethernet::Receive(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
EthernetPacket *Packet = (EthernetPacket *)Data;
|
||||
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));
|
||||
|
||||
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);
|
||||
break;
|
||||
case TYPE_ARP:
|
||||
foreach (auto var in RegisteredEvents)
|
||||
if (var.Type == TYPE_ARP)
|
||||
Reply = var.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);
|
||||
break;
|
||||
case TYPE_IPV6:
|
||||
foreach (auto var in RegisteredEvents)
|
||||
if (var.Type == TYPE_IPV6)
|
||||
Reply = var.Ptr->OnEthernetPacketReceived((uint8_t *)Packet->Data, Length);
|
||||
break;
|
||||
default:
|
||||
warn("ETH: Unknown packet type %#lx", Packet->Header.Type);
|
||||
break;
|
||||
}
|
||||
if (Reply)
|
||||
{
|
||||
Packet->Header.DestinationMAC = Packet->Header.SourceMAC;
|
||||
Packet->Header.SourceMAC = b48(this->Interface->MAC.ToHex());
|
||||
}
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
void Ethernet::OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
if (Interface == this->Interface)
|
||||
this->Receive(Data, Length);
|
||||
}
|
||||
|
||||
EthernetEvents::EthernetEvents(FrameType Type)
|
||||
{
|
||||
FType = Type;
|
||||
RegisteredEvents.push_back({.Ptr = this, .Type = (uint16_t)Type});
|
||||
}
|
||||
|
||||
EthernetEvents::~EthernetEvents()
|
||||
{
|
||||
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i].Ptr == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
42
Network/InternetControlMessageProtocol.cpp
Normal file
42
Network/InternetControlMessageProtocol.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <net/icmpv4.hpp>
|
||||
#include <net/icmpv6.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkICMPv4
|
||||
{
|
||||
ICMPv4::ICMPv4(NetworkInterfaceManager::DeviceInterface *Interface) { this->Interface = Interface; }
|
||||
ICMPv4::~ICMPv4() {}
|
||||
|
||||
void ICMPv4::Send(/* ???? */)
|
||||
{
|
||||
fixme("Unimplemented");
|
||||
}
|
||||
|
||||
void ICMPv4::Receive(ICMPPacket *Packet)
|
||||
{
|
||||
if (Packet->Header.Type == ICMPv4Type::TYPE_ECHO)
|
||||
{
|
||||
// TODO: This probably doesn't work
|
||||
netdbg("ICMPv4: 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("ICMPv4: Unknown type %d", Packet->Header.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace NetworkICMPv6
|
||||
{
|
||||
ICMPv6::ICMPv6(NetworkInterfaceManager::DeviceInterface *Interface) { this->Interface = Interface; }
|
||||
ICMPv6::~ICMPv6() {}
|
||||
|
||||
void ICMPv6::Send(uint8_t *Data, uint64_t Length) { fixme("Unimplemented"); }
|
||||
void ICMPv6::Receive(uint8_t *Data) { fixme("Unimplemented"); }
|
||||
}
|
108
Network/InternetProtocol.cpp
Normal file
108
Network/InternetProtocol.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include <net/ipv4.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkIPv4
|
||||
{
|
||||
IPv4::IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet) : NetworkEthernet::EthernetEvents(NetworkEthernet::TYPE_IPV4)
|
||||
{
|
||||
netdbg("IPv4: Initializing.");
|
||||
this->ARP = ARP;
|
||||
this->Ethernet = Ethernet;
|
||||
}
|
||||
|
||||
IPv4::~IPv4()
|
||||
{
|
||||
}
|
||||
|
||||
void IPv4::Send(uint8_t *Data, uint64_t Length, uint8_t Protocol, InternetProtocol4 DestinationIP)
|
||||
{
|
||||
netdbg("IPv4: Sending %ld bytes to %d.%d.%d.%d", Length, DestinationIP.Address[0], DestinationIP.Address[1], DestinationIP.Address[2], DestinationIP.Address[3]);
|
||||
IPv4Packet *Packet = (IPv4Packet *)kmalloc(Length + sizeof(IPv4Header));
|
||||
|
||||
Packet->Header.Version = 4;
|
||||
Packet->Header.IHL = sizeof(IPv4Header) / 4;
|
||||
Packet->Header.TypeOfService = 0;
|
||||
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.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()))
|
||||
DestinationRoute = SubNetworkMaskIP;
|
||||
|
||||
Ethernet->Send(MediaAccessControl().FromHex(ARP->Resolve(DestinationRoute)), this->GetFrameType(), (uint8_t *)Packet, Length + sizeof(IPv4Header));
|
||||
kfree(Packet);
|
||||
}
|
||||
|
||||
Vector<IPv4Events *> RegisteredEvents;
|
||||
|
||||
bool IPv4::OnEthernetPacketReceived(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
IPv4Packet *Packet = (IPv4Packet *)Data;
|
||||
netdbg("IPv4: Received %d bytes [Protocol %ld]", Length, Packet->Header.Protocol);
|
||||
if (Length < sizeof(IPv4Header))
|
||||
{
|
||||
warn("IPv4: 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)
|
||||
{
|
||||
uint64_t TotalLength = Packet->Header.TotalLength;
|
||||
if (TotalLength > Length)
|
||||
TotalLength = Length;
|
||||
|
||||
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))
|
||||
Reply = true;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i] == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace NetworkIPv6
|
||||
{
|
||||
|
||||
}
|
182
Network/NetworkController.cpp
Normal file
182
Network/NetworkController.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include <net/nc.hpp>
|
||||
#include <net/eth.hpp>
|
||||
#include <net/arp.hpp>
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/dhcp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
#include "../DAPI.hpp"
|
||||
#include "../Fex.hpp"
|
||||
|
||||
namespace NetworkInterfaceManager
|
||||
{
|
||||
Vector<Events *> RegisteredEvents;
|
||||
|
||||
NetworkInterface::NetworkInterface()
|
||||
{
|
||||
mem = new Memory::MemMgr;
|
||||
if (DriverManager->GetDrivers().size() > 0)
|
||||
{
|
||||
foreach (auto Driver in DriverManager->GetDrivers())
|
||||
if (((FexExtended *)((uintptr_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Network)
|
||||
this->FetchNetworkCards(Driver->DriverUID);
|
||||
}
|
||||
else
|
||||
KPrint("\eE85230No network drivers found! Cannot fetch network cards!");
|
||||
|
||||
DbgNetwork();
|
||||
}
|
||||
|
||||
NetworkInterface::~NetworkInterface()
|
||||
{
|
||||
// Stop the network stack
|
||||
this->StopNetworkStack();
|
||||
|
||||
// Unregister all events
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
RegisteredEvents.remove(i);
|
||||
|
||||
// Delete all interfaces and their callbacks and free the memory
|
||||
delete mem;
|
||||
}
|
||||
|
||||
void NetworkInterface::FetchNetworkCards(unsigned long DriverUID)
|
||||
{
|
||||
KernelCallback *cb = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback)));
|
||||
memset(cb, 0, sizeof(KernelCallback));
|
||||
cb->Reason = FetchReason;
|
||||
DriverManager->IOCB(DriverUID, (void *)cb);
|
||||
|
||||
DeviceInterface *Iface = (DeviceInterface *)mem->RequestPages(TO_PAGES(sizeof(DeviceInterface)));
|
||||
strcpy(Iface->Name, cb->NetworkCallback.Fetch.Name);
|
||||
Iface->ID = this->CardIDs++;
|
||||
Iface->MAC.FromHex(cb->NetworkCallback.Fetch.MAC);
|
||||
Iface->DriverCallBackAddress = cb;
|
||||
Iface->DriverID = DriverUID;
|
||||
Interfaces.push_back(Iface);
|
||||
|
||||
foreach (auto var in RegisteredEvents)
|
||||
var->OnInterfaceAdded(Iface);
|
||||
|
||||
debug("Network Card: %s; MAC: %#lx", Iface->Name, Iface->MAC.ToHex());
|
||||
}
|
||||
|
||||
void NetworkInterface::StartNetworkStack()
|
||||
{
|
||||
TaskManager->GetCurrentThread()->SetPriority(100);
|
||||
DeviceInterface *DefaultDevice = nullptr;
|
||||
foreach (auto var in Interfaces)
|
||||
if (var && var->DriverCallBackAddress)
|
||||
{
|
||||
DefaultDevice = var;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!DefaultDevice)
|
||||
error("No network device found!");
|
||||
else
|
||||
{
|
||||
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);
|
||||
NetworkDHCP::DHCP *dhcp = new NetworkDHCP::DHCP(DHCP_Socket, DefaultDevice);
|
||||
udp->Bind(DHCP_Socket, dhcp);
|
||||
dhcp->Request();
|
||||
DefaultDevice->IP = InternetProtocol4().FromHex(b32(dhcp->IP.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]);
|
||||
|
||||
/* TODO: Store everything in an vector and initialize all network cards */
|
||||
}
|
||||
|
||||
TaskManager->GetCurrentThread()->SetPriority(1);
|
||||
CPU::Pause(true);
|
||||
}
|
||||
|
||||
void NetworkInterface::StopNetworkStack()
|
||||
{
|
||||
fixme("Stop network stack");
|
||||
}
|
||||
|
||||
ReadFSFunction(NetRead)
|
||||
{
|
||||
fixme("Not implemented.");
|
||||
return Size;
|
||||
}
|
||||
|
||||
WriteFSFunction(NetWrite)
|
||||
{
|
||||
fixme("Not implemented.");
|
||||
return Size;
|
||||
}
|
||||
|
||||
void CallStartNetworkStackWrapper() { NIManager->StartNetworkStack(); }
|
||||
|
||||
void NetworkInterface::StartService()
|
||||
{
|
||||
this->NetSvcProcess = TaskManager->CreateProcess(nullptr, "Network Service", Tasking::TaskTrustLevel::System);
|
||||
Vector<AuxiliaryVector> auxv;
|
||||
auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}});
|
||||
this->NetSvcThread = TaskManager->CreateThread(this->NetSvcProcess, (Tasking::IP)CallStartNetworkStackWrapper, nullptr, nullptr, auxv);
|
||||
}
|
||||
|
||||
void NetworkInterface::DrvSend(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
foreach (auto var in this->Interfaces)
|
||||
if (var->DriverID == DriverID)
|
||||
NIManager->Send(var, Data, Size);
|
||||
}
|
||||
|
||||
void NetworkInterface::DrvReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
foreach (auto var in this->Interfaces)
|
||||
if (var->DriverID == DriverID)
|
||||
NIManager->Receive(var, Data, Size);
|
||||
}
|
||||
|
||||
void NetworkInterface::Send(DeviceInterface *Interface, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
void *DataToBeSent = mem->RequestPages(TO_PAGES(Length));
|
||||
memcpy(DataToBeSent, Data, Length);
|
||||
|
||||
KernelCallback *cb = (KernelCallback *)Interface->DriverCallBackAddress;
|
||||
|
||||
memset(cb, 0, sizeof(KernelCallback));
|
||||
cb->Reason = SendReason;
|
||||
cb->NetworkCallback.Send.Data = (uint8_t *)DataToBeSent;
|
||||
cb->NetworkCallback.Send.Length = Length;
|
||||
DriverManager->IOCB(Interface->DriverID, (void *)cb);
|
||||
|
||||
mem->FreePages(DataToBeSent, TO_PAGES(Length));
|
||||
foreach (auto var in RegisteredEvents)
|
||||
var->OnInterfaceSent(Interface, Data, Length);
|
||||
}
|
||||
|
||||
void NetworkInterface::Receive(DeviceInterface *Interface, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
foreach (auto var in RegisteredEvents)
|
||||
var->OnInterfaceReceived(Interface, Data, Length);
|
||||
}
|
||||
|
||||
Events::Events(DeviceInterface *Interface) { RegisteredEvents.push_back(this); }
|
||||
|
||||
Events::~Events()
|
||||
{
|
||||
for (size_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i] == this)
|
||||
{
|
||||
RegisteredEvents.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
78
Network/NetworkDebugger.cpp
Normal file
78
Network/NetworkDebugger.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <net/nc.hpp>
|
||||
|
||||
/*
|
||||
TODO: This code is a mess. It needs to be cleaned up.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_NETWORK
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <printf.h>
|
||||
#include "../drivers/serial.h"
|
||||
|
||||
namespace NetDbg
|
||||
{
|
||||
class NETWORK_DEBUG : public NetworkInterfaceManager::Events
|
||||
{
|
||||
public:
|
||||
static inline void print_wrapper(char c, void *unused) { write_serial(COM1, 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)
|
||||
{
|
||||
WriteRaw("-------------------------------------------------------------------------\n");
|
||||
unsigned char *AddressChar = (unsigned char *)Address;
|
||||
unsigned char Buffer[17];
|
||||
unsigned long Iterate;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
WriteRaw(" %02x", AddressChar[Iterate]);
|
||||
|
||||
if ((AddressChar[Iterate] < 0x20) || (AddressChar[Iterate] > 0x7e))
|
||||
Buffer[Iterate % 16] = '.';
|
||||
else
|
||||
Buffer[Iterate % 16] = AddressChar[Iterate];
|
||||
|
||||
Buffer[(Iterate % 16) + 1] = '\0';
|
||||
}
|
||||
|
||||
while ((Iterate % 16) != 0)
|
||||
{
|
||||
WriteRaw(" ");
|
||||
Iterate++;
|
||||
}
|
||||
|
||||
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, uint64_t Length) { DumpData("Received", Data, Length); }
|
||||
void OnInterfaceSent(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, uint64_t Length) { DumpData("Sent", Data, Length); }
|
||||
};
|
||||
}
|
||||
|
||||
NetDbg::NETWORK_DEBUG *N;
|
||||
void DbgNetwork() { N = new NetDbg::NETWORK_DEBUG; }
|
||||
void DbgDumpData(const char *Description, void *Address, unsigned long Length) { N->DumpData(Description, Address, Length); }
|
||||
|
||||
#endif
|
21
Network/NetworkTimeProtocol.cpp
Normal file
21
Network/NetworkTimeProtocol.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include <net/ntp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkNTP
|
||||
{
|
||||
NTP::NTP(NetworkUDP::Socket *Socket) : NetworkUDP::UDPEvents()
|
||||
{
|
||||
this->Socket = Socket;
|
||||
}
|
||||
|
||||
NTP::~NTP()
|
||||
{
|
||||
}
|
||||
|
||||
void ReadTime()
|
||||
{
|
||||
fixme("ReadTime()");
|
||||
}
|
||||
}
|
8
Network/TransmissionControlProtocol.cpp
Normal file
8
Network/TransmissionControlProtocol.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <net/tcp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkTCP
|
||||
{
|
||||
}
|
119
Network/UserDatagramProtocol.cpp
Normal file
119
Network/UserDatagramProtocol.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include <net/udp.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace NetworkUDP
|
||||
{
|
||||
struct EventInfo
|
||||
{
|
||||
Socket *UDPSocket;
|
||||
uint16_t Port;
|
||||
};
|
||||
Vector<EventInfo> RegisteredEvents;
|
||||
|
||||
UDPEvents::UDPEvents() {}
|
||||
|
||||
UDPEvents::~UDPEvents() {}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
UDP::UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface) : NetworkIPv4::IPv4Events(NetworkIPv4::PROTOCOL_UDP)
|
||||
{
|
||||
netdbg("UDP: Initializing.");
|
||||
this->ipv4 = ipv4;
|
||||
this->Interface = Interface;
|
||||
}
|
||||
|
||||
UDP::~UDP() {}
|
||||
|
||||
uint16_t UsablePort = 0x200;
|
||||
|
||||
Socket *UDP::Connect(InternetProtocol4 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);
|
||||
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);
|
||||
RegisteredEvents.push_back({.UDPSocket = socket, .Port = socket->LocalPort});
|
||||
return socket;
|
||||
}
|
||||
|
||||
Socket *UDP::Listen(uint16_t Port)
|
||||
{
|
||||
fixme("Not implemented.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UDP::Disconnect(Socket *Socket)
|
||||
{
|
||||
fixme("Not implemented.");
|
||||
}
|
||||
|
||||
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);
|
||||
uint16_t TotalLength = 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) { Socket->EventHandler = EventHandler; }
|
||||
|
||||
bool UDP::OnIPv4PacketReceived(InternetProtocol4 SourceIP, InternetProtocol4 DestinationIP, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("UDP: Received %d bytes from %d.%d.%d.%d", Length, SourceIP.Address[0], SourceIP.Address[1], SourceIP.Address[2], SourceIP.Address[3]);
|
||||
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));
|
||||
|
||||
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",
|
||||
b16(var.UDPSocket->LocalPort),
|
||||
var.UDPSocket->LocalIP.Address[0], var.UDPSocket->LocalIP.Address[1], var.UDPSocket->LocalIP.Address[2], var.UDPSocket->LocalIP.Address[3],
|
||||
b16(var.UDPSocket->RemotePort),
|
||||
var.UDPSocket->RemoteIP.Address[0], var.UDPSocket->RemoteIP.Address[1], var.UDPSocket->RemoteIP.Address[2], var.UDPSocket->RemoteIP.Address[3],
|
||||
b16(var.UDPSocket->Listening));
|
||||
if (var.UDPSocket->LocalPort == udp->DestinationPort &&
|
||||
var.UDPSocket->LocalIP == DestinationIP &&
|
||||
var.UDPSocket->Listening == true)
|
||||
{
|
||||
var.UDPSocket->Listening = false;
|
||||
var.UDPSocket->RemotePort = b16(udp->SourcePort);
|
||||
var.UDPSocket->RemoteIP = SourceIP;
|
||||
netdbg("UDP: E1");
|
||||
return true;
|
||||
}
|
||||
|
||||
GoodSocket = var.UDPSocket;
|
||||
}
|
||||
if (GoodSocket)
|
||||
GoodSocket->EventHandler->OnUDPPacketReceived(GoodSocket, ((UDPPacket *)Data)->Data, Length);
|
||||
|
||||
netdbg("UDP: E0 (Success)");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
Socket::Socket(UDP *_UDP) { this->SocketUDP = _UDP; }
|
||||
|
||||
Socket::~Socket() {}
|
||||
}
|
89
include/net/arp.hpp
Normal file
89
include/net/arp.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_ARP_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_ARP_H__
|
||||
|
||||
#include <net/eth.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <vector.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkARP
|
||||
{
|
||||
enum ARPOperation
|
||||
{
|
||||
REQUEST = 0x1,
|
||||
REPLY = 0x2
|
||||
};
|
||||
|
||||
enum ARPHardwareType
|
||||
{
|
||||
HTYPE_ETHERNET = 1,
|
||||
HTYPE_802_3 = 6,
|
||||
HTYPE_ARCNET = 7,
|
||||
HTYPE_FRAME_RELAY = 15,
|
||||
HTYPE_ATM = 16,
|
||||
HTYPE_HDLC = 17,
|
||||
HTYPE_FIBRE_CHANNEL = 18,
|
||||
HTYPE_ATM_2 = 19,
|
||||
HTYPE_SERIAL_LINE = 20
|
||||
};
|
||||
|
||||
struct ARPHeader
|
||||
{
|
||||
uint16_t HardwareType;
|
||||
uint16_t ProtocolType;
|
||||
uint8_t HardwareSize;
|
||||
uint8_t ProtocolSize;
|
||||
uint16_t Operation;
|
||||
uint48_t SenderMAC : 48;
|
||||
uint32_t SenderIP;
|
||||
uint48_t TargetMAC : 48;
|
||||
uint32_t TargetIP;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DiscoveredAddress
|
||||
{
|
||||
MediaAccessControl MAC;
|
||||
InternetProtocol4 IP;
|
||||
};
|
||||
|
||||
class ARP : public NetworkEthernet::EthernetEvents
|
||||
{
|
||||
private:
|
||||
NetworkEthernet::Ethernet *Ethernet;
|
||||
|
||||
enum DAType
|
||||
{
|
||||
DA_ADD = 1,
|
||||
DA_DEL = 2,
|
||||
DA_SEARCH = 3,
|
||||
DA_UPDATE = 4
|
||||
};
|
||||
|
||||
Vector<NetworkARP::DiscoveredAddress *> DiscoveredAddresses;
|
||||
DiscoveredAddress *ManageDA(DAType Type, InternetProtocol4 IP, MediaAccessControl MAC);
|
||||
DiscoveredAddress *Search(InternetProtocol4 TargetIP);
|
||||
DiscoveredAddress *Update(InternetProtocol4 TargetIP, MediaAccessControl TargetMAC);
|
||||
bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
ARP(NetworkEthernet::Ethernet *Ethernet);
|
||||
~ARP();
|
||||
|
||||
/**
|
||||
* @brief Resolve an IP address to a MAC address.
|
||||
*
|
||||
* @param IP The IP address to resolve. (Little-endian)
|
||||
* @return uint48_t The MAC address of the IP address.
|
||||
*/
|
||||
uint48_t Resolve(InternetProtocol4 IP);
|
||||
|
||||
/**
|
||||
* @brief Broadcast an ARP packet.
|
||||
*
|
||||
* @param IP The IP address to broadcast.
|
||||
*/
|
||||
void Broadcast(InternetProtocol4 IP);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_ARP_H__
|
166
include/net/dhcp.hpp
Normal file
166
include/net/dhcp.hpp
Normal file
@ -0,0 +1,166 @@
|
||||
#ifndef __FENNIX_KERNEL_DHCP_H__
|
||||
#define __FENNIX_KERNEL_DHCP_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkDHCP
|
||||
{
|
||||
struct DHCPHeader
|
||||
{
|
||||
uint8_t Opcode;
|
||||
uint8_t HardwareType;
|
||||
uint8_t HardwareAddressLength;
|
||||
uint8_t Hops;
|
||||
uint32_t TransactionID;
|
||||
uint16_t Seconds;
|
||||
uint16_t Flags;
|
||||
uint32_t ClientIP;
|
||||
uint32_t YourIP;
|
||||
uint32_t ServerIP;
|
||||
uint32_t GatewayIP;
|
||||
uint8_t ClientHardwareAddress[16];
|
||||
uint8_t ServerHostName[64];
|
||||
uint8_t BootFileName[128];
|
||||
uint8_t Options[64];
|
||||
} __attribute__((packed));
|
||||
|
||||
enum DHCPOperation
|
||||
{
|
||||
DHCP_OP_BOOTREQUEST = 1,
|
||||
DHCP_OP_BOOTREPLY = 2
|
||||
};
|
||||
|
||||
/* TODO: Complete list from https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#Options */
|
||||
enum DHCPOption
|
||||
{
|
||||
DHCP_OPTION_PAD = 0,
|
||||
DHCP_OPTION_SUBNETMASK = 1,
|
||||
DHCP_OPTION_TIME_OFFSET = 2,
|
||||
DHCP_OPTION_ROUTER = 3,
|
||||
DHCP_OPTION_TIME_SERVER = 4,
|
||||
DHCP_OPTION_NAME_SERVER = 5,
|
||||
DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
|
||||
DHCP_OPTION_LOG_SERVER = 7,
|
||||
DHCP_OPTION_COOKIE_SERVER = 8,
|
||||
DHCP_OPTION_LPR_SERVER = 9,
|
||||
DHCP_OPTION_IMPRESS_SERVER = 10,
|
||||
DHCP_OPTION_RESOURCE_LOCATION_SERVER = 11,
|
||||
DHCP_OPTION_HOST_NAME = 12,
|
||||
DHCP_OPTION_BOOT_FILE_SIZE = 13,
|
||||
DHCP_OPTION_MERIT_DUMP_FILE = 14,
|
||||
DHCP_OPTION_DOMAIN_NAME = 15,
|
||||
DHCP_OPTION_SWAP_SERVER = 16,
|
||||
DHCP_OPTION_ROOT_PATH = 17,
|
||||
DHCP_OPTION_EXTENSION_PATH = 18,
|
||||
|
||||
DHCP_OPTION_IP_FORWARDING = 19,
|
||||
DHCP_OPTION_NON_LOCAL_SOURCE_ROUTING = 20,
|
||||
DHCP_OPTION_POLICY_FILTER = 21,
|
||||
DHCP_OPTION_MAX_DATAGRAM_REASSEMBLY_SIZE = 22,
|
||||
DHCP_OPTION_DEFAULT_IP_TTL = 23,
|
||||
DHCP_OPTION_PATH_MTU_AGING_TIMEOUT = 24,
|
||||
DHCP_OPTION_PATH_MTU_PLATEAU_TABLE = 25,
|
||||
|
||||
DHCP_OPTION_INTERFACE_MTU = 26,
|
||||
DHCP_OPTION_ALL_SUBNETS_ARE_LOCAL = 27,
|
||||
DHCP_OPTION_BROADCAST_ADDRESS = 28,
|
||||
DHCP_OPTION_PERFORM_MASK_DISCOVERY = 29,
|
||||
DHCP_OPTION_MASK_SUPPLIER = 30,
|
||||
DHCP_OPTION_ROUTER_DISCOVERY = 31,
|
||||
DHCP_OPTION_ROUTER_SOLICITATION_ADDRESS = 32,
|
||||
DHCP_OPTION_STATIC_ROUTE = 33,
|
||||
|
||||
DHCP_OPTION_TRAILER_ENCAPSULATION = 34,
|
||||
DHCP_OPTION_ARP_CACHE_TIMEOUT = 35,
|
||||
DHCP_OPTION_ETHERNET_ENCAPSULATION = 36,
|
||||
|
||||
DHCP_OPTION_DEFAULT_TCP_TTL = 37,
|
||||
DHCP_OPTION_TCP_KEEPALIVE_INTERVAL = 38,
|
||||
DHCP_OPTION_TCP_KEEPALIVE_GARBAGE = 39,
|
||||
|
||||
DHCP_OPTION_NIS_DOMAIN = 40,
|
||||
DHCP_OPTION_NIS_SERVERS = 41,
|
||||
DHCP_OPTION_NTP_SERVERS = 42,
|
||||
DHCP_OPTION_VENDOR_SPECIFIC = 43,
|
||||
DHCP_OPTION_NETBIOS_NAME_SERVERS = 44,
|
||||
DHCP_OPTION_NETBIOS_DD_SERVER = 45,
|
||||
DHCP_OPTION_NETBIOS_NODE_TYPE = 46,
|
||||
DHCP_OPTION_NETBIOS_SCOPE = 47,
|
||||
DHCP_OPTION_X_FONT_SERVERS = 48,
|
||||
DHCP_OPTION_X_DISPLAY_MANAGER = 49,
|
||||
|
||||
DHCP_OPTION_REQUESTED_IP = 50,
|
||||
DHCP_OPTION_IP_LEASE_TIME = 51,
|
||||
DHCP_OPTION_OPTION_OVERLOAD = 52,
|
||||
DHCP_OPTION_MESSAGE_TYPE = 53,
|
||||
DHCP_OPTION_SERVER_IDENTIFIER = 54,
|
||||
DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
|
||||
DHCP_OPTION_MESSAGE = 56,
|
||||
DHCP_OPTION_MAX_MESSAGE_SIZE = 57,
|
||||
DHCP_OPTION_T1_TIMEOUT = 58,
|
||||
DHCP_OPTION_T2_TIMEOUT = 59,
|
||||
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
|
||||
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
|
||||
|
||||
DHCP_OPTION_NETWORK_TIME_SERVER = 62,
|
||||
|
||||
DHCP_OPTION_END = 255
|
||||
};
|
||||
|
||||
enum DHCPMessageType
|
||||
{
|
||||
DHCP_MESSAGE_TYPE_DISCOVER = 1,
|
||||
DHCP_MESSAGE_TYPE_OFFER = 2,
|
||||
DHCP_MESSAGE_TYPE_REQUEST = 3,
|
||||
DHCP_MESSAGE_TYPE_DECLINE = 4,
|
||||
DHCP_MESSAGE_TYPE_ACK = 5,
|
||||
DHCP_MESSAGE_TYPE_NAK = 6,
|
||||
DHCP_MESSAGE_TYPE_RELEASE = 7,
|
||||
DHCP_MESSAGE_TYPE_INFORM = 8,
|
||||
DHCP_MESSAGE_TYPE_FORCERENEW = 9,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERY = 10,
|
||||
DHCP_MESSAGE_TYPE_LEASEUNASSIGNED = 11,
|
||||
DHCP_MESSAGE_TYPE_LEASEUNKNOWN = 12,
|
||||
DHCP_MESSAGE_TYPE_LEASEACTIVE = 13,
|
||||
DHCP_MESSAGE_TYPE_BULKLEASEQUERY = 14,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERYDONE = 15,
|
||||
DHCP_MESSAGE_TYPE_ACTIVELEASEQUERY = 16,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERYSTATUS = 17,
|
||||
DHCP_MESSAGE_TYPE_DHCPTLS = 18
|
||||
};
|
||||
|
||||
#define DHCP_TRANSACTION_ID 0xFE2EC005
|
||||
|
||||
class DHCP : public NetworkUDP::UDPEvents
|
||||
{
|
||||
private:
|
||||
NetworkUDP::Socket *UDPSocket;
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
bool Received = false;
|
||||
|
||||
void CreatePacket(DHCPHeader *Packet, uint8_t MessageType, uint32_t RequestIP);
|
||||
void *GetOption(DHCPHeader *Packet, uint8_t Type);
|
||||
|
||||
public:
|
||||
/** @brief IP address (Little-endian) */
|
||||
InternetProtocol4 IP = {.Address = {0x0, 0x0, 0x0, 0x0}};
|
||||
/** @brief Gateway address (Little-endian) */
|
||||
InternetProtocol4 Gateway = {.Address = {0x0, 0x0, 0x0, 0x0}};
|
||||
/** @brief Subnet mask (Little-endian) */
|
||||
InternetProtocol4 SubNetworkMask = {.Address = {0x0, 0x0, 0x0, 0x0}};
|
||||
/** @brief DNS server address (Little-endian) */
|
||||
InternetProtocol4 DomainNameSystem = {.Address = {0x0, 0x0, 0x0, 0x0}};
|
||||
|
||||
DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~DHCP();
|
||||
void Request();
|
||||
void Request(InternetProtocol4 IP);
|
||||
|
||||
virtual void OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, uint64_t Length);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DHCP_H__
|
77
include/net/eth.hpp
Normal file
77
include/net/eth.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <net/nc.hpp>
|
||||
|
||||
namespace NetworkEthernet
|
||||
{
|
||||
enum FrameType
|
||||
{
|
||||
TYPE_IPV4 = 0x0800,
|
||||
TYPE_ARP = 0x0806,
|
||||
TYPE_RARP = 0x8035,
|
||||
TYPE_IPV6 = 0x86DD
|
||||
};
|
||||
|
||||
struct EthernetHeader
|
||||
{
|
||||
uint48_t DestinationMAC : 48;
|
||||
uint48_t SourceMAC : 48;
|
||||
uint16_t Type;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct EthernetPacket
|
||||
{
|
||||
EthernetHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class EthernetEvents
|
||||
{
|
||||
private:
|
||||
FrameType FType;
|
||||
|
||||
protected:
|
||||
EthernetEvents(FrameType Type);
|
||||
~EthernetEvents();
|
||||
|
||||
public:
|
||||
FrameType GetFrameType() { return FType; }
|
||||
virtual void OnEthernetPacketSent(EthernetPacket *Packet) { netdbg("Event not handled. [%p]", Packet); }
|
||||
virtual bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
netdbg("Event not handled. [%p, %d]", Data, Length);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Ethernet : public NetworkInterfaceManager::Events
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
void Receive(uint8_t *Data, uint64_t Length);
|
||||
void OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
/** @brief Get driver interface
|
||||
* @return Driver interface
|
||||
*/
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
Ethernet(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~Ethernet();
|
||||
|
||||
/**
|
||||
* @brief Send an Ethernet packet.
|
||||
*
|
||||
* @param MAC The MAC address of the destination. (Big-endian)
|
||||
* @param Type The type of the packet.
|
||||
* @param Data The data to send.
|
||||
* @param Length The length of the data.
|
||||
*/
|
||||
void Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, uint64_t Length);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
54
include/net/icmpv4.hpp
Normal file
54
include/net/icmpv4.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef __FENNIX_KERNEL_ICMPv4_H__
|
||||
#define __FENNIX_KERNEL_ICMPv4_H__
|
||||
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkICMPv4
|
||||
{
|
||||
enum ICMPv4Type
|
||||
{
|
||||
TYPE_ECHO_REPLY = 0,
|
||||
TYPE_DESTINATION_UNREACHABLE = 3,
|
||||
TYPE_SOURCE_QUENCH = 4,
|
||||
TYPE_REDIRECT = 5,
|
||||
TYPE_ECHO = 8,
|
||||
TYPE_ROUTER_ADVERTISEMENT = 9,
|
||||
TYPE_ROUTER_SELECTION = 10,
|
||||
TYPE_TIME_EXCEEDED = 11,
|
||||
TYPE_PARAMETER_PROBLEM = 12,
|
||||
TYPE_TIMESTAMP = 13,
|
||||
TYPE_TIMESTAMP_REPLY = 14
|
||||
};
|
||||
|
||||
struct ICMPHeader
|
||||
{
|
||||
uint8_t Type;
|
||||
uint8_t Code;
|
||||
uint16_t Checksum;
|
||||
uint16_t Identifier;
|
||||
uint16_t SequenceNumber;
|
||||
};
|
||||
|
||||
struct ICMPPacket
|
||||
{
|
||||
ICMPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class ICMPv4
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
ICMPv4(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~ICMPv4();
|
||||
void Send(/* ???? */);
|
||||
void Receive(ICMPPacket *Packet);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ICMPv4_H__
|
39
include/net/icmpv6.hpp
Normal file
39
include/net/icmpv6.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef __FENNIX_KERNEL_ICMPv6_H__
|
||||
#define __FENNIX_KERNEL_ICMPv6_H__
|
||||
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkICMPv6
|
||||
{
|
||||
struct ICMPHeader
|
||||
{
|
||||
uint8_t Type;
|
||||
uint8_t Code;
|
||||
uint16_t Checksum;
|
||||
uint16_t Identifier;
|
||||
uint16_t SequenceNumber;
|
||||
};
|
||||
|
||||
struct ICMPPacket
|
||||
{
|
||||
ICMPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class ICMPv6
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
ICMPv6(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~ICMPv6();
|
||||
void Send(uint8_t *Data, uint64_t Length);
|
||||
void Receive(uint8_t *Data);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ICMPv6_H__
|
115
include/net/ipv4.hpp
Normal file
115
include/net/ipv4.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef __FENNIX_KERNEL_IPv4_H__
|
||||
#define __FENNIX_KERNEL_IPv4_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/arp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkIPv4
|
||||
{
|
||||
struct IPv4Header
|
||||
{
|
||||
uint8_t IHL : 4;
|
||||
uint8_t Version : 4;
|
||||
uint8_t TypeOfService;
|
||||
uint16_t TotalLength;
|
||||
uint16_t Identification;
|
||||
uint16_t FlagsAndFragmentOffset;
|
||||
uint8_t TimeToLive;
|
||||
uint8_t Protocol;
|
||||
uint16_t HeaderChecksum;
|
||||
uint32_t SourceIP;
|
||||
uint32_t DestinationIP;
|
||||
|
||||
/* On wikipedia page we have this: https://en.wikipedia.org/wiki/File:IPv4_Packet-en.svg
|
||||
but only the code above works... */
|
||||
// uint8_t Version : 4;
|
||||
// uint8_t IHL : 4;
|
||||
// uint16_t TypeOfService : 8;
|
||||
// uint16_t TotalLength : 12;
|
||||
// uint16_t Identification : 16;
|
||||
// uint16_t Flags : 3;
|
||||
// uint16_t FragmentOffset : 13;
|
||||
// uint8_t TimeToLive : 8;
|
||||
// uint8_t Protocol : 8;
|
||||
// uint16_t HeaderChecksum;
|
||||
// uint32_t SourceIP;
|
||||
// uint32_t DestinationIP;
|
||||
};
|
||||
|
||||
struct IPv4Packet
|
||||
{
|
||||
IPv4Header Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
enum IPv4Protocols
|
||||
{
|
||||
PROTOCOL_ICMP = 1,
|
||||
PROTOCOL_IGMP = 2,
|
||||
PROTOCOL_TCP = 6,
|
||||
PROTOCOL_UDP = 17,
|
||||
PROTOCOL_IPV6 = 41,
|
||||
PROTOCOL_ROUTING = 43,
|
||||
PROTOCOL_FRAGMENT = 44,
|
||||
PROTOCOL_ESP = 50,
|
||||
PROTOCOL_AH = 51,
|
||||
PROTOCOL_ICMPV6 = 58,
|
||||
PROTOCOL_NONE = 59,
|
||||
PROTOCOL_DSTOPTS = 60,
|
||||
PROTOCOL_ND = 77,
|
||||
PROTOCOL_ICLFXBM = 78,
|
||||
PROTOCOL_PIM = 103,
|
||||
PROTOCOL_COMP = 108,
|
||||
PROTOCOL_SCTP = 132,
|
||||
PROTOCOL_UDPLITE = 136,
|
||||
PROTOCOL_RAW = 255
|
||||
};
|
||||
|
||||
class IPv4 : public NetworkEthernet::EthernetEvents
|
||||
{
|
||||
private:
|
||||
NetworkARP::ARP *ARP;
|
||||
NetworkEthernet::Ethernet *Ethernet;
|
||||
|
||||
virtual bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
InternetProtocol4 GatewayIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
InternetProtocol4 SubNetworkMaskIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet);
|
||||
~IPv4();
|
||||
|
||||
/**
|
||||
* @brief Send an IPv4 packet.
|
||||
*
|
||||
* @param Data The data to send.
|
||||
* @param Length The length of the data.
|
||||
* @param Protocol The protocol of the packet.
|
||||
* @param DestinationIP The IP address of the destination. (Big-endian)
|
||||
*/
|
||||
void Send(uint8_t *Data, uint64_t Length, uint8_t Protocol, InternetProtocol4 DestinationIP);
|
||||
};
|
||||
|
||||
class IPv4Events
|
||||
{
|
||||
private:
|
||||
uint8_t Protocol;
|
||||
|
||||
protected:
|
||||
IPv4Events(IPv4Protocols Protocol);
|
||||
~IPv4Events();
|
||||
|
||||
public:
|
||||
uint8_t GetProtocol() { return Protocol; }
|
||||
|
||||
virtual bool OnIPv4PacketReceived(InternetProtocol4 SourceIP, InternetProtocol4 DestinationIP, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
warn("Not implemented.");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IPv4_H__
|
27
include/net/ipv6.hpp
Normal file
27
include/net/ipv6.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __FENNIX_KERNEL_IPv6_H__
|
||||
#define __FENNIX_KERNEL_IPv6_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkIPv6
|
||||
{
|
||||
struct IPv6Header
|
||||
{
|
||||
uint32_t Version;
|
||||
uint8_t TrafficClass;
|
||||
uint16_t FlowLabel;
|
||||
uint16_t PayloadLength;
|
||||
uint8_t NextHeader;
|
||||
uint8_t HopLimit;
|
||||
uint32_t SourceIP;
|
||||
uint32_t DestinationIP;
|
||||
};
|
||||
|
||||
struct IPv6Packet
|
||||
{
|
||||
IPv6Header Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IPv6_H__
|
75
include/net/nc.hpp
Normal file
75
include/net/nc.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
||||
|
||||
#include <net/net.hpp>
|
||||
#include <vector.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <task.hpp>
|
||||
#include <types.h>
|
||||
#include <debug.h>
|
||||
|
||||
namespace NetworkInterfaceManager
|
||||
{
|
||||
struct DeviceInterface
|
||||
{
|
||||
/** @brief Device interface name */
|
||||
char Name[128];
|
||||
|
||||
/** @brief Device interface index */
|
||||
uint64_t ID;
|
||||
|
||||
/** @brief Device interface MAC address (Big-endian) */
|
||||
MediaAccessControl MAC;
|
||||
|
||||
/** @brief Device interface IP address (Big-endian) */
|
||||
InternetProtocol4 IP;
|
||||
|
||||
/** @brief Reserved */
|
||||
void *DriverCallBackAddress;
|
||||
|
||||
/** @brief Reserved */
|
||||
unsigned int DriverID;
|
||||
};
|
||||
|
||||
class Events
|
||||
{
|
||||
protected:
|
||||
Events(DeviceInterface *Interface);
|
||||
~Events();
|
||||
|
||||
public:
|
||||
virtual void OnInterfaceAdded(DeviceInterface *Interface) { netdbg("Event for %s not handled.", Interface->Name); }
|
||||
virtual void OnInterfaceRemoved(DeviceInterface *Interface) { netdbg("Event for %s not handled.", Interface->Name); }
|
||||
virtual void OnInterfaceChanged(DeviceInterface *Interface) { netdbg("Event for %s not handled.", Interface->Name); }
|
||||
virtual void OnInterfaceReceived(DeviceInterface *Interface, uint8_t *Data, uint64_t Length) { netdbg("Event for %s not handled.", Interface->Name); }
|
||||
virtual void OnInterfaceSent(DeviceInterface *Interface, uint8_t *Data, uint64_t Length) { netdbg("Event for %s not handled.", Interface->Name); }
|
||||
};
|
||||
|
||||
class NetworkInterface
|
||||
{
|
||||
private:
|
||||
Memory::MemMgr *mem;
|
||||
int CardIDs = 0;
|
||||
Vector<DeviceInterface *> Interfaces;
|
||||
|
||||
Tasking::PCB *NetSvcProcess;
|
||||
Tasking::TCB *NetSvcThread;
|
||||
void StopNetworkStack();
|
||||
void FetchNetworkCards(unsigned long DriverUID);
|
||||
|
||||
public:
|
||||
NetworkInterface();
|
||||
~NetworkInterface();
|
||||
|
||||
void StartService();
|
||||
|
||||
void Send(DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
void Receive(DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
|
||||
void DrvSend(unsigned int DriverID, unsigned char *Data, unsigned short Size);
|
||||
void DrvReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size);
|
||||
void StartNetworkStack();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
150
include/net/net.hpp
Normal file
150
include/net/net.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// #define DEBUG_NETWORK 1
|
||||
|
||||
#ifdef DEBUG_NETWORK
|
||||
#define netdbg(m, ...) debug(m, ##__VA_ARGS__)
|
||||
void DbgNetwork();
|
||||
void DbgDumpData(const char *Description, void *Address, unsigned long Length);
|
||||
#else
|
||||
#define netdbg(m, ...)
|
||||
static inline void DbgNetwork() { return; }
|
||||
static inline void DbgDumpData(const char *Description, void *Address, unsigned long Length) { return; }
|
||||
#endif
|
||||
|
||||
// TODO: How i would do this?
|
||||
typedef __UINT64_TYPE__ uint48_t;
|
||||
|
||||
#define b4(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4)
|
||||
#define b8(x) ((x)&0xFF)
|
||||
#define b16(x) __builtin_bswap16(x)
|
||||
#define b32(x) __builtin_bswap32(x)
|
||||
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
|
||||
#define b64(x) __builtin_bswap64(x)
|
||||
|
||||
struct MediaAccessControl
|
||||
{
|
||||
uint8_t Address[6];
|
||||
|
||||
inline bool operator==(const MediaAccessControl &lhs) const
|
||||
{
|
||||
return lhs.Address[0] == this->Address[0] &&
|
||||
lhs.Address[1] == this->Address[1] &&
|
||||
lhs.Address[2] == this->Address[2] &&
|
||||
lhs.Address[3] == this->Address[3] &&
|
||||
lhs.Address[4] == this->Address[4] &&
|
||||
lhs.Address[5] == this->Address[5];
|
||||
}
|
||||
|
||||
inline bool operator==(const uint48_t &lhs) const
|
||||
{
|
||||
MediaAccessControl MAC;
|
||||
MAC.Address[0] = (uint8_t)((lhs >> 40) & 0xFF);
|
||||
MAC.Address[1] = (uint8_t)((lhs >> 32) & 0xFF);
|
||||
MAC.Address[2] = (uint8_t)((lhs >> 24) & 0xFF);
|
||||
MAC.Address[3] = (uint8_t)((lhs >> 16) & 0xFF);
|
||||
MAC.Address[4] = (uint8_t)((lhs >> 8) & 0xFF);
|
||||
MAC.Address[5] = (uint8_t)(lhs & 0xFF);
|
||||
return MAC.Address[0] == this->Address[0] &&
|
||||
MAC.Address[1] == this->Address[1] &&
|
||||
MAC.Address[2] == this->Address[2] &&
|
||||
MAC.Address[3] == this->Address[3] &&
|
||||
MAC.Address[4] == this->Address[4] &&
|
||||
MAC.Address[5] == this->Address[5];
|
||||
}
|
||||
|
||||
inline bool operator!=(const MediaAccessControl &lhs) const { return !(*this == lhs); }
|
||||
inline bool operator!=(const uint48_t &lhs) const { return !(*this == lhs); }
|
||||
|
||||
inline uint48_t ToHex()
|
||||
{
|
||||
return ((uint48_t)this->Address[0] << 40) |
|
||||
((uint48_t)this->Address[1] << 32) |
|
||||
((uint48_t)this->Address[2] << 24) |
|
||||
((uint48_t)this->Address[3] << 16) |
|
||||
((uint48_t)this->Address[4] << 8) |
|
||||
((uint48_t)this->Address[5]);
|
||||
}
|
||||
|
||||
inline MediaAccessControl FromHex(uint48_t Hex)
|
||||
{
|
||||
this->Address[0] = (uint8_t)((Hex >> 40) & 0xFF);
|
||||
this->Address[1] = (uint8_t)((Hex >> 32) & 0xFF);
|
||||
this->Address[2] = (uint8_t)((Hex >> 24) & 0xFF);
|
||||
this->Address[3] = (uint8_t)((Hex >> 16) & 0xFF);
|
||||
this->Address[4] = (uint8_t)((Hex >> 8) & 0xFF);
|
||||
this->Address[5] = (uint8_t)(Hex & 0xFF);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Valid()
|
||||
{
|
||||
// TODO: More complex MAC validation
|
||||
return (this->Address[0] != 0 ||
|
||||
this->Address[1] != 0 ||
|
||||
this->Address[2] != 0 ||
|
||||
this->Address[3] != 0 ||
|
||||
this->Address[4] != 0 ||
|
||||
this->Address[5] != 0) &&
|
||||
(this->Address[0] != 0xFF ||
|
||||
this->Address[1] != 0xFF ||
|
||||
this->Address[2] != 0xFF ||
|
||||
this->Address[3] != 0xFF ||
|
||||
this->Address[4] != 0xFF ||
|
||||
this->Address[5] != 0xFF);
|
||||
}
|
||||
};
|
||||
|
||||
struct InternetProtocol4
|
||||
{
|
||||
uint8_t Address[4];
|
||||
|
||||
inline bool operator==(const InternetProtocol4 &lhs) const
|
||||
{
|
||||
return lhs.Address[0] == this->Address[0] &&
|
||||
lhs.Address[1] == this->Address[1] &&
|
||||
lhs.Address[2] == this->Address[2] &&
|
||||
lhs.Address[3] == this->Address[3];
|
||||
}
|
||||
|
||||
inline bool operator==(const uint32_t &lhs) const
|
||||
{
|
||||
InternetProtocol4 IP;
|
||||
IP.Address[0] = (uint8_t)((lhs >> 24) & 0xFF);
|
||||
IP.Address[1] = (uint8_t)((lhs >> 16) & 0xFF);
|
||||
IP.Address[2] = (uint8_t)((lhs >> 8) & 0xFF);
|
||||
IP.Address[3] = (uint8_t)(lhs & 0xFF);
|
||||
|
||||
return IP.Address[0] == this->Address[0] &&
|
||||
IP.Address[1] == this->Address[1] &&
|
||||
IP.Address[2] == this->Address[2] &&
|
||||
IP.Address[3] == this->Address[3];
|
||||
}
|
||||
|
||||
inline bool operator!=(const InternetProtocol4 &lhs) const { return !(*this == lhs); }
|
||||
inline bool operator!=(const uint32_t &lhs) const { return !(*this == lhs); }
|
||||
|
||||
inline uint32_t ToHex()
|
||||
{
|
||||
return ((uint64_t)this->Address[0] << 24) |
|
||||
((uint64_t)this->Address[1] << 16) |
|
||||
((uint64_t)this->Address[2] << 8) |
|
||||
((uint64_t)this->Address[3]);
|
||||
}
|
||||
|
||||
inline InternetProtocol4 FromHex(uint32_t Hex)
|
||||
{
|
||||
this->Address[0] = (uint8_t)((Hex >> 24) & 0xFF);
|
||||
this->Address[1] = (uint8_t)((Hex >> 16) & 0xFF);
|
||||
this->Address[2] = (uint8_t)((Hex >> 8) & 0xFF);
|
||||
this->Address[3] = (uint8_t)(Hex & 0xFF);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
uint16_t CalculateChecksum(uint16_t *Data, uint64_t Length);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_H__
|
39
include/net/ntp.hpp
Normal file
39
include/net/ntp.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef __FENNIX_KERNEL_NTP_H__
|
||||
#define __FENNIX_KERNEL_NTP_H__
|
||||
|
||||
#include <net/udp.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkNTP
|
||||
{
|
||||
struct NTPHeader
|
||||
{
|
||||
uint8_t LIv;
|
||||
uint8_t VN;
|
||||
uint8_t Mode;
|
||||
uint8_t Stratum;
|
||||
uint8_t Poll;
|
||||
uint8_t Precision;
|
||||
uint32_t RootDelay;
|
||||
uint32_t RootDispersion;
|
||||
uint32_t ReferenceID;
|
||||
uint32_t ReferenceTimestamp;
|
||||
uint32_t OriginateTimestamp;
|
||||
uint32_t ReceiveTimestamp;
|
||||
uint32_t TransmitTimestamp;
|
||||
} __attribute__((packed));
|
||||
|
||||
class NTP : public NetworkUDP::UDPEvents
|
||||
{
|
||||
private:
|
||||
NetworkUDP::Socket *Socket;
|
||||
|
||||
public:
|
||||
NTP(NetworkUDP::Socket *Socket);
|
||||
~NTP();
|
||||
|
||||
void ReadTime();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NTP_H__
|
10
include/net/tcp.hpp
Normal file
10
include/net/tcp.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __FENNIX_KERNEL_TCP_H__
|
||||
#define __FENNIX_KERNEL_TCP_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkTCP
|
||||
{
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TCP_H__
|
77
include/net/udp.hpp
Normal file
77
include/net/udp.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef __FENNIX_KERNEL_UDP_H__
|
||||
#define __FENNIX_KERNEL_UDP_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkUDP
|
||||
{
|
||||
struct UDPHeader
|
||||
{
|
||||
uint16_t SourcePort;
|
||||
uint16_t DestinationPort;
|
||||
uint16_t Length;
|
||||
uint16_t Checksum;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct UDPPacket
|
||||
{
|
||||
UDPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class Socket;
|
||||
|
||||
class UDPEvents
|
||||
{
|
||||
protected:
|
||||
UDPEvents();
|
||||
~UDPEvents();
|
||||
|
||||
public:
|
||||
virtual void OnUDPPacketReceived(Socket *Socket, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
warn("Not implemented.");
|
||||
}
|
||||
};
|
||||
|
||||
class UDP : public NetworkIPv4::IPv4Events
|
||||
{
|
||||
private:
|
||||
NetworkIPv4::IPv4 *ipv4;
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~UDP();
|
||||
|
||||
virtual Socket *Connect(InternetProtocol4 IP, uint16_t Port);
|
||||
virtual Socket *Listen(uint16_t Port);
|
||||
virtual void Disconnect(Socket *Socket);
|
||||
virtual void Send(Socket *Socket, uint8_t *Data, uint64_t Length);
|
||||
virtual void Bind(Socket *Socket, UDPEvents *EventHandler);
|
||||
|
||||
virtual bool OnIPv4PacketReceived(InternetProtocol4 SourceIP, InternetProtocol4 DestinationIP, uint8_t *Data, uint64_t Length);
|
||||
};
|
||||
|
||||
class Socket
|
||||
{
|
||||
public:
|
||||
InternetProtocol4 LocalIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
uint16_t LocalPort = 0;
|
||||
InternetProtocol4 RemoteIP = {.Address = {0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
uint16_t RemotePort = 0;
|
||||
bool Listening = false;
|
||||
UDPEvents *EventHandler = nullptr;
|
||||
UDP *SocketUDP = nullptr;
|
||||
|
||||
Socket(UDP *_UDP);
|
||||
~Socket();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_UDP_H__
|
2
kernel.h
2
kernel.h
@ -5,6 +5,7 @@
|
||||
|
||||
#include <boot/binfo.h>
|
||||
#ifdef __cplusplus
|
||||
#include <net/nc.hpp>
|
||||
#include <filesystem.hpp>
|
||||
#include <display.hpp>
|
||||
#include <symbols.hpp>
|
||||
@ -29,6 +30,7 @@ extern Time::time *TimeManager;
|
||||
extern FileSystem::Virtual *vfs;
|
||||
extern Driver::Driver *DriverManager;
|
||||
extern Disk::Manager *DiskManager;
|
||||
extern NetworkInterfaceManager::NetworkInterface *NIManager;
|
||||
|
||||
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
|
||||
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
|
||||
|
Loading…
x
Reference in New Issue
Block a user