Monitor mainframe sessions remotely
Build a simple shell script and view everything a mainframe user is doing, in real-time
Users typically connect to mainframe computers (System z™) using a 3270 terminal emulator such as IBM Personal Communications (PCOMM is a host communication and terminal emulation package that features 3270, 5250, and VT emulation; SNA application support; integration; and SNA and TCP/IP connectivity). If those users are located in the same place as the support team, it's easy for support people to help them recover from problems.
However, these days users are likely to be geographically distributed. Whether it's employees working from home or students taking an instructor-led online (ILO) class, often it is impractical to see the users' screens to help them with difficulties.
In this article, learn how to build a simple shell script to run on UNIX or Linux that lets you tap into a user session on a 3270 terminal emulator, the gateway access to z/OS mainframe sessions. The script lets you run a second terminal emulator so you can follow everything a user is doing in real time.
To start, let's look at how terminal emulation works.
How terminal emulation sessions work
Terminal emulators typically connect to the mainframe using TCP/IP. A session is identified by IP addresses, which specify the computers that participate in it, and port numbers, which identify the programs on those computers. The telnet port, used on the mainframe to listen for terminal emulators, is port 23.
Figure 1. Ports and IP addresses
Figure 1 shows two PCs connected to a mainframe. The mainframe uses IP address 18.104.22.168 and port 23. The first PC has two instances of PCOMM—one runs on port 5000, and the other runs on port 5025. The second PC sports one instance that runs on port 5000. Because every communication contains the source IP address and source port, the mainframe can distinguish between those three different connections.
The OS you choose: Knoppix
If you don't already have a working UNIX or Linux system, I suggest you use Knoppix. It's a version of Linux that runs directly off the CD so you can run it on any PC you don't need at the moment without having to touch the PC's disk. It can easily run on an old PC with only 256MB of RAM.
After Knoppix boots, click the icon to start a command-line window as shown in Figure 2:
Figure 2. Knoppix command-line icon
To become the system administrator, run the
command. Run it again every time you open a new command-line window.
Most networks assign IP addresses automatically using a protocol called DHCP. To
check to see if you have such an IP address, run this command:
ipconfig eth0. If you don't have an IP address, get one
assigned and the address of the router. To set it up, run these commands:
ipconfig eth0 <computer's IP address> route add default gw <router's IP address>
To verify connectivity to the mainframe, run this command:
telnet <mainframe's IP address>. If it
works, either use Ctrl-] to quit or start another command-line window.
Remember to run
sudo bash if necessary.
Monitoring a single user connection
This section covers:
- How to set up the simple proxy using pipes
- What the commands are doing during setup
- How to add a monitoring tap
Simple proxy using pipes
The first step is to create a simple proxy. Instead of connecting directly to the mainframe, have the user connect to a PC running Knoppix or another version of Linux, and have that computer connect to the mainframe (as in Figure 3):
Figure 3. User connecting through a proxy
Run the following commands as root:
mknod pc2mf p mknod mf2pc p cat pc2mf | nc <mainframe IP> 23 | tee tap | tee mf2pc & cat mf2pc | nc -l -p 2300 | tee mf2pc &
Now connect using a 3270 terminal emulator to the computer that runs Linux, on port 2300—you should be redirected to the mainframe. Once the connection is finished, you should stop all the commands executed by the third and fourth lines. Unless you have other commands running in the background, these are the commands to do that:
kill %1 kill %2
How does this work?
The first two commands create a couple of First-In-First-Out (FIFO) pipes.
mknod pc2mf p #For the stream going from PC to mainframe mknod mf2pc p #For the stream going from mainframe to PC
The third line:
cat pc2mf | nc <mainframe IP> 23 | tee tap | tee mf2pc &
is more complicated. It is composed of four different commands, connected by pipes. This means that the output of the first command is the input to the second command, the output of the second is input to the third command, and third to fourth. This is somewhat similar to the use of the PASS keyword in JCL jobs to pass the output of one job step as the input to another:
cat pc2mfreads the pipe for the stream of data from the PC to the mainframe.
nc <ip address> 23opens a TCP connection to the mainframe and sends it the output of that pipe.
- The output from the mainframe then goes to the next part,
tee tap. The
teecommand functions as a T-pipe, taking its input (the output from the mainframe) and sending it to the next command as well as a file called tap. We will use this file later for monitoring purposes.
tee mf2pcsends the output from the mainframe to the mf2pc pipe. This line has an ampersand (&) at the end to tell the computer to run it in the background while the user is doing something else.
The fourth line is similar to the third:
cat mf2pc | nc -l -p 2300 | tee mf2pc &
cat mf2pccommand reads the stream that goes from the mainframe to the terminal emulator.
nc -l -p 2300command listens to TCP port 2300. If a program (such as a terminal emulator) connects to that port, it will get the stream from the mainframe through the connection. Whatever it sends to the connection will go to the next program...
tee pc2mf, which will put it in the pipe where it will be retrieved by the third line.
Figure 4 shows what this process looks like.
Figure 4. Simple proxy
Adding a monitoring tap
The output from the mainframe is also sent to a file called tap. Because the stream is in EBCDIC and not ASCII, there is no easy way to view it from Linux. However, after you stop the proxy, you can run these commands to restart with a tap that is accessible from another 3270 terminal emulator:
rm -f tap mknod tap p cat pc2mf | nc <mainframe IP> 23 | tee tap | tee mf2pc & cat mf2pc | nc -l -p 2300 | tee mf2pc & cat tap | nc -l -p 2301 &
The first two lines delete the existing tap file and replace it with another
FIFO pipe. The third and fourth lines run the simple proxy as I did in the
previous code example. The last line reads the information from tap and sends it
nc -l -p 2301, which listens to TCP port 2301. If a
program (such as a terminal emulator) connects to that port, it will get the
tapped stream from the mainframe through the connection. However, anything it
sends back will be sent to the command prompt where the command was executed.
Figure 5 demonstrates the proxy with the tap installed.
Figure 5. Simple proxy with a monitoring tap
Multiple connections using the same TCP port
The solution I just proposed works, but it requires each user to connect to a different port and for ports to be allocated manually. A better solution would be to use the same TCP port for multiple users. The solution in Listing 1 uses a shell script file called proxy.sh:
Listing 1. Shell script proxy.sh works for multiple connections/one port
#! /bin/sh # Run another nc to listen for the next connection nc -l -p 2300 -c ./proxy.sh & # Create a pipe for the tap tap=/tmp/proxy.sh.$$ mknod $tap p # Start the tap connection cat $tap | nc -l -p $$ & echo Connection from `date` tapped at port $$ >> taplist # Because this script is executed by nc, the input and output # are already the TCP connection to the user. Use nc to connect # to the mainframe nc <mainframe's IP address> 23 | tee $tap
Make the script executable with
chmod +x proxy.sh,
and execute it with
nc -l -p 2300 -c ./proxy.sh. Every
time a user connects to port 2300 on the proxy, the user will be connected to the
mainframe and a new port will be opened for a monitoring user.
To get the value of the port, look in the file taplist. It will have the date and time of the connection and the port. If no users connected since the connection you wish to monitor, it will be the last line of the file.
The first line
The first line,
#! /bin/sh, tells the operating
system that this is a script and that it needs to be interpreted using the program
/bin/sh, also known as shell. Other lines that start with a hash sign (#) are
comments and are ignored by the computer.
Listening for connections
nc is executed with the command-line parameters
-l -p <port> -c <command>,
it waits until it receives a connection to that port, and then it executes the
command. The stream coming from the TCP connection is the command's standard
input, and the command's standard output is sent back through the TCP connection.
nc stops listening to the port once it
receives the connection and executes proxy.sh, the first thing the script does is
start another instance of
nc to do the same thing:
nc -l -p 2300 -c ./proxy.sh &. The ampersand
means that this command is to run in the background and not hold up the script
until it is finished.
Creating the tap
Because multiple instances of this script will probably be running at the same
time, it is necessary to create a separate FIFO pipe for each one. To distinguish
between different pipes, the script uses
$$, which is
the current process ID (also known as pid). Multiple invocations of the same
script that run at the same time will have different process IDs.
# Create a pipe for the tap tap=/tmp/proxy.sh.$$ mknod $tap p
The first line is a comment. The second sets the value of the variable tap to
/tmp/proxy.sh.<pid>. This will be the
file name for the pipe.
In the third line,
$tap is replaced with the value of
the variable created by the previous line. This is similar to the use of
&SYSUID in JCL jobs for the user that started
The tap connection
The next step is to create the tap connection for the monitoring user.
# Start the tap connection cat $tap | nc -l -p $$ & echo Connection from `date` tapped at port $$ >> taplist
The first line is, once again, a comment. The second line is similar to the tap in the single connection proxy we created earlier with two differences:
- The name of the pipe is
- The port number available for a monitoring user cannot be a constant because this script will be running in multiple instances in parallel. Only one process can listen to a specific port at a time. Instead the monitoring user, will need to connect to a port that is the same number as the pid of this instance of proxy.sh.
This solution creates a new problem. How does a monitor know which port number
to connect to? The third line is the solution. The
command takes the parameters it gets on the command line and writes them to the
>> taplist part specifies
that the output of the command is to be appended to the file taplist.
Most of the message is written as is to taplist, but two parts of it are
If any part of a shell command is enclosed by back quotes (a character also known
as a grave accent), it is executed and the output placed on the command line. In
`date` runs the date command that reports
the current date and time. This is placed in the message.
$$ has the same meaning as always: the pid that is also
the port number for the monitoring user.
The mainframe connection
The final part of the script connects to the mainframe. Because the input and output of the script are already connected to the user's terminal emulator, this part is very simple.
# Because this script is executed by nc, the input and output # are already the TCP connection to the user. Use nc to connect # to the mainframe nc <mainframe's IP address> 23 | tee $tap
Using the proxy in an instructor-led online class
To use this system in an instructor-led online (ILO) class, configure a Knoppix proxy somewhere on the network and have the students connect to it. The instructor can then open as many instances of a terminal emulator as needed to monitor the students and minimize them.
If a student has a question during an exercise, the instructor can look at the proper terminal emulator to see what the student is doing. Every time the student presses Enter, the student's terminal emulator output is synchronized with the instructor's. If the instructor does not know which terminal emulator window corresponds to the student, he or she can ask the student to enter a keyword on a particular form and see which window displays it.
Figure 6. Proxy with a monitoring tap
- "Linux Shell Scripting Tutorial v1.05r3: A Beginner's handbook" is an exhaustive guide to shell scripting that a beginner can love.
- Review this explanation of TCP connections from Daryl's TCP/IP Primer.
- Learn more about Knoppix in these developerWorks articles.
man <name of command>or consult the Linux man pages to learn about the various Linux commands available to you.
- In the developerWorks Linux zone, find more resources for Linux developers, and scan our most popular articles and tutorials.
- See all Linux tips and Linux tutorials on developerWorks.