Listing the STCP IP connections (sockets) associated with a process

Blue Bar separator

This page includes two macros. The first list_process_network.cm dumps the STCP IP attachements that a process has in an easily readable table. It will display all the TCP attachments in any VOS release and starting with 14.7 (fix for av-1307) is will also display UDP attachments. The second macro, list_all_process_network.cm, will display a table of all the process running on the system that have STCP IP attachments. It does this by building a list of all running processes and then calling list_process_network for each process.

Note that both these macros makes use of attach_default_output. If you interrupt the macro while it is executing you will probably have to issue the detach_default_output_command to restore output to the terminal.

The list_all_process_network.cm generates a lot of intermediate output before compiling the process_network_table.(date) file in the current dir. It also can take a while to run. For that reason I expect that it will typically be run as a started process.

list_all_process_network example

start_process list_all_process_network -privileged -wait
ready  10:07:29
d process_network_table.(date)

%phx_vos#m16_mas>SysAdmin>Noah_Davids>process_network_table.08-01-30  08-01-30 1

List of processes that have attached TCP and UDP sockets
created 08-01-30 10:07:02 by the list_all_process_network.cm macro


34 8BA34800 55108022 Overseer.System {iked}
      Local                      Remote
  udp 10.10.1.1:500              0.0.0.0:0

  udp 172.16.1.116:500           0.0.0.0:0

  udp 164.152.77.128:500         0.0.0.0:0

==================================================

35 8BA35100 55108023 Overseer.System {telnetd}
      Local                      Remote
  tcp 0.0.0.0:23                 0.0.0.0:0

==================================================

36 8BA36000 55108024 Overseer.System {ftpd}
      Local                      Remote
  tcp 0.0.0.0:21                 0.0.0.0:0
  . . .

Some examples of list_process_network:

If you know the process number of the process you are interested in you can just supply the number.

Note that when executing this macro "for real" the terminal window is cleared before the table (starting with the "list_process_network" line) is printed. For this first example I have changed my terminal type to prevent the clear so you can see what will be written to the window while the macro is executing.

list_process_network 40
VOS Release 16.2.0as, analyze_system Release 16.2.0af
Current process is 94, ptep 8C531000, Noah_Davids.CAC
as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:
+ as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as:  as
+:  as:  as:  list_process_network 40                                          



Current process is 40, ptep 8C2AE6C0, root.root (stcp_inetd)

      Local                      Remote
  tcp 0.0.0.0:7                  0.0.0.0:0

  udp 0.0.0.0:7                  0.0.0.0:0

  tcp 0.0.0.0:9                  0.0.0.0:0

  udp 0.0.0.0:9                  0.0.0.0:0

  tcp 0.0.0.0:13                 0.0.0.0:0

  udp 0.0.0.0:13                 0.0.0.0:0

  tcp 0.0.0.0:19                 0.0.0.0:0

  udp 0.0.0.0:19                 0.0.0.0:0

  tcp 0.0.0.0:37                 0.0.0.0:0

  udp 0.0.0.0:37                 0.0.0.0:0

  tcp 0.0.0.0:901                0.0.0.0:0

ready  13:04:08

If you know the name of the process you can use it, or some star name that matches the process name.

list_process_network -user *.* -process_name NTP*

Current process is 85, ptep 8C480340, root.root (NTP Daemon)                   

      Local                      Remote
  udp 0.0.0.0:123                0.0.0.0:0

  udp 127.0.0.1:123              0.0.0.0:0

  udp 10.10.1.1:123              0.0.0.0:0

  udp 172.16.1.116:123           0.0.0.0:0

  udp 164.152.77.128:123         0.0.0.0:0

ready  13:05:30

If you have 2 processes with the same name but running under different user names you can add in the user name or a user star name. Note that by default the user name is *.*.

list_process_network -user Apache* -process_name httpd

Current process is 78, ptep 8C4CF280, Apache.SysAdmin (httpd)                  

      Local                      Remote
  tcp 0.0.0.0:80                 0.0.0.0:0

ready  13:06:38

