Bash: Finding IP Networks

Let’s say you are a network operator and are given a text file with IP addresses with the task of finding their registered CIDR blocks, perhaps for creating an access control list.

199.43.0.0
149.112.152.0
101.100.49.1  

You have been asked to provide this information in a CSV file.

Using a simple bash script, the curl command, and jq, you come up with this very simple solution (source code is here):

echo "start address", "end address", "cidr block" > ip_inventory.csv
cat ip_inventory.txt | while read ip
do
curl -s -L \
  -H "accept: application/rdap+json" \
  https://rdap-bootstrap.arin.net/bootstrap/ip/$ip | 
  jq -r \
  '. | [.startAddress, .endAddress, "\(.cidr0_cidrs[0].v4prefix)/\(.cidr0_cidrs[0].length)"] | @csv' \
  >> ip_inventory.csv
done  

How does this work? First, the script pipes the inventory text file into a loop and executes a curl command for each IP address. Then curl pipes its output to jq which appends the information to the CSV file.

Here is what to note about the curl command:

  1. The -s suppresses progress output so only JSON is passed to jq.
  2. The accept header is set to the RDAP media type.
  3. The target is a bootstrap server that redirects queries to the appropriate authoritative server.
  4. The -L instructs curl to follow redirects.

These last two items are important to understand. The set of IP addresses are not all registered with the same RIR, yet the script has no logic to find the right server to query. Instead, all queries are sent to a “redirect” server which then redirects curl to the right place.

The jq command does the parsing of the JSON and converting it to CSV. There are a couple of interesting things to note here:

  1. “startAddress” and “endAddress” are defined in RFC 9083
  2. “cidr0_cidrs” is from an RDAP extension used by the RIRs for expressing CIDR blocks.

The final result is this CSV file:

start address, end address, cidr block
"199.43.0.0","199.43.0.255","199.43.0.0/24"
"149.112.152.0","149.112.155.255","149.112.152.0/22"
"101.100.0.0","101.100.127.255","101.100.0.0/17"