Question
· Aug 17, 2023

ICMP/Ping with ObjectScript

Is it possible to "Ping" a remote host in IRIS for Health using ObjectScript? We host hundreds of TCP connections over hundreds of VPNs. I'm working on a project that would make it nice to have way to ping remove clients over the VPN to monitor connectivity and keep the tunnels alive.  

Another thought/method would be to make an OS system call (AWS Linux), but I don't see a way to do that either.

Product version: IRIS 2023.1
Discussion (9)1
Log in or sign up to continue

Four short lines of Objectscript code


ClassMethod Ping(host)
{
	set cmd="ping "_host
	open cmd:"QR":10
	for {use cmd read ans quit:$zeof  use 0 write ans,!}
	close cmd
}

// some test
do ##class(your.class).Ping("google.com")

Pinging google.com [142.250.185.110] with 32 bytes of data:
Reply from 142.250.185.110: bytes=32 time=25ms TTL=114
Reply from 142.250.185.110: bytes=32 time=26ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114

Ping statistics for 142.250.185.110:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 19ms, Maximum = 26ms, Average = 22ms

Nice, the first part of the problem (or project, if you wish) is solved. What about a "side project", not pinging all but the active VPNs only? Use the netstat command to get all the established connections

/// Execute an arbitrary OS command and return the command output
ClassMethod OSCmd(cmd, ByRef ans)
{
    kill ans
    open cmd:"QR":10
    set old=$system.Process.SetZEOF(1), ans=0
    if $test {
        use cmd
        for {read line quit:$zeof  set ans($increment(ans))=line}
        close cmd
    }
    quit ans
}

Of course, you have to take into account OS specific differences and access rights

do ##class(your.classname).OSCmd("ping google.com", .ans) zw ans
ans=11
ans(1)=""
ans(2)="Pinging google.com [142.250.185.174] with 32 bytes of data:"
ans(3)="Reply from 142.250.185.174: bytes=32 time=21ms TTL=114"
ans(4)="Reply from 142.250.185.174: bytes=32 time=27ms TTL=114"
ans(5)="Reply from 142.250.185.174: bytes=32 time=19ms TTL=114"
ans(6)="Reply from 142.250.185.174: bytes=32 time=18ms TTL=114"
ans(7)=""
ans(8)="Ping statistics for 142.250.185.174:"
ans(9)="    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
ans(10)="Approximate round trip times in milli-seconds:"
ans(11)=""

do ##class(your.classname).OSCmd("netstat -ano | findstr ""ESTABLISHED""", .ans) zw ans
ans=6
ans(1)="  TCP    127.0.0.1:23           127.0.0.1:50814        ESTABLISHED     8272"
ans(2)="  TCP    127.0.0.1:23           127.0.0.1:60874        ESTABLISHED     2872"
ans(3)="  TCP    127.0.0.1:23           127.0.0.1:63199        ESTABLISHED     8272"
ans(4)="  TCP    127.0.0.1:1972         127.0.0.1:49436        ESTABLISHED     2404"
ans(5)="  TCP    127.0.0.1:1972         127.0.0.1:51840        ESTABLISHED     2404"
ans(6)="  TCP    127.0.0.1:1972         127.0.0.1:54330        ESTABLISHED     2404"

Now you can analyse and process the command output...

Also, see this post too.