# SPDX-License-Identifier: LSL-1.0 # Copyright (c) 2026 Markus Maiwald # Stewardship: Self Sovereign Society Foundation # # This file is part of the Nexus Sovereign Core. # See legal/LICENSE_SOVEREIGN.md for license terms. ## Nexus Membrane: POSIX Network Shim # core/rumpk/libs/membrane/libc_net.nim # Phase 37: The Shim (LwIP Socket Bridge) - Raw API Version import libc import strutils # --- Helpers --- proc parse_ipv4(host: string): uint32 = # Simple parser: "a.b.c.d" -> uint32 try: var parts = host.split('.') if parts.len != 4: return 0 let a = parts[0].parseInt.uint32 let b = parts[1].parseInt.uint32 let c = parts[2].parseInt.uint32 let d = parts[3].parseInt.uint32 # Pack into uint32 (A | B<<8 | C<<16 | D<<24) - LwIP Native Order return (a shl 0) or (b shl 8) or (c shl 16) or (d shl 24) except: return 0 # --- Public API --- proc net_dial_tcp*(host: string, port: uint16): int = ## Connect to a remote host via TCP let target_ip = parse_ipv4(host) if target_ip == 0 and host != "0.0.0.0": return -1 # DNS not implemented yet # 1. Create Socket (AF_INET=2, SOCK_STREAM=1, TCP=6) let fd = libc.socket(2, 1, 6) if fd < 0: return -2 # 2. Setup SockAddr # struct sockaddr_in { u8 family; u8 len; u16 port; u32 ip; ... } # Layout expected by Kernel glue: # Offset 0: Family (ignored?) # Offset 2: Port # Offset 4: IP var addr_buf: array[16, byte] addr_buf[0] = 2 # AF_INET # Copy Port (Little Endian?) copyMem(addr addr_buf[2], unsafeAddr port, 2) copyMem(addr addr_buf[4], unsafeAddr target_ip, 4) # 3. Connect (Blocking) if libc.connect(fd, addr addr_buf[0], 16) != 0: discard libc.close(fd) return -3 return fd proc net_send*(fd: int, data: string): int = ## Send string data over the socket if data.len == 0: return 0 return libc.send(fd, unsafeAddr data[0], uint64(data.len), 0) proc net_recv*(fd: int, size: int): string = ## Receive up to `size` bytes if size <= 0: return "" var buf = newString(size) let bytes = libc.recv(fd, addr buf[0], uint64(size), 0) if bytes > 0: buf.setLen(bytes) return buf return "" proc net_close*(fd: int) = discard libc.close(fd)