2021-07-01 02:00:23 -07:00
|
|
|
// https://github.com/ben-bradley/ping-lite/blob/master/ping-lite.js
|
|
|
|
// Fixed on Windows
|
2021-08-10 05:39:58 -07:00
|
|
|
const net = require("net");
|
|
|
|
const spawn = require("child_process").spawn,
|
2021-07-27 10:47:13 -07:00
|
|
|
events = require("events"),
|
|
|
|
fs = require("fs"),
|
2021-07-01 02:00:23 -07:00
|
|
|
WIN = /^win/.test(process.platform),
|
|
|
|
LIN = /^linux/.test(process.platform),
|
|
|
|
MAC = /^darwin/.test(process.platform);
|
2021-08-16 19:48:37 -07:00
|
|
|
FBSD = /^freebsd/.test(process.platform);
|
2021-08-10 06:47:14 -07:00
|
|
|
const { debug } = require("../src/util");
|
2021-07-01 02:00:23 -07:00
|
|
|
|
|
|
|
module.exports = Ping;
|
|
|
|
|
2021-08-10 07:00:29 -07:00
|
|
|
function Ping(host, options) {
|
2021-07-27 10:47:13 -07:00
|
|
|
if (!host) {
|
|
|
|
throw new Error("You must specify a host to ping!");
|
|
|
|
}
|
2021-07-01 02:00:23 -07:00
|
|
|
|
|
|
|
this._host = host;
|
|
|
|
this._options = options = (options || {});
|
|
|
|
|
|
|
|
events.EventEmitter.call(this);
|
|
|
|
|
|
|
|
if (WIN) {
|
2021-07-27 10:47:13 -07:00
|
|
|
this._bin = "c:/windows/system32/ping.exe";
|
|
|
|
this._args = (options.args) ? options.args : [ "-n", "1", "-w", "5000", host ];
|
2021-07-01 02:00:23 -07:00
|
|
|
this._regmatch = /[><=]([0-9.]+?)ms/;
|
2021-08-10 05:39:58 -07:00
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
} else if (LIN) {
|
|
|
|
this._bin = "/bin/ping";
|
2021-08-10 05:39:58 -07:00
|
|
|
|
|
|
|
const defaultArgs = [ "-n", "-w", "2", "-c", "1", host ];
|
|
|
|
|
2021-08-10 06:03:14 -07:00
|
|
|
if (net.isIPv6(host) || options.ipv6) {
|
2021-08-10 05:39:58 -07:00
|
|
|
defaultArgs.unshift("-6");
|
|
|
|
}
|
|
|
|
|
|
|
|
this._args = (options.args) ? options.args : defaultArgs;
|
|
|
|
this._regmatch = /=([0-9.]+?) ms/;
|
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
} else if (MAC) {
|
2021-08-10 06:07:11 -07:00
|
|
|
|
|
|
|
if (net.isIPv6(host) || options.ipv6) {
|
|
|
|
this._bin = "/sbin/ping6";
|
|
|
|
} else {
|
|
|
|
this._bin = "/sbin/ping";
|
|
|
|
}
|
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
this._args = (options.args) ? options.args : [ "-n", "-t", "2", "-c", "1", host ];
|
2021-07-01 02:00:23 -07:00
|
|
|
this._regmatch = /=([0-9.]+?) ms/;
|
2021-08-16 19:48:37 -07:00
|
|
|
|
|
|
|
} else if (FBSD) {
|
|
|
|
this._bin = "/sbin/ping";
|
|
|
|
|
|
|
|
const defaultArgs = [ "-n", "-t", "2", "-c", "1", host ];
|
|
|
|
|
|
|
|
if (net.isIPv6(host) || options.ipv6) {
|
|
|
|
defaultArgs.unshift("-6");
|
|
|
|
}
|
|
|
|
|
|
|
|
this._args = (options.args) ? options.args : defaultArgs;
|
|
|
|
this._regmatch = /=([0-9.]+?) ms/;
|
2021-08-10 05:39:58 -07:00
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
} else {
|
|
|
|
throw new Error("Could not detect your ping binary.");
|
2021-07-01 02:00:23 -07:00
|
|
|
}
|
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
if (!fs.existsSync(this._bin)) {
|
|
|
|
throw new Error("Could not detect " + this._bin + " on your system");
|
|
|
|
}
|
2021-07-01 02:00:23 -07:00
|
|
|
|
|
|
|
this._i = 0;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ping.prototype.__proto__ = events.EventEmitter.prototype;
|
|
|
|
|
|
|
|
// SEND A PING
|
|
|
|
// ===========
|
2021-08-10 06:47:14 -07:00
|
|
|
Ping.prototype.send = function (callback) {
|
2021-07-27 10:47:13 -07:00
|
|
|
let self = this;
|
2021-08-10 06:47:14 -07:00
|
|
|
callback = callback || function (err, ms) {
|
2021-07-27 10:47:13 -07:00
|
|
|
if (err) {
|
|
|
|
return self.emit("error", err);
|
|
|
|
}
|
|
|
|
return self.emit("result", ms);
|
2021-07-01 02:00:23 -07:00
|
|
|
};
|
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
let _ended, _exited, _errored;
|
2021-07-01 02:00:23 -07:00
|
|
|
|
|
|
|
this._ping = spawn(this._bin, this._args); // spawn the binary
|
|
|
|
|
2021-08-10 06:47:14 -07:00
|
|
|
this._ping.on("error", function (err) { // handle binary errors
|
2021-07-01 02:00:23 -07:00
|
|
|
_errored = true;
|
|
|
|
callback(err);
|
|
|
|
});
|
|
|
|
|
2021-08-10 06:47:14 -07:00
|
|
|
this._ping.stdout.on("data", function (data) { // log stdout
|
2021-07-27 10:47:13 -07:00
|
|
|
this._stdout = (this._stdout || "") + data;
|
2021-07-01 02:00:23 -07:00
|
|
|
});
|
|
|
|
|
2021-08-10 06:47:14 -07:00
|
|
|
this._ping.stdout.on("end", function () {
|
2021-07-01 02:00:23 -07:00
|
|
|
_ended = true;
|
2021-07-27 10:47:13 -07:00
|
|
|
if (_exited && !_errored) {
|
|
|
|
onEnd.call(self._ping);
|
|
|
|
}
|
2021-07-01 02:00:23 -07:00
|
|
|
});
|
|
|
|
|
2021-08-10 06:47:14 -07:00
|
|
|
this._ping.stderr.on("data", function (data) { // log stderr
|
2021-07-27 10:47:13 -07:00
|
|
|
this._stderr = (this._stderr || "") + data;
|
2021-07-01 02:00:23 -07:00
|
|
|
});
|
|
|
|
|
2021-08-10 06:47:14 -07:00
|
|
|
this._ping.on("exit", function (code) { // handle complete
|
2021-07-01 02:00:23 -07:00
|
|
|
_exited = true;
|
2021-07-27 10:47:13 -07:00
|
|
|
if (_ended && !_errored) {
|
|
|
|
onEnd.call(self._ping);
|
|
|
|
}
|
2021-07-01 02:00:23 -07:00
|
|
|
});
|
|
|
|
|
2021-08-10 07:00:29 -07:00
|
|
|
function onEnd() {
|
2021-07-27 10:47:13 -07:00
|
|
|
let stdout = this.stdout._stdout,
|
2021-07-01 02:00:23 -07:00
|
|
|
stderr = this.stderr._stderr,
|
|
|
|
ms;
|
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
if (stderr) {
|
2021-07-01 02:00:23 -07:00
|
|
|
return callback(new Error(stderr));
|
2021-07-27 10:47:13 -07:00
|
|
|
}
|
2021-07-27 11:02:20 -07:00
|
|
|
|
2021-07-27 10:47:13 -07:00
|
|
|
if (!stdout) {
|
|
|
|
return callback(new Error("No stdout detected"));
|
|
|
|
}
|
2021-07-01 02:00:23 -07:00
|
|
|
|
|
|
|
ms = stdout.match(self._regmatch); // parse out the ##ms response
|
|
|
|
ms = (ms && ms[1]) ? Number(ms[1]) : ms;
|
|
|
|
|
2021-08-10 06:03:14 -07:00
|
|
|
callback(null, ms, stdout);
|
2021-07-01 02:00:23 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// CALL Ping#send(callback) ON A TIMER
|
|
|
|
// ===================================
|
2021-08-10 06:47:14 -07:00
|
|
|
Ping.prototype.start = function (callback) {
|
2021-07-27 10:47:13 -07:00
|
|
|
let self = this;
|
2021-08-10 06:47:14 -07:00
|
|
|
this._i = setInterval(function () {
|
2021-07-01 02:00:23 -07:00
|
|
|
self.send(callback);
|
|
|
|
}, (self._options.interval || 5000));
|
|
|
|
self.send(callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
// STOP SENDING PINGS
|
|
|
|
// ==================
|
2021-08-10 06:47:14 -07:00
|
|
|
Ping.prototype.stop = function () {
|
2021-07-01 02:00:23 -07:00
|
|
|
clearInterval(this._i);
|
|
|
|
};
|