diff options
Diffstat (limited to 'dev/kernel/src/Network/IPCMessage.cc')
| -rw-r--r-- | dev/kernel/src/Network/IPCMessage.cc | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/dev/kernel/src/Network/IPCMessage.cc b/dev/kernel/src/Network/IPCMessage.cc new file mode 100644 index 00000000..6f8223f7 --- /dev/null +++ b/dev/kernel/src/Network/IPCMessage.cc @@ -0,0 +1,129 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <KernelKit/KPC.h> +#include <KernelKit/ProcessScheduler.h> +#include <NetworkKit/IPC.h> + +namespace Kernel { +/***********************************************************************************/ +/// @internal internal use for IPC system only. +/// @brief The internal sanitize function. +/***********************************************************************************/ +Bool ipc_int_sanitize_packet(IPC_MSG* pckt) { + auto endian = RTL_ENDIAN(pckt, ((Char*) pckt)[0]); + + switch (endian) { + case Endian::kEndianBig: { + if (pckt->IpcEndianess == kIPCLittleEndian) goto ipc_check_failed; + + break; + } + case Endian::kEndianLittle: { + if (pckt->IpcEndianess == kIPCBigEndian) goto ipc_check_failed; + + break; + } + case Endian::kEndianMixed: { + if (pckt->IpcEndianess == kIPCMixedEndian) goto ipc_check_failed; + + break; + } + default: + goto ipc_check_failed; + } + + if (pckt->IpcFrom == pckt->IpcTo || pckt->IpcPacketSize > kIPCMsgSize) { + goto ipc_check_failed; + } + + return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic; + +ipc_check_failed: + err_local_get() = kErrorIPC; + return false; +} + +/***********************************************************************************/ +/// @brief Sanitize packet function +/// @retval true packet is correct. +/// @retval false packet is incorrect and process has crashed. +/***********************************************************************************/ +Bool ipc_sanitize_packet(IPC_MSG* pckt) { + if (!pckt || !ipc_int_sanitize_packet(pckt)) { + return false; + } + + return true; +} + +/***********************************************************************************/ +/// @brief Construct packet function +/// @retval true packet is correct. +/// @retval false packet is incorrect and process has crashed. +/***********************************************************************************/ +Bool ipc_construct_packet(_Output IPC_MSG** pckt_in) { + // don't act if it's not even valid. + if (!pckt_in) return false; + + if (!*pckt_in) *pckt_in = new IPC_MSG(); + + MUST_PASS(*pckt_in); + + if (*pckt_in) { + const auto endianess = RTL_ENDIAN((*pckt_in), ((Char*) (*pckt_in))[0]); + + (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic; + + (*pckt_in)->IpcEndianess = static_cast<UInt8>(endianess); + (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG); + + (*pckt_in)->IpcTo.UserProcessID = 0; + (*pckt_in)->IpcTo.UserProcessTeam = 0; + + (*pckt_in)->IpcFrom.UserProcessID = 0; + (*pckt_in)->IpcFrom.UserProcessTeam = 0; + + (*pckt_in)->IpcLock = kIPCLockFree; + + return Yes; + } + + return No; +} + +/***********************************************************************************/ +/// @brief Pass message from **src** to **target** +/// @param src Source message. +/// @param target Target message. +/***********************************************************************************/ +Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) noexcept { + if (src && target && (target != src)) { + if (src->IpcMsgSz > target->IpcMsgSz) return No; + if (target->IpcMsgSz > src->IpcMsgSz) return No; + + auto timeout = 0U; + + const auto kLimitTimeout = 1000000U; + + while ((target->IpcLock % kIPCLockUsed) != 0) { + if (timeout > kLimitTimeout) { + return No; + } + } + + ++target->IpcLock; + + rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, kIPCMsgSize); + + --target->IpcLock; + + return Yes; + } + + return No; +} +} // namespace Kernel |