If you provide both a process number and process_name and or user, the process number takes precedence. In the following example I actually executed the command:

list_process_network 40 -user *.* -process_name NTP*
However, the command that is echoed reflects only the process number and you can see that the process selected is stcp_inetd NOT NTP_Daemon.

list_process_network 40

Current process is 40, ptep 8C2AE6C0, root.root (stcp_inetd)                   

      Local                      Remote
  tcp 0.0.0.0:7                  0.0.0.0:0

  udp 0.0.0.0:7                  0.0.0.0:0

  tcp 0.0.0.0:9                  0.0.0.0:0

  udp 0.0.0.0:9                  0.0.0.0:0

  tcp 0.0.0.0:13                 0.0.0.0:0

  udp 0.0.0.0:13                 0.0.0.0:0

  tcp 0.0.0.0:19                 0.0.0.0:0
  . . .

Process selection is done with the analyze_system process request. Like that request if the process_name and or user match more than 1 process you get the first process so be careful how you specify the process you want. As you can see from the following example there are many processes matching the osl* process name and we select the process with the lowest number.

list_process_network -user *.* -process_name osl*

Current process is 41, ptep 8C2CA3C0, Overseer.System (osl_daemon)             

      Local                      Remote
  tcp 0.0.0.0:3000               0.0.0.0:0

  tcp 0.0.0.0:3001               0.0.0.0:0

  tcp 0.0.0.0:3002               0.0.0.0:0

  tcp 0.0.0.0:3003               0.0.0.0:0

  tcp 0.0.0.0:3004               0.0.0.0:0

  tcp 0.0.0.0:3005               0.0.0.0:0
. . .

as:  match osl; who
   41  8C2CA3C0  55108029  Overseer.System (osl_daemon)
   42  8C2CD000  5510802A  Overseer.System (osl_admin)
   43  8C2D1380  5510802B  Overseer.System (OSL_Overseer)
   44  8C2F5040  5510802C  Overseer.System (osl_server1)
   45  8C2F8A80  5510802D  Overseer.System (osl_server2)
   46  8C2FB100  5510802E  Overseer.System (osl_server3)
   47  8C2FD140  5510802F  Overseer.System (osl_server4)
   48  8C2FF840  55108030  Overseer.System (osl_server5)
   49  8C3012C0  55108031  Overseer.System (osl_server6)
   50  8C304000  55108032  Overseer.System (osl_server7)
   51  8C3053C0  55108033  Overseer.System (osl_server8)
   52  8C308040  55108034  Overseer.System (osl_server9)
   53  8C30A500  55108035  Overseer.System (osl_server10)
   54  8C30C000  55108036  Overseer.System (osl_server11)
   55  8C30EB40  55108037  Overseer.System (osl_server12)
   56  8C310840  55108038  Overseer.System (osl_server13)
   57  8C313000  55108039  Overseer.System (osl_server14)
   58  8C315000  5510803A  Overseer.System (osl_server15)
   59  8C317140  5510803B  Overseer.System (osl_server16)
as:

Finally here is what it looks like if the process has no IP attachments

list_process_network -user *.* -process_name *NT*

Current process is 38, ptep 8BA4D000, Overseer.System (MAINTNET_MD_Daemon)     

      Local                      Remote
ready  13:21:06

list_process_network.cm

