-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmod.ts
More file actions
124 lines (108 loc) · 2.42 KB
/
mod.ts
File metadata and controls
124 lines (108 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { exec, OutputMode } from "https://deno.land/x/exec/mod.ts";
interface Detail {
domain: string
ip: string
bytes: number
}
interface Hops {
bytes: number
ip: string
sequence: number
ttl: number
time: number
}
interface Result {
transmitted: number
received: number
loss: number
}
interface Stats {
min: number
avg: number
max: number
stddev: number
}
type Output = {
hops: Array<Hops>
stats: Stats
detail: Detail
result: Result
}
const PATTERN_HOPS = /^(\d+).*?from\s(.+)\:.*?icmp_seq=(\d+).*?ttl=(\d+).*?time=(.+)\s\ms.*?/
const PATTERN_STATS = /.+\s=\s(.+)\/(.+)\/(.+)\/(.+)\s\ms/
const PATTERN_RESULT = /^(\d+).+(\d+).+\,\s(\d\.?\d?).+/
const PATTERN_DETAIL = /^PING\s(.+)\s\((.+)\):?\s(\d+)/
function Parser(raw: string): Output {
const data = <Output>{}
data.hops = []
raw.split('\n')
.map(line => {
if (PATTERN_HOPS.test(line)) {
const [,
bytes,
ip,
icmp_seq,
ttl,
time
] = PATTERN_HOPS.exec(line) || []
data['hops'].push({
ip,
bytes: parseFloat(bytes),
sequence: parseFloat(icmp_seq),
ttl: parseFloat(ttl),
time: parseFloat(time)
})
}
if (PATTERN_STATS.test(line)) {
const [,
min,
avg,
max,
stddev
] = PATTERN_STATS.exec(line) || []
data['stats'] = {
min: parseFloat(min),
avg: parseFloat(avg),
max: parseFloat(max),
stddev: parseFloat(stddev)
}
}
if (PATTERN_RESULT.test(line)) {
const [,
transmitted,
received,
loss
] = PATTERN_RESULT.exec(line) || []
data['result'] = {
transmitted: parseFloat(transmitted),
received: parseFloat(received),
loss: parseFloat(loss)
}
}
if (PATTERN_DETAIL.test(line)) {
const [,
domain,
ip,
bytes] = PATTERN_DETAIL.exec(line) || []
data['detail'] = {
ip,
domain,
bytes: parseFloat(bytes)
}
}
})
.filter(line => line)
return data
}
export default async function Ping(
destination: string,
times: number = 4
): Promise<Output> {
let result = await exec(
`ping ${destination} -c ${times}`,
{
output: OutputMode.Capture
}
);
return Parser(result.output)
}