Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

How to determine to which IP address a process connected

 
SOLVED
Go to solution
Jim Geier_1
Regular Advisor

How to determine to which IP address a process connected

I have systems with multiple NICs and IP addresses on each NIC. Is there a clean way during the system-wide login to determine to which IP address the process connected?

These systems are running TCP/IP services, so the messy way is to do the following basic steps:
1. Use f$getjpi(0,"tt_accpornam") to get the actual port string and from that the port number.
2. Use TCPIP SHOW DEVICE/PORT= and parse that output to get the BG device.
3. Using TCPIP SHOW DEVICE BGnnnn /FULL and parse that output.

Or I could add /FULL to step 2, the TCPIP SHOW DEVICE/PORT= command, and parse that output.

Is there a simpler way? Maybe a method I have overlooked and maybe a means of not having to send output to a file and parse the file contents?
15 REPLIES 15
Joseph Huber_1
Honored Contributor

Re: How to determine to which IP address a process connected

You are using TCPIP commands, so I assume the stack is TCPIP services for VMS (UCX).
It depends which kind of login (telnet, ssh, ftp), what tt_accpornam contains.
With telnet it is already the IP address (not the port number), with TCPIP SSH my (rather old) version contains nothing, maybe recent TCPIP version containn the same info as for telnet.

In case of no info in tt_accpornam,, there would be a way to do a device scan:
for BG devices, get the owner process ID.
If owner process is my own, then this BG device is one of my connections. Then TCPIP show device will reveal the IP address (although I don't know how to do it "programmatically" other than scanning the output of TCPIP show device).

And caveat: for SSH login, this also doesn't work for non-privileged users, because the device is owned by the SSH server.

For privileged users, there is of course the SDA> SHOW PROCESS/CHANNEL,
which will list the BG device if the process has one allocated.
http://www.mpp.mpg.de/~huber
Jim Geier_1
Regular Advisor

Re: How to determine to which IP address a process connected

This is what I came up with...not elegant, but it seems to work consistently.

$! Source_IP.COM
$! Get the IP address to which this process connected
$! Jim Geier 25-Mar-2010
$ space = " "
$ if f$mode().nes."INTERACTIVE") then exit
$ nodename = f$getsyi("nodename")
$ fao_ip = "Process !AS on device !AS connected to IP !AS"
$ fao_non_tna = "Process !AS on device !AS not connected via TCP/IP"
$ process_id = f$getjpi(0,"pid")
$ process_device = f$getjpi(process_id,"tt_phydevnam") - "_" - ":"
$ process_username = f$edit(f$getjpi(process_id,"username"),"trim,compress")
$ if f$extract(0,3,process_device) .nes. "TNA"
$ then
$ write sys$output f$fao(fao_non_tna,process_username,process_device)
$ exit
$ endif
$ process_actual_port = f$getjpi(process_id,"tt_accpornam")
$ port_number = f$element(3,space,f$edit(process_actual_port,"trim,compress"))
$
$ create/fdl=sys$input: sys$scratch:bg_port.tmp
record
format stream
$ define/user_mode sys$output sys$scratch:bg_port.tmp
$ tcpip show device/port='port_number'/full
$ open/read bg$file sys$scratch:bg_port.tmp
$ read bg$file bg_record ! Device_socket: line
$ read bg$file bg_record ! heading (LOCAL REMOTE)
$ read bg$file bg_record ! Port: line
$ read bg$file bg_record ! host/data line
$ close/nolog/disposition=delete bg$file
$ bg_record = f$edit(bg_record,"trim,compress")
$ connected_ip_address = f$element(1,space,bg_record)
$ message = f$fao(fao_ip,process_username,process_device,connected_ip_address)
$ write sys$output message
$ exit
labadie_1
Honored Contributor

Re: How to determine to which IP address a process connected

If you are on Alpha, you may find those procedures useful

bg_process shows the bg devices of a process and their statistics
http://dcl.openvms.org/stories.php?story=08/12/02/3240441

find_bg just shows the bg devices owned by a process
http://dcl.openvms.org/stories.php?story=08/06/09/6088086

Steven Schweda
Honored Contributor

Re: How to determine to which IP address a process connected

