code wiki / (root) / nx_port_audit.nx

nx_port_audit.nx source

↩ module page · 142 lines · 7879 B

1// nx_port_audit.nx -- SOVEREIGN LISTENING_VS_CLAIMED audit (the capability nx_daemon_health_audit lists 2// as MISSING). Parses /proc/net/tcp (no ss/netstat/shell) for sockets in LISTEN state (st=0A), extracts 3// their local ports, and checks each KNOWN Nishi daemon port: is something ACTUALLY listening, or does the 4// daemon merely CLAIM up (pidfile UP, port unbound -- the exact torrent :8097 restart-wedge symptom)? 5// Run: nx_port_audit. license_tier: ORIGINAL 6// module: nishi-core.perception.port_audit capability: PERCEPTION (daemon health) 7import "nx_syscalls.nx" 8const PA_MAGIC_1048576: i64 = 1048576 9const PA_MAGIC_8097: i64 = 8097 10const PA_MAGIC_18090: i64 = 18090 11const PA_MAGIC_7702: i64 = 7702 12const PA_MAGIC_8446: i64 = 8446 13const PA_MAGIC_8447: i64 = 8447 14const PA_MAGIC_8443: i64 = 8443 15const PA_MAGIC_8080: i64 = 8080 16 17const PA_CAP: i64 = 1024 18 19func pa_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 20func pa_n(v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let b: *u8=sys_mmap(28); var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 21func pa_hv(c: i64) -> i64 { if c>=48 { if c<=57 { return c-48 } } if c>=65 { if c<=70 { return c-55 } } if c>=97 { if c<=102 { return c-87 } } return 0-1 } 22 23// parse all LISTEN (st=0A) local ports from `path` (/proc/net/tcp or tcp6) into out[] starting at `start`. 24// line fields: 0=sl 1=local(ADDR:PORT) 2=rem 3=st ; port = the 4 hex after the LAST ':' in the local field. 25func pa_scan_file(path: *u8, out: *i64, start: i64, cap: i64) -> i64 { 26 let fd: i64 = sys_openat_rd(path); if fd < 0 { return start } 27 let buf: *u8 = sys_mmap(PA_MAGIC_1048576); var total: i64 = 0; var r: i64 = 1 28 while r > 0 { r = sys_read(fd, ((buf as i64)+total) as *u8, PA_MAGIC_1048576-total); if r > 0 { total = total + r } } 29 sys_close(fd) 30 var n: i64 = start; var i: i64 = 0; var lineno: i64 = 0 31 while i < total { 32 let ls: i64 = i 33 var le: i64 = ls; var fe: i64 = 0 34 while fe == 0 { if le >= total { fe = 1 } else { if buf[le]==(10 as u8) { fe = 1 } else { le = le + 1 } } } 35 i = le + 1 36 if lineno > 0 { 37 var p: i64 = ls; var d: i64 = 0 38 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { p = p + 1 } else { d = 1 } } } // skip leading spaces 39 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { d = 1 } else { p = p + 1 } } } // skip token0 (sl) 40 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { p = p + 1 } else { d = 1 } } } // skip spaces 41 let t1: i64 = p 42 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { d = 1 } else { p = p + 1 } } } // token1 = local_addr [t1,p) 43 let te: i64 = p 44 var colon: i64 = 0 - 1; var q: i64 = t1 45 while q < te { if buf[q]==(58 as u8) { colon = q } q = q + 1 } // ':' in local_addr 46 var port: i64 = 0 47 if colon >= 0 { var h: i64 = colon + 1; while h < te { let hv: i64 = pa_hv(buf[h] as i64); if hv >= 0 { port = port*16 + hv } h = h + 1 } } 48 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { p = p + 1 } else { d = 1 } } } // skip spaces 49 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { d = 1 } else { p = p + 1 } } } // skip token2 (rem) 50 d = 0; while d == 0 { if p >= le { d = 1 } else { if buf[p]==(32 as u8) { p = p + 1 } else { d = 1 } } } // skip spaces -> token3 = st 51 if p + 1 < le { if buf[p]==(48 as u8) { if buf[p+1]==(65 as u8) { if n < cap { out[n] = port; n = n + 1 } } } } // "0A" = LISTEN 52 } 53 lineno = lineno + 1 54 } 55 return n 56} 57 58func pa_check(ports: *i64, np: i64, port: i64, name: *u8) -> i64 { 59 var found: i64 = 0; var i: i64 = 0; while i < np { if ports[i] == port { found = 1 } i = i + 1 } 60 pa_p(" :" as *u8); pa_n(port); pa_p(" " as *u8); pa_p(name); pa_p(" -> " as *u8) 61 if found == 1 { pa_p("LISTENING\n" as *u8) } else { pa_p("DOWN (pidfile may CLAIM up, but nothing is bound)\n" as *u8) } 62 return found 63} 64 65// ---- SSOT-DRIVEN AUDIT (2026-08-07) --------------------------------------------------------- 66// WAS: seven hardcoded PA_MAGIC_* ports, i.e. 7 of the 46 services actually listening -- an audit 67// covering 15% of the estate that could never notice a new service or a moved one. The port map now 68// lives in knowledge/status/portmap.conf (rule 11: data, not code), so this reads every declared row. 69// REFUSES on a missing registry rather than printing an all-clear: an audit that silently checks 70// nothing is the precondition lie -- "I could not look" must never wear the same word as "all good". 71const PA_CONF: *u8 = "knowledge/status/portmap.conf" 72const PA_CONFCAP: i64 = 65536 73const PA_HASH: i64 = 35 74const PA_TABC: i64 = 9 75const PA_LF: i64 = 10 76 77func pa_eol(buf: *u8, from: i64, total: i64) -> i64 { 78 var k: i64 = from 79 while k < total { if (buf[k] as i64) == PA_LF { return k } k = k + 1 } 80 return total 81} 82func pa_tabpos(buf: *u8, from: i64, eol: i64) -> i64 { 83 var k: i64 = from 84 while k < eol { if (buf[k] as i64) == PA_TABC { return k } k = k + 1 } 85 return 0 - 1 86} 87 88// returns rows audited, or -1 when the registry is absent; down_out[0] = count of DECLARED-but-DOWN 89func pa_audit_conf(ports: *i64, np: i64, down_out: *i64) -> i64 { 90 let fd: i64 = sys_openat_rd(PA_CONF) 91 if fd < 0 { return 0 - 1 } 92 let buf: *u8 = sys_mmap(PA_CONFCAP) 93 var total: i64 = 0 94 var r: i64 = 1 95 while r > 0 { r = sys_read(fd, ((buf as i64)+total) as *u8, PA_CONFCAP-total); if r > 0 { total = total + r } } 96 sys_close(fd) 97 var i: i64 = 0 98 var rows: i64 = 0 99 var down: i64 = 0 100 while i < total { 101 let e: i64 = pa_eol(buf, i, total) 102 if (buf[i] as i64) != PA_HASH { 103 let t: i64 = pa_tabpos(buf, i, e) 104 if t > i { 105 var p: i64 = 0 106 var k: i64 = i 107 while k < t { let c: i64 = buf[k] as i64; if c >= 48 { if c <= 57 { p = p * 10 + (c - 48) } } k = k + 1 } 108 if p > 0 { 109 buf[e] = 0 as u8 110 if pa_check(ports, np, p, ((buf as i64) + t + 1) as *u8) == 0 { down = down + 1 } 111 rows = rows + 1 112 } 113 } 114 } 115 i = e + 1 116 } 117 down_out[0] = down 118 return rows 119} 120 121func main() -> i64 { 122 pa_p("=== NISHI PORT AUDIT (LISTENING vs CLAIMED) ===\n" as *u8) 123 let ports: *i64 = sys_mmap(8*PA_CAP) as *i64 124 let np4: i64 = pa_scan_file("/proc/net/tcp" as *u8, ports, 0, PA_CAP) 125 let np: i64 = pa_scan_file("/proc/net/tcp6" as *u8, ports, np4, PA_CAP) // include IPv6 LISTENers (dual-stack daemons) 126 pa_p("total LISTEN ports (tcp+tcp6)=" as *u8); pa_n(np); pa_p("\n" as *u8) 127 let dn: *i64 = sys_mmap(8) as *i64 128 dn[0] = 0 129 let rows: i64 = pa_audit_conf(ports, np, dn) 130 if rows < 0 { 131 pa_p("REFUSED: knowledge/status/portmap.conf is ABSENT -- audited NOTHING.\n" as *u8) 132 pa_p(" This is not an all-clear. Restore the registry, then re-run.\n" as *u8) 133 sys_exit(2); return 2 134 } 135 pa_p("audited " as *u8); pa_n(rows); pa_p(" declared ports, DOWN=" as *u8); pa_n(dn[0]); pa_p("\n" as *u8) 136 // The exit code now MEANS something. It used to be sys_exit(0) unconditionally, so a service 137 // being down could never fail anything and nothing could gate on this organ -- a report wearing 138 // a gate name. 0 = every declared port is bound, 1 = at least one declared service is DOWN, 139 // 2 = registry missing (could not look). 140 if dn[0] > 0 { sys_exit(1); return 1 } 141 sys_exit(0); return 0 142}