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:
- The
-s
suppresses progress output so only JSON is passed tojq
. - The
accept
header is set to the RDAP media type. - The target is a bootstrap server that redirects queries to the appropriate authoritative server.
- The
-L
instructscurl
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:
- “startAddress” and “endAddress” are defined in RFC 9083
- “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"