Photo by Micah Tindell on Unsplash

Photo by Micah Tindell on Unsplash

Have a Bash with the Zing network utility

Zinger

Article from ADMIN 77/2023
By
We show you how to implement the zero-packet Ping utility, Zing, as a Bash shell script.

Zing is a zero-packet network utility similar to Ping that I first introduced in December 2022 [1]. Zing has the distinct advantage that hosts without Ping capability can be zinged without sending network packets. Thus, zinging a remote host with multiple zing requests is not a "Ping flood" [2] attack, making Zing a network-safe utility that does not add network traffic.

Zing is implemented in a variety of programming languages, is open source, and is available for download [3]. Yet the idea occurred to me to implement zing as a Bash shell script, which has the advantage of avoiding recompilation and of customization or tailoring for specific idiosyncrasies of a system platform or application.

Netcat

The netcat utility (nc) is a key command-line application and "Swiss army knife" of network utilities [4]. Netcat is described as a simple Unix utility that reads and writes data across network connections by the TCP or UDP protocol [5]. Originally developed for Unix, netcat has since been ported to many other computer platforms. Thus, netcat has the advantage of being somewhat ubiquitous across different operating systems.

The decision to implement zing with netcat in a shell script left one major design consideration decision. Put simply: Which shell to use? I develop on macOS, so Zsh seemed a likely obvious choice. However, I also work with Linux, so other shells were possible.

Ultimately I opted to go with Bash because it is ubiquitous, and I have done much more scripting for work and tinkering with the Bash shell. Moreover, Bash scripting is powerful, and with many users and a large pool of questions and answers on many tech boards, I was likely to find the solutions to unexpected problems, errors, and anomalies quickly. Thus, a Zing Bash script was the final choice.

Bash Shell Script for Zing

Having settled on netcat as the core of a Bash shell script to implement zing, two design principles were determined:

  • Explicit specified parameters to eliminate ambiguity; an erroneous parameter then terminates the script.
  • Early Failure; when a required explicit parameter is missing, the Bash script terminates and exits.

The Bash implementation with netcat has four essential sections: (1) initialize, check, and process command-line interface (CLI) arguments; (2) check for the host and get the hostname and host address; (3) echo and perform the zing operation and accumulate time; and (4) calculate simple statistics and report the results. Each section can then be broken down into specific operations and functions. To keep the code and design simple, all of these operations are centered on netcat as the only network tool.

Initializing sets the zing variable defaults for the count, operations limit, network timeout, port list, and remote host. After initialization, the CLI arguments then re-initialize specific zing parameters. This re-initialization requires some checks on the CLI arguments and number of arguments.

The initialization section also checks for at least one parameter and whether the argument is asking for help. If the CLI argument is not -h or --help, then the arguments submitted are processed. The processing is a loop to identify the argument and its value and then to reinitialize the particular zing parameter as a variable. Any unknown CLI arguments will cause immediate error and exit from the script.

Netcat is used initially to get the name and address of the network host. HTTP port 80 is used per the netcat report:

localhost [127.0.0.1] 80 (http): Connection refused

The result in the hosttext variable is then checked for warnings and errors, which are reported if detected, and the script exits. Again the Fail Early principle for warnings or errors causes the script to abort and exit rather than continuing with a problematic host or port.

The original script extracted the hostname and address from the hosttext variable, but that was dependent on the netcat utility on macOS. The netcat utility returns information differently for macOS, Linux, and the Windows Linux subsystem; thus, the name and address of the host is obtained by netcat to avoid greater coupling to the idiosyncrasies of the network utilities of each platform.

This information of the host, hostname, and host address is later used in the fourth section of the Bash script. The report of the simple statistics also uses the hostname and address as part of the text datum for output.

The Bash script uses three nested loops that work in tandem to perform the zing operation and accumulate and store the network throughput time. The outermost loop iterates through the port list, getting each port specified from the port list. The default port list is for port 80 (HTTP) and port 443 (HTTPS).

