#!/bin/ksh

CIDRS[0]=0   ; CIDRS[1]=128 ; CIDRS[2]=192 ; CIDRS[3]=224 ; CIDRS[4]=240 ;
CIDRS[5]=248 ; CIDRS[6]=252 ; CIDRS[7]=254 ; CIDRS[8]=255

CIDR=":255-8:254-7:252-6:248-5:240-4:224-3:192-2:128-1:0-0:00-0:000-0"

while [ $# -ge 1 ]
do
    txt_ip=$1 ; shift
    if expr "$txt_ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/[0-9][0-9]*$' > /dev/null
    then
      cidr=${txt_ip#*/}
      txt_ip=${txt_ip%%/*}
      if [ "$cidr" -lt 1 -o "$cidr" -gt 30 ] ||
	expr "$cidr" : '.*[^0-9]' > /dev/null
      then
	echo "Invalid IP CIDR value '$cidr'" >&2
	exit 2
      fi
      let p=32-cidr h=2**p-2
      echo "$h hosts" >&2
      txt_mask=""
      zeros=".0.0.0"
      while [ "$cidr" -gt 0 ]
      do
	if [ "$cidr" -gt 8 ]
	then
	  txt_mask="$txt_mask.255"
	  let cidr=cidr-8
	  zeros="${zeros#??}"
	else
	  txt_mask="$txt_mask.${CIDRS[$cidr]}$zeros"
	  cidr=0
	fi
      done
      txt_mask="${txt_mask#?}"
    else
      txt_mask=$1 ; shift
    fi

    p_ip="$txt_ip"
    p_mask="$txt_mask"
    bcast=""
    net=""
    host=""
    o_ip=""
    o_mask=""
    cidr=0
    cidr_set=1

    dot=""

    if expr "$p_ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null
    then
      : So far so good
    else
      echo "Invalid IP address '$txt_ip'" >&2
      return 2
    fi

    if expr "$p_mask" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null
    then
      : So far so good
    else
      echo "Invalid IP mask '$txt_mask'" >&2
      return 2
    fi

    i=1
    while [ $i -lt 5 ]
    do
      ip=${p_ip%%.*}		;p_ip=${p_ip#*.}
      mask=${p_mask%%.*}	;p_mask=${p_mask#*.}

      if [ -z "$ip" -o "$ip" -lt 0 -o "$ip" -gt 255 ] ||
	expr "$ip" : '.*[^0-9]' > /dev/null
      then
	echo "Invalid IP address '$txt_ip'" >&2
	exit 2
      fi

      if [ -z "$mask" -o "$mask" -lt 0 -o "$mask" -gt 255 ] ||
	expr "$mask" : '.*[^0-9]' > /dev/null
      then
	echo "Invalid IP netmask '$txt_mask'" >&2
	exit 2
      fi

      bits=${CIDR#*:$mask-}
      bits=${bits%%:*}
      if [ -z "$bits" -o "$bits" -lt 0 -o "$bits" -gt 8 ] ||
	[ $bits != 0 -a $cidr_set = 0 ]
      then
        echo "Invalid IP netmask '$txt_mask'" >&2
        return 2
      fi

      test $bits != 8 && cidr_set=0
      let cidr=cidr+bits

      o_ip="$o_ip$dot$(($ip & 255 ))"
      o_mask="$o_mask$dot$(($mask & 255 ))"

      bcast="$bcast$dot$(($ip | ( $mask ^ 255 ) ))"
      net="$net$dot$(($ip & $mask ))"
      host="$host$dot$(($ip & ( $mask ^ 255 ) ))"

      dot="."
      let i=i+1
    done

    test "$o_ip" = "$bcast" &&
     echo "WARNING: IP address is Broadcast address" >&2

    test "$o_ip" = "$net" &&
     echo "WARNING: IP address is Network address" >&2

    o1=${o_ip%%.*}
    class=8                             # Class A
    test $o1 -ge 128 && class=16        # Class B
    test $o1 -ge 192 && class=24        # Class C
    test $o1 -ge 224 && class=4         # Class D - The whole Class
    test $o1 -ge 240 && class=x         # Class E - No default Mask - I think
    cidr_net="${net%%.0*}"
    test $class = $cidr || cidr_net="$cidr_net/$cidr"

    echo "$o_ip	$o_mask	$bcast	$net	$host	$cidr	$cidr_net"
done