> $ process_id = f$getjpi(0,"pid")
> $ process_device = f$getjpi(process_id,"tt_phydevnam") [...]

What's wrong with:
f$getjpi( "", "tt_phydevnam")
?

HELP LEXICALS F$GETJPI Arguments

[...]
If you specify a null string (""), the current PID number is
used.
[...]
Tim E. Sneddon
Occasional Advisor

Re: How to determine to which IP address a process connected

I am a big fan of using DCL's PIPE command. So here is my solution:

$ getips == "pipe netstat -an " -
+ "| sea sys$pipe ''f$el(3," ",f$getj("","TT_ACCPORNAM"))' " -
+ "| ( read sys$pipe t ; " -
+ "t=f$ed(t,""COMPRESS"") ; " -
+ "l=f$el(3,"" "",t) ; r=f$el(4,"" "",t) ; " -
+ "p=f$el(4,""."",l) ; l=l-("".""+p) ; " -
+ "p=f$el(4,""."",r) ; r=r-("".""+p) ; " -
+ "def/j/nol MY_LOCAL_IP &l ; def/j/nol MY_REMOTE_IP &r )"
$ getips
$ show logical my_*_ip

All the commands in getips have been stripped to their absolute minimum so that this will work on an OpenVMS VAX system. The fully expanded commands are:

$ getips == "pipe netstat -an " -
+ "| search sys$pipe ''f$element(3, " ", f$getjpi("", "TT_ACCPORNAM"))' " -
+ "| ( read sys$pipe txt ; " -
+ "txt = f$edit(txt, ""COMPRESS"") ; " -
+ "lcl = f$element(3, "" "", txt) ; rem = f$element(4, "" "", txt) ; " -
+ "port = f$element(4, ""."", lcl) ; lcl = lcl - (""."" + port) ; " -
+ "port = f$element(4, ""."", rem) ; rem = rem - (""."" + port) ; " -
+ "define/job/nolog MY_LOCAL_IP &lcl ; " -
+ "define/job/nolog MY_REMOTE_IP &rem )"

The above definition will work on OpenVMS I64 and Alpha (with extended DCL) systems.
Joseph Huber_1
Honored Contributor

Re: How to determine to which IP address a process connected

Maybe I don't see the obvious or my ageing VMS/TCPIP version does it completely different than yours:
for telnet login I get:

write sys$output f$getj("","TT_ACCPORNAM")
Host: x.y.z.n Port: 58968
tcpip show version
HP TCP/IP Services for OpenVMS Alpha Version V5.4 - ECO 7
on a Digital Personal WorkStation running OpenVMS V7.3-1

So one gets the remote IP address simply by

f$element(1," ",f$getjpi("","TT_ACCPORNAM"))

http://www.mpp.mpg.de/~huber
Volker Halle
Honored Contributor

Re: How to determine to which IP address a process connected

Joseph,

the question was how to obtain the LOCAL IP address to which a session is connected (if you have multiple local IP interfaces).

Volker.
Joseph Huber_1
Honored Contributor

Re: How to determine to which IP address a process connected

Sorry for my premature answer, forget it !
After reading I misunderstood the question as the source address of the login, not the destion.
http://www.mpp.mpg.de/~huber
Jim Geier_1
Regular Advisor

Re: How to determine to which IP address a process connected

