diff --git a/package.json b/package.json index b3c3c7c..2f22c1e 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint-staged": "lint-staged", "install:void": ":", "install:kissik/port-sniffer": "cd ./submissions/kissik/port-sniffer && yarn", + "install:xsorter/port-sniffer": "cd ./submissions/xsorter/port-sniffer && yarn", "postinstall": "run-p install:**" }, "repository": { diff --git a/submissions/xsorter/port-sniffer/package.json b/submissions/xsorter/port-sniffer/package.json new file mode 100644 index 0000000..307e74f --- /dev/null +++ b/submissions/xsorter/port-sniffer/package.json @@ -0,0 +1,16 @@ +{ + "name": "port_sniffer", + "version": "1.0.0", + "description": "", + "main": "program.js", + "dependencies": { + "minimist": "^1.2.0", + "async": "^3.1.0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/submissions/xsorter/port-sniffer/program.js b/submissions/xsorter/port-sniffer/program.js new file mode 100644 index 0000000..462c5b8 --- /dev/null +++ b/submissions/xsorter/port-sniffer/program.js @@ -0,0 +1,103 @@ +const mapLimit = require('async/mapLimit'); +const net = require('net'); +const dns = require('dns'); +const args = require('minimist')(process.argv.slice(2)); +const range = findPortsRange(); + +const ports = { + portList: fillArrayRange((range[1] - range[0]) + 1, range[0]), + firstPort: range[0], + lastPort: range[1] ? range[1] : range[0], + openedPorts: [] +}; + +const openedPortCheck = (host, port, checkCallback) => { + const socket = net.createConnection(port, host); + const time = socket.setTimeout(300, () => { + socket.destroy(); + checkCallback(false); + }); + + socket.on('connect', () => { + clearTimeout(time); + socket.destroy(); + console.log('.'); + ports.openedPorts.push(port); + checkCallback(true); + }); + socket.on('error', function () { + clearTimeout(time); + checkCallback(false); + }); +}; + +const showResult = host => { + if (args.help) { + console.table(messages().help); + return false; + } + if (!args.host) { + return false; + } else { + mapLimit(ports.portList, 10, async currentPort => { + await openedPortCheck(host, currentPort, () => { + if (currentPort === ports.lastPort) { + if (ports.openedPorts.length) { + console.table( + messages(ports.openedPorts.join()).openedPorts + ); + process.exit(0); + } else { + console.table(messages().portsNotFound); + return false; + } + } + }); + }); + } +}; + +function findPortsRange () { + if (args.ports) { + if (args.ports.length) { + return args.ports.split('-').map(Number); + } else { + console.table(messages().emptyPortsParameter); + return false; + } + } else { + return [0, 65535]; + } +} + +function messages (openedPortsNumbers) { + return { + help: `Port sniffer CLI tool. \n + Parameters: + --ports - type ports range + --host - provide host IP adress or domain name \n + Usage example: node program.js --ports 80-87 --host google.com`, + noHost: 'Please provide host name. Type --help for usage manual.', + openedPorts: `\nports ${openedPortsNumbers} are opened`, + portsNotFound: 'No opened ports was found', + emptyPortsParameter: + 'Please provide a port numbers range or skip --port parameter for default values (0-65535)' + }; +} + +function fillArrayRange (arrLength, firstVal) { + return Array.from(new Array(arrLength), (_, i) => (i + firstVal)); +} + +const ipLookup = () => { + return new Promise((resolve, reject) => { + dns.lookup(args.host, (err, address) => { + if (err) reject(err); + resolve(address); + }); + }); +}; + +ipLookup() + .then(res => showResult(res)) + .catch(() => console.table('Adress not found'));