From 6870a94f54d4705ebe3ad8f01deec6b72ede96d8 Mon Sep 17 00:00:00 2001 From: apalamarchuk Date: Thu, 10 Oct 2019 11:14:22 +0300 Subject: [PATCH] port-sniffer is developed --- submissions/assmass13/port-sniffer/README.md | 0 submissions/assmass13/port-sniffer/sniffer.js | 127 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 submissions/assmass13/port-sniffer/README.md create mode 100644 submissions/assmass13/port-sniffer/sniffer.js diff --git a/submissions/assmass13/port-sniffer/README.md b/submissions/assmass13/port-sniffer/README.md new file mode 100644 index 0000000..e69de29 diff --git a/submissions/assmass13/port-sniffer/sniffer.js b/submissions/assmass13/port-sniffer/sniffer.js new file mode 100644 index 0000000..f3049d6 --- /dev/null +++ b/submissions/assmass13/port-sniffer/sniffer.js @@ -0,0 +1,127 @@ +const dns = require('dns'); +const { Socket } = require('net'); + +const defaultPortLimits = { + startPort: 0, + endPort: 65535 +}; +const timeout = 300; + +const helpMessage = `Sniffer params usage: +--host - required argument which can be either domain name, like google.com or IP address like 172.217.3.110 +--ports - limits range of ports to scan, should be provided in format (start_port)-(end_port), for instance: 3-600 +--help - flag to see hint about how to use TCP sniffer\n`; +const hostErrorMessage = `--host parameter with its value should be passed\n`; +const portsErrorMessage = `--ports value should be passed as a port range with limits(0-65535), like 15-333\n`; +function lookupErrorMessage(error) { + return `Error ${error.code} occurred during ${error.syscall} call for '${error.hostname}' host\n`; +} + +function stdoutWrite(str) { + process.stdout.write(str); +} + +function exit(code) { + process.exit(code); +} + +function parseArgs(args) { + if (args.includes('--help')) { + stdoutWrite(helpMessage); + exit(0); + } else if ( + args.indexOf('--host') === -1 || + !args[args.indexOf('--host') + 1] + ) { + stdoutWrite(hostErrorMessage); + exit(1); + } + + return args.reduce((result, item, index, arr) => { + if (item.indexOf('--') === 0 && arr[index + 1]) { + return { ...result, [item]: arr[index + 1] }; + } + return result; + }, {}); +} + +async function getAddress(host) { + return new Promise((resolve, reject) => { + dns.lookup(host, (err, address) => { + if (err) reject(err); + resolve(address); + }); + }).catch(e => { + stdoutWrite(lookupErrorMessage(e)); + exit(1); + }); +} + +function getPortLimits(portsRange) { + const arePortsValid = ports => + ports.length === 2 && + ports[0] >= defaultPortLimits.startPort && + ports[1] > ports[0] && + ports[1] <= defaultPortLimits.endPort; + + const portArr = portsRange.split('-').map(portNum => parseInt(portNum, 10)); + + if (!arePortsValid(portArr)) { + stdoutWrite(portsErrorMessage); + exit(1); + } + return { startPort: portArr[0], endPort: portArr[1] }; +} + +async function scanAddressPort(address, port) { + return new Promise(resolve => { + const socket = new Socket(); + socket.setTimeout(timeout); + + socket.on('connect', () => { + stdoutWrite('.'); + resolve(port); + socket.destroy(); + }); + + socket.on('timeout', () => { + resolve(false); + socket.destroy(); + }); + + socket.on('error', () => { + resolve(false); + socket.destroy(); + }); + + socket.connect(port, address); + }); +} + +function getAddressOpenPorts(address, startPort, endPort) { + const openPorts = []; + for (let port = startPort; port < endPort; port += 1) { + openPorts.push(scanAddressPort(address, port)); + } + return Promise.all(openPorts).then(values => values.filter(Number.isFinite)); +} + +(async function sniff() { + const processArgs = process.argv.slice(2); + const parsedArgs = parseArgs(processArgs); + const address = await getAddress(parsedArgs['--host']); + const portLimits = + '--ports' in parsedArgs + ? getPortLimits(parsedArgs['--ports']) + : defaultPortLimits; + const openPorts = await getAddressOpenPorts( + address, + portLimits.startPort, + portLimits.endPort + ); + if (openPorts.length > 0) { + stdoutWrite(`\n${openPorts.join(', ')} ports are opened\n`); + } else { + stdoutWrite('No opened ports\n'); + } +})();