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

Reverted to npm version. Handle ports array, optional host. Backward compatible. Added Tests. #36

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
The portscanner module is
an asynchronous JavaScript port scanner for Node.js.

Portscanner can check a port,
or range of ports,
for 'open' or 'closed' statuses.
Portscanner can check a port, range of ports, or array of ports for 'open' or 'closed' statuses.

[Looking for maintainer](https://github.com/baalexander/node-portscanner/issues/25)!

Expand Down Expand Up @@ -39,15 +37,28 @@ portscanner.findAPortNotInUse(3000, 3010, '127.0.0.1', function(error, port) {
portscanner.findAPortInUse(3000, 3010, '127.0.0.1', function(error, port) {
console.log('PORT IN USE AT: ' + port)
})

// You can also pass array of ports to check
portscanner.findAPortInUse([3000, 3005, 3006], '127.0.0.1', function(error, port) {
console.log('PORT IN USE AT: ' + port)
})

// And skip host param. Default is '127.0.0.1'
portscanner.findAPortInUse([3000, 3005, 3006], function(error, port) {
console.log('PORT IN USE AT: ' + port)
})

// You can do this on every method
portscanner.findAPortNotInUse(3000, 4000, function(error, port) {
console.log('PORT IN USE AT: ' + port)
})
```

The example directory contains a more detailed example.

## Test

There are currently no tests.
If you have ideas,
please open an issue.
```$ npm test```

## Future

Expand Down
124 changes: 92 additions & 32 deletions lib/portscanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,59 +8,83 @@ var portscanner = exports
* Finds the first port with a status of 'open', implying the port is in use and
* there is likely a service listening on it.
*
* @param {Number} startPort - Port to begin status check on (inclusive).
* @param {Number} endPort - Last port to check status on (inclusive).
* Defaults to 65535.
* @param {String} host - Where to scan. Defaults to '127.0.0.1'.
* @param {Function} callback - function (error, port) { ... }
* portsArray - Array of ports to check
* startPort - Port to begin status check on (inclusive).
* endPort - Last port to check status on (inclusive).
* host - Where to scan. Defaults to '127.0.0.1'.
* callback - function (error, port) { ... }
* - {Object|null} error - Any errors that occurred while port scanning.
* - {Number|Boolean} port - The first open port found. Note, this is the
* first port that returns status as 'open', not
* necessarily the first open port checked. If no
* open port is found, the value is false.
* first port that returns status as 'open', not
* necessarily the first open port checked. If no
* open port is found, the value is false.
*
*
* @param {Array |Number} params portsArray or startPort
* @param {String |Number} params host or endPort
* @param {Function|String} params callback or host
* @param {* |Function} params empty or callback
*
* @examples
* portscanner.findAPortInUse([3000, 3001, 3002], '127.0.0.1', callback)
* portscanner.findAPortInUse(3000, 3002, '127.0.0.1', callback)
*/
portscanner.findAPortInUse = function(startPort, endPort, host, callback) {
findAPortWithStatus('open', startPort, endPort, host, callback)
}
portscanner.findAPortInUse = function(params) {
findAPortWithStatus('open', arguments)
};

/**
* Finds the first port with a status of 'closed', implying the port is not in
* use.
*
* @param {Number} startPort - Port to begin status check on (inclusive).
* @param {Number} endPort - Last port to check status on (inclusive).
* Defaults to 65535.
* @param {String} host - Where to scan. Defaults to '127.0.0.1'.
* @param {Function} callback - function (error, port) { ... }
* portsArray - Array of ports to check
* startPort - Port to begin status check on (inclusive).
* endPort - Last port to check status on (inclusive).
* host - Where to scan. Defaults to '127.0.0.1'.
* callback - function (error, port) { ... }
* - {Object|null} error - Any errors that occurred while port scanning.
* - {Number|Boolean} port - The first closed port found. Note, this is the
* first port that returns status as 'closed', not
* necessarily the first closed port checked. If no
* closed port is found, the value is false.
* first port that returns status as 'closed', not
* necessarily the first closed port checked. If no
* closed port is found, the value is false.
*
* @param {Array |Number} params portsArray or startPort
* @param {String |Number} params host or endPort
* @param {Function|String} params callback or host
* @param {* |Function} params empty or callback
*
* @examples
* portscanner.findAPortNotInUse([3000, 3001, 3002], '127.0.0.1', callback)
* portscanner.findAPortNotInUse(3000, 3002, '127.0.0.1', callback)
*/
portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) {
findAPortWithStatus('closed', startPort, endPort, host, callback)
portscanner.findAPortNotInUse = function(params) {
findAPortWithStatus('closed', arguments)
}

/**
* Checks the status of an individual port.
*
* @param {Number} port - Port to check status on.
* @param {String|Object} options - host or options
* @param {String|Object|Function} arg2 - host or options or function
* - {String} host - Host of where to scan. Defaults to '127.0.0.1'.
* - {Object} options
* - {String} host - Host of where to scan. Defaults to '127.0.0.1'.
* - {Number} timeout - Connection timeout. Defaults to 400ms.
* @param {Function} callback - function (error, port) { ... }
* @param {Function} arg3 - function (error, port) { ... }
* - {Object|null} error - Any errors that occurred while port scanning.
* - {String} status - 'open' if the port is in use.
* 'closed' if the port is available.
* 'closed' if the port is available.
*/
portscanner.checkPortStatus = function(port, options, callback) {
if (typeof options === 'string') {
portscanner.checkPortStatus = function(port, arg2, arg3) {
var options = {}
, callback

if (typeof arg2 === 'string') {
// Assume this param is the host option
options = {host: options}
}
options = {host: arg2}
}

callback = Array.prototype.slice.call(arguments).slice(-1)[0];

var host = options.host || '127.0.0.1'
var timeout = options.timeout || 400
Expand Down Expand Up @@ -107,28 +131,64 @@ portscanner.checkPortStatus = function(port, options, callback) {
socket.connect(port, host)
}

function findAPortWithStatus(status, startPort, endPort, host, callback) {
/**
*
* @param {Number} from
* @param {Number} to
* @return {Array} Array of integers from @from to @to inclusive
*/
function range(from, to) {
const arr = [];

while(from <= to) {
arr.push(~~from);
from += 1;
}

return arr;
}

function findAPortWithStatus(status, params) {
var host;
var callback;

//use array of ports
if (typeof params[0] === 'object') {
var ports = params[0];
host = typeof params[1] === 'string' ? params[1] : null;

//use startPort and endPort
} else if (typeof params[0] === 'number') {
var startPort = params[0];
var endPort = params[1];
host = typeof params[2] === 'string' ? params[2] : null;
}

//callback always at the end
callback = Array.prototype.slice.call(params).slice(-1)[0];

endPort = endPort || 65535
var foundPort = false
var numberOfPortsChecked = 0
var port = startPort
var port = ports ? ports[0] : startPort

// Returns true if a port with matching status has been found or if checked
// the entire range of ports
var hasFoundPort = function() {
return foundPort || numberOfPortsChecked === (endPort - startPort + 1)
return foundPort || numberOfPortsChecked === (ports ? ports.length : endPort - startPort + 1)
}

// Checks the status of the port
var checkNextPort = function(callback) {

portscanner.checkPortStatus(port, host, function(error, statusOfPort) {
numberOfPortsChecked++
if (statusOfPort === status) {
foundPort = true
callback(error)
}
else {
port++
port = ports ? ports[numberOfPortsChecked] : port + 1;
callback(null)
}
})
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"name": "portscanner",
"description": "Asynchronous port scanner for Node.js",
"scripts": {
"test": "ava"
},
"keywords": [
"portscanner",
"port",
Expand Down Expand Up @@ -29,15 +32,12 @@
"dependencies": {
"async": "0.1.15"
},
"devDependencies": {},
"devDependencies": {
"ava": "^0.4.2"
},
"engines": {
"node": ">=0.4",
"npm": ">=1.0.0"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/baalexander/node-portscanner/raw/master/LICENSE"
}
]
"license": "MIT"
}
Loading