& list_process_network begins here
&
& list_process_network.cm
& version 1.0 08-01-29
& version 1.1 08-02-01 Added a line showing what the command line was and
&             the process that was selected is (for -no_quiet mode)
& version 1.2 10-11-26 Added disclaimer
& noah.davids@stratus.com
&
& This macro goes into analyze_system, selects a process based on the
& input arguments and for each port attachment, dumps the porte matching
& on any IP address and port numbers. It converts the output from hex
& into dotted decimal notation and prints out a pretty table.
&
& This will work for all TCP STCP attachments. Starting with 14.7 it will
& work with UDP attachments as well.
&
& Usage
& list_process_network [process_number] [-user string] [-process_name string]
&                      [-quiet]
&
& process_number    This is the process number of the process you are
&                   interested in. If a process number is given any
&                   user and process_name arguments are ignored
&
& -user             A user star name, default is *.*
&
& -process_name     A star name representing the process name. Note that if
&                   there are multiple processes that match the star name
&                   user name the first process will be selected.
&
& -quiet            If given then final output, clearing the screen and
&                   display of the table is not done. This is here so that
&                   when list_all_process_network is called there is not
&                   a lot of intermediate output.
&
&                            NOTE NOTE NOTE
& This only works for STCP attachments
&
& This macro makes use of the attach_default_output command. Terminating
& this macro before it completes may leave your output redirected to a
& file.
&
& This macro must be run in a privileged process
&
& This software is provided on an "AS IS" basis, WITHOUT ANY WARRANTY OR ANY
& SUPPORT OF ANY KIND. The AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES
& OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE.  This disclaimer
& applies, despite any verbal representations of any kind provided by the
& author or anyone else.
&      
&
&begin_parameters
PROCESS_NUM process_number:number
USER option(-user),string,='*.*'
PROCESS_NAME option(-process_name),string
QUIET switch(-quiet),=0
&end_parameters
&
&
&echo no_input_lines no_command_lines no_macro_lines
&if (process_type) ^= interactive
&then set_ready -format off
&
&
& Create final output file and its header line. This will also
& delete any preexisting file.
attach_default_output (process_dir)>list
display_line '      Local                      Remote'
detach_default_output
&
&
&attach_input
analyze_system
&
&
& Process the input arguments to create a "process" command.
& If a process_number is given use that and ignore the other arguments
& Otherwise use the process name and user. User defaults to *.* so it is
& OK to always include it. NOTE, that if more than 1 process matches the
& user and process_name the system will select the process with the lower
& process number. There is no indication that multiple processes are matched.
&if X&PROCESS_NUM&X ^= 'XX'
&then &set_string CMD 'process ' &PROCESS_NUM&
&else &set_string CMD 'process -user ' &USER& ' -process_name ' &PROCESS_NAME&
&
&
& capture the output from the process command so we can display the
& actual process later
..attach_default_output (process_dir)>process
&CMD&
..detach_default_output
&
&
& Build the first output file which is a list of all the port attachments
& for the process. The end of the file contains the string END which is used
& to stop the loop reading the file.
..attach_default_output (process_dir)>port_list
match ' at '; list_port_attachments
..display_line END
..detach_default_output
&
&
& The beginining of the major loop. Read each line of the file containing
& the port attachments and process the porte. Beacuse of the "as: ' prompts
& in the outputfile the location of the porte number on the first line is
& different from the rest of the lines. Hence OFFSET variable which starts
& out at 11 and change to 6 at the end of the loop.
&set OFFSET 11
&set LINE 1
&while (contents (process_dir)>port_list &LINE&) ^= 'as:  END'
&
&
& The porte number is extracted from the line in 3 steps. First everything
& before the porte is removed, Then the space following the number is located
& and finaly, everything beyond the space is removed.
&set PORT (substr (contents (process_dir)>port_list &LINE&) &OFFSET&)
&set SPACE (index (string &PORT&) ' ')
&set PORT (substr (string &PORT&) 1 &SPACE&)
&        
&
& Once we have the porte number we can dump the porte matching first on the
& local address and port number and then on the foreign address and port
& number. Note that for a porte that is not attached to a socket these
& matches will come up null. Also in earlier versions of VOS the protocol
& control block for UDP was not displayed, so in those versions a porte
& connected to a UDP socket will also come up null. Unfortunately, I am
& not sure exactly when dump_porte was modified to display the UDP protocol
& control block.
..attach_default_output (process_dir)>addr_port
match laddr -or lport; dump_porte -number &PORT&
match faddr -or fport; dump_porte -number &PORT&
..detach_default_output
&
&
& If the above match did not come up null, i.e the porte is connected
& to a socket then continue processing
&if (string (contents (process_dir)>addr_port 1)) ^= 'as:  as:  as:'
&then &do
&
&
& The lables are different for a TCP and UDP sockets. Which is good because
& the UDP data is displayed in a different order than the TCP data. Note
& that the offsets (41 and 36) are different because of the "as: " prompt
& string that is part of the first line of data for each match command.
& The protocol is recorded so we can label the the output as TCP or UDP.
&if (index (contents (process_dir)>addr_port 1) ub_) > 0
&then &do
&set_string PROTOCOL udp
&set LPORT (substr (contents (process_dir)>addr_port 1) 41)
&set_string LADDR (substr (contents (process_dir)>addr_port 2) 36)
&set FPORT (substr (contents (process_dir)>addr_port 3) 41)
&set_string FADDR (substr (contents (process_dir)>addr_port 4) 36)
&end
&else &do
&set_string PROTOCOL tcp
&set_string LADDR (substr (contents (process_dir)>addr_port 1) 41)
&set LPORT (substr (contents (process_dir)>addr_port 2) 36)
&set FPORT (substr (contents (process_dir)>addr_port 3) 41)
&set_string FADDR (substr (contents (process_dir)>addr_port 4) 36)
&end
&
&
& Early versions of VOS displayed the TCP port as a signed integer. Current
& vesrions of VOS still display the UDP port as a signed integer. So
& ports greater than 32767 may be displayed as a negative number. This
& converts the number back to its unsigned value.
&if (index &LPORT& -) > 0
&then &set LPORT (calc 65536 - (substr &LPORT& 2))
&if (index &FPORT& -) > 0
&then &set FPORT (calc 65536 - (substr &FPORT& 2))
&
&
& This converts the IP address which is displayed as an integer back into
& doted decimal notation. It also adds the a colon and the port number
& to the string for output.
&set_string IP1 (substr &LADDR& 1 2)
&set_string IP2 (substr &LADDR& 3 2)
&set_string IP3 (substr &LADDR& 5 2)
&set_string IP4 (substr &LADDR& 7 2)
&set_string LADDR1 (calc 0&IP1&x).(calc 0&IP2&x)
&set_string LADDR2 (calc 0&IP3&x).(calc 0&IP4&x):&LPORT&
&set_string IP1 (substr &FADDR& 1 2)
&set_string IP2 (substr &FADDR& 3 2)
&set_string IP3 (substr &FADDR& 5 2)
&set_string IP4 (substr &FADDR& 7 2)
&set_string FADDR1 (calc 0&IP1&x).(calc 0&IP2&x)
&set_string FADDR2 (calc 0&IP3&x).(calc 0&IP4&x):&FPORT&
&        
&
& Figure out how long the local address so we know how many spaces to
& add after it so that the foreign addresses all line up. Note that since
& display_line tends to collaps multiple spaces int 1 space I actually use
& an underscrore character. These will be converted into spaces at the
& end of the macro.
&set LEN (length &LADDR1&.&LADDR2&)
&set_string SPACES (substr '_________________________' 1 (calc 25 - &LEN&))
&
&
& Output the protocol addresses.
..attach_default_output (process_dir)>list -append
..display_line &PROTOCOL& &LADDR1&.&LADDR2& &SPACES& &FADDR1&.&FADDR2&
..detach_default_output
&
&end
&
& We have now come to the end of the while loop processing the porte numbers.
& We need to increment the line count and the OFFSET need sto change from 11
& for thefirst line to 6 for all other lines. We obviously only have to do
& this once but it seemed that an IF to test the line number was just
& overkill.
&set LINE (calc &LINE& + 1)
&set OFFSET 6
&end
&
& We have completed the loop so we exit analyze_system
quit
&
&
& The output file has 2 things wrong with it. First it contains a lot of lines
& that are just "as:" and second we have underscrores separating the local
& and remove addresses. Using line_edit we can delete the "as:" characters
& and convert the underscores to spaces.
&attach_input
line_edit (process_dir)>list -no_keystrokes -no_backup -no_verbose
change * !as:!! *
change * !_! ! *
write
quit
&detach_input
&
&
& If the quiet flag is not set clear the screen, it has a bunch of left over
& analyze_system output display the initial command line, the output from
& the process analyze_system request so we know what process we are really
& looking at and then the list file which contains the final results.
& If quiet is set do not display anything.
&
&if &QUIET& = 0
&then &do
display_line (byte 27)(byte 2)
&if X&PROCESS_NUM&X ^= 'XX'
&then display_line list_process_network &PROCESS_NUM&
&else display_line list_process_network -user &USER& -process_name &+
                   &PROCESS_NAME&
