code wiki / _hdl_build / nx_doh_probe.nx

nx_doh_probe.nx source

↩ module page · 77 lines · 3881 B

1// nx_doh_probe.nx -- SOVEREIGN DNS-over-HTTPS probe: the TRUE public A record even when the LAN 2// transparently intercepts port-53 UDP (split-horizon). Queries dns.google's RFC-8484-style JSON API 3// (https://dns.google/resolve?name=<host>&type=A) over the sovereign TLS-1.3 client + Mozilla trust 4// store -- HTTPS the interceptor cannot rewrite -- and prints the "data":"a.b.c.d" answers. This is the 5// discriminator: if DoH returns a PUBLIC ip but nx_dns_probe (plain UDP) returns a PRIVATE 192.168.x, 6// the LAN is doing split-horizon and the PUBLIC record is fine; if DoH ALSO returns the private ip, 7// the authoritative record is genuinely broken (external users can't reach it). 8// usage: nx_doh_probe [<host> ...] (defaults to the andelinwest/nishifamily edge set) 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_trust_store_load_from_certdata.nx" 12import "nx_https_fetch_follow.nx" 13const K_MAGIC_65536: i64 = 65536 14const K_MAGIC_4194304: i64 = 4194304 15 16func dh_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 17func dh_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 18func dh_putn(v: i64) -> i64 { let b: *u8=sys_mmap(24); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(24); 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} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 19 20// find every occurrence of `"data":"` in body and print the quoted value (an A-record answer or CNAME) 21func dh_print_data(body: *u8, n: i64) -> i64 { 22 let key: *u8 = "\"data\":\"" as *u8 23 let kl: i64 = 8 24 var found: i64 = 0 25 var i: i64 = 0 26 while i + kl <= n { 27 var m: i64 = 1 28 var j: i64 = 0 29 while j < kl { if (body[i+j] as i64) != (key[j] as i64) { m = 0; j = kl } else { j = j + 1 } } 30 if m == 1 { 31 var k: i64 = i + kl 32 dh_puts(" data=" as *u8) 33 while k < n { if (body[k] as i64) == 34 { k = n } else { sys_write(1, ((body as i64)+k) as *u8, 1); k = k + 1 } } 34 dh_puts("\n" as *u8) 35 found = found + 1 36 i = i + kl 37 } else { i = i + 1 } 38 } 39 if found == 0 { dh_puts(" (no data field -- check Status/Answer below)\n" as *u8) } 40 return found 41} 42 43func dh_one(store: *TrustStore, host: *u8) -> i64 { 44 let url: *u8 = sys_mmap(512) 45 var o: i64 = 0 46 let p1: *u8 = "https://dns.google/resolve?type=A&name=" as *u8 47 var i: i64 = 0 48 while p1[i] != (0 as u8) { url[o] = p1[i]; o = o + 1; i = i + 1 } 49 i = 0 50 while host[i] != (0 as u8) { url[o] = host[i]; o = o + 1; i = i + 1 } 51 url[o] = 0 as u8 52 dh_puts(" " as *u8); dh_puts(host); dh_puts(" (DoH dns.google):\n" as *u8) 53 let out: *u8 = sys_mmap(K_MAGIC_65536) 54 let stbox: *i64 = sys_mmap(16) as *i64 55 stbox[0] = 0 56 let n: i64 = nx_https_fetch_follow(url, store, out, K_MAGIC_65536, 4, stbox) 57 if n <= 0 { dh_puts(" FETCH-FAIL rc=" as *u8); dh_putn(n); dh_puts(" status=" as *u8); dh_putn(stbox[0]); dh_puts("\n" as *u8); return 0 } 58 dh_print_data(out, n) 59 return 0 60} 61 62func main(argc: i64, argv: *i64) -> i64 { 63 dh_puts("=== nx_doh_probe: TRUE public A record over DNS-over-HTTPS (bypasses LAN :53 interception) ===\n" as *u8) 64 let r: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt\x00" as *u8, 512, K_MAGIC_4194304) 65 if r <= 0 { dh_puts("certdata load failed\n" as *u8); return 1 } 66 let store: *TrustStore = r as *TrustStore 67 if argc > 1 { 68 var i: i64 = 1 69 while i < argc { dh_one(store, argv[i] as *u8); i = i + 1 } 70 return 0 71 } 72 dh_one(store, "andelinwest.com" as *u8) 73 dh_one(store, "admin.andelinwest.com" as *u8) 74 dh_one(store, "mail.andelinwest.com" as *u8) 75 dh_one(store, "nishifamily.com" as *u8) 76 return 0 77}