Fix ping bug on certain platforms
This commit is contained in:
1 parent
7ccdbace70
commit
7941d929d2
2 files changed
+92
-46
No files matched your search
+56
-46
@@ -40,68 +40,78 @@ function isValidHost(host: string): boolean {
|
||||
return /^[a-zA-Z0-9\-.:[\]-]+$/.test(domainToASCII(host));
|
||||
}
|
||||
|
||||
export function ping(
|
||||
host: string,
|
||||
callback: (err: Error, res?: PingResult, stdout?: string) => void
|
||||
): void {
|
||||
let cmd: string, parseRegExp1: RegExp, parseRegExp2: RegExp;
|
||||
// Validate input to prevent possible remote code execution
|
||||
// Credit to Alex Hordijk for reporting this vulnerability
|
||||
if (!isValidHost(host)) return callback(new Error("Invalid host"));
|
||||
host = host.replace("[", "").replace("]", "");
|
||||
switch (platform()) {
|
||||
export function parsePing(osPlatform: string, stdout: string): PingResult {
|
||||
let parseRegExp1: RegExp, parseRegExp2: RegExp, parsed: PingResult;
|
||||
switch (osPlatform) {
|
||||
case "linux":
|
||||
cmd = `ping -w 1 -i 0.2 -c 3 ${host}`;
|
||||
parseRegExp1 =
|
||||
/(\d+) packets transmitted, (\d+) received, ([\d.]+)% packet loss[^]*([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+)/;
|
||||
/(\d+) packets transmitted, (\d+) .*received, ([\d.]+)% .*loss[^]*= ([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+)/;
|
||||
parseRegExp2 =
|
||||
/(\d+) packets transmitted, (\d+) received, ([\d.]+)% packet loss/;
|
||||
/(\d+) packets transmitted, (\d+) .*received, ([\d.]+)% .*loss/;
|
||||
break;
|
||||
|
||||
case "freebsd":
|
||||
// Send a single packet because on FreeBSD only superuser can send
|
||||
// packets that are only 200 ms apart.
|
||||
cmd = `ping -t 1 -c 3 ${host}`;
|
||||
parseRegExp1 =
|
||||
/(\d+) packets transmitted, (\d+) packets received, ([\d.]+)% packet loss\nround-trip min\/avg\/max\/stddev = ([\d.]+)\/([\d.]+)\/([\d.]+)\/([\d.]+) ms/;
|
||||
parseRegExp2 =
|
||||
/(\d+) packets transmitted, (\d+) packets received, ([\d.]+)% packet loss/;
|
||||
break;
|
||||
}
|
||||
|
||||
const m1 = stdout.match(parseRegExp1);
|
||||
if (m1) {
|
||||
parsed = {
|
||||
packetsTransmitted: +m1[1],
|
||||
packetsReceived: +m1[2],
|
||||
packetLoss: +m1[3],
|
||||
min: +m1[4],
|
||||
avg: +m1[5],
|
||||
max: +m1[6],
|
||||
mdev: +m1[7],
|
||||
};
|
||||
} else {
|
||||
const m2 = stdout.match(parseRegExp2);
|
||||
if (m2) {
|
||||
parsed = {
|
||||
packetsTransmitted: +m2[1],
|
||||
packetsReceived: +m2[2],
|
||||
packetLoss: +m2[3],
|
||||
min: null,
|
||||
avg: null,
|
||||
max: null,
|
||||
mdev: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
export function ping(
|
||||
host: string,
|
||||
callback: (err: Error, res?: PingResult, stdout?: string) => void
|
||||
): void {
|
||||
// Validate input to prevent possible remote code execution
|
||||
// Credit to Alex Hordijk for reporting this vulnerability
|
||||
if (!isValidHost(host)) return callback(new Error("Invalid host"));
|
||||
host = host.replace("[", "").replace("]", "");
|
||||
let cmd: string;
|
||||
|
||||
switch (platform()) {
|
||||
case "linux":
|
||||
cmd = `ping -w 1 -i 0.2 -c 3 ${host}`;
|
||||
break;
|
||||
case "freebsd":
|
||||
// Send a single packet because on FreeBSD only superuser can send
|
||||
// packets that are only 200 ms apart.
|
||||
cmd = `ping -t 1 -c 3 ${host}`;
|
||||
break;
|
||||
default:
|
||||
return callback(new Error("Platform not supported"));
|
||||
}
|
||||
|
||||
exec(cmd, (err, stdout) => {
|
||||
let parsed: PingResult;
|
||||
if (stdout) {
|
||||
const m1 = stdout.match(parseRegExp1);
|
||||
if (m1) {
|
||||
parsed = {
|
||||
packetsTransmitted: +m1[1],
|
||||
packetsReceived: +m1[2],
|
||||
packetLoss: +m1[3],
|
||||
min: +m1[4],
|
||||
avg: +m1[5],
|
||||
max: +m1[6],
|
||||
mdev: +m1[7],
|
||||
};
|
||||
} else {
|
||||
const m2 = stdout.match(parseRegExp2);
|
||||
if (m2) {
|
||||
parsed = {
|
||||
packetsTransmitted: +m2[1],
|
||||
packetsReceived: +m2[2],
|
||||
packetLoss: +m2[3],
|
||||
min: null,
|
||||
avg: null,
|
||||
max: null,
|
||||
mdev: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(err, parsed, stdout);
|
||||
if (err) return callback(err);
|
||||
const parsed: PingResult = parsePing(platform(), stdout);
|
||||
return callback(err, parsed, stdout);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import ava from "ava";
|
||||
import { parsePing } from "../lib/ping";
|
||||
|
||||
ava("linux Case-1", (t) => {
|
||||
const platform = "linux";
|
||||
const stdout =
|
||||
"PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data\n64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=6.66 ms\n64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=6.50 ms\n64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=6.38 ms\n\n--- 8.8.8.8 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 402ms\nrtt min/avg/max/mdev = 6.381/6.511/6.656/0.112 ms";
|
||||
const parsedResult = {
|
||||
packetsTransmitted: 3,
|
||||
packetsReceived: 3,
|
||||
packetLoss: 0,
|
||||
min: 6.381,
|
||||
avg: 6.511,
|
||||
max: 6.656,
|
||||
mdev: 0.112,
|
||||
};
|
||||
const parsed = parsePing(platform, stdout);
|
||||
t.deepEqual(parsedResult, parsed);
|
||||
});
|
||||
|
||||
ava("linux Case-2", (t) => {
|
||||
const platform = "linux";
|
||||
const stdout =
|
||||
"PING 10.251.9.108 (10.251.9.108): 56 data bytes\n64 bytes from 10.251.9.108: icmp_seq=0 ttl=57 time=36.758 ms\n64 bytes from 10.251.9.108: icmp_seq=1 ttl=57 time=69.094 ms\n64 bytes from 10.251.9.108: icmp_seq=2 ttl=57 time=28.868 ms\n--- 10.251.9.108 ping statistics ---3 packets transmitted, 3 packets received, 0% packet loss\nround-trip min/avg/max/stddev = 28.868/44.907/69.094/17.404 ms";
|
||||
const parsedResult = {
|
||||
packetsTransmitted: 3,
|
||||
packetsReceived: 3,
|
||||
packetLoss: 0,
|
||||
min: 28.868,
|
||||
avg: 44.907,
|
||||
max: 69.094,
|
||||
mdev: 17.404,
|
||||
};
|
||||
const parsed = parsePing(platform, stdout);
|
||||
t.deepEqual(parsedResult, parsed);
|
||||
});
|
||||
Reference in new issue
Block a user