Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port-sniffer task #17

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions submissions/Vitamin/port-sniffer/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const help = `
Usage: sniffer.js [--help] [--ports <number>-<number>] [--host <value>]

These are commands used in sniffer application:

host Host address, IP or URL.
Examples: --host ukr.net,
--host 172.217.3.110

ports Ports range. Numbers must be more than 0 and less than 65535.
Examples: --port 30-562,
--port 1-65535.

help Show all commands.
`;
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved

const composeAsync = (...fns) => async x => {
let res = x;
for (const fn of fns) {
res = await fn(res);
}
return res;
};

module.exports = { help, compose, composeAsync };
91 changes: 91 additions & 0 deletions submissions/Vitamin/port-sniffer/sniffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const Net = require("net");
const dns = require("dns").promises;
const { help } = require("./helpers");

const [, , ...arguments] = process.argv;
const [minPortValue, maxPortValue] = [0, 65535];

const ipToURL = async host => {
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
try {
const result = await dns.lookup(host);
return await result.address;
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
throw Error("Invalid host");
}
};

const isPortInRange = port => port >= minPortValue && port <= maxPortValue;

const getPortsRange = ports => {
const [firstPort, last] = ports.split("-");
const lastPort = isPortInRange(last) ? last : firstPort;
if (isPortInRange(firstPort)) {
return [firstPort, lastPort];
} else {
console.log("Invalid ports range");
process.exit(1);
}
};

const tryToConnect = (host, port) => {
const client = new Net.Socket();
client.setTimeout(300);
client.connect({ port, host });
return new Promise(resolve => {
client.on("connect", () => {
process.stdout.write(".");
client.destroy();
return resolve(port);
});
client.on("timeout", () => {
client.destroy();
return resolve(false);
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
});
client.on("error", () => {
client.destroy();
return resolve(false);
});
});
};

const getOpenedPorts = async ({ host, firstPort, lastPort }) => {
const promises = [];
for (let i = firstPort; i <= lastPort; i++) {
promises.push(tryToConnect(host, i));
}
const ports = await Promise.all(promises);
return ports.filter(Boolean);
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
};

parseArguments = async args => {
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
if (args.includes("--help")) {
console.log(help);
process.exit(0);
} else if (
args.length < 4 ||
!args.includes("--ports") ||
!args.includes("--host")
) {
console.log("Use --help to correct input");
process.exit(1);
}
const [firstPort, lastPort] = getPortsRange(args[1]);
const host = await ipToURL(args[3]);
return { host, firstPort, lastPort };
};

const getMessageToLog = openPorts => {
if (openPorts.length > 1) return `\n${openPorts} ports are opened`;
else if (openPorts.length === 1) return `\n${openPorts} port is opened`;
return "\nAll ports in range are closed";
};

const sniffing = async args => {
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
const { host, firstPort, lastPort } = await parseArguments(args);
return await getOpenedPorts({ host, firstPort, lastPort });
Vitaminvp marked this conversation as resolved.
Show resolved Hide resolved
};

sniffing(arguments)
.then(getMessageToLog)
.then(console.log);