Skip to content

Commit

Permalink
Merge pull request #1 from isnogudus/master
Browse files Browse the repository at this point in the history
OpenBSD support
  • Loading branch information
louislam committed Jul 18, 2023
2 parents 2075ee6 + 97f2248 commit de1b8a0
Show file tree
Hide file tree
Showing 12 changed files with 630 additions and 396 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"tabWidth": 4
}
26 changes: 17 additions & 9 deletions lib/builder/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const commandExistsSync = require('command-exists').sync;
var linuxBuilder = require('./linux');
var macBuilder = require('./mac');
var winBuilder = require('./win');
var obsdBuilder = require('./openbsd');

let linuxPing = null;
let linuxPing6 = null;
Expand Down Expand Up @@ -52,11 +53,7 @@ function factory() {}
* Check out linux platform
*/
factory.isLinux = function (p) {
var platforms = [
'aix',
'android',
'linux',
];
var platforms = ['aix', 'android', 'linux'];

return platforms.indexOf(p) >= 0;
};
Expand All @@ -65,10 +62,16 @@ factory.isLinux = function (p) {
* Check out macos platform
*/
factory.isMacOS = function (p) {
var platforms = [
'darwin',
'freebsd',
];
var platforms = ['darwin', 'freebsd'];

return platforms.indexOf(p) >= 0;
};

/**
* Check out openbsd platform
*/
factory.isOpenBSD = function (p) {
var platforms = ['openbsd'];

return platforms.indexOf(p) >= 0;
};
Expand All @@ -90,6 +93,7 @@ factory.isPlatformSupport = function (p) {
this.isWindow(p),
this.isLinux(p),
this.isMacOS(p),
this.isOpenBSD(p),
]);
};

Expand All @@ -115,6 +119,8 @@ factory.getExecutablePath = function (platform, v6) {
ret = process.env.SystemRoot + '/system32/ping.exe';
} else if (factory.isMacOS(platform)) {
ret = v6 ? '/sbin/ping6' : '/sbin/ping';
} else if (factory.isOpenBSD(platform)) {
ret = v6 ? '/sbin/ping6' : '/sbin/ping';
}

return ret;
Expand All @@ -139,6 +145,8 @@ factory.createBuilder = function (platform) {
ret = winBuilder;
} else if (factory.isMacOS(platform)) {
ret = macBuilder;
} else if (factory.isOpenBSD(platform)) {
ret = obsdBuilder;
}

return ret;
Expand Down
118 changes: 118 additions & 0 deletions lib/builder/openbsd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'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
// Fallback to deadline
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 {};
};

module.exports = builder;
3 changes: 3 additions & 0 deletions lib/parser/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var builderFactory = require('../builder/factory');
var WinParser = require('./win');
var MacParser = require('./mac');
var LinuxParser = require('./linux');
var OpenBSDParser = require('./openbsd');

/**
* A factory creates a parser for parsing output from system ping
Expand Down Expand Up @@ -36,6 +37,8 @@ factory.createParser = function (addr, platform, config) {
ret = new MacParser(addr, _config);
} else if (builderFactory.isLinux(platform)) {
ret = new LinuxParser(addr, _config);
} else if (builderFactory.isOpenBSD(platform)) {
ret = new OpenBSDParser(addr, _config);
}

return ret;
Expand Down
84 changes: 84 additions & 0 deletions lib/parser/openbsd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'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 OpenBSDParser(addr, config) {
base.call(this, addr, config);
}

util.inherits(OpenBSDParser, base);

/**
* Process output's header
* @param {string} line - A line from system ping
*/
OpenBSDParser.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
*/
OpenBSDParser.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
*/
OpenBSDParser.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 = OpenBSDParser;
12 changes: 5 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit de1b8a0

Please sign in to comment.