summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src/Network/IPCMessage.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-08-25 10:28:07 +0200
committerGitHub <noreply@github.com>2025-08-25 10:28:07 +0200
commit1057fd299e17fcc04f6b3a1aa3ace1026f8652a0 (patch)
treea663c7dcd26779295ce0d9681418964f802f2d14 /dev/kernel/src/Network/IPCMessage.cc
parent1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (diff)
parent328b34360ab8b2462ea5858441693277b3d23f08 (diff)
Merge pull request #56 from nekernel-org/dev
Errata: v0.0.4
Diffstat (limited to 'dev/kernel/src/Network/IPCMessage.cc')
-rw-r--r--dev/kernel/src/Network/IPCMessage.cc129
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