display_line
display_line (contents (process_dir)>process 2)
display_line
display -no_header (process_dir)>list
&end
&
& list_process_network ends here

list_all_process_network.cm

& list_all_process_network.cm begins here
&
& This software is provided on an "AS IS" basis, WITHOUT ANY WARRANTY OR ANY
& SUPPORT OF ANY KIND. The AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES
& OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE.  This disclaimer
& applies, despite any verbal representations of any kind provided by the
& author or anyone else.
&
&echo no_input_lines no_command_lines no_macro_lines
&if (process_type) ^= interactive
&then set_ready -format off
&
&
& Get a list of all the current processes. Append the string END to the list
& as an easy way to know when we are at the end of the list.
&attach_input
analyze_system
..attach_default_output (process_dir)>process_list
who
..display_line END
..detach_default_output
quit
&
&
& The format of above process list will include paren "()" characters. These
& screw with command processing so edit the process_list file so that the
& commands are translated into curly bracket "{}" characters.
&attach_input
line_edit (process_dir)>process_list -no_keystrokes -no_backup -no_verbose
change * !(!{! *
change * !)!}! *
write
quit
&detach_input
&
&
& Write a nice header to th efinal output file. Include the date time that
& the macro was run. This also has the effect of deleting any existing file.
attach_default_output (process_dir)>table
display_line List of processes that have attached TCP and UDP sockets
display_line created (date) (time) by the list_all_process_network.cm macro
display_line
display_line
detach_default_output
&
& The first line of output is a header so we can just skip it and start at
& line 2
&set LINE 2
&
&        
& This is the major loop. Read line line of the file containing the
& processes, extract the process number and call list_process_network.cm
& to list all (if any) sockets that the process is using.
&while (contents (process_dir)>process_list &LINE&) ^= 'as:  END'
&set_string PROCESS (string (contents (process_dir)>process_list &LINE&))
&
&
& The process number is extracted from the line in 3 steps. First everything
& before the process number is removed, Then the space following the number
& is located and finaly, everything beyond the space is removed.
&set P_NUM (substr (contents (process_dir)>process_list &LINE&) 3)
&set SPACE (index (string &P_NUM&) ' ')
&set P_NUM (substr (string &P_NUM&) 1 &SPACE&)
&
& If the process is one of the CPU Idle processes we can skip it. Otherwise
& process it.
&if (index (string &PROCESS&) 'Idle') = 0
&then &do
&
& First call list_process_network using the process number and the -quiet
& argument since we aren't looking for displayed output at this point.
list_process_network &P_NUM& -quiet
&        
& Next we need to see if the process any attached sockets. Look at the
& list file produced by list_process_network. If the record count as
& displayed by display_file_status  is not one then there is at least
& 1 line of useful output, so . . .
attach_default_output (process_dir)>size
display_file_status (process_dir)>list
detach_default_output
&set SIZE (substr (contents (process_dir)>size 23) 28)
&if &SIZE& ^= 1
&then &do
&
&
& Output the PROCESS line which will identify the process and the
& list file from list_process_network and a separator line
attach_default_output (process_dir)>table -append
display_line &PROCESS&
display (process_dir)>list -no_header
display_line ==================================================
display_line
detach_default_output
&end
&
&end     
&
& We are at the end of the loop so increment the line count and go back
& and read another line from the process_list file
&set LINE (calc &LINE& + 1)
&end
&
&
& we have processed all the processes, copy the output file from the process
& directory in to the current dir and rename if, adding the current date.
& Note that this will write over any existing file.
copy_file (process_dir)>table process_network_table.(date) -delete
&
& list_all_process_network.cm ends here


Blue Bar separator
This page was last modified on 10-11-26
mailbox Send comments and suggestions
to ndav1@cox.net