Thanks for all the suggestions. The reason I was using f$getjpi(process_id was that this script evolved from a script that looped through many processes based on a context.

TT_ACCPORNAM does include the port to use in the TCPIP SHOW DEVICE/PORT=nnnn/FULL. But this only occurs IF the telnet session originates on a non-VMS system, for example TT_ACCPORNAM is "Host: 10.1.16.70 Port: 3627" for a current session I have active from my home PC. If the telnet session originates on a VMS system, the format of TT_ACCPORNAM changes to: "Host: 10.1.20.62 Locn: _TNA24:/JGEIER" and that port number is not available.

I can find my source address in "netstat -an" and get the address to which I telnetted, but if there are multiple processes coming from the same source adderss, how do I tell which one is me? it seems that having the port is pretty useful.
Volker Halle
Honored Contributor
Solution

Re: How to determine to which IP address a process connected

Jim,

if you want to, you can get the remote port number for the TNA device from SDA:

$ ANAL/SYS
SDA> TCP SHOW DEVICE TNA36:/FULL

Terminal TNA36: service type None, protocol Telnet
Network Device: (not connected)
Accessportname: Host: axpvms.invenate.local Locn: _TNA56:/HALLE
Remote address: 10.20.30.203 port 52980
Local address: 10.20.30.200 port 23
...

Volker.
Jim Geier_1
Regular Advisor

Re: How to determine to which IP address a process connected

This looks promising, but I am not getting success with the TCP command in SDA on Alpha or on Integrity:

$ analyze/system
OpenVMS system analyzer
SDA> tcp show device tna11:/full
%CLI-W-SYNTAX, error parsing 'TCP'
SDA>

How does one get access to that "TCP" command in SDA?
Volker Halle
Honored Contributor

Re: How to determine to which IP address a process connected

Jim,

I'm sorry, this was a typo ;-(

Try

SDA> tcpip show device tna11:/full

If the first token on the SDA command line is not a recognized command within SDA, it will try to find a SDA extension and invoke that. SDA looks for extensions under SYS$SHARE:xxx$SDA.EXE.

In this case, there is no TCP$SDA.EXE, but a TCPIP$SDA.EXE.

Volker.
Jim Geier_1
Regular Advisor

Re: How to determine to which IP address a process connected

The SDA TCPIP command works every time in all situations in which I have tried it. Below is the DCL script I put together. Note that when in SDA, the command
TCPIP SHOW DEVICE _TNA111: /FULL produces:
%TCPIP-E-NOTBGDEVICE, Not a BG (INET network socket) device
-TCPIP-E-NOTTNDEVICE, Not a TN (network terminal) device

but TCPIP SHOW DEVICE TNA111: /FULL (without the leading underscore) works just fine.

$! CONNECTED_IP.COM
$! Get the IP address to which the session connected on this system
$
$ tna_device = f$getjpi(0,"tt_phydevnam") - "_"
$ if f$extract(0,3,tna_device) .nes. "TNA" then exit
$ proc_name = f$getjpi(0,"prcnam")
$ sda_file = f$parse(f$unique(),"sys$scratch:.tmp")
$ tna_file = f$parse(f$unique(),"sys$scratch:.tmp")
$ open/write sda$file 'sda_file'
$ write sda$file "$ analyze/system"
$ write sda$file f$fao("set output !AS",tna_file)
$ write sda$file f$fao("tcpip show device !AS /full",tna_device)
$ write sda$file "exit"
$ close sda$file
$ define/user_mode sys$output nla0:
$ @'sda_file'
$ open/read tna$file 'tna_file'
$TNA_LOOP:
$ read/end_of_file=tna_done tna$file record
$ record = f$edit(record,"trim,compress")
$ if f$extract(0,13,record) .nes. "Local address" then goto tna_loop
$ ip_address = f$element(2," ",record)
$ write sys$output f$fao("Process !AS connected to IP address !AS",-
f$getjpi(0,"prcnam"),ip_address)
$TNA_DONE:
$ close tna$file
$ delete 'tna_file'
$ delete 'sda_file'
$ exit
Jim Geier_1
Regular Advisor

Re: How to determine to which IP address a process connected

The bad thing about this solution is that SDA required CMKRNL privilege. So this solution is not going to work as a means to detect during the system-wide login the ip address to which a user has connected.
Hoff
Honored Contributor

Re: How to determine to which IP address a process connected

>The bad thing about this solution is that SDA required CMKRNL privilege. So this solution is not going to work as a means to detect during the system-wide login the ip address to which a user has connected

Here's an example of how to do a DECnet connection to connect to a server process using just DCL:

http://labs.hoffmanlabs.com/node/1524

This target server process can execute (using a proxy) and return the data.

There are other ways to resolve this, and without passing out CMKRNL.

A somewhat sneaky (and fully documented) approach is to set CMKRNL in the default mask but not the authorized mask, and to then strip off the privilege after you're done with it in LOGIN or SYLOGIN. Add a CTRL/Y block in the UAF flags, and you're good to go.

It's also not particularly difficult to implement this via available (installed) code, but that's more work than the above approaches. Presuming you can't locate somebody that's implemented this and posted it.