The second loop iterates through the count of the number of operations driving the third, innermost loop. The third loop limits the number of individual operations to perform for a single overall operation, which allows for an accumulated average time for network throughput to be determined, because network performance times are often in flux when considering operations from one computer system to another.

The three loops then perform the total zing operation to a network host on the port list. Thus, the number of netcat calls is simply the product of the number of ports, the count, and the limit of the operation. The defaults are ports = 2, count = 6, and limit = 4, so the product, 2x6x4=48, is the total number of netcat operations.

The fourth and final section of the Bash script summarizes the zing operation for a host on a port, which involves two subsections that calculate some simple statistics and report the results of the zing operation before exiting.

The first part, calculating the statistics, is very straightforward and determines the minimums, maximums, averages, and standard deviations. The one challenging statistic to compute is the standard deviation of the timing values. Ultimately it requires an Awk script within the Bash script to make this computation.

The second part reports the statistics and the timing values, along with the hostname and host address. The only difficulty was in ensuring that the formatting worked and was consistent. After reporting the summary information of the zing operation, the script exits.

Among the challenges and difficulties in implementing the Zing network utility as a Bash script was developing the original script on macOS and then running and using it on several different Linux systems with different distributions (e.g., Debian, Ubuntu, etc.).

Some notable "gotchas" in writing and porting the Bash script from macOS to Linux were:

  • GNU gdate vs. date for timing on Linux and macOS, respectively.
  • Awk script double asterisk exponentiation notation vs. the ^ operator for stddev.
  • The use of mawk for Windows Linux subsystem with Bash instead of awk.
  • Format of the text returned by netcat on the various operating systems, which required adjusting the cut text utility field to extract the correct information, depending on whether the address information was in parenthesis (e.g., (127.0.0.1)) or brackets (e.g., [127.0.0.1]).

With some online searching and several technical discussion boards, I found the answers for these minor variations.

Zing CLI Parameters

The zing parameters are enumerated at the command line as:

zing [-c <count>][-op <limit>][-p <port>][-t timeout] <hostname> | (-h|--help)

The parameters for the Zing Bash script are mostly the same as those for the binary compiled version. The one absent parameter in this implementation is for TCP/IPv4 or TCP/IPv6 addresses.

The implementation of zing uses netcat [6], which does not support that particular feature or option; thus, the kind of IP address is dependent on netcat. However, TCP/IPv4 or TCP/IPv6 network addresses can be used along with a hostname for a computer system on the network.

The CLI parameters for the Zing Bash script network utility are:

  • count – the number of zing operations to perform on a host
  • limit – the limit or operations limit per zing operation
  • port – list of ports on which to zing the host
  • timeout – the timeout of the network connecting to a host
  • host , hostname , or host IP address – the host computer system on a network
  • help – a list of the command-line parameters

When the -h or --help parameter is used, the help text for the Zing Bash shell script is printed and then exits. The minimum parameter is the hostname for the computer system on a network.

The working examples of the Zing network utility are Bash scripts running on macOS Ventura version 13.4. Both as success and failure, zings to a host on a network illustrate the operation of the Zing Bash script.

Two working examples of a Zing Bash script (1) address an internal home network with a printer scanner that has no hostname and (2) zing a host on the Internet that cannot be pinged.

In the first example, the internal home network has an IPv4 address but no hostname. This device is a multifunction laser printer that resides on an IPv4 address in the internal private IPv4 address range from 10.0.0.1 to 10.255.255.255. Thus, it has no DNS entry and no hostname.

The command (Listing 1) zings the two HTTP ports: one for unsecured HTTP (port 80) and the other for secure HTTPS (port 443). The Error: message indicates the lack of a hostname for the IPv4 address. However, the Zing Bash script is able to detect and determine the throughput time across the local home network.

Listing 1

Zing an IPv4 Address for Internal Network

