Initial commit
This commit is contained in:
113
node_modules/ping/lib/builder/factory.js
generated
vendored
Normal file
113
node_modules/ping/lib/builder/factory.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
var __ = require('underscore');
|
||||
var util = require('util');
|
||||
|
||||
// Our library
|
||||
var linuxBuilder = require('./linux');
|
||||
var macBuilder = require('./mac');
|
||||
var winBuilder = require('./win');
|
||||
|
||||
/**
|
||||
* A factory creates argument builders for different platform
|
||||
* @constructor
|
||||
*/
|
||||
function factory() {}
|
||||
|
||||
/**
|
||||
* Check out linux platform
|
||||
*/
|
||||
factory.isLinux = function (p) {
|
||||
var platforms = [
|
||||
'aix',
|
||||
'android',
|
||||
'linux',
|
||||
];
|
||||
|
||||
return platforms.indexOf(p) >= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check out macos platform
|
||||
*/
|
||||
factory.isMacOS = function (p) {
|
||||
var platforms = [
|
||||
'darwin',
|
||||
'freebsd',
|
||||
];
|
||||
|
||||
return platforms.indexOf(p) >= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check out window platform
|
||||
*/
|
||||
factory.isWindow = function (p) {
|
||||
return p && p.match(/^win/) !== null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether given platform is supported
|
||||
* @param {string} p - Name of the platform
|
||||
* @return {bool} - True or False
|
||||
*/
|
||||
factory.isPlatformSupport = function (p) {
|
||||
return __.some([
|
||||
this.isWindow(p),
|
||||
this.isLinux(p),
|
||||
this.isMacOS(p),
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a path to the ping executable in the system
|
||||
* @param {string} platform - Name of the platform
|
||||
* @param {bool} v6 - Ping via ipv6 or not
|
||||
* @return {string} - Executable path for system command ping
|
||||
* @throw if given platform is not supported
|
||||
*/
|
||||
factory.getExecutablePath = function (platform, v6) {
|
||||
if (!this.isPlatformSupport(platform)) {
|
||||
throw new Error(util.format('Platform |%s| is not support', platform));
|
||||
}
|
||||
|
||||
var ret = null;
|
||||
|
||||
if (platform === 'aix') {
|
||||
ret = '/usr/sbin/ping';
|
||||
} else if (factory.isLinux(platform)) {
|
||||
ret = v6 ? 'ping6' : 'ping';
|
||||
} else if (factory.isWindow(platform)) {
|
||||
ret = process.env.SystemRoot + '/system32/ping.exe';
|
||||
} else if (factory.isMacOS(platform)) {
|
||||
ret = v6 ? '/sbin/ping6' : '/sbin/ping';
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a builder
|
||||
* @param {string} platform - Name of the platform
|
||||
* @return {object} - Argument builder
|
||||
* @throw if given platform is not supported
|
||||
*/
|
||||
factory.createBuilder = function (platform) {
|
||||
if (!this.isPlatformSupport(platform)) {
|
||||
throw new Error(util.format('Platform |%s| is not support', platform));
|
||||
}
|
||||
|
||||
var ret = null;
|
||||
|
||||
if (factory.isLinux(platform)) {
|
||||
ret = linuxBuilder;
|
||||
} else if (factory.isWindow(platform)) {
|
||||
ret = winBuilder;
|
||||
} else if (factory.isMacOS(platform)) {
|
||||
ret = macBuilder;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
module.exports = factory;
|
125
node_modules/ping/lib/builder/linux.js
generated
vendored
Normal file
125
node_modules/ping/lib/builder/linux.js
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A builder builds command line arguments for ping in linux environment
|
||||
* @module lib/builder/linux
|
||||
*/
|
||||
var util = require('util');
|
||||
|
||||
var builder = {};
|
||||
|
||||
/**
|
||||
* Cross platform config representation
|
||||
* @typedef {Object} PingConfig
|
||||
* @property {boolean} numeric - Map IP address to hostname or not
|
||||
* @property {number} timeout - Time to wait for a response, in seconds.
|
||||
* The option affects only timeout in absence of any responses,
|
||||
* otherwise ping waits for two RTTs.
|
||||
* @property {number} deadline - Specify a timeout, in seconds,
|
||||
* before ping exits regardless of how many packets have been sent or received.
|
||||
* In this case ping does not stop after count packet are sent,
|
||||
* it waits either for deadline expire or until count probes are answered
|
||||
* or for some error notification from network.
|
||||
* This option is only available on linux and mac.
|
||||
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
|
||||
* @property {boolean} v6 - Use IPv4 (default) or IPv6
|
||||
* @property {string} sourceAddr - source address for sending the ping
|
||||
* @property {number} packetSize - Specifies the number of data bytes to be sent
|
||||
* Default: Linux / MAC: 56 Bytes,
|
||||
* Window: 32 Bytes
|
||||
* @property {string[]} extra - Optional options does not provided
|
||||
*/
|
||||
|
||||
var defaultConfig = {
|
||||
numeric: true,
|
||||
timeout: 2,
|
||||
deadline: false,
|
||||
min_reply: 1,
|
||||
v6: false,
|
||||
sourceAddr: '',
|
||||
packetSize: 56,
|
||||
extra: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the finalized array of command line arguments
|
||||
* @param {string} target - hostname or ip address
|
||||
* @param {PingConfig} [config] - Configuration object for cmd line argument
|
||||
* @return {string[]} - Command line argument according to the configuration
|
||||
*/
|
||||
builder.getCommandArguments = function (target, config) {
|
||||
var _config = config || {};
|
||||
|
||||
// Empty argument
|
||||
var ret = [];
|
||||
|
||||
// Make every key in config has been setup properly
|
||||
var keys = ['numeric', 'timeout', 'deadline', 'min_reply', 'v6',
|
||||
'sourceAddr', 'extra', 'packetSize'];
|
||||
keys.forEach(function (k) {
|
||||
// Falsy value will be overridden without below checking
|
||||
if (typeof(_config[k]) !== 'boolean') {
|
||||
_config[k] = _config[k] || defaultConfig[k];
|
||||
}
|
||||
});
|
||||
|
||||
if (_config.numeric) {
|
||||
ret.push('-n');
|
||||
}
|
||||
|
||||
if (_config.timeout) {
|
||||
ret = ret.concat([
|
||||
'-W',
|
||||
util.format('%d', _config.timeout),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.deadline) {
|
||||
ret = ret.concat([
|
||||
'-w',
|
||||
util.format('%d', _config.deadline),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.min_reply) {
|
||||
ret = ret.concat([
|
||||
'-c',
|
||||
util.format('%d', _config.min_reply),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.sourceAddr) {
|
||||
ret = ret.concat([
|
||||
'-I',
|
||||
util.format('%s', _config.sourceAddr),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.packetSize) {
|
||||
ret = ret.concat([
|
||||
'-s',
|
||||
util.format('%d', _config.packetSize),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.extra) {
|
||||
ret = ret.concat(_config.extra);
|
||||
}
|
||||
|
||||
ret.push(target);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute an option object for child_process.spawn
|
||||
* @return {object} - Refer to document of child_process.spawn
|
||||
*/
|
||||
builder.getSpawnOptions = function () {
|
||||
return {
|
||||
shell: false,
|
||||
env: Object.assign(process.env, {LANG: 'C'}),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = builder;
|
129
node_modules/ping/lib/builder/mac.js
generated
vendored
Normal file
129
node_modules/ping/lib/builder/mac.js
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A builder builds command line arguments for ping in mac environment
|
||||
* @module lib/builder/mac
|
||||
*/
|
||||
var util = require('util');
|
||||
|
||||
var builder = {};
|
||||
|
||||
/**
|
||||
* Cross platform config representation
|
||||
* @typedef {Object} PingConfig
|
||||
* @property {boolean} numeric - Map IP address to hostname or not
|
||||
* @property {number} timeout - Time to wait for a response, in seconds.
|
||||
* The option affects only timeout in absence of any responses,
|
||||
* otherwise ping waits for two RTTs.
|
||||
* @property {number} deadline - Specify a timeout, in seconds,
|
||||
* before ping exits regardless of how many packets have been sent or received.
|
||||
* In this case ping does not stop after count packet are sent,
|
||||
* it waits either for deadline expire or until count probes are answered
|
||||
* or for some error notification from network.
|
||||
* This option is only available on linux and mac.
|
||||
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
|
||||
* @property {boolean} v6 - Use IPv4 (default) or IPv6
|
||||
* @property {string} sourceAddr - source address for sending the ping
|
||||
* @property {number} packetSize - Specifies the number of data bytes to be sent
|
||||
* Default: Linux / MAC: 56 Bytes,
|
||||
* Window: 32 Bytes
|
||||
* @property {string[]} extra - Optional options does not provided
|
||||
*/
|
||||
|
||||
var defaultConfig = {
|
||||
numeric: true,
|
||||
timeout: 2,
|
||||
deadline: false,
|
||||
min_reply: 1,
|
||||
v6: false,
|
||||
sourceAddr: '',
|
||||
packetSize: 56,
|
||||
extra: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the finalized array of command line arguments
|
||||
* @param {string} target - hostname or ip address
|
||||
* @param {PingConfig} [config] - Configuration object for cmd line argument
|
||||
* @return {string[]} - Command line argument according to the configuration
|
||||
* @throws If there are errors on building arguments with given inputs
|
||||
*/
|
||||
builder.getCommandArguments = function (target, config) {
|
||||
var _config = config || {};
|
||||
|
||||
// Empty argument
|
||||
var ret = [];
|
||||
|
||||
// Make every key in config has been setup properly
|
||||
var keys = ['numeric', 'timeout', 'deadline', 'min_reply', 'v6',
|
||||
'sourceAddr', 'extra', 'packetSize'];
|
||||
keys.forEach(function (k) {
|
||||
// Falsy value will be overridden without below checking
|
||||
if (typeof(_config[k]) !== 'boolean') {
|
||||
_config[k] = _config[k] || defaultConfig[k];
|
||||
}
|
||||
});
|
||||
|
||||
if (_config.numeric) {
|
||||
ret.push('-n');
|
||||
}
|
||||
|
||||
if (_config.timeout) {
|
||||
// XXX: There is no timeout option on mac's ping6
|
||||
if (config.v6) {
|
||||
throw new Error('There is no timeout option on ping6');
|
||||
}
|
||||
|
||||
ret = ret.concat([
|
||||
'-W',
|
||||
util.format('%d', _config.timeout * 1000),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.deadline) {
|
||||
ret = ret.concat([
|
||||
'-t',
|
||||
util.format('%d', _config.deadline),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.min_reply) {
|
||||
ret = ret.concat([
|
||||
'-c',
|
||||
util.format('%d', _config.min_reply),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.sourceAddr) {
|
||||
ret = ret.concat([
|
||||
'-S',
|
||||
util.format('%s', _config.sourceAddr),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.packetSize) {
|
||||
ret = ret.concat([
|
||||
'-s',
|
||||
util.format('%d', _config.packetSize),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.extra) {
|
||||
ret = ret.concat(_config.extra);
|
||||
}
|
||||
|
||||
ret.push(target);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute an option object for child_process.spawn
|
||||
* @return {object} - Refer to document of child_process.spawn
|
||||
*/
|
||||
builder.getSpawnOptions = function () {
|
||||
return {};
|
||||
};
|
||||
|
||||
|
||||
module.exports = builder;
|
119
node_modules/ping/lib/builder/win.js
generated
vendored
Normal file
119
node_modules/ping/lib/builder/win.js
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A builder builds command line arguments for ping in window environment
|
||||
* @module lib/builder/win
|
||||
*/
|
||||
var util = require('util');
|
||||
|
||||
var builder = {};
|
||||
|
||||
/**
|
||||
* Cross platform config representation
|
||||
* @typedef {Object} PingConfig
|
||||
* @property {boolean} numeric - Map IP address to hostname or not
|
||||
* @property {number} timeout - Timeout in seconds for each ping request
|
||||
* @property {number} min_reply - Exit after sending number of ECHO_REQUEST
|
||||
* @property {boolean} v6 - Use IPv4 (default) or IPv6
|
||||
* @property {string} sourceAddr - source address for sending the ping
|
||||
* @property {number} packetSize - Specifies the number of data bytes to be sent
|
||||
* Default: Linux / MAC: 56 Bytes,
|
||||
* Window: 32 Bytes
|
||||
* @property {string[]} extra - Optional options does not provided
|
||||
*/
|
||||
|
||||
var defaultConfig = {
|
||||
numeric: true,
|
||||
timeout: 5,
|
||||
min_reply: 1,
|
||||
v6: false,
|
||||
sourceAddr: '',
|
||||
packetSize: 32,
|
||||
extra: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the finalized array of command line arguments
|
||||
* @param {string} target - hostname or ip address
|
||||
* @param {PingConfig} [config] - Configuration object for cmd line argument
|
||||
* @return {string[]} - Command line argument according to the configuration
|
||||
*/
|
||||
builder.getCommandArguments = function (target, config) {
|
||||
var _config = config || {};
|
||||
|
||||
// Empty argument
|
||||
var ret = [];
|
||||
|
||||
// Make every key in config has been setup properly
|
||||
var keys = [
|
||||
'numeric', 'timeout', 'min_reply', 'v6', 'sourceAddr', 'extra',
|
||||
'packetSize',
|
||||
];
|
||||
keys.forEach(function (k) {
|
||||
// Falsy value will be overrided without below checking
|
||||
if (typeof(_config[k]) !== 'boolean') {
|
||||
_config[k] = _config[k] || defaultConfig[k];
|
||||
}
|
||||
});
|
||||
|
||||
ret.push(_config.v6 ? '-6' : '-4');
|
||||
|
||||
if (!_config.numeric) {
|
||||
ret.push('-a');
|
||||
}
|
||||
|
||||
if (_config.timeout) {
|
||||
// refs #56: Unit problem
|
||||
// Our timeout is in second while timeout in window is in milliseconds
|
||||
// so we need to convert our units accordingly
|
||||
ret = ret.concat([
|
||||
'-w',
|
||||
util.format('%d', _config.timeout * 1000),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.deadline) {
|
||||
throw new Error('There is no deadline option on windows');
|
||||
}
|
||||
|
||||
if (_config.min_reply) {
|
||||
ret = ret.concat([
|
||||
'-n',
|
||||
util.format('%d', _config.min_reply),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.sourceAddr) {
|
||||
ret = ret.concat([
|
||||
'-S',
|
||||
util.format('%s', _config.sourceAddr),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.packetSize) {
|
||||
ret = ret.concat([
|
||||
'-l',
|
||||
util.format('%d', _config.packetSize),
|
||||
]);
|
||||
}
|
||||
|
||||
if (_config.extra) {
|
||||
ret = ret.concat(_config.extra);
|
||||
}
|
||||
|
||||
ret.push(target);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute an option object for child_process.spawn
|
||||
* @return {object} - Refer to document of child_process.spawn
|
||||
*/
|
||||
builder.getSpawnOptions = function () {
|
||||
return {
|
||||
windowsHide: true,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = builder;
|
203
node_modules/ping/lib/parser/base.js
generated
vendored
Normal file
203
node_modules/ping/lib/parser/base.js
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
var __ = require('underscore');
|
||||
|
||||
/**
|
||||
* Parsed response
|
||||
* @typedef {object} PingResponse
|
||||
* @param {string} inputHost - The input IP address or HOST
|
||||
* @param {string} host - The input IP address or HOST
|
||||
* @param {string} numeric_host - Target IP address
|
||||
* @param {boolean} alive - True for existed host
|
||||
* @param {string} output - Raw stdout from system ping
|
||||
* @param {number} time - Time (float) in ms for first successful ping response
|
||||
* @param {string} min - Minimum time for collection records
|
||||
* @param {string} max - Maximum time for collection records
|
||||
* @param {string} avg - Average time for collection records
|
||||
* @param {number} packetLoss - Packet Losses in percent (number)
|
||||
* @param {string} stddev - Standard deviation time for collected records
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Config object in probe()
|
||||
*/
|
||||
function parser(addr, config) {
|
||||
// Initial state is 0
|
||||
this._state = 0;
|
||||
|
||||
// Initial cache value
|
||||
this._response = {
|
||||
inputHost: addr,
|
||||
host: 'unknown',
|
||||
alive: false,
|
||||
output: 'unknown',
|
||||
time: 'unknown',
|
||||
times: [],
|
||||
min: 'unknown',
|
||||
max: 'unknown',
|
||||
avg: 'unknown',
|
||||
stddev: 'unknown',
|
||||
packetLoss: 'unknown',
|
||||
};
|
||||
|
||||
// Initial times storage for ping time
|
||||
this._times = [];
|
||||
|
||||
// Initial lines storage for ping output
|
||||
this._lines = [];
|
||||
|
||||
// strip string regexp
|
||||
this._stripRegex = /[ ]*\r?\n?$/g;
|
||||
|
||||
// Ping Config
|
||||
this._pingConfig = config || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for parser states
|
||||
* @readonly
|
||||
* @enum {number}
|
||||
*/
|
||||
parser.prototype.STATES = {
|
||||
INIT: 0,
|
||||
HEADER: 1,
|
||||
BODY: 2,
|
||||
FOOTER: 3,
|
||||
END: 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* Change state of this parser
|
||||
* @param {number} state - parser.STATES
|
||||
* @return {this} - This instance
|
||||
*/
|
||||
parser.prototype._changeState = function (state) {
|
||||
var states = __.values(this.STATES);
|
||||
if (states.indexOf(state) < 0) {
|
||||
throw new Error('Unknown state');
|
||||
}
|
||||
|
||||
this._state = state;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's header
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processHeader = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processBody = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's footer
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processFooter = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process a line from system ping
|
||||
* @param {string} line - A line from system ping
|
||||
* @return {this} - This instance
|
||||
*/
|
||||
parser.prototype.eat = function (line) {
|
||||
var headerStates = [
|
||||
this.STATES.INIT,
|
||||
this.STATES.HEADER,
|
||||
];
|
||||
|
||||
// Store lines
|
||||
this._lines.push(line);
|
||||
|
||||
// Strip all space \r\n at the end
|
||||
var _line = line.replace(this._stripRegex, '');
|
||||
|
||||
if (_line.length === 0) {
|
||||
// Do nothing if this is an empty line
|
||||
} else if (headerStates.indexOf(this._state) >= 0) {
|
||||
this._processHeader(_line);
|
||||
} else if (this._state === this.STATES.BODY) {
|
||||
this._processBody(_line);
|
||||
} else if (this._state === this.STATES.FOOTER) {
|
||||
this._processFooter(_line);
|
||||
} else if (this._state === this.STATES.END) {
|
||||
// Do nothing
|
||||
} else {
|
||||
throw new Error('Unknown state');
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get results after parsing certain lines from system ping
|
||||
* @return {PingResponse} - Response from parsing ping output
|
||||
*/
|
||||
parser.prototype.getResult = function () {
|
||||
var ret = __.extend({}, this._response);
|
||||
|
||||
// Concat output
|
||||
ret.output = this._lines.join('\n');
|
||||
|
||||
// Determine alive
|
||||
ret.alive = this._times.length > 0;
|
||||
|
||||
// Update time at first successful line
|
||||
if (ret.alive) {
|
||||
this._response.time = this._times[0];
|
||||
ret.time = this._response.time;
|
||||
this._response.times = this._times;
|
||||
ret.times = this._response.times;
|
||||
}
|
||||
|
||||
// Get stddev
|
||||
if (
|
||||
ret.stddev === 'unknown' && ret.alive
|
||||
) {
|
||||
var numberOfSamples = this._times.length;
|
||||
|
||||
var sumOfAllSquareDifferences = __.reduce(
|
||||
this._times,
|
||||
function (memory, time) {
|
||||
var differenceFromMean = time - ret.avg;
|
||||
var squaredDifference =
|
||||
differenceFromMean * differenceFromMean;
|
||||
return memory + squaredDifference;
|
||||
},
|
||||
0
|
||||
);
|
||||
var variances = sumOfAllSquareDifferences / numberOfSamples;
|
||||
|
||||
ret.stddev = Math.round(
|
||||
Math.sqrt(variances) * 1000
|
||||
) / 1000;
|
||||
}
|
||||
|
||||
// Fix min, avg, max, stddev up to 3 decimal points
|
||||
__.each(['min', 'avg', 'max', 'stddev', 'packetLoss'], function (key) {
|
||||
var v = ret[key];
|
||||
if (__.isNumber(v)) {
|
||||
ret[key] = v.toFixed(3);
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
module.exports = parser;
|
44
node_modules/ping/lib/parser/factory.js
generated
vendored
Normal file
44
node_modules/ping/lib/parser/factory.js
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var builderFactory = require('../builder/factory');
|
||||
var WinParser = require('./win');
|
||||
var MacParser = require('./mac');
|
||||
var LinuxParser = require('./linux');
|
||||
|
||||
/**
|
||||
* A factory creates a parser for parsing output from system ping
|
||||
* @constructor
|
||||
*/
|
||||
function factory() {}
|
||||
|
||||
/**
|
||||
* Create a parser for a given platform
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {string} platform - Name of the platform
|
||||
* @param {PingConfig} [config] - Config object in probe()
|
||||
* @return {object} - Parser
|
||||
* @throw if given platform is not supported
|
||||
*/
|
||||
factory.createParser = function (addr, platform, config) {
|
||||
// Avoid function reassignment
|
||||
var _config = config || {};
|
||||
|
||||
if (!builderFactory.isPlatformSupport(platform)) {
|
||||
throw new Error(util.format('Platform |%s| is not support', platform));
|
||||
}
|
||||
|
||||
var ret = null;
|
||||
if (builderFactory.isWindow(platform)) {
|
||||
ret = new WinParser(addr, _config);
|
||||
} else if (builderFactory.isMacOS(platform)) {
|
||||
ret = new MacParser(addr, _config);
|
||||
} else if (builderFactory.isLinux(platform)) {
|
||||
ret = new LinuxParser(addr, _config);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
module.exports = factory;
|
59
node_modules/ping/lib/parser/linux.js
generated
vendored
Normal file
59
node_modules/ping/lib/parser/linux.js
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var base = require('./base');
|
||||
var MacParser = require('./mac');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Config object in probe()
|
||||
*/
|
||||
function LinuxParser(addr, config) {
|
||||
base.call(this, addr, config);
|
||||
}
|
||||
|
||||
util.inherits(LinuxParser, base);
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
LinuxParser.prototype._processHeader = function (line) {
|
||||
// Get host and numeric_host
|
||||
var tokens = line.split(' ');
|
||||
var isProbablyIPv4 = tokens[1].indexOf('(') === -1;
|
||||
|
||||
if (isProbablyIPv4) {
|
||||
this._response.host = tokens[1];
|
||||
this._response.numeric_host = tokens[2].slice(1, -1);
|
||||
} else {
|
||||
// Normalise into either a 2 or 3 element array
|
||||
var foundAddresses = tokens.slice(1, -3).join('').match(/([^\s()]+)/g);
|
||||
this._response.host = foundAddresses.shift();
|
||||
this._response.numeric_host = foundAddresses.pop();
|
||||
}
|
||||
|
||||
this._changeState(this.STATES.BODY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
LinuxParser.prototype._processBody = function (line) {
|
||||
// Reuse mac parser implementation
|
||||
MacParser.prototype._processBody.call(this, line);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's footer
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
LinuxParser.prototype._processFooter = function (line) {
|
||||
// Reuse mac parser implementation
|
||||
MacParser.prototype._processFooter.call(this, line);
|
||||
};
|
||||
|
||||
module.exports = LinuxParser;
|
85
node_modules/ping/lib/parser/mac.js
generated
vendored
Normal file
85
node_modules/ping/lib/parser/mac.js
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var __ = require('underscore');
|
||||
|
||||
var base = require('./base');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Config object in probe()
|
||||
*/
|
||||
function MacParser(addr, config) {
|
||||
base.call(this, addr, config);
|
||||
}
|
||||
|
||||
util.inherits(MacParser, base);
|
||||
|
||||
/**
|
||||
* Process output's header
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
MacParser.prototype._processHeader = function (line) {
|
||||
// Get host and numeric_host
|
||||
var tokens = line.split(' ');
|
||||
|
||||
this._response.host = tokens[1];
|
||||
this._response.numeric_host = tokens[2].slice(1, -2);
|
||||
|
||||
this._changeState(this.STATES.BODY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
MacParser.prototype._processBody = function (line) {
|
||||
// XXX: Assume there is at least 3 '=' can be found
|
||||
var count = (line.match(/=/g) || []).length;
|
||||
if (count >= 3) {
|
||||
var regExp = /([0-9.]+)[ ]*ms/;
|
||||
var match = regExp.exec(line);
|
||||
this._times.push(parseFloat(match[1], 10));
|
||||
}
|
||||
|
||||
// Change state if it see a '---'
|
||||
if (line.indexOf('---') >= 0) {
|
||||
this._changeState(this.STATES.FOOTER);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's footer
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
MacParser.prototype._processFooter = function (line) {
|
||||
var packetLoss = line.match(/ ([\d.]+)%/);
|
||||
if (packetLoss) {
|
||||
this._response.packetLoss = parseFloat(packetLoss[1], 10);
|
||||
}
|
||||
|
||||
// XXX: Assume number of keywords '/' more than 3
|
||||
var count = (line.match(/[/]/g) || []).length;
|
||||
if (count >= 3) {
|
||||
var regExp = /([0-9.]+)/g;
|
||||
// XXX: Assume min avg max stddev
|
||||
var m1 = regExp.exec(line);
|
||||
var m2 = regExp.exec(line);
|
||||
var m3 = regExp.exec(line);
|
||||
var m4 = regExp.exec(line);
|
||||
|
||||
if (__.all([m1, m2, m3, m4])) {
|
||||
this._response.min = parseFloat(m1[1], 10);
|
||||
this._response.avg = parseFloat(m2[1], 10);
|
||||
this._response.max = parseFloat(m3[1], 10);
|
||||
this._response.stddev = parseFloat(m4[1], 10);
|
||||
this._changeState(this.STATES.END);
|
||||
}
|
||||
|
||||
this._changeState(this.STATES.END);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = MacParser;
|
179
node_modules/ping/lib/parser/win.js
generated
vendored
Normal file
179
node_modules/ping/lib/parser/win.js
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var __ = require('underscore');
|
||||
|
||||
var base = require('./base');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Config object in probe()
|
||||
*/
|
||||
function WinParser(addr, config) {
|
||||
base.call(this, addr, config);
|
||||
this._ipv4Regex = /^([0-9]{1,3}\.){3}[0-9]{1,3}$/;
|
||||
}
|
||||
|
||||
util.inherits(WinParser, base);
|
||||
|
||||
/**
|
||||
* Process output's header
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
WinParser.prototype._processHeader = function (line) {
|
||||
// XXX: Expect to find [****] when pinging domain like google.com
|
||||
// Read fixture/win/**/* for the detail
|
||||
var isPingNumeric = line.indexOf('[') === -1;
|
||||
|
||||
// Get host and numeric_host
|
||||
var tokens = line.split(' ');
|
||||
|
||||
if (isPingNumeric) {
|
||||
// For those missing [***], get the first token which match IPV4 regex
|
||||
this._response.host = __.find(tokens, function (t) {
|
||||
return this._ipv4Regex.test(t);
|
||||
}, this);
|
||||
this._response.numeric_host = this._response.host;
|
||||
} else {
|
||||
// For those has [***], anchor with such token
|
||||
var numericHost = __.find(tokens, function (t) {
|
||||
return t.indexOf('[') !== -1;
|
||||
}, this);
|
||||
var numericHostIndex = tokens.indexOf(numericHost);
|
||||
var match = /\[(.*)\]/.exec(numericHost);
|
||||
|
||||
if (match) {
|
||||
// Capture IP inside [] only. refs #71
|
||||
this._response.numeric_host = match[1];
|
||||
} else {
|
||||
// Otherwise, just mark as NA to indicate an error
|
||||
this._response.numeric_host = 'NA';
|
||||
}
|
||||
this._response.host = tokens[numericHostIndex - 1];
|
||||
}
|
||||
|
||||
this._changeState(this.STATES.BODY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process ipv6 output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
WinParser.prototype._processIPV6Body = function (line) {
|
||||
var tokens = line.split(' ');
|
||||
var dataFields = __.filter(tokens, function (token) {
|
||||
var isDataField = token.indexOf('=') >= 0 || token.indexOf('<') >= 0;
|
||||
return isDataField;
|
||||
});
|
||||
|
||||
// refs #65: Support system like french which has an extra space
|
||||
dataFields = __.map(dataFields, function (dataField) {
|
||||
var ret = dataField;
|
||||
var dataFieldIndex = tokens.indexOf(dataField);
|
||||
var nextIndex = dataFieldIndex + 1;
|
||||
|
||||
// Append the missing *ms*
|
||||
if (nextIndex < tokens.length) {
|
||||
if (tokens[nextIndex] === 'ms') {
|
||||
ret += 'ms';
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
});
|
||||
|
||||
var expectDataFieldInReplyLine = 1;
|
||||
if (dataFields.length >= expectDataFieldInReplyLine) {
|
||||
// XXX: Assume time will alaways get keyword ms for all language
|
||||
var timeKVP = __.find(dataFields, function (dataField) {
|
||||
return dataField.search(/(ms|мс)/i) >= 0;
|
||||
});
|
||||
var regExp = /([0-9.]+)/;
|
||||
var match = regExp.exec(timeKVP);
|
||||
|
||||
this._times.push(parseFloat(match[1], 10));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process ipv4 output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
WinParser.prototype._processIPV4Body = function (line) {
|
||||
var tokens = line.split(' ');
|
||||
var byteTimeTTLFields = __.filter(tokens, function (token) {
|
||||
var isDataField = token.indexOf('=') >= 0 || token.indexOf('<') >= 0;
|
||||
return isDataField;
|
||||
});
|
||||
|
||||
var expectDataFieldInReplyLine = 3;
|
||||
var isReplyLine = byteTimeTTLFields.length >= expectDataFieldInReplyLine;
|
||||
if (isReplyLine) {
|
||||
var packetSize = this._pingConfig.packetSize;
|
||||
var byteField = __.find(byteTimeTTLFields, function (dataField) {
|
||||
var packetSizeToken = util.format('=%d', packetSize);
|
||||
var isByteField = dataField.indexOf(packetSizeToken) >= 0;
|
||||
return isByteField;
|
||||
});
|
||||
|
||||
// XXX: Assume time field will always be next of byte field
|
||||
var byteFieldIndex = byteTimeTTLFields.indexOf(byteField);
|
||||
var timeFieldIndex = byteFieldIndex + 1;
|
||||
var timeKVP = byteTimeTTLFields[timeFieldIndex];
|
||||
|
||||
var regExp = /([0-9.]+)/;
|
||||
var match = regExp.exec(timeKVP);
|
||||
|
||||
this._times.push(parseFloat(match[1], 10));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
WinParser.prototype._processBody = function (line) {
|
||||
var isPingSummaryLineShown = line.slice(-1) === ':';
|
||||
if (isPingSummaryLineShown) {
|
||||
this._changeState(this.STATES.FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
var isIPV6 = this._pingConfig.v6;
|
||||
if (isIPV6) {
|
||||
this._processIPV6Body(line);
|
||||
} else {
|
||||
this._processIPV4Body(line);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's footer
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
WinParser.prototype._processFooter = function (line) {
|
||||
var packetLoss = line.match(/([\d.]+)%/);
|
||||
if (packetLoss) {
|
||||
this._response.packetLoss = parseFloat(packetLoss[1], 10);
|
||||
}
|
||||
|
||||
// XXX: Assume there is a keyword ms
|
||||
if (line.search(/(ms|мсек)/i) >= 0) {
|
||||
// XXX: Assume the ordering is Min Max Avg
|
||||
var regExp = /([0-9.]+)/g;
|
||||
var m1 = regExp.exec(line);
|
||||
var m2 = regExp.exec(line);
|
||||
var m3 = regExp.exec(line);
|
||||
|
||||
if (__.all([m1, m2, m3])) {
|
||||
this._response.min = parseFloat(m1[1], 10);
|
||||
this._response.max = parseFloat(m2[1], 10);
|
||||
this._response.avg = parseFloat(m3[1], 10);
|
||||
this._changeState(this.STATES.END);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = WinParser;
|
46
node_modules/ping/lib/ping-pcap.js
generated
vendored
Executable file
46
node_modules/ping/lib/ping-pcap.js
generated
vendored
Executable file
@ -0,0 +1,46 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* LICENSE MIT
|
||||
* (C) Daniel Zelisko
|
||||
* http://github.com/danielzzz/node-ping
|
||||
*
|
||||
* A poor man's ping for node.js
|
||||
* It uses UDP_scanning (as node is not able to generate iCPM packets)
|
||||
* http://en.wikipedia.org/wiki/Port_scanner#UDP_scanning
|
||||
* it may not work correct for hosts that silently drop UDP traffic on their firewall
|
||||
* you need at pcap version 0.1.9 or higher
|
||||
*
|
||||
*/
|
||||
|
||||
var sys = require("util"),
|
||||
pcap = require('pcap');
|
||||
|
||||
var addr = process.argv[3] || 'localhost';
|
||||
setInterval(function() {probe(addr)}, 1000);
|
||||
|
||||
|
||||
function probe(addr) {
|
||||
sys.puts('sending a probe to ' + addr);
|
||||
var dgram = require('dgram');
|
||||
var message = new Buffer("Some bytes");
|
||||
var client = dgram.createSocket("udp4");
|
||||
client.send(message, 0, message.length, 21111, addr);
|
||||
client.close();
|
||||
}
|
||||
|
||||
// create a pcap session
|
||||
pcap_session = pcap.createSession(process.argv[2] || 'eth0', "");
|
||||
|
||||
|
||||
// listen for packets, decode them, and feed the simple printer
|
||||
pcap_session.addListener('packet', function (raw_packet) {
|
||||
var packet = pcap.decode.packet(raw_packet);
|
||||
if (packet.link && packet.link.ip && packet.link.ip.saddr==addr) {
|
||||
packet.link && packet.link.ip && sys.puts(packet.link.ip.saddr + " is alive");
|
||||
}
|
||||
});
|
||||
|
||||
//-------- example ------------------------
|
||||
|
||||
|
111
node_modules/ping/lib/ping-promise.js
generated
vendored
Normal file
111
node_modules/ping/lib/ping-promise.js
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* LICENSE MIT
|
||||
* (C) Daniel Zelisko
|
||||
* http://github.com/danielzzz/node-ping
|
||||
*
|
||||
* a simple wrapper for ping
|
||||
* Now with support of not only english Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
// System library
|
||||
var util = require('util');
|
||||
var net = require('net');
|
||||
var cp = require('child_process');
|
||||
var os = require('os');
|
||||
|
||||
// 3rd-party library
|
||||
var Q = require('q');
|
||||
var __ = require('underscore');
|
||||
|
||||
// Our library
|
||||
var builderFactory = require('./builder/factory');
|
||||
var parserFactory = require('./parser/factory');
|
||||
|
||||
/**
|
||||
* Refer to probe()
|
||||
*/
|
||||
function _probe(addr, config) {
|
||||
// Do not reassign function argument
|
||||
var _config = config || {};
|
||||
if (_config.v6 === undefined) {
|
||||
_config.v6 = net.isIPv6(addr);
|
||||
}
|
||||
|
||||
// Convert callback base system command to promise base
|
||||
var deferred = Q.defer();
|
||||
|
||||
// Spawn a ping process
|
||||
var ping = null;
|
||||
var platform = os.platform();
|
||||
try {
|
||||
var argumentBuilder = builderFactory.createBuilder(platform);
|
||||
var pingExecutablePath = builderFactory.getExecutablePath(
|
||||
platform, _config.v6
|
||||
);
|
||||
var pingArgs = argumentBuilder.getCommandArguments(addr, _config);
|
||||
var spawnOptions = argumentBuilder.getSpawnOptions();
|
||||
ping = cp.spawn(pingExecutablePath, pingArgs, spawnOptions);
|
||||
} catch (err) {
|
||||
deferred.reject(err);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Initial parser
|
||||
var parser = parserFactory.createParser(addr, platform, _config);
|
||||
|
||||
// Register events from system ping
|
||||
ping.once('error', function () {
|
||||
var err = new Error(
|
||||
util.format(
|
||||
'ping.probe: %s. %s',
|
||||
'there was an error while executing the ping program. ',
|
||||
'Check the path or permissions...'
|
||||
)
|
||||
);
|
||||
deferred.reject(err);
|
||||
});
|
||||
|
||||
// Cache all lines from the system ping
|
||||
var outstring = [];
|
||||
ping.stdout.on('data', function (data) {
|
||||
outstring.push(String(data));
|
||||
});
|
||||
|
||||
// Parse lines we have on closing system ping
|
||||
ping.once('close', function () {
|
||||
// Merge lines we have and split it by \n
|
||||
var lines = outstring.join('').split('\n');
|
||||
|
||||
// Parse line one by one
|
||||
__.each(lines, parser.eat, parser);
|
||||
|
||||
// Get result
|
||||
var ret = parser.getResult();
|
||||
|
||||
deferred.resolve(ret);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class::PromisePing
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Configuration for command ping
|
||||
* @return {Promise}
|
||||
*/
|
||||
function probe(addr, config) {
|
||||
try {
|
||||
var probePromise = _probe(addr, config);
|
||||
return probePromise;
|
||||
} catch (error) {
|
||||
var errorPromise = Q.reject(error);
|
||||
return errorPromise;
|
||||
}
|
||||
}
|
||||
|
||||
exports.probe = probe;
|
44
node_modules/ping/lib/ping-sys.js
generated
vendored
Executable file
44
node_modules/ping/lib/ping-sys.js
generated
vendored
Executable file
@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* LICENSE MIT
|
||||
* (C) Daniel Zelisko
|
||||
* http://github.com/danielzzz/node-ping
|
||||
*
|
||||
* a simple wrapper for ping
|
||||
* Now with support of not only english Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
// Promise implementation
|
||||
var ping = require('./ping-promise');
|
||||
|
||||
// TODO:
|
||||
// 1. Port round trip time to this callback
|
||||
// 2. However, it may breaks backward compatability
|
||||
// 3. Need discussion
|
||||
/**
|
||||
* Callback after probing given host
|
||||
* @callback probeCallback
|
||||
* @param {boolean} isAlive - Whether target is alive or not
|
||||
* @param {Object} error - Null if no error occurs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class::Ping construtor
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {probeCallback} cb - Callback
|
||||
* @param {PingConfig} config - Configuration for command ping
|
||||
*/
|
||||
function probe(addr, cb, config) {
|
||||
// Do not reassign function parameter
|
||||
var _config = config || {};
|
||||
|
||||
return ping.probe(addr, _config).then(function (res) {
|
||||
cb(res.alive, null);
|
||||
}).catch(function (err) {
|
||||
cb(null, err);
|
||||
}).done();
|
||||
}
|
||||
|
||||
exports.probe = probe;
|
Reference in New Issue
Block a user