From 01a20181b41851b188cd9b7b12a2e883b0ed4a46 Mon Sep 17 00:00:00 2001 From: Nick Chambers Date: Sun, 25 Jul 2021 20:38:27 -0500 Subject: [PATCH] bash/cidr: ip routing calculator for convenience --- bash/cidr | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 bash/cidr diff --git a/bash/cidr b/bash/cidr new file mode 100755 index 0000000..66b6672 --- /dev/null +++ b/bash/cidr @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +bin() { + local str num=$1 + + while (( num > 0 )); do + str=$(( num % 2 ))$str + (( num /= 2 )) + done + + while (( ${#str} < 8 )); do + str=0$str + done + + printf %s "$str" +} + +dec() { + local pow=$(( ${#1} - 1 )) num=0 + + for (( count = 0; count < ${#1}; ++count )); do + (( num += ${1:count:1} * (2 ** pow) )) + (( pow -= 1 )) + done + + printf %d "$num" +} + +2ip() { + local ip=( ) count + + for count in {0..3}; do + ip[$count]=$(dec "${1:count * 8:8}") + done + + printf %s.%s.%s.%s "${ip[@]}" +} + +if (( ! $# )); then + printf 'usage: %s ip/cidr\n' "$0" + exit 1 +fi + +IFS=/ read -r ip size <<< "$1" +IFS=. read -ra octets <<< "$ip" + +for (( count = 0; count < 4; ++count )); do + octets[$count]=$(bin "${octets[$count]}") +done + +IFS= ip=${octets[*]} network=${ip:0:size} broadcast=${ip:0:size} + +while (( ${#network} < 32 )); do + network+=0 + broadcast+=1 +done + +for (( count=0; count < size; ++count )); do + mask+=1 +done + +for (( count=32 - size; count < 32; ++count )); do + mask+=0 +done + +printf 'subnet mask: %s\n' "$(2ip "$mask")" +printf 'range: %s - %s\n' "$(2ip "$network")" "$(2ip "$broadcast")" +printf 'total assignable hosts: %d\n' "$(( (2 ** (32 - size)) - 2 ))"