[{"data":1,"prerenderedAt":3775},["ShallowReactive",2],{"post:\u002F2026\u002F02\u002F11\u002Fnode-js-discovery-scanning-a-subnet-for-open-rdp-and-ssh\u002F":3},{"post":4,"newer":3729,"older":3738,"related":3749,"series":3773},{"id":5,"title":6,"body":7,"canonical":3708,"categories":3709,"date":3712,"description":3713,"extension":3714,"featured":3715,"hero":3716,"image":3716,"meta":3717,"navigation":275,"path":3718,"readingTime":191,"seo":3719,"series":3716,"seriesOrder":3716,"sites":3720,"source":3716,"stem":3721,"tags":3722,"updated":3716,"url":3727,"__hash__":3728},"blog\u002Fblog\u002F2026\u002F02\u002F11\u002Fnode-js-discovery-scanning-a-subnet-for-open-rdp-and-ssh.md","Node.js: Discovery – Scanning a Subnet for Open RDP and SSH",{"type":8,"value":9,"toc":3701},"minimark",[10,14,28,33,66,70,73,98,101,143,146,154,166,170,3541,3545,3639,3643,3697],[11,12,13],"p",{},"Before I trust a network diagram, I like to check it against reality, and the fastest reality check I know is \"what's actually listening.\" Nmap is the right tool for a serious scan, but when I just want a quick answer to \"which hosts on this \u002F24 have RDP or SSH open\" from inside a script or a CI job without pulling in a system dependency, a plain Node.js TCP connect scan does the job with nothing beyond the standard library.",[11,15,16,17,22,23,27],{},"It's the routed-subnet counterpart to the ",[18,19,21],"a",{"href":20},"\u002F2026\u002F01\u002F07\u002Fpython-discovery-fingerprint-every-device-on-a-subnet\u002F","Python ARP fingerprinting script"," (ARP only sees your own VLAN; a TCP connect works across routers) and one of the collectors in the ",[18,24,26],{"href":25},"\u002F2026\u002F07\u002F15\u002Finfrastructure-a-discovery-first-approach-to-documenting-an-undocumented-network\u002F","discovery-first approach to documenting an undocumented network",".",[29,30,32],"h2",{"id":31},"requirements","Requirements",[34,35,36,52,63],"ul",{},[37,38,39,40,44,45,48,49,27],"li",{},"A supported Node.js LTS release (22 or later). Only the built-in ",[41,42,43],"code",{},"net"," and ",[41,46,47],{},"fs"," modules are used; no ",[41,50,51],{},"npm install",[37,53,54,55,58,59,62],{},"Network reachability from wherever the script runs to the target subnet. No root needed: a TCP connect scan uses the operating system's normal ",[41,56,57],{},"connect()"," call, the same thing nmap falls back to (",[41,60,61],{},"-sT",") when it lacks raw-packet privileges.",[37,64,65],{},"Written authorization to scan the target range. It's a plain connect scan, not a stealth technique, but scanning a network you don't own or manage without permission is not okay regardless of how the scan is implemented.",[29,67,69],{"id":68},"usage","Usage",[11,71,72],{},"Scan a \u002F24 for the default ports (22 and 3389):",[74,75,80],"pre",{"className":76,"code":77,"language":78,"meta":79,"style":79},"language-bash shiki shiki-themes github-dark","node scan-subnet.js 10.0.10.0\u002F24\n","bash","",[41,81,82],{"__ignoreMap":79},[83,84,87,91,95],"span",{"class":85,"line":86},"line",1,[83,88,90],{"class":89},"svObZ","node",[83,92,94],{"class":93},"sU2Wk"," scan-subnet.js",[83,96,97],{"class":93}," 10.0.10.0\u002F24\n",[11,99,100],{},"Scan a smaller range for a custom port list (adding WinRM on 5985) with a longer per-connection timeout for a slow WAN link, and write every result, not just open ones, to CSV:",[74,102,104],{"className":76,"code":103,"language":78,"meta":79,"style":79},"node scan-subnet.js 10.0.10.0\u002F28 --ports 22,3389,5985 --timeout 1500 --concurrency 50 --all --csv results.csv\n",[41,105,106],{"__ignoreMap":79},[83,107,108,110,112,115,119,122,125,128,131,134,137,140],{"class":85,"line":86},[83,109,90],{"class":89},[83,111,94],{"class":93},[83,113,114],{"class":93}," 10.0.10.0\u002F28",[83,116,118],{"class":117},"sDLfK"," --ports",[83,120,121],{"class":93}," 22,3389,5985",[83,123,124],{"class":117}," --timeout",[83,126,127],{"class":117}," 1500",[83,129,130],{"class":117}," --concurrency",[83,132,133],{"class":117}," 50",[83,135,136],{"class":117}," --all",[83,138,139],{"class":117}," --csv",[83,141,142],{"class":93}," results.csv\n",[11,144,145],{},"Sample output from the default run:",[74,147,152],{"className":148,"code":150,"language":151,"meta":79},[149],"language-text","Scanning 10.0.10.0\u002F24 (254 host(s)) for ports [22, 3389]\nConcurrency: 100, timeout: 500ms per attempt\n\n10.0.10.12     22\u002Ftcp open     (ssh)  SSH-2.0-OpenSSH_9.6\n10.0.10.45     3389\u002Ftcp open     (rdp)\n10.0.10.201    22\u002Ftcp open     (ssh)  SSH-2.0-OpenSSH_8.7\n10.0.10.201    3389\u002Ftcp open     (rdp)\n\nScan complete in 4.8s. 3 host(s) with at least one open port out of 254 scanned.\nStates: open 4, closed 61, filtered 443\n","text",[41,153,150],{"__ignoreMap":79},[11,155,156,157,161,162,165],{},"The last line is the useful part for an exposure check. ",[158,159,160],"strong",{},"Closed"," means the host answered with a TCP reset (it's alive, nothing listening). ",[158,163,164],{},"Filtered"," means no answer before the timeout (no host there, or a firewall silently dropping the connection) or any other connection error, such as host or network unreachable.",[29,167,169],{"id":168},"script","Script",[74,171,175],{"className":172,"code":173,"language":174,"meta":79,"style":79},"language-javascript shiki shiki-themes github-dark","\u002F**\n * scan-subnet.js\n *\n * Dependency-free TCP connect scanner for a small set of ports (SSH\u002FRDP by default)\n * across every usable host in an IPv4 CIDR range. Classifies each attempt as open,\n * closed (ECONNREFUSED) or filtered (timeout \u002F unreachable), and records the SSH\n * identification string where the server sends one.\n *\n * Reads: command-line arguments only.\n * Writes: stdout, and a CSV file when --csv is given.\n *\n * Usage:\n *   node scan-subnet.js \u003Ccidr> [--ports 22,3389] [--timeout 500] [--concurrency 100] [--all] [--csv out.csv]\n *\n * Only run this against networks you are authorized to scan.\n *\u002F\n\n'use strict';\n\nconst fs = require('fs');\nconst net = require('net');\n\nconst SERVICE_NAMES = { 22: 'ssh', 3389: 'rdp', 5985: 'winrm-http', 5986: 'winrm-https' };\nconst BANNER_PORTS = new Set([22]);\n\nfunction parseArgs(argv) {\n    const args = { cidr: null, ports: [22, 3389], timeout: 500, concurrency: 100, all: false, csv: null };\n\n    for (let i = 0; i \u003C argv.length; i++) {\n        const arg = argv[i];\n        if (arg === '--ports') {\n            args.ports = argv[++i].split(',').map((p) => parseInt(p.trim(), 10));\n        } else if (arg === '--timeout') {\n            args.timeout = parseInt(argv[++i], 10);\n        } else if (arg === '--concurrency') {\n            args.concurrency = parseInt(argv[++i], 10);\n        } else if (arg === '--csv') {\n            args.csv = argv[++i];\n        } else if (arg === '--all') {\n            args.all = true;\n        } else if (!args.cidr) {\n            args.cidr = arg;\n        }\n    }\n\n    if (!args.cidr) {\n        throw new Error('Usage: node scan-subnet.js \u003Ccidr> [--ports 22,3389] [--timeout 500] [--concurrency 100] [--all] [--csv out.csv]');\n    }\n    if (args.ports.some((p) => !Number.isInteger(p) || p \u003C 1 || p > 65535)) {\n        throw new Error('Ports must be integers between 1 and 65535.');\n    }\n    if (!Number.isInteger(args.timeout) || args.timeout \u003C 1 || !Number.isInteger(args.concurrency) || args.concurrency \u003C 1) {\n        throw new Error('--timeout and --concurrency must be positive integers.');\n    }\n    return args;\n}\n\nfunction ipToInt(ip) {\n    return ip.split('.').reduce((acc, octet) => ((acc \u003C\u003C 8) + parseInt(octet, 10)) >>> 0, 0);\n}\n\nfunction intToIp(int) {\n    return [24, 16, 8, 0].map((shift) => (int >>> shift) & 255).join('.');\n}\n\nfunction expandCidr(cidr) {\n    const [base, prefixStr] = cidr.split('\u002F');\n    const prefix = parseInt(prefixStr ?? '32', 10);\n\n    if (!net.isIPv4(base)) {\n        throw new Error(`Not an IPv4 address: ${base}`);\n    }\n    if (!Number.isInteger(prefix) || prefix \u003C 16 || prefix > 32) {\n        throw new Error(`Prefix \u002F${prefixStr} out of range: use \u002F16 to \u002F32.`);\n    }\n\n    const size = 2 ** (32 - prefix);\n    const network = (ipToInt(base) & ((0xffffffff \u003C\u003C (32 - prefix)) >>> 0)) >>> 0;\n\n    \u002F\u002F \u002F31 and \u002F32 have no network\u002Fbroadcast addresses to skip (RFC 3021 for \u002F31).\n    const first = prefix >= 31 ? 0 : 1;\n    const last = prefix >= 31 ? size - 1 : size - 2;\n\n    const ips = [];\n    for (let i = first; i \u003C= last; i++) {\n        ips.push(intToIp((network + i) >>> 0));\n    }\n    return ips;\n}\n\nfunction checkPort(host, port, timeoutMs) {\n    return new Promise((resolve) => {\n        const socket = new net.Socket();\n        let state = null;\n        let banner = '';\n\n        const finish = (result) => {\n            if (state) {\n                return;\n            }\n            state = result;\n            \u002F\u002F A 'timeout' event does not close the socket by itself; destroy() does.\n            socket.destroy();\n            resolve({ host, port, state, banner });\n        };\n\n        socket.setTimeout(timeoutMs);\n        socket.once('connect', () => {\n            if (!BANNER_PORTS.has(port)) {\n                finish('open');\n                return;\n            }\n            \u002F\u002F Both sides send an identification string (RFC 4253 section 4.2); servers\n            \u002F\u002F normally send theirs without waiting. Buffer until the SSH- line is complete,\n            \u002F\u002F since it can be split across chunks or follow other lines.\n            let received = '';\n            socket.on('data', (chunk) => {\n                received += chunk.toString('utf8');\n                const lines = received.split('\\n');\n                const line = lines.slice(0, -1).find((l) => l.startsWith('SSH-'));\n                if (line || received.length > 8192) {\n                    banner = line ? line.trim() : '';\n                    finish('open');\n                }\n            });\n            \u002F\u002F The server may accept and then hang up without sending anything.\n            socket.once('close', () => finish('open'));\n        });\n        socket.once('timeout', () => finish(socket.connecting ? 'filtered' : 'open'));\n        socket.once('error', (error) => finish(error.code === 'ECONNREFUSED' ? 'closed' : 'filtered'));\n\n        socket.connect(port, host);\n    });\n}\n\nasync function asyncPool(limit, items, iteratorFn) {\n    const results = [];\n    const executing = new Set();\n\n    for (const item of items) {\n        const promise = Promise.resolve().then(() => iteratorFn(item));\n        results.push(promise);\n        executing.add(promise);\n        const cleanup = () => executing.delete(promise);\n        promise.then(cleanup, cleanup);\n        if (executing.size >= limit) {\n            await Promise.race(executing);\n        }\n    }\n    return Promise.all(results);\n}\n\nfunction csvEscape(value) {\n    const text = String(value ?? '');\n    return \u002F[\",\\n]\u002F.test(text) ? `\"${text.replace(\u002F\"\u002Fg, '\"\"')}\"` : text;\n}\n\nasync function main() {\n    const args = parseArgs(process.argv.slice(2));\n    const hosts = expandCidr(args.cidr);\n\n    console.log(`Scanning ${args.cidr} (${hosts.length} host(s)) for ports [${args.ports.join(', ')}]`);\n    console.log(`Concurrency: ${args.concurrency}, timeout: ${args.timeout}ms per attempt`);\n    console.log('');\n\n    const startTime = Date.now();\n    const targets = hosts.flatMap((host) => args.ports.map((port) => ({ host, port })));\n\n    const results = await asyncPool(args.concurrency, targets, async ({ host, port }) => {\n        const result = await checkPort(host, port, args.timeout);\n        if (result.state === 'open' || args.all) {\n            const service = SERVICE_NAMES[port] ? `(${SERVICE_NAMES[port]})` : '';\n            console.log(`${host.padEnd(15)}${`${port}\u002Ftcp`} ${result.state.padEnd(8)} ${service}  ${result.banner}`.trimEnd());\n        }\n        return result;\n    });\n\n    const counts = { open: 0, closed: 0, filtered: 0 };\n    const openHosts = new Set();\n    for (const result of results) {\n        counts[result.state]++;\n        if (result.state === 'open') {\n            openHosts.add(result.host);\n        }\n    }\n\n    if (args.csv) {\n        const rows = (args.all ? results : results.filter((r) => r.state === 'open'))\n            .map((r) => [r.host, r.port, SERVICE_NAMES[r.port] ?? '', r.state, r.banner].map(csvEscape).join(','));\n        fs.writeFileSync(args.csv, ['ip_address,port,service,state,banner', ...rows].join('\\n') + '\\n', 'utf8');\n    }\n\n    const elapsedSeconds = ((Date.now() - startTime) \u002F 1000).toFixed(1);\n    console.log('');\n    console.log(`Scan complete in ${elapsedSeconds}s. ${openHosts.size} host(s) with at least one open port out of ${hosts.length} scanned.`);\n    console.log(`States: open ${counts.open}, closed ${counts.closed}, filtered ${counts.filtered}`);\n}\n\nmain().catch((error) => {\n    console.error(error.message);\n    process.exitCode = 1;\n});\n","javascript",[41,176,177,183,189,195,201,207,213,219,224,230,236,241,247,253,258,264,270,277,287,292,317,336,341,397,421,426,444,495,500,541,555,572,631,652,674,692,712,730,745,763,776,793,804,810,816,821,833,851,856,912,928,933,980,996,1001,1010,1016,1021,1036,1106,1111,1116,1131,1195,1200,1205,1220,1252,1279,1284,1302,1323,1328,1365,1386,1391,1396,1423,1473,1478,1484,1514,1550,1555,1568,1594,1622,1627,1635,1640,1645,1670,1692,1713,1729,1744,1749,1770,1779,1787,1793,1804,1810,1821,1830,1836,1841,1853,1873,1893,1906,1913,1918,1924,1930,1936,1951,1976,1998,2026,2080,2103,2132,2144,2150,2156,2162,2186,2192,2225,2267,2272,2283,2289,2294,2299,2328,2340,2356,2361,2379,2412,2423,2434,2457,2468,2481,2497,2502,2507,2522,2527,2532,2547,2569,2632,2637,2642,2655,2678,2693,2698,2755,2789,2803,2808,2826,2866,2871,2906,2923,2940,2981,3059,3064,3072,3077,3082,3109,3125,3141,3151,3164,3175,3180,3185,3190,3198,3243,3287,3337,3342,3347,3385,3398,3438,3482,3487,3492,3513,3523,3535],{"__ignoreMap":79},[83,178,179],{"class":85,"line":86},[83,180,182],{"class":181},"sAwPA","\u002F**\n",[83,184,186],{"class":85,"line":185},2,[83,187,188],{"class":181}," * scan-subnet.js\n",[83,190,192],{"class":85,"line":191},3,[83,193,194],{"class":181}," *\n",[83,196,198],{"class":85,"line":197},4,[83,199,200],{"class":181}," * Dependency-free TCP connect scanner for a small set of ports (SSH\u002FRDP by default)\n",[83,202,204],{"class":85,"line":203},5,[83,205,206],{"class":181}," * across every usable host in an IPv4 CIDR range. Classifies each attempt as open,\n",[83,208,210],{"class":85,"line":209},6,[83,211,212],{"class":181}," * closed (ECONNREFUSED) or filtered (timeout \u002F unreachable), and records the SSH\n",[83,214,216],{"class":85,"line":215},7,[83,217,218],{"class":181}," * identification string where the server sends one.\n",[83,220,222],{"class":85,"line":221},8,[83,223,194],{"class":181},[83,225,227],{"class":85,"line":226},9,[83,228,229],{"class":181}," * Reads: command-line arguments only.\n",[83,231,233],{"class":85,"line":232},10,[83,234,235],{"class":181}," * Writes: stdout, and a CSV file when --csv is given.\n",[83,237,239],{"class":85,"line":238},11,[83,240,194],{"class":181},[83,242,244],{"class":85,"line":243},12,[83,245,246],{"class":181}," * Usage:\n",[83,248,250],{"class":85,"line":249},13,[83,251,252],{"class":181}," *   node scan-subnet.js \u003Ccidr> [--ports 22,3389] [--timeout 500] [--concurrency 100] [--all] [--csv out.csv]\n",[83,254,256],{"class":85,"line":255},14,[83,257,194],{"class":181},[83,259,261],{"class":85,"line":260},15,[83,262,263],{"class":181}," * Only run this against networks you are authorized to scan.\n",[83,265,267],{"class":85,"line":266},16,[83,268,269],{"class":181}," *\u002F\n",[83,271,273],{"class":85,"line":272},17,[83,274,276],{"emptyLinePlaceholder":275},true,"\n",[83,278,280,283],{"class":85,"line":279},18,[83,281,282],{"class":93},"'use strict'",[83,284,286],{"class":285},"s95oV",";\n",[83,288,290],{"class":85,"line":289},19,[83,291,276],{"emptyLinePlaceholder":275},[83,293,295,299,302,305,308,311,314],{"class":85,"line":294},20,[83,296,298],{"class":297},"snl16","const",[83,300,301],{"class":117}," fs",[83,303,304],{"class":297}," =",[83,306,307],{"class":89}," require",[83,309,310],{"class":285},"(",[83,312,313],{"class":93},"'fs'",[83,315,316],{"class":285},");\n",[83,318,320,322,325,327,329,331,334],{"class":85,"line":319},21,[83,321,298],{"class":297},[83,323,324],{"class":117}," net",[83,326,304],{"class":297},[83,328,307],{"class":89},[83,330,310],{"class":285},[83,332,333],{"class":93},"'net'",[83,335,316],{"class":285},[83,337,339],{"class":85,"line":338},22,[83,340,276],{"emptyLinePlaceholder":275},[83,342,344,346,349,351,354,357,360,363,366,369,371,374,376,379,381,384,386,389,391,394],{"class":85,"line":343},23,[83,345,298],{"class":297},[83,347,348],{"class":117}," SERVICE_NAMES",[83,350,304],{"class":297},[83,352,353],{"class":285}," { ",[83,355,356],{"class":117},"22",[83,358,359],{"class":285},": ",[83,361,362],{"class":93},"'ssh'",[83,364,365],{"class":285},", ",[83,367,368],{"class":117},"3389",[83,370,359],{"class":285},[83,372,373],{"class":93},"'rdp'",[83,375,365],{"class":285},[83,377,378],{"class":117},"5985",[83,380,359],{"class":285},[83,382,383],{"class":93},"'winrm-http'",[83,385,365],{"class":285},[83,387,388],{"class":117},"5986",[83,390,359],{"class":285},[83,392,393],{"class":93},"'winrm-https'",[83,395,396],{"class":285}," };\n",[83,398,400,402,405,407,410,413,416,418],{"class":85,"line":399},24,[83,401,298],{"class":297},[83,403,404],{"class":117}," BANNER_PORTS",[83,406,304],{"class":297},[83,408,409],{"class":297}," new",[83,411,412],{"class":89}," Set",[83,414,415],{"class":285},"([",[83,417,356],{"class":117},[83,419,420],{"class":285},"]);\n",[83,422,424],{"class":85,"line":423},25,[83,425,276],{"emptyLinePlaceholder":275},[83,427,429,432,435,437,441],{"class":85,"line":428},26,[83,430,431],{"class":297},"function",[83,433,434],{"class":89}," parseArgs",[83,436,310],{"class":285},[83,438,440],{"class":439},"s9osk","argv",[83,442,443],{"class":285},") {\n",[83,445,447,450,453,455,458,461,464,466,468,470,473,476,479,482,485,488,491,493],{"class":85,"line":446},27,[83,448,449],{"class":297},"    const",[83,451,452],{"class":117}," args",[83,454,304],{"class":297},[83,456,457],{"class":285}," { cidr: ",[83,459,460],{"class":117},"null",[83,462,463],{"class":285},", ports: [",[83,465,356],{"class":117},[83,467,365],{"class":285},[83,469,368],{"class":117},[83,471,472],{"class":285},"], timeout: ",[83,474,475],{"class":117},"500",[83,477,478],{"class":285},", concurrency: ",[83,480,481],{"class":117},"100",[83,483,484],{"class":285},", all: ",[83,486,487],{"class":117},"false",[83,489,490],{"class":285},", csv: ",[83,492,460],{"class":117},[83,494,396],{"class":285},[83,496,498],{"class":85,"line":497},28,[83,499,276],{"emptyLinePlaceholder":275},[83,501,503,506,509,512,515,518,521,524,527,530,533,536,539],{"class":85,"line":502},29,[83,504,505],{"class":297},"    for",[83,507,508],{"class":285}," (",[83,510,511],{"class":297},"let",[83,513,514],{"class":285}," i ",[83,516,517],{"class":297},"=",[83,519,520],{"class":117}," 0",[83,522,523],{"class":285},"; i ",[83,525,526],{"class":297},"\u003C",[83,528,529],{"class":285}," argv.",[83,531,532],{"class":117},"length",[83,534,535],{"class":285},"; i",[83,537,538],{"class":297},"++",[83,540,443],{"class":285},[83,542,544,547,550,552],{"class":85,"line":543},30,[83,545,546],{"class":297},"        const",[83,548,549],{"class":117}," arg",[83,551,304],{"class":297},[83,553,554],{"class":285}," argv[i];\n",[83,556,558,561,564,567,570],{"class":85,"line":557},31,[83,559,560],{"class":297},"        if",[83,562,563],{"class":285}," (arg ",[83,565,566],{"class":297},"===",[83,568,569],{"class":93}," '--ports'",[83,571,443],{"class":285},[83,573,575,578,580,583,585,588,591,593,596,599,602,605,607,610,613,616,619,622,625,628],{"class":85,"line":574},32,[83,576,577],{"class":285},"            args.ports ",[83,579,517],{"class":297},[83,581,582],{"class":285}," argv[",[83,584,538],{"class":297},[83,586,587],{"class":285},"i].",[83,589,590],{"class":89},"split",[83,592,310],{"class":285},[83,594,595],{"class":93},"','",[83,597,598],{"class":285},").",[83,600,601],{"class":89},"map",[83,603,604],{"class":285},"((",[83,606,11],{"class":439},[83,608,609],{"class":285},") ",[83,611,612],{"class":297},"=>",[83,614,615],{"class":89}," parseInt",[83,617,618],{"class":285},"(p.",[83,620,621],{"class":89},"trim",[83,623,624],{"class":285},"(), ",[83,626,627],{"class":117},"10",[83,629,630],{"class":285},"));\n",[83,632,634,637,640,643,645,647,650],{"class":85,"line":633},33,[83,635,636],{"class":285},"        } ",[83,638,639],{"class":297},"else",[83,641,642],{"class":297}," if",[83,644,563],{"class":285},[83,646,566],{"class":297},[83,648,649],{"class":93}," '--timeout'",[83,651,443],{"class":285},[83,653,655,658,660,662,665,667,670,672],{"class":85,"line":654},34,[83,656,657],{"class":285},"            args.timeout ",[83,659,517],{"class":297},[83,661,615],{"class":89},[83,663,664],{"class":285},"(argv[",[83,666,538],{"class":297},[83,668,669],{"class":285},"i], ",[83,671,627],{"class":117},[83,673,316],{"class":285},[83,675,677,679,681,683,685,687,690],{"class":85,"line":676},35,[83,678,636],{"class":285},[83,680,639],{"class":297},[83,682,642],{"class":297},[83,684,563],{"class":285},[83,686,566],{"class":297},[83,688,689],{"class":93}," '--concurrency'",[83,691,443],{"class":285},[83,693,695,698,700,702,704,706,708,710],{"class":85,"line":694},36,[83,696,697],{"class":285},"            args.concurrency ",[83,699,517],{"class":297},[83,701,615],{"class":89},[83,703,664],{"class":285},[83,705,538],{"class":297},[83,707,669],{"class":285},[83,709,627],{"class":117},[83,711,316],{"class":285},[83,713,715,717,719,721,723,725,728],{"class":85,"line":714},37,[83,716,636],{"class":285},[83,718,639],{"class":297},[83,720,642],{"class":297},[83,722,563],{"class":285},[83,724,566],{"class":297},[83,726,727],{"class":93}," '--csv'",[83,729,443],{"class":285},[83,731,733,736,738,740,742],{"class":85,"line":732},38,[83,734,735],{"class":285},"            args.csv ",[83,737,517],{"class":297},[83,739,582],{"class":285},[83,741,538],{"class":297},[83,743,744],{"class":285},"i];\n",[83,746,748,750,752,754,756,758,761],{"class":85,"line":747},39,[83,749,636],{"class":285},[83,751,639],{"class":297},[83,753,642],{"class":297},[83,755,563],{"class":285},[83,757,566],{"class":297},[83,759,760],{"class":93}," '--all'",[83,762,443],{"class":285},[83,764,766,769,771,774],{"class":85,"line":765},40,[83,767,768],{"class":285},"            args.all ",[83,770,517],{"class":297},[83,772,773],{"class":117}," true",[83,775,286],{"class":285},[83,777,779,781,783,785,787,790],{"class":85,"line":778},41,[83,780,636],{"class":285},[83,782,639],{"class":297},[83,784,642],{"class":297},[83,786,508],{"class":285},[83,788,789],{"class":297},"!",[83,791,792],{"class":285},"args.cidr) {\n",[83,794,796,799,801],{"class":85,"line":795},42,[83,797,798],{"class":285},"            args.cidr ",[83,800,517],{"class":297},[83,802,803],{"class":285}," arg;\n",[83,805,807],{"class":85,"line":806},43,[83,808,809],{"class":285},"        }\n",[83,811,813],{"class":85,"line":812},44,[83,814,815],{"class":285},"    }\n",[83,817,819],{"class":85,"line":818},45,[83,820,276],{"emptyLinePlaceholder":275},[83,822,824,827,829,831],{"class":85,"line":823},46,[83,825,826],{"class":297},"    if",[83,828,508],{"class":285},[83,830,789],{"class":297},[83,832,792],{"class":285},[83,834,836,839,841,844,846,849],{"class":85,"line":835},47,[83,837,838],{"class":297},"        throw",[83,840,409],{"class":297},[83,842,843],{"class":89}," Error",[83,845,310],{"class":285},[83,847,848],{"class":93},"'Usage: node scan-subnet.js \u003Ccidr> [--ports 22,3389] [--timeout 500] [--concurrency 100] [--all] [--csv out.csv]'",[83,850,316],{"class":285},[83,852,854],{"class":85,"line":853},48,[83,855,815],{"class":285},[83,857,859,861,864,867,869,871,873,875,878,881,884,887,890,893,895,898,901,903,906,909],{"class":85,"line":858},49,[83,860,826],{"class":297},[83,862,863],{"class":285}," (args.ports.",[83,865,866],{"class":89},"some",[83,868,604],{"class":285},[83,870,11],{"class":439},[83,872,609],{"class":285},[83,874,612],{"class":297},[83,876,877],{"class":297}," !",[83,879,880],{"class":285},"Number.",[83,882,883],{"class":89},"isInteger",[83,885,886],{"class":285},"(p) ",[83,888,889],{"class":297},"||",[83,891,892],{"class":285}," p ",[83,894,526],{"class":297},[83,896,897],{"class":117}," 1",[83,899,900],{"class":297}," ||",[83,902,892],{"class":285},[83,904,905],{"class":297},">",[83,907,908],{"class":117}," 65535",[83,910,911],{"class":285},")) {\n",[83,913,915,917,919,921,923,926],{"class":85,"line":914},50,[83,916,838],{"class":297},[83,918,409],{"class":297},[83,920,843],{"class":89},[83,922,310],{"class":285},[83,924,925],{"class":93},"'Ports must be integers between 1 and 65535.'",[83,927,316],{"class":285},[83,929,931],{"class":85,"line":930},51,[83,932,815],{"class":285},[83,934,936,938,940,942,944,946,949,951,954,956,958,960,962,964,966,969,971,974,976,978],{"class":85,"line":935},52,[83,937,826],{"class":297},[83,939,508],{"class":285},[83,941,789],{"class":297},[83,943,880],{"class":285},[83,945,883],{"class":89},[83,947,948],{"class":285},"(args.timeout) ",[83,950,889],{"class":297},[83,952,953],{"class":285}," args.timeout ",[83,955,526],{"class":297},[83,957,897],{"class":117},[83,959,900],{"class":297},[83,961,877],{"class":297},[83,963,880],{"class":285},[83,965,883],{"class":89},[83,967,968],{"class":285},"(args.concurrency) ",[83,970,889],{"class":297},[83,972,973],{"class":285}," args.concurrency ",[83,975,526],{"class":297},[83,977,897],{"class":117},[83,979,443],{"class":285},[83,981,983,985,987,989,991,994],{"class":85,"line":982},53,[83,984,838],{"class":297},[83,986,409],{"class":297},[83,988,843],{"class":89},[83,990,310],{"class":285},[83,992,993],{"class":93},"'--timeout and --concurrency must be positive integers.'",[83,995,316],{"class":285},[83,997,999],{"class":85,"line":998},54,[83,1000,815],{"class":285},[83,1002,1004,1007],{"class":85,"line":1003},55,[83,1005,1006],{"class":297},"    return",[83,1008,1009],{"class":285}," args;\n",[83,1011,1013],{"class":85,"line":1012},56,[83,1014,1015],{"class":285},"}\n",[83,1017,1019],{"class":85,"line":1018},57,[83,1020,276],{"emptyLinePlaceholder":275},[83,1022,1024,1026,1029,1031,1034],{"class":85,"line":1023},58,[83,1025,431],{"class":297},[83,1027,1028],{"class":89}," ipToInt",[83,1030,310],{"class":285},[83,1032,1033],{"class":439},"ip",[83,1035,443],{"class":285},[83,1037,1039,1041,1044,1046,1048,1051,1053,1056,1058,1061,1063,1066,1068,1070,1073,1076,1079,1081,1084,1086,1089,1091,1094,1097,1099,1101,1104],{"class":85,"line":1038},59,[83,1040,1006],{"class":297},[83,1042,1043],{"class":285}," ip.",[83,1045,590],{"class":89},[83,1047,310],{"class":285},[83,1049,1050],{"class":93},"'.'",[83,1052,598],{"class":285},[83,1054,1055],{"class":89},"reduce",[83,1057,604],{"class":285},[83,1059,1060],{"class":439},"acc",[83,1062,365],{"class":285},[83,1064,1065],{"class":439},"octet",[83,1067,609],{"class":285},[83,1069,612],{"class":297},[83,1071,1072],{"class":285}," ((acc ",[83,1074,1075],{"class":297},"\u003C\u003C",[83,1077,1078],{"class":117}," 8",[83,1080,609],{"class":285},[83,1082,1083],{"class":297},"+",[83,1085,615],{"class":89},[83,1087,1088],{"class":285},"(octet, ",[83,1090,627],{"class":117},[83,1092,1093],{"class":285},")) ",[83,1095,1096],{"class":297},">>>",[83,1098,520],{"class":117},[83,1100,365],{"class":285},[83,1102,1103],{"class":117},"0",[83,1105,316],{"class":285},[83,1107,1109],{"class":85,"line":1108},60,[83,1110,1015],{"class":285},[83,1112,1114],{"class":85,"line":1113},61,[83,1115,276],{"emptyLinePlaceholder":275},[83,1117,1119,1121,1124,1126,1129],{"class":85,"line":1118},62,[83,1120,431],{"class":297},[83,1122,1123],{"class":89}," intToIp",[83,1125,310],{"class":285},[83,1127,1128],{"class":439},"int",[83,1130,443],{"class":285},[83,1132,1134,1136,1139,1142,1144,1147,1149,1152,1154,1156,1159,1161,1163,1166,1168,1170,1173,1175,1178,1181,1184,1186,1189,1191,1193],{"class":85,"line":1133},63,[83,1135,1006],{"class":297},[83,1137,1138],{"class":285}," [",[83,1140,1141],{"class":117},"24",[83,1143,365],{"class":285},[83,1145,1146],{"class":117},"16",[83,1148,365],{"class":285},[83,1150,1151],{"class":117},"8",[83,1153,365],{"class":285},[83,1155,1103],{"class":117},[83,1157,1158],{"class":285},"].",[83,1160,601],{"class":89},[83,1162,604],{"class":285},[83,1164,1165],{"class":439},"shift",[83,1167,609],{"class":285},[83,1169,612],{"class":297},[83,1171,1172],{"class":285}," (int ",[83,1174,1096],{"class":297},[83,1176,1177],{"class":285}," shift) ",[83,1179,1180],{"class":297},"&",[83,1182,1183],{"class":117}," 255",[83,1185,598],{"class":285},[83,1187,1188],{"class":89},"join",[83,1190,310],{"class":285},[83,1192,1050],{"class":93},[83,1194,316],{"class":285},[83,1196,1198],{"class":85,"line":1197},64,[83,1199,1015],{"class":285},[83,1201,1203],{"class":85,"line":1202},65,[83,1204,276],{"emptyLinePlaceholder":275},[83,1206,1208,1210,1213,1215,1218],{"class":85,"line":1207},66,[83,1209,431],{"class":297},[83,1211,1212],{"class":89}," expandCidr",[83,1214,310],{"class":285},[83,1216,1217],{"class":439},"cidr",[83,1219,443],{"class":285},[83,1221,1223,1225,1227,1230,1232,1235,1238,1240,1243,1245,1247,1250],{"class":85,"line":1222},67,[83,1224,449],{"class":297},[83,1226,1138],{"class":285},[83,1228,1229],{"class":117},"base",[83,1231,365],{"class":285},[83,1233,1234],{"class":117},"prefixStr",[83,1236,1237],{"class":285},"] ",[83,1239,517],{"class":297},[83,1241,1242],{"class":285}," cidr.",[83,1244,590],{"class":89},[83,1246,310],{"class":285},[83,1248,1249],{"class":93},"'\u002F'",[83,1251,316],{"class":285},[83,1253,1255,1257,1260,1262,1264,1267,1270,1273,1275,1277],{"class":85,"line":1254},68,[83,1256,449],{"class":297},[83,1258,1259],{"class":117}," prefix",[83,1261,304],{"class":297},[83,1263,615],{"class":89},[83,1265,1266],{"class":285},"(prefixStr ",[83,1268,1269],{"class":297},"??",[83,1271,1272],{"class":93}," '32'",[83,1274,365],{"class":285},[83,1276,627],{"class":117},[83,1278,316],{"class":285},[83,1280,1282],{"class":85,"line":1281},69,[83,1283,276],{"emptyLinePlaceholder":275},[83,1285,1287,1289,1291,1293,1296,1299],{"class":85,"line":1286},70,[83,1288,826],{"class":297},[83,1290,508],{"class":285},[83,1292,789],{"class":297},[83,1294,1295],{"class":285},"net.",[83,1297,1298],{"class":89},"isIPv4",[83,1300,1301],{"class":285},"(base)) {\n",[83,1303,1305,1307,1309,1311,1313,1316,1318,1321],{"class":85,"line":1304},71,[83,1306,838],{"class":297},[83,1308,409],{"class":297},[83,1310,843],{"class":89},[83,1312,310],{"class":285},[83,1314,1315],{"class":93},"`Not an IPv4 address: ${",[83,1317,1229],{"class":285},[83,1319,1320],{"class":93},"}`",[83,1322,316],{"class":285},[83,1324,1326],{"class":85,"line":1325},72,[83,1327,815],{"class":285},[83,1329,1331,1333,1335,1337,1339,1341,1344,1346,1349,1351,1354,1356,1358,1360,1363],{"class":85,"line":1330},73,[83,1332,826],{"class":297},[83,1334,508],{"class":285},[83,1336,789],{"class":297},[83,1338,880],{"class":285},[83,1340,883],{"class":89},[83,1342,1343],{"class":285},"(prefix) ",[83,1345,889],{"class":297},[83,1347,1348],{"class":285}," prefix ",[83,1350,526],{"class":297},[83,1352,1353],{"class":117}," 16",[83,1355,900],{"class":297},[83,1357,1348],{"class":285},[83,1359,905],{"class":297},[83,1361,1362],{"class":117}," 32",[83,1364,443],{"class":285},[83,1366,1368,1370,1372,1374,1376,1379,1381,1384],{"class":85,"line":1367},74,[83,1369,838],{"class":297},[83,1371,409],{"class":297},[83,1373,843],{"class":89},[83,1375,310],{"class":285},[83,1377,1378],{"class":93},"`Prefix \u002F${",[83,1380,1234],{"class":285},[83,1382,1383],{"class":93},"} out of range: use \u002F16 to \u002F32.`",[83,1385,316],{"class":285},[83,1387,1389],{"class":85,"line":1388},75,[83,1390,815],{"class":285},[83,1392,1394],{"class":85,"line":1393},76,[83,1395,276],{"emptyLinePlaceholder":275},[83,1397,1399,1401,1404,1406,1409,1412,1414,1417,1420],{"class":85,"line":1398},77,[83,1400,449],{"class":297},[83,1402,1403],{"class":117}," size",[83,1405,304],{"class":297},[83,1407,1408],{"class":117}," 2",[83,1410,1411],{"class":297}," **",[83,1413,508],{"class":285},[83,1415,1416],{"class":117},"32",[83,1418,1419],{"class":297}," -",[83,1421,1422],{"class":285}," prefix);\n",[83,1424,1426,1428,1431,1433,1435,1438,1441,1443,1446,1449,1452,1454,1456,1458,1461,1463,1465,1467,1469,1471],{"class":85,"line":1425},78,[83,1427,449],{"class":297},[83,1429,1430],{"class":117}," network",[83,1432,304],{"class":297},[83,1434,508],{"class":285},[83,1436,1437],{"class":89},"ipToInt",[83,1439,1440],{"class":285},"(base) ",[83,1442,1180],{"class":297},[83,1444,1445],{"class":285}," ((",[83,1447,1448],{"class":117},"0xffffffff",[83,1450,1451],{"class":297}," \u003C\u003C",[83,1453,508],{"class":285},[83,1455,1416],{"class":117},[83,1457,1419],{"class":297},[83,1459,1460],{"class":285}," prefix)) ",[83,1462,1096],{"class":297},[83,1464,520],{"class":117},[83,1466,1093],{"class":285},[83,1468,1096],{"class":297},[83,1470,520],{"class":117},[83,1472,286],{"class":285},[83,1474,1476],{"class":85,"line":1475},79,[83,1477,276],{"emptyLinePlaceholder":275},[83,1479,1481],{"class":85,"line":1480},80,[83,1482,1483],{"class":181},"    \u002F\u002F \u002F31 and \u002F32 have no network\u002Fbroadcast addresses to skip (RFC 3021 for \u002F31).\n",[83,1485,1487,1489,1492,1494,1496,1499,1502,1505,1507,1510,1512],{"class":85,"line":1486},81,[83,1488,449],{"class":297},[83,1490,1491],{"class":117}," first",[83,1493,304],{"class":297},[83,1495,1348],{"class":285},[83,1497,1498],{"class":297},">=",[83,1500,1501],{"class":117}," 31",[83,1503,1504],{"class":297}," ?",[83,1506,520],{"class":117},[83,1508,1509],{"class":297}," :",[83,1511,897],{"class":117},[83,1513,286],{"class":285},[83,1515,1517,1519,1522,1524,1526,1528,1530,1532,1535,1538,1540,1542,1544,1546,1548],{"class":85,"line":1516},82,[83,1518,449],{"class":297},[83,1520,1521],{"class":117}," last",[83,1523,304],{"class":297},[83,1525,1348],{"class":285},[83,1527,1498],{"class":297},[83,1529,1501],{"class":117},[83,1531,1504],{"class":297},[83,1533,1534],{"class":285}," size ",[83,1536,1537],{"class":297},"-",[83,1539,897],{"class":117},[83,1541,1509],{"class":297},[83,1543,1534],{"class":285},[83,1545,1537],{"class":297},[83,1547,1408],{"class":117},[83,1549,286],{"class":285},[83,1551,1553],{"class":85,"line":1552},83,[83,1554,276],{"emptyLinePlaceholder":275},[83,1556,1558,1560,1563,1565],{"class":85,"line":1557},84,[83,1559,449],{"class":297},[83,1561,1562],{"class":117}," ips",[83,1564,304],{"class":297},[83,1566,1567],{"class":285}," [];\n",[83,1569,1571,1573,1575,1577,1579,1581,1584,1587,1590,1592],{"class":85,"line":1570},85,[83,1572,505],{"class":297},[83,1574,508],{"class":285},[83,1576,511],{"class":297},[83,1578,514],{"class":285},[83,1580,517],{"class":297},[83,1582,1583],{"class":285}," first; i ",[83,1585,1586],{"class":297},"\u003C=",[83,1588,1589],{"class":285}," last; i",[83,1591,538],{"class":297},[83,1593,443],{"class":285},[83,1595,1597,1600,1603,1605,1608,1611,1613,1616,1618,1620],{"class":85,"line":1596},86,[83,1598,1599],{"class":285},"        ips.",[83,1601,1602],{"class":89},"push",[83,1604,310],{"class":285},[83,1606,1607],{"class":89},"intToIp",[83,1609,1610],{"class":285},"((network ",[83,1612,1083],{"class":297},[83,1614,1615],{"class":285}," i) ",[83,1617,1096],{"class":297},[83,1619,520],{"class":117},[83,1621,630],{"class":285},[83,1623,1625],{"class":85,"line":1624},87,[83,1626,815],{"class":285},[83,1628,1630,1632],{"class":85,"line":1629},88,[83,1631,1006],{"class":297},[83,1633,1634],{"class":285}," ips;\n",[83,1636,1638],{"class":85,"line":1637},89,[83,1639,1015],{"class":285},[83,1641,1643],{"class":85,"line":1642},90,[83,1644,276],{"emptyLinePlaceholder":275},[83,1646,1648,1650,1653,1655,1658,1660,1663,1665,1668],{"class":85,"line":1647},91,[83,1649,431],{"class":297},[83,1651,1652],{"class":89}," checkPort",[83,1654,310],{"class":285},[83,1656,1657],{"class":439},"host",[83,1659,365],{"class":285},[83,1661,1662],{"class":439},"port",[83,1664,365],{"class":285},[83,1666,1667],{"class":439},"timeoutMs",[83,1669,443],{"class":285},[83,1671,1673,1675,1677,1680,1682,1685,1687,1689],{"class":85,"line":1672},92,[83,1674,1006],{"class":297},[83,1676,409],{"class":297},[83,1678,1679],{"class":117}," Promise",[83,1681,604],{"class":285},[83,1683,1684],{"class":439},"resolve",[83,1686,609],{"class":285},[83,1688,612],{"class":297},[83,1690,1691],{"class":285}," {\n",[83,1693,1695,1697,1700,1702,1704,1707,1710],{"class":85,"line":1694},93,[83,1696,546],{"class":297},[83,1698,1699],{"class":117}," socket",[83,1701,304],{"class":297},[83,1703,409],{"class":297},[83,1705,1706],{"class":285}," net.",[83,1708,1709],{"class":89},"Socket",[83,1711,1712],{"class":285},"();\n",[83,1714,1716,1719,1722,1724,1727],{"class":85,"line":1715},94,[83,1717,1718],{"class":297},"        let",[83,1720,1721],{"class":285}," state ",[83,1723,517],{"class":297},[83,1725,1726],{"class":117}," null",[83,1728,286],{"class":285},[83,1730,1732,1734,1737,1739,1742],{"class":85,"line":1731},95,[83,1733,1718],{"class":297},[83,1735,1736],{"class":285}," banner ",[83,1738,517],{"class":297},[83,1740,1741],{"class":93}," ''",[83,1743,286],{"class":285},[83,1745,1747],{"class":85,"line":1746},96,[83,1748,276],{"emptyLinePlaceholder":275},[83,1750,1752,1754,1757,1759,1761,1764,1766,1768],{"class":85,"line":1751},97,[83,1753,546],{"class":297},[83,1755,1756],{"class":89}," finish",[83,1758,304],{"class":297},[83,1760,508],{"class":285},[83,1762,1763],{"class":439},"result",[83,1765,609],{"class":285},[83,1767,612],{"class":297},[83,1769,1691],{"class":285},[83,1771,1773,1776],{"class":85,"line":1772},98,[83,1774,1775],{"class":297},"            if",[83,1777,1778],{"class":285}," (state) {\n",[83,1780,1782,1785],{"class":85,"line":1781},99,[83,1783,1784],{"class":297},"                return",[83,1786,286],{"class":285},[83,1788,1790],{"class":85,"line":1789},100,[83,1791,1792],{"class":285},"            }\n",[83,1794,1796,1799,1801],{"class":85,"line":1795},101,[83,1797,1798],{"class":285},"            state ",[83,1800,517],{"class":297},[83,1802,1803],{"class":285}," result;\n",[83,1805,1807],{"class":85,"line":1806},102,[83,1808,1809],{"class":181},"            \u002F\u002F A 'timeout' event does not close the socket by itself; destroy() does.\n",[83,1811,1813,1816,1819],{"class":85,"line":1812},103,[83,1814,1815],{"class":285},"            socket.",[83,1817,1818],{"class":89},"destroy",[83,1820,1712],{"class":285},[83,1822,1824,1827],{"class":85,"line":1823},104,[83,1825,1826],{"class":89},"            resolve",[83,1828,1829],{"class":285},"({ host, port, state, banner });\n",[83,1831,1833],{"class":85,"line":1832},105,[83,1834,1835],{"class":285},"        };\n",[83,1837,1839],{"class":85,"line":1838},106,[83,1840,276],{"emptyLinePlaceholder":275},[83,1842,1844,1847,1850],{"class":85,"line":1843},107,[83,1845,1846],{"class":285},"        socket.",[83,1848,1849],{"class":89},"setTimeout",[83,1851,1852],{"class":285},"(timeoutMs);\n",[83,1854,1856,1858,1861,1863,1866,1869,1871],{"class":85,"line":1855},108,[83,1857,1846],{"class":285},[83,1859,1860],{"class":89},"once",[83,1862,310],{"class":285},[83,1864,1865],{"class":93},"'connect'",[83,1867,1868],{"class":285},", () ",[83,1870,612],{"class":297},[83,1872,1691],{"class":285},[83,1874,1876,1878,1880,1882,1885,1887,1890],{"class":85,"line":1875},109,[83,1877,1775],{"class":297},[83,1879,508],{"class":285},[83,1881,789],{"class":297},[83,1883,1884],{"class":117},"BANNER_PORTS",[83,1886,27],{"class":285},[83,1888,1889],{"class":89},"has",[83,1891,1892],{"class":285},"(port)) {\n",[83,1894,1896,1899,1901,1904],{"class":85,"line":1895},110,[83,1897,1898],{"class":89},"                finish",[83,1900,310],{"class":285},[83,1902,1903],{"class":93},"'open'",[83,1905,316],{"class":285},[83,1907,1909,1911],{"class":85,"line":1908},111,[83,1910,1784],{"class":297},[83,1912,286],{"class":285},[83,1914,1916],{"class":85,"line":1915},112,[83,1917,1792],{"class":285},[83,1919,1921],{"class":85,"line":1920},113,[83,1922,1923],{"class":181},"            \u002F\u002F Both sides send an identification string (RFC 4253 section 4.2); servers\n",[83,1925,1927],{"class":85,"line":1926},114,[83,1928,1929],{"class":181},"            \u002F\u002F normally send theirs without waiting. Buffer until the SSH- line is complete,\n",[83,1931,1933],{"class":85,"line":1932},115,[83,1934,1935],{"class":181},"            \u002F\u002F since it can be split across chunks or follow other lines.\n",[83,1937,1939,1942,1945,1947,1949],{"class":85,"line":1938},116,[83,1940,1941],{"class":297},"            let",[83,1943,1944],{"class":285}," received ",[83,1946,517],{"class":297},[83,1948,1741],{"class":93},[83,1950,286],{"class":285},[83,1952,1954,1956,1959,1961,1964,1967,1970,1972,1974],{"class":85,"line":1953},117,[83,1955,1815],{"class":285},[83,1957,1958],{"class":89},"on",[83,1960,310],{"class":285},[83,1962,1963],{"class":93},"'data'",[83,1965,1966],{"class":285},", (",[83,1968,1969],{"class":439},"chunk",[83,1971,609],{"class":285},[83,1973,612],{"class":297},[83,1975,1691],{"class":285},[83,1977,1979,1982,1985,1988,1991,1993,1996],{"class":85,"line":1978},118,[83,1980,1981],{"class":285},"                received ",[83,1983,1984],{"class":297},"+=",[83,1986,1987],{"class":285}," chunk.",[83,1989,1990],{"class":89},"toString",[83,1992,310],{"class":285},[83,1994,1995],{"class":93},"'utf8'",[83,1997,316],{"class":285},[83,1999,2001,2004,2007,2009,2012,2014,2016,2019,2022,2024],{"class":85,"line":2000},119,[83,2002,2003],{"class":297},"                const",[83,2005,2006],{"class":117}," lines",[83,2008,304],{"class":297},[83,2010,2011],{"class":285}," received.",[83,2013,590],{"class":89},[83,2015,310],{"class":285},[83,2017,2018],{"class":93},"'",[83,2020,2021],{"class":117},"\\n",[83,2023,2018],{"class":93},[83,2025,316],{"class":285},[83,2027,2029,2031,2034,2036,2039,2042,2044,2046,2048,2050,2053,2055,2058,2060,2063,2065,2067,2070,2073,2075,2078],{"class":85,"line":2028},120,[83,2030,2003],{"class":297},[83,2032,2033],{"class":117}," line",[83,2035,304],{"class":297},[83,2037,2038],{"class":285}," lines.",[83,2040,2041],{"class":89},"slice",[83,2043,310],{"class":285},[83,2045,1103],{"class":117},[83,2047,365],{"class":285},[83,2049,1537],{"class":297},[83,2051,2052],{"class":117},"1",[83,2054,598],{"class":285},[83,2056,2057],{"class":89},"find",[83,2059,604],{"class":285},[83,2061,2062],{"class":439},"l",[83,2064,609],{"class":285},[83,2066,612],{"class":297},[83,2068,2069],{"class":285}," l.",[83,2071,2072],{"class":89},"startsWith",[83,2074,310],{"class":285},[83,2076,2077],{"class":93},"'SSH-'",[83,2079,630],{"class":285},[83,2081,2083,2086,2089,2091,2093,2095,2098,2101],{"class":85,"line":2082},121,[83,2084,2085],{"class":297},"                if",[83,2087,2088],{"class":285}," (line ",[83,2090,889],{"class":297},[83,2092,2011],{"class":285},[83,2094,532],{"class":117},[83,2096,2097],{"class":297}," >",[83,2099,2100],{"class":117}," 8192",[83,2102,443],{"class":285},[83,2104,2106,2109,2111,2114,2117,2120,2122,2125,2128,2130],{"class":85,"line":2105},122,[83,2107,2108],{"class":285},"                    banner ",[83,2110,517],{"class":297},[83,2112,2113],{"class":285}," line ",[83,2115,2116],{"class":297},"?",[83,2118,2119],{"class":285}," line.",[83,2121,621],{"class":89},[83,2123,2124],{"class":285},"() ",[83,2126,2127],{"class":297},":",[83,2129,1741],{"class":93},[83,2131,286],{"class":285},[83,2133,2135,2138,2140,2142],{"class":85,"line":2134},123,[83,2136,2137],{"class":89},"                    finish",[83,2139,310],{"class":285},[83,2141,1903],{"class":93},[83,2143,316],{"class":285},[83,2145,2147],{"class":85,"line":2146},124,[83,2148,2149],{"class":285},"                }\n",[83,2151,2153],{"class":85,"line":2152},125,[83,2154,2155],{"class":285},"            });\n",[83,2157,2159],{"class":85,"line":2158},126,[83,2160,2161],{"class":181},"            \u002F\u002F The server may accept and then hang up without sending anything.\n",[83,2163,2165,2167,2169,2171,2174,2176,2178,2180,2182,2184],{"class":85,"line":2164},127,[83,2166,1815],{"class":285},[83,2168,1860],{"class":89},[83,2170,310],{"class":285},[83,2172,2173],{"class":93},"'close'",[83,2175,1868],{"class":285},[83,2177,612],{"class":297},[83,2179,1756],{"class":89},[83,2181,310],{"class":285},[83,2183,1903],{"class":93},[83,2185,630],{"class":285},[83,2187,2189],{"class":85,"line":2188},128,[83,2190,2191],{"class":285},"        });\n",[83,2193,2195,2197,2199,2201,2204,2206,2208,2210,2213,2215,2218,2220,2223],{"class":85,"line":2194},129,[83,2196,1846],{"class":285},[83,2198,1860],{"class":89},[83,2200,310],{"class":285},[83,2202,2203],{"class":93},"'timeout'",[83,2205,1868],{"class":285},[83,2207,612],{"class":297},[83,2209,1756],{"class":89},[83,2211,2212],{"class":285},"(socket.connecting ",[83,2214,2116],{"class":297},[83,2216,2217],{"class":93}," 'filtered'",[83,2219,1509],{"class":297},[83,2221,2222],{"class":93}," 'open'",[83,2224,630],{"class":285},[83,2226,2228,2230,2232,2234,2237,2239,2242,2244,2246,2248,2251,2253,2256,2258,2261,2263,2265],{"class":85,"line":2227},130,[83,2229,1846],{"class":285},[83,2231,1860],{"class":89},[83,2233,310],{"class":285},[83,2235,2236],{"class":93},"'error'",[83,2238,1966],{"class":285},[83,2240,2241],{"class":439},"error",[83,2243,609],{"class":285},[83,2245,612],{"class":297},[83,2247,1756],{"class":89},[83,2249,2250],{"class":285},"(error.code ",[83,2252,566],{"class":297},[83,2254,2255],{"class":93}," 'ECONNREFUSED'",[83,2257,1504],{"class":297},[83,2259,2260],{"class":93}," 'closed'",[83,2262,1509],{"class":297},[83,2264,2217],{"class":93},[83,2266,630],{"class":285},[83,2268,2270],{"class":85,"line":2269},131,[83,2271,276],{"emptyLinePlaceholder":275},[83,2273,2275,2277,2280],{"class":85,"line":2274},132,[83,2276,1846],{"class":285},[83,2278,2279],{"class":89},"connect",[83,2281,2282],{"class":285},"(port, host);\n",[83,2284,2286],{"class":85,"line":2285},133,[83,2287,2288],{"class":285},"    });\n",[83,2290,2292],{"class":85,"line":2291},134,[83,2293,1015],{"class":285},[83,2295,2297],{"class":85,"line":2296},135,[83,2298,276],{"emptyLinePlaceholder":275},[83,2300,2302,2305,2308,2311,2313,2316,2318,2321,2323,2326],{"class":85,"line":2301},136,[83,2303,2304],{"class":297},"async",[83,2306,2307],{"class":297}," function",[83,2309,2310],{"class":89}," asyncPool",[83,2312,310],{"class":285},[83,2314,2315],{"class":439},"limit",[83,2317,365],{"class":285},[83,2319,2320],{"class":439},"items",[83,2322,365],{"class":285},[83,2324,2325],{"class":439},"iteratorFn",[83,2327,443],{"class":285},[83,2329,2331,2333,2336,2338],{"class":85,"line":2330},137,[83,2332,449],{"class":297},[83,2334,2335],{"class":117}," results",[83,2337,304],{"class":297},[83,2339,1567],{"class":285},[83,2341,2343,2345,2348,2350,2352,2354],{"class":85,"line":2342},138,[83,2344,449],{"class":297},[83,2346,2347],{"class":117}," executing",[83,2349,304],{"class":297},[83,2351,409],{"class":297},[83,2353,412],{"class":89},[83,2355,1712],{"class":285},[83,2357,2359],{"class":85,"line":2358},139,[83,2360,276],{"emptyLinePlaceholder":275},[83,2362,2364,2366,2368,2370,2373,2376],{"class":85,"line":2363},140,[83,2365,505],{"class":297},[83,2367,508],{"class":285},[83,2369,298],{"class":297},[83,2371,2372],{"class":117}," item",[83,2374,2375],{"class":297}," of",[83,2377,2378],{"class":285}," items) {\n",[83,2380,2382,2384,2387,2389,2391,2393,2395,2398,2401,2404,2406,2409],{"class":85,"line":2381},141,[83,2383,546],{"class":297},[83,2385,2386],{"class":117}," promise",[83,2388,304],{"class":297},[83,2390,1679],{"class":117},[83,2392,27],{"class":285},[83,2394,1684],{"class":89},[83,2396,2397],{"class":285},"().",[83,2399,2400],{"class":89},"then",[83,2402,2403],{"class":285},"(() ",[83,2405,612],{"class":297},[83,2407,2408],{"class":89}," iteratorFn",[83,2410,2411],{"class":285},"(item));\n",[83,2413,2415,2418,2420],{"class":85,"line":2414},142,[83,2416,2417],{"class":285},"        results.",[83,2419,1602],{"class":89},[83,2421,2422],{"class":285},"(promise);\n",[83,2424,2426,2429,2432],{"class":85,"line":2425},143,[83,2427,2428],{"class":285},"        executing.",[83,2430,2431],{"class":89},"add",[83,2433,2422],{"class":285},[83,2435,2437,2439,2442,2444,2447,2449,2452,2455],{"class":85,"line":2436},144,[83,2438,546],{"class":297},[83,2440,2441],{"class":89}," cleanup",[83,2443,304],{"class":297},[83,2445,2446],{"class":285}," () ",[83,2448,612],{"class":297},[83,2450,2451],{"class":285}," executing.",[83,2453,2454],{"class":89},"delete",[83,2456,2422],{"class":285},[83,2458,2460,2463,2465],{"class":85,"line":2459},145,[83,2461,2462],{"class":285},"        promise.",[83,2464,2400],{"class":89},[83,2466,2467],{"class":285},"(cleanup, cleanup);\n",[83,2469,2471,2473,2476,2478],{"class":85,"line":2470},146,[83,2472,560],{"class":297},[83,2474,2475],{"class":285}," (executing.size ",[83,2477,1498],{"class":297},[83,2479,2480],{"class":285}," limit) {\n",[83,2482,2484,2487,2489,2491,2494],{"class":85,"line":2483},147,[83,2485,2486],{"class":297},"            await",[83,2488,1679],{"class":117},[83,2490,27],{"class":285},[83,2492,2493],{"class":89},"race",[83,2495,2496],{"class":285},"(executing);\n",[83,2498,2500],{"class":85,"line":2499},148,[83,2501,809],{"class":285},[83,2503,2505],{"class":85,"line":2504},149,[83,2506,815],{"class":285},[83,2508,2510,2512,2514,2516,2519],{"class":85,"line":2509},150,[83,2511,1006],{"class":297},[83,2513,1679],{"class":117},[83,2515,27],{"class":285},[83,2517,2518],{"class":89},"all",[83,2520,2521],{"class":285},"(results);\n",[83,2523,2525],{"class":85,"line":2524},151,[83,2526,1015],{"class":285},[83,2528,2530],{"class":85,"line":2529},152,[83,2531,276],{"emptyLinePlaceholder":275},[83,2533,2535,2537,2540,2542,2545],{"class":85,"line":2534},153,[83,2536,431],{"class":297},[83,2538,2539],{"class":89}," csvEscape",[83,2541,310],{"class":285},[83,2543,2544],{"class":439},"value",[83,2546,443],{"class":285},[83,2548,2550,2552,2555,2557,2560,2563,2565,2567],{"class":85,"line":2549},154,[83,2551,449],{"class":297},[83,2553,2554],{"class":117}," text",[83,2556,304],{"class":297},[83,2558,2559],{"class":89}," String",[83,2561,2562],{"class":285},"(value ",[83,2564,1269],{"class":297},[83,2566,1741],{"class":93},[83,2568,316],{"class":285},[83,2570,2572,2574,2577,2580,2583,2585,2588,2591,2593,2596,2598,2600,2603,2605,2607,2611,2613,2616,2618,2621,2624,2627,2629],{"class":85,"line":2571},155,[83,2573,1006],{"class":297},[83,2575,2576],{"class":93}," \u002F",[83,2578,2579],{"class":117},"[\",\\n]",[83,2581,2582],{"class":93},"\u002F",[83,2584,27],{"class":285},[83,2586,2587],{"class":89},"test",[83,2589,2590],{"class":285},"(text) ",[83,2592,2116],{"class":297},[83,2594,2595],{"class":93}," `\"${",[83,2597,151],{"class":285},[83,2599,27],{"class":93},[83,2601,2602],{"class":89},"replace",[83,2604,310],{"class":93},[83,2606,2582],{"class":93},[83,2608,2610],{"class":2609},"sns5M","\"",[83,2612,2582],{"class":93},[83,2614,2615],{"class":297},"g",[83,2617,365],{"class":93},[83,2619,2620],{"class":93},"'\"\"'",[83,2622,2623],{"class":93},")",[83,2625,2626],{"class":93},"}\"`",[83,2628,1509],{"class":297},[83,2630,2631],{"class":285}," text;\n",[83,2633,2635],{"class":85,"line":2634},156,[83,2636,1015],{"class":285},[83,2638,2640],{"class":85,"line":2639},157,[83,2641,276],{"emptyLinePlaceholder":275},[83,2643,2645,2647,2649,2652],{"class":85,"line":2644},158,[83,2646,2304],{"class":297},[83,2648,2307],{"class":297},[83,2650,2651],{"class":89}," main",[83,2653,2654],{"class":285},"() {\n",[83,2656,2658,2660,2662,2664,2666,2669,2671,2673,2676],{"class":85,"line":2657},159,[83,2659,449],{"class":297},[83,2661,452],{"class":117},[83,2663,304],{"class":297},[83,2665,434],{"class":89},[83,2667,2668],{"class":285},"(process.argv.",[83,2670,2041],{"class":89},[83,2672,310],{"class":285},[83,2674,2675],{"class":117},"2",[83,2677,630],{"class":285},[83,2679,2681,2683,2686,2688,2690],{"class":85,"line":2680},160,[83,2682,449],{"class":297},[83,2684,2685],{"class":117}," hosts",[83,2687,304],{"class":297},[83,2689,1212],{"class":89},[83,2691,2692],{"class":285},"(args.cidr);\n",[83,2694,2696],{"class":85,"line":2695},161,[83,2697,276],{"emptyLinePlaceholder":275},[83,2699,2701,2704,2707,2709,2712,2715,2717,2719,2722,2725,2727,2729,2732,2734,2736,2739,2741,2743,2745,2748,2750,2753],{"class":85,"line":2700},162,[83,2702,2703],{"class":285},"    console.",[83,2705,2706],{"class":89},"log",[83,2708,310],{"class":285},[83,2710,2711],{"class":93},"`Scanning ${",[83,2713,2714],{"class":285},"args",[83,2716,27],{"class":93},[83,2718,1217],{"class":285},[83,2720,2721],{"class":93},"} (${",[83,2723,2724],{"class":285},"hosts",[83,2726,27],{"class":93},[83,2728,532],{"class":117},[83,2730,2731],{"class":93},"} host(s)) for ports [${",[83,2733,2714],{"class":285},[83,2735,27],{"class":93},[83,2737,2738],{"class":285},"ports",[83,2740,27],{"class":93},[83,2742,1188],{"class":89},[83,2744,310],{"class":93},[83,2746,2747],{"class":93},"', '",[83,2749,2623],{"class":93},[83,2751,2752],{"class":93},"}]`",[83,2754,316],{"class":285},[83,2756,2758,2760,2762,2764,2767,2769,2771,2774,2777,2779,2781,2784,2787],{"class":85,"line":2757},163,[83,2759,2703],{"class":285},[83,2761,2706],{"class":89},[83,2763,310],{"class":285},[83,2765,2766],{"class":93},"`Concurrency: ${",[83,2768,2714],{"class":285},[83,2770,27],{"class":93},[83,2772,2773],{"class":285},"concurrency",[83,2775,2776],{"class":93},"}, timeout: ${",[83,2778,2714],{"class":285},[83,2780,27],{"class":93},[83,2782,2783],{"class":285},"timeout",[83,2785,2786],{"class":93},"}ms per attempt`",[83,2788,316],{"class":285},[83,2790,2792,2794,2796,2798,2801],{"class":85,"line":2791},164,[83,2793,2703],{"class":285},[83,2795,2706],{"class":89},[83,2797,310],{"class":285},[83,2799,2800],{"class":93},"''",[83,2802,316],{"class":285},[83,2804,2806],{"class":85,"line":2805},165,[83,2807,276],{"emptyLinePlaceholder":275},[83,2809,2811,2813,2816,2818,2821,2824],{"class":85,"line":2810},166,[83,2812,449],{"class":297},[83,2814,2815],{"class":117}," startTime",[83,2817,304],{"class":297},[83,2819,2820],{"class":285}," Date.",[83,2822,2823],{"class":89},"now",[83,2825,1712],{"class":285},[83,2827,2829,2831,2834,2836,2839,2842,2844,2846,2848,2850,2853,2855,2857,2859,2861,2863],{"class":85,"line":2828},167,[83,2830,449],{"class":297},[83,2832,2833],{"class":117}," targets",[83,2835,304],{"class":297},[83,2837,2838],{"class":285}," hosts.",[83,2840,2841],{"class":89},"flatMap",[83,2843,604],{"class":285},[83,2845,1657],{"class":439},[83,2847,609],{"class":285},[83,2849,612],{"class":297},[83,2851,2852],{"class":285}," args.ports.",[83,2854,601],{"class":89},[83,2856,604],{"class":285},[83,2858,1662],{"class":439},[83,2860,609],{"class":285},[83,2862,612],{"class":297},[83,2864,2865],{"class":285}," ({ host, port })));\n",[83,2867,2869],{"class":85,"line":2868},168,[83,2870,276],{"emptyLinePlaceholder":275},[83,2872,2874,2876,2878,2880,2883,2885,2888,2890,2893,2895,2897,2899,2902,2904],{"class":85,"line":2873},169,[83,2875,449],{"class":297},[83,2877,2335],{"class":117},[83,2879,304],{"class":297},[83,2881,2882],{"class":297}," await",[83,2884,2310],{"class":89},[83,2886,2887],{"class":285},"(args.concurrency, targets, ",[83,2889,2304],{"class":297},[83,2891,2892],{"class":285}," ({ ",[83,2894,1657],{"class":439},[83,2896,365],{"class":285},[83,2898,1662],{"class":439},[83,2900,2901],{"class":285}," }) ",[83,2903,612],{"class":297},[83,2905,1691],{"class":285},[83,2907,2909,2911,2914,2916,2918,2920],{"class":85,"line":2908},170,[83,2910,546],{"class":297},[83,2912,2913],{"class":117}," result",[83,2915,304],{"class":297},[83,2917,2882],{"class":297},[83,2919,1652],{"class":89},[83,2921,2922],{"class":285},"(host, port, args.timeout);\n",[83,2924,2926,2928,2931,2933,2935,2937],{"class":85,"line":2925},171,[83,2927,560],{"class":297},[83,2929,2930],{"class":285}," (result.state ",[83,2932,566],{"class":297},[83,2934,2222],{"class":93},[83,2936,900],{"class":297},[83,2938,2939],{"class":285}," args.all) {\n",[83,2941,2943,2946,2949,2951,2953,2956,2958,2961,2964,2967,2969,2972,2975,2977,2979],{"class":85,"line":2942},172,[83,2944,2945],{"class":297},"            const",[83,2947,2948],{"class":117}," service",[83,2950,304],{"class":297},[83,2952,348],{"class":117},[83,2954,2955],{"class":285},"[port] ",[83,2957,2116],{"class":297},[83,2959,2960],{"class":93}," `(${",[83,2962,2963],{"class":117},"SERVICE_NAMES",[83,2965,2966],{"class":93},"[",[83,2968,1662],{"class":285},[83,2970,2971],{"class":93},"]",[83,2973,2974],{"class":93},"})`",[83,2976,1509],{"class":297},[83,2978,1741],{"class":93},[83,2980,286],{"class":285},[83,2982,2984,2987,2989,2991,2994,2996,2998,3001,3003,3006,3008,3011,3013,3016,3018,3020,3023,3025,3027,3029,3031,3033,3036,3039,3042,3044,3046,3049,3051,3053,3056],{"class":85,"line":2983},173,[83,2985,2986],{"class":285},"            console.",[83,2988,2706],{"class":89},[83,2990,310],{"class":285},[83,2992,2993],{"class":93},"`${",[83,2995,1657],{"class":285},[83,2997,27],{"class":93},[83,2999,3000],{"class":89},"padEnd",[83,3002,310],{"class":93},[83,3004,3005],{"class":117},"15",[83,3007,2623],{"class":93},[83,3009,3010],{"class":93},"}${`${",[83,3012,1662],{"class":285},[83,3014,3015],{"class":93},"}\u002Ftcp`} ${",[83,3017,1763],{"class":285},[83,3019,27],{"class":93},[83,3021,3022],{"class":285},"state",[83,3024,27],{"class":93},[83,3026,3000],{"class":89},[83,3028,310],{"class":93},[83,3030,1151],{"class":117},[83,3032,2623],{"class":93},[83,3034,3035],{"class":93},"} ${",[83,3037,3038],{"class":285},"service",[83,3040,3041],{"class":93},"}  ${",[83,3043,1763],{"class":285},[83,3045,27],{"class":93},[83,3047,3048],{"class":285},"banner",[83,3050,1320],{"class":93},[83,3052,27],{"class":285},[83,3054,3055],{"class":89},"trimEnd",[83,3057,3058],{"class":285},"());\n",[83,3060,3062],{"class":85,"line":3061},174,[83,3063,809],{"class":285},[83,3065,3067,3070],{"class":85,"line":3066},175,[83,3068,3069],{"class":297},"        return",[83,3071,1803],{"class":285},[83,3073,3075],{"class":85,"line":3074},176,[83,3076,2288],{"class":285},[83,3078,3080],{"class":85,"line":3079},177,[83,3081,276],{"emptyLinePlaceholder":275},[83,3083,3085,3087,3090,3092,3095,3097,3100,3102,3105,3107],{"class":85,"line":3084},178,[83,3086,449],{"class":297},[83,3088,3089],{"class":117}," counts",[83,3091,304],{"class":297},[83,3093,3094],{"class":285}," { open: ",[83,3096,1103],{"class":117},[83,3098,3099],{"class":285},", closed: ",[83,3101,1103],{"class":117},[83,3103,3104],{"class":285},", filtered: ",[83,3106,1103],{"class":117},[83,3108,396],{"class":285},[83,3110,3112,3114,3117,3119,3121,3123],{"class":85,"line":3111},179,[83,3113,449],{"class":297},[83,3115,3116],{"class":117}," openHosts",[83,3118,304],{"class":297},[83,3120,409],{"class":297},[83,3122,412],{"class":89},[83,3124,1712],{"class":285},[83,3126,3128,3130,3132,3134,3136,3138],{"class":85,"line":3127},180,[83,3129,505],{"class":297},[83,3131,508],{"class":285},[83,3133,298],{"class":297},[83,3135,2913],{"class":117},[83,3137,2375],{"class":297},[83,3139,3140],{"class":285}," results) {\n",[83,3142,3144,3147,3149],{"class":85,"line":3143},181,[83,3145,3146],{"class":285},"        counts[result.state]",[83,3148,538],{"class":297},[83,3150,286],{"class":285},[83,3152,3154,3156,3158,3160,3162],{"class":85,"line":3153},182,[83,3155,560],{"class":297},[83,3157,2930],{"class":285},[83,3159,566],{"class":297},[83,3161,2222],{"class":93},[83,3163,443],{"class":285},[83,3165,3167,3170,3172],{"class":85,"line":3166},183,[83,3168,3169],{"class":285},"            openHosts.",[83,3171,2431],{"class":89},[83,3173,3174],{"class":285},"(result.host);\n",[83,3176,3178],{"class":85,"line":3177},184,[83,3179,809],{"class":285},[83,3181,3183],{"class":85,"line":3182},185,[83,3184,815],{"class":285},[83,3186,3188],{"class":85,"line":3187},186,[83,3189,276],{"emptyLinePlaceholder":275},[83,3191,3193,3195],{"class":85,"line":3192},187,[83,3194,826],{"class":297},[83,3196,3197],{"class":285}," (args.csv) {\n",[83,3199,3201,3203,3206,3208,3211,3213,3216,3218,3221,3224,3226,3229,3231,3233,3236,3238,3240],{"class":85,"line":3200},188,[83,3202,546],{"class":297},[83,3204,3205],{"class":117}," rows",[83,3207,304],{"class":297},[83,3209,3210],{"class":285}," (args.all ",[83,3212,2116],{"class":297},[83,3214,3215],{"class":285}," results ",[83,3217,2127],{"class":297},[83,3219,3220],{"class":285}," results.",[83,3222,3223],{"class":89},"filter",[83,3225,604],{"class":285},[83,3227,3228],{"class":439},"r",[83,3230,609],{"class":285},[83,3232,612],{"class":297},[83,3234,3235],{"class":285}," r.state ",[83,3237,566],{"class":297},[83,3239,2222],{"class":93},[83,3241,3242],{"class":285},"))\n",[83,3244,3246,3249,3251,3253,3255,3257,3259,3262,3264,3267,3269,3271,3274,3276,3279,3281,3283,3285],{"class":85,"line":3245},189,[83,3247,3248],{"class":285},"            .",[83,3250,601],{"class":89},[83,3252,604],{"class":285},[83,3254,3228],{"class":439},[83,3256,609],{"class":285},[83,3258,612],{"class":297},[83,3260,3261],{"class":285}," [r.host, r.port, ",[83,3263,2963],{"class":117},[83,3265,3266],{"class":285},"[r.port] ",[83,3268,1269],{"class":297},[83,3270,1741],{"class":93},[83,3272,3273],{"class":285},", r.state, r.banner].",[83,3275,601],{"class":89},[83,3277,3278],{"class":285},"(csvEscape).",[83,3280,1188],{"class":89},[83,3282,310],{"class":285},[83,3284,595],{"class":93},[83,3286,630],{"class":285},[83,3288,3290,3293,3296,3299,3302,3304,3307,3310,3312,3314,3316,3318,3320,3322,3324,3327,3329,3331,3333,3335],{"class":85,"line":3289},190,[83,3291,3292],{"class":285},"        fs.",[83,3294,3295],{"class":89},"writeFileSync",[83,3297,3298],{"class":285},"(args.csv, [",[83,3300,3301],{"class":93},"'ip_address,port,service,state,banner'",[83,3303,365],{"class":285},[83,3305,3306],{"class":297},"...",[83,3308,3309],{"class":285},"rows].",[83,3311,1188],{"class":89},[83,3313,310],{"class":285},[83,3315,2018],{"class":93},[83,3317,2021],{"class":117},[83,3319,2018],{"class":93},[83,3321,609],{"class":285},[83,3323,1083],{"class":297},[83,3325,3326],{"class":93}," '",[83,3328,2021],{"class":117},[83,3330,2018],{"class":93},[83,3332,365],{"class":285},[83,3334,1995],{"class":93},[83,3336,316],{"class":285},[83,3338,3340],{"class":85,"line":3339},191,[83,3341,815],{"class":285},[83,3343,3345],{"class":85,"line":3344},192,[83,3346,276],{"emptyLinePlaceholder":275},[83,3348,3350,3352,3355,3357,3360,3362,3364,3366,3369,3371,3374,3376,3379,3381,3383],{"class":85,"line":3349},193,[83,3351,449],{"class":297},[83,3353,3354],{"class":117}," elapsedSeconds",[83,3356,304],{"class":297},[83,3358,3359],{"class":285}," ((Date.",[83,3361,2823],{"class":89},[83,3363,2124],{"class":285},[83,3365,1537],{"class":297},[83,3367,3368],{"class":285}," startTime) ",[83,3370,2582],{"class":297},[83,3372,3373],{"class":117}," 1000",[83,3375,598],{"class":285},[83,3377,3378],{"class":89},"toFixed",[83,3380,310],{"class":285},[83,3382,2052],{"class":117},[83,3384,316],{"class":285},[83,3386,3388,3390,3392,3394,3396],{"class":85,"line":3387},194,[83,3389,2703],{"class":285},[83,3391,2706],{"class":89},[83,3393,310],{"class":285},[83,3395,2800],{"class":93},[83,3397,316],{"class":285},[83,3399,3401,3403,3405,3407,3410,3413,3416,3419,3421,3424,3427,3429,3431,3433,3436],{"class":85,"line":3400},195,[83,3402,2703],{"class":285},[83,3404,2706],{"class":89},[83,3406,310],{"class":285},[83,3408,3409],{"class":93},"`Scan complete in ${",[83,3411,3412],{"class":285},"elapsedSeconds",[83,3414,3415],{"class":93},"}s. ${",[83,3417,3418],{"class":285},"openHosts",[83,3420,27],{"class":93},[83,3422,3423],{"class":285},"size",[83,3425,3426],{"class":93},"} host(s) with at least one open port out of ${",[83,3428,2724],{"class":285},[83,3430,27],{"class":93},[83,3432,532],{"class":117},[83,3434,3435],{"class":93},"} scanned.`",[83,3437,316],{"class":285},[83,3439,3441,3443,3445,3447,3450,3453,3455,3458,3461,3463,3465,3468,3471,3473,3475,3478,3480],{"class":85,"line":3440},196,[83,3442,2703],{"class":285},[83,3444,2706],{"class":89},[83,3446,310],{"class":285},[83,3448,3449],{"class":93},"`States: open ${",[83,3451,3452],{"class":285},"counts",[83,3454,27],{"class":93},[83,3456,3457],{"class":285},"open",[83,3459,3460],{"class":93},"}, closed ${",[83,3462,3452],{"class":285},[83,3464,27],{"class":93},[83,3466,3467],{"class":285},"closed",[83,3469,3470],{"class":93},"}, filtered ${",[83,3472,3452],{"class":285},[83,3474,27],{"class":93},[83,3476,3477],{"class":285},"filtered",[83,3479,1320],{"class":93},[83,3481,316],{"class":285},[83,3483,3485],{"class":85,"line":3484},197,[83,3486,1015],{"class":285},[83,3488,3490],{"class":85,"line":3489},198,[83,3491,276],{"emptyLinePlaceholder":275},[83,3493,3495,3498,3500,3503,3505,3507,3509,3511],{"class":85,"line":3494},199,[83,3496,3497],{"class":89},"main",[83,3499,2397],{"class":285},[83,3501,3502],{"class":89},"catch",[83,3504,604],{"class":285},[83,3506,2241],{"class":439},[83,3508,609],{"class":285},[83,3510,612],{"class":297},[83,3512,1691],{"class":285},[83,3514,3516,3518,3520],{"class":85,"line":3515},200,[83,3517,2703],{"class":285},[83,3519,2241],{"class":89},[83,3521,3522],{"class":285},"(error.message);\n",[83,3524,3526,3529,3531,3533],{"class":85,"line":3525},201,[83,3527,3528],{"class":285},"    process.exitCode ",[83,3530,517],{"class":297},[83,3532,897],{"class":117},[83,3534,286],{"class":285},[83,3536,3538],{"class":85,"line":3537},202,[83,3539,3540],{"class":285},"});\n",[29,3542,3544],{"id":3543},"notes","Notes",[34,3546,3547,3560,3581,3587,3608,3622,3628],{},[37,3548,3549,3552,3553,3555,3556,3559],{},[158,3550,3551],{},"What changed from the first version."," The earlier draft's sample output listed ",[41,3554,3467],{}," lines the script never printed, it scanned the network and broadcast addresses, it accepted any prefix down to ",[41,3557,3558],{},"\u002F0"," (four billion targets), and it lumped refused and timed-out connections together. It now skips network\u002Fbroadcast on \u002F30 and larger, refuses anything bigger than a \u002F16, and reports closed and filtered separately.",[37,3561,3562,3565,3566,3569,3570,3572,3573,3576,3577,3580],{},[158,3563,3564],{},"Timeouts need an explicit destroy."," Node's ",[41,3567,3568],{},"socket.setTimeout()"," only emits a ",[41,3571,2203],{}," event when the socket goes idle; it does not sever the connection. The ",[41,3574,3575],{},"finish()"," helper calls ",[41,3578,3579],{},"socket.destroy()"," on every path so pending sockets don't pile up at high concurrency.",[37,3582,3583,3586],{},[158,3584,3585],{},"Filtered is ambiguous by design."," A timeout could be an empty address, a host firewall, or a network ACL. If you need to tell those apart, compare against an ARP-based sweep of the same VLAN or DHCP leases.",[37,3588,3589,3592,3593,3596,3597,3600,3601,3603,3604,3607],{},[158,3590,3591],{},"SSH banners"," come for free because servers normally send their identification string without waiting for the client (RFC 4253 has both sides send one), so the script collects it passively, best effort; they identify the implementation and version (",[41,3594,3595],{},"SSH-2.0-OpenSSH_9.6","), which is enough to spot an appliance running an old build. The spec allows a server to send other lines before the ",[41,3598,3599],{},"SSH-"," line, so the script buffers input until a complete line starting with ",[41,3602,3599],{}," arrives rather than taking the first line. RDP doesn't volunteer anything without a protocol handshake; use ",[41,3605,3606],{},"nmap -sV -p 3389"," when you need the service confirmed.",[37,3609,3610,3613,3614,3617,3618,3621],{},[158,3611,3612],{},"Tune for the path."," Concurrency of 100 against a local \u002F24 finishes in a few seconds. Across a WAN link or a firewall that rate-limits new connections, raise ",[41,3615,3616],{},"--timeout"," and lower ",[41,3619,3620],{},"--concurrency",", or you'll get false \"filtered\" results from connections still pending when the timer fired.",[37,3623,3624,3627],{},[158,3625,3626],{},"Detectable on purpose."," This completes the TCP handshake and closes it. It will show up in firewall and IDS logs, which is what you want for a sanctioned inventory sweep.",[37,3629,3630,3631,3634,3635,27],{},"To track changes over time, run nmap with ",[41,3632,3633],{},"-oX"," on a schedule and compare runs with the ",[18,3636,3638],{"href":3637},"\u002F2026\u002F03\u002F11\u002Fnode-js-discovery-diffing-two-network-scans-to-flag-new-hosts\u002F","scan diff script",[29,3640,3642],{"id":3641},"references","References",[34,3644,3645,3666,3673,3680,3690],{},[37,3646,3647],{},[18,3648,3652,3653,3655,3656,365,3658,3660,3661,365,3663],{"href":3649,"rel":3650},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fnet.html",[3651],"nofollow","Node.js ",[41,3654,43],{}," module: ",[41,3657,3568],{},[41,3659,2203],{}," event, ",[41,3662,3579],{},[41,3664,3665],{},"net.isIPv4()",[37,3667,3668],{},[18,3669,3672],{"href":3670,"rel":3671},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc4253.html#section-4.2",[3651],"RFC 4253, section 4.2: SSH protocol version exchange",[37,3674,3675],{},[18,3676,3679],{"href":3677,"rel":3678},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc3021.html",[3651],"RFC 3021: using 31-bit prefixes on point-to-point links",[37,3681,3682],{},[18,3683,3686,3687,3689],{"href":3684,"rel":3685},"https:\u002F\u002Fnmap.org\u002Fbook\u002Fman-port-scanning-techniques.html",[3651],"Nmap port scanning techniques (",[41,3688,61],{}," connect scan, privileges)",[37,3691,3692],{},[18,3693,3696],{"href":3694,"rel":3695},"https:\u002F\u002Fnmap.org\u002Fbook\u002Flegal-issues.html",[3651],"Nmap legal issues: get written authorization first",[3698,3699,3700],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sns5M, html code.shiki .sns5M{--shiki-default:#DBEDFF}",{"title":79,"searchDepth":185,"depth":185,"links":3702},[3703,3704,3705,3706,3707],{"id":31,"depth":185,"text":32},{"id":68,"depth":185,"text":69},{"id":168,"depth":185,"text":169},{"id":3543,"depth":185,"text":3544},{"id":3641,"depth":185,"text":3642},"techcolumnist",[3710,3711],"scripts","engineering","2026-02-11T14:00:00Z","A dependency-free Node.js TCP connect scanner that sweeps a subnet for RDP and SSH, separates closed from filtered ports, grabs SSH banners and writes CSV.","md",false,null,{},"\u002Fblog\u002F2026\u002F02\u002F11\u002Fnode-js-discovery-scanning-a-subnet-for-open-rdp-and-ssh",{"title":6,"description":3713},[3708],"blog\u002F2026\u002F02\u002F11\u002Fnode-js-discovery-scanning-a-subnet-for-open-rdp-and-ssh",[3723,3724,3725,3726],"nodejs","discovery","network","ssh","\u002F2026\u002F02\u002F11\u002Fnode-js-discovery-scanning-a-subnet-for-open-rdp-and-ssh\u002F","ENUTwexQIMcg75FyJ-l7xm53NplfyoQvQmWHP3Od_VQ",{"title":3730,"description":3731,"date":3732,"url":3733,"categories":3734,"tags":3735,"image":3716,"readingTime":203,"canonical":3708,"sites":3737,"series":3716,"seriesOrder":3716},"Node.js: Azure – A Slack Bot for Resource Group Budget Alerts","A Node.js script that queries month-to-date Azure cost per resource group, projects month-end spend, and posts Block Kit messages to Slack for groups over budget.","2026-02-18T14:00:00Z","\u002F2026\u002F02\u002F18\u002Fnode-js-azure-a-slack-bot-for-resource-group-budget-alerts\u002F",[3710,3711],[3723,3736],"azure",[3708],{"title":3739,"description":3740,"date":3741,"url":3742,"categories":3743,"tags":3744,"image":3716,"readingTime":203,"canonical":3708,"sites":3748,"series":3716,"seriesOrder":3716},"Python: Talos – Health-Checking a Kubernetes Cluster from a Cron Job","A cron-friendly Python health check for Talos clusters: talosctl health, etcd alarms, node readiness, cordons and crash-looping pods, with a webhook alert.","2026-02-04T14:00:00Z","\u002F2026\u002F02\u002F04\u002Fpython-talos-health-checking-a-kubernetes-cluster-from-a-cron-job\u002F",[3710,3711],[3745,3746,3747],"python","talos","kubernetes",[3708],[3750,3757,3766],{"title":3751,"description":3752,"date":3753,"url":3637,"categories":3754,"tags":3755,"image":3716,"readingTime":191,"canonical":3708,"sites":3756,"series":3716,"seriesOrder":3716},"Node.js: Discovery – Diffing Two Network Scans to Flag New Hosts","A dependency-free Node.js script that diffs two nmap XML scans and flags new, missing and moved hosts plus port changes, with an exit code for cron or CI.","2026-03-11T14:00:00Z",[3710,3711],[3723,3724,3725],[3708],{"title":3758,"description":3759,"date":3760,"url":3761,"categories":3762,"tags":3763,"image":3716,"readingTime":191,"canonical":3708,"sites":3765,"series":3716,"seriesOrder":3716},"Python: Discovery – Crawling DNS Zones for Orphaned Records","A dnspython script that transfers a zone with AXFR, probes every A\u002FAAAA record for signs of life, flags dangling CNAMEs, and reports orphan cleanup candidates.","2026-01-28T14:00:00Z","\u002F2026\u002F01\u002F28\u002Fpython-discovery-crawling-dns-zones-for-orphaned-records\u002F",[3710,3711],[3745,3724,3725,3764],"windows",[3708],{"title":3767,"description":3768,"date":3769,"url":20,"categories":3770,"tags":3771,"image":3716,"readingTime":191,"canonical":3708,"sites":3772,"series":3716,"seriesOrder":3716},"Python: Discovery – Fingerprint Every Device on a Subnet","A Python script that ARP-sweeps a local subnet with Scapy, maps MACs to IEEE vendors, probes common ports for banners, and writes one CSV row per device.","2026-01-07T14:00:00Z",[3710,3711],[3745,3724,3725],[3708],{"doc":3716,"posts":3774},[],1790052513632]