IP Probe: A “telnet-like” IP probe utility for z/TPF
Background
Whilst the use of telnet as a terminal emulator for remote systems is, baring a small number of niche cases, all but obsolete, it remains useful on many platforms as a quick and easy way to test tcp/ip connectivity to a remote address and port where nmap might be overkill, not installed, or otherwise unavailable. z/tpf does not provide such a facility. IP Probe fulfils this requirement.
Design objectives
Unlike most programs, IP Probe is designed to expose its inner workings specifically to identify any point of failure and the reason for that. Thus, its output is somewhat verbose, for example:
IP Probe Utility Version: 1.0; built: Jun 7 2023 11:15:52
Creating TCP socket…
…Created socket 12582949
Setting receive/connect timeout of 10 seconds on socket 12582949…
…Options set, rc = 0
Connecting socket 12582949 to 10.27.186.207:21…
…Connected TCP socket, rc = 0
Sending on socket 12582949 (15 bytes): EtoA(Metatron speaks)…
…Sent 15 bytes
Receiving on socket 12582949…
…Received 42 bytes: 220 TPF FTP server (Version 1.02) ready.
Setting receive/connect timeout of 1 seconds on socket 12582949…
…Options set, rc = 0
Receiving on socket 12582949…
…Receive timeout: no data received
Closing TCP socket 12582949…
…Closed TCP socket, rc = 0
Test finished.
The sequence of events is:
Create a TCP socket.
Set a primary timeout period to be used for both the initial connection and the receipt of the first response datagram.
Attempt to connect to target, wait for connection to be established.
Send some data.
Attempt to receive a datagram. We’re not overly bothered by its contents. Indeed the data we send is likely to be rejected by most servers so this operation will oftentimes fail.
In case any datagram sent to us has been fragmented, or more than one was sent, we’re going to issue another receive. But we don’t want to wait for a long time so set a short secondary timeout period.
Now issue the secondary receive.
On receiving a timeout or an error from the secondary receive close the socket and terminate the connection.
Usage
The utility itself provides full help text:
> zuipp –help
zuipp [-hV] [–version] [-d <string>] [-1 <positive integer>]
[-2 <positive integer>] IP_Address TCP_Port
Where:
-d <string>, –data <string>
The message data to send.
1 <positive integer>, –timeout1 <positive integer>
Timeout for connect and first receive.
-2 <positive integer>, –timeout2 <positive integer>
Timeout for subsequent receives.
-V, –verbose (accepted multiple times)
Show some additional diagnostics
–, –ignore_rest
Ignores the rest of the labeled arguments following this flag.
–version
Displays version information and exits.
-h, –help
Displays usage information and exits.
IP_Address <string>
(required) Target IP Address to probe.
TCP_Port <positive integer.
(required) Target TCP Port to probe.
This is a telnet-style IP probe utility to test connectivity to a
specific IP address and port.
Examples
- The most common usage will be to query a specific address and port using the default options, e.g.:
> zuipp 10.27.186.207 21
Typical response:
IP Probe Utility Version: 1.0; built: Jun 7 2023 11:15:52
Creating TCP socket…
…Created socket 12582949
Setting receive/connect timeout of 10 seconds on socket 12582949…
…Options set, rc = 0
Connecting socket 12582949 to 10.27.186.207:21…
…Connected TCP socket, rc = 0
Sending on socket 12582949 (15 bytes): EtoA(Metatron speaks)…
…Sent 15 bytes
Receiving on socket 12582949…
…Received 42 bytes: 220 TPF FTP server (Version 1.02) ready.
Setting receive/connect timeout of 1 seconds on socket 12582949…
…Options set, rc = 0
Receiving on socket 12582949…
…Receive timeout: no data received
Closing TCP socket 12582949…
…Closed TCP socket, rc = 0
Test finished.
The response is a verbose explanation of all activities performed by the utility and their results.
- The data sent by the utility, the timeout for the initial connection and expected first receive, and the timeout for subsequent unexpected receives may be set by optional parameters.
For example, to override the text, wait 30 seconds for the connection and primary response, and 5 seconds for any additional responses:
> zuipp 10.27.186.207 21 –data “Messages with spaces may be sent using quotes” –timeout1 30 –timeout2 5
Errors
Some sort of error, usually on the first receive operation, is normal and expected, as the data sent by this utility will not be acceptable to most servers excepting the most primitive.
The reason for any error is clearly indicated in the applicable message. Numeric return codes are deciphered using z/tpf facilities, but this is, regrettably, incomplete. Thus, an indication is provided of which source segment the numeric value is likely to be enumerated in, in the hope that this might provide a clue to the failure, or at least a starting point for a search. (IBM is expected to issue a fix for this incompleteness later in 2023).
Source
SNCF z/TPF systems management have requested and authorised that this utility be made publically available. It has also been submitted to IBM should they wish to include it in the z/TPF distribution.
The complete source and full documentation for this utility may be obtained (here).
Programming notes
- The following open-source projects are required for compilation:
- TCLAP (tclap.sourceforge.net, MIT licensed)
- FMT (fmt.dev, MIT licensed)
- I’m not a huge fan of the z/tpf iprse parser, preferring to use open-source options. For c++, cli11 is arguably the best of breed, and best documented, but this project uses tclap as sncf is currently using an older level of gcc incompatible with cli11.
- The latest version of this utility has started to use the fmt project’s i/o classes to replace c stdio and c++ iostreams calls with modern c++20 std::format alternatives with much-improved capabilities. Not all previously existing code has been updated.
- tclap requires a tokenised command line to be passed to it, which we would normally obtain from main()’s argv parameters, but z/tpf does not generate these from the command line, so instead we parse the input message ourselves, which means we can handle quoted strings with spaces in them, for example.
- Sncf’s uenv.c does not correctly define the stdout and stderr environment variables so, at the very start of the program, we open the correct paths so that writes to stdoutm stderr, cout, and cerr work correctly. I am, obviously, unable to verify if the utility works with correctly-defined variables, but there is a
#definewhich should turn this section of code off, if required. - The utility’s core routines are all gathered into a single class as a collection of static members, just for the sake of tidiness.
Thanks
This article is based on work performed for SNCF, and is published with their permission, for which many thanks.