zing.bash -c 4 -op 2 -p 80,443 10.0.0.23
ZING:80/ 10.0.0.23 / Warning:
Error: on 80 is: Active. Continue.
Port: 80: op 1.1. 10.0.0.23 80 Time: 28 ms.
Port: 80: op 1.2. 10.0.0.23 80 Time: 55 ms.
Port: 80: op 2.1. 10.0.0.23 80 Time: 26 ms.
Port: 80: op 2.2. 10.0.0.23 80 Time: 56 ms.
Port: 80: op 3.1. 10.0.0.23 80 Time: 25 ms.
Port: 80: op 3.2. 10.0.0.23 80 Time: 48 ms.
Port: 80: op 4.1. 10.0.0.23 80 Time: 101 ms.
Port: 80: op 4.2. 10.0.0.23 80 Time: 128 ms.
ZING:80/ 10.0.0.23 / Warning:
Error: on 443 is: Active. Continue.
Port: 443: op 1.1. 10.0.0.23 443 Time: 27 ms.
Port: 443: op 1.2. 10.0.0.23 443 Time: 56 ms.
Port: 443: op 2.1. 10.0.0.23 443 Time: 28 ms.
Port: 443: op 2.2. 10.0.0.23 443 Time: 55 ms.
Port: 443: op 3.1. 10.0.0.23 443 Time: 27 ms.
Port: 443: op 3.2. 10.0.0.23 443 Time: 58 ms.
Port: 443: op 4.1. 10.0.0.23 443 Time: 27 ms.
Port: 443: op 4.2. 10.0.0.23 443 Time: 53 ms.
--- ZING: the host at IP address:80
--- hostname: 10.0.0.23 / Warning:
Error:
--- for 4 ops at a limit of 2 per op; statistics:
Time for min/avg/max/stddev=24/63/64/12.32-ms

The next example is an Internet host that does not respond to a ping Internet Control Message Protocol (ICMP) packet (Listing 2).

Listing 2

Pinging an Internet Host

ping -c 4 nist.gov
PING nist.gov (129.6.13.49): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
--- nist.gov ping statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss

The host is the National Institute for Standards and Technology (NIST), a US government agency at host nist.gov . The ping command fails, but the Zing Bash script succeeds, giving the timing for Internet throughput (Listing 3).

Listing 3

Zinging an Internet Host

zing.bash -c 4 -op 2 -p 80,443 nist.gov
ZING: 129.6.13.49 / nist.gov / disasterhub.nist.gov on 80 is: Active. Continue.
Port: 80: op 1.1. nist.gov [129.6.13.49] Time: 103 ms.
Port: 80: op 1.2. nist.gov [129.6.13.49] Time: 205 ms.
[...]
ZING: 129.6.13.49 / nist.gov / disasterhub.nist.gov on 443 is: Active. Continue.
Port: 443: op 1.1. nist.gov [129.6.13.49] Time: 105 ms.
Port: 443: op 1.2. nist.gov [129.6.13.49] Time: 209 ms.
[...]
--- ZING: the host at IP address: 129.6.13.49
--- host name: nist.gov / disasterhub.nist.gov
--- for 4 ops at limit of 2 per op; statistics:
Time for min/avg/max/stddev=101/207/110/2.59-ms

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Netcat – The Admin’s Best Friend

    With the seemingly unlimited number of Linux packages available today in repositories, sometimes it’s easy to get lost and miss out on the really high quality packages – those that offer the most impressive functionality.

  • Pen Testing with netcat

    Once you have successfully exploited a target machine, you might be faced with a dilemma common among penetration testers: Do I have shell access or terminal access? These are not the same, and careful knowledge must be used when interacting with a shell compared with a terminal.

  • Customizing PortSentry

    Do you have a sentry to keep an eye on your servers? We’ll show you how to customize PortSentry’s response to suspicious activity.

  • Protect Your Servers with Nmap

    If you've ever had to test the security of your servers, you've almost certainly come across the ever-flexible Nmap (Network Mapper) – used by sys admins to help protect their servers and diagnose problems.

  • Hacking Mutillidae II
    Ethical hacking against the Mutillidae II vulnerable application can improve your security knowledge.
comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=