[25023] | 1 | #!/bin/sh |
---|
| 2 | # $Id: netparams.sh,v 1.2 1998/05/17 03:25:03 ghudson Exp $ |
---|
| 3 | |
---|
| 4 | # Usage: netparams [-d defaultbits] [-e] [-f file] address ... |
---|
| 5 | # |
---|
| 6 | # Computes the netmask for each address and outputs the netmask, |
---|
| 7 | # network, broadcast address, and gateway address. Options are: |
---|
| 8 | # |
---|
| 9 | # -d defaultbits Give the default number of bits to use if an |
---|
| 10 | # IP address is not located on the file. The |
---|
| 11 | # default is 24. |
---|
| 12 | # |
---|
| 13 | # -e Error if an IP address is not located in the |
---|
| 14 | # file. |
---|
| 15 | # |
---|
| 16 | # -f file Give the masks filename to use. The default |
---|
| 17 | # is the concatenation of /etc/athena/masks.local |
---|
| 18 | # (if it exists) and /etc/athena/masks. |
---|
| 19 | # |
---|
| 20 | # The format of each line of the masks file is: |
---|
| 21 | # |
---|
| 22 | # address significant-bits mask-bits [gateway] |
---|
| 23 | # |
---|
| 24 | # The first <significant-bits> of <address> are compared against the |
---|
| 25 | # given IP address. If they match, <mask-bits> is the number of bits |
---|
| 26 | # in the netmask, and <gateway> is the gateway address if given. (If |
---|
| 27 | # gateway is not given, it is assumed to be one greater than the |
---|
| 28 | # network address.) The first match in the file is taken. Blank lines |
---|
| 29 | # and lines beginning with a '#' are ignored. |
---|
| 30 | |
---|
| 31 | # This script may want to run before /usr is mounted on BSD-ish |
---|
| 32 | # systems, so it uses a very limited set of external commands (expr, |
---|
| 33 | # test, echo). If you want to use a command not in that set, make |
---|
| 34 | # sure it lives in /bin or /sbin in BSD 4.4. |
---|
| 35 | |
---|
| 36 | # Regular expression to match things that looklike IP addresss. |
---|
| 37 | ipreg='[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' |
---|
| 38 | |
---|
| 39 | # Usage message |
---|
| 40 | usage="$0 [-f file] [-d defaultbits] [-e] address ..." |
---|
| 41 | |
---|
| 42 | # octet <ip address> sets o1..o4 to the octets of the address. |
---|
| 43 | octets() { |
---|
| 44 | OLDIFS="$IFS" |
---|
| 45 | IFS=. |
---|
| 46 | set -- $1 |
---|
| 47 | o1=$1 o2=$2 o3=$3 o4=$4 |
---|
| 48 | IFS="$OLDIFS" |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | # octetbits <n> splits <n> up into four values b1..b4 each between 0 |
---|
| 52 | # and 8. If you want the first n bits of a 32-bit value, then you |
---|
| 53 | # want the first b1..b4 bits of the corresponding octets. |
---|
| 54 | octetbits() { |
---|
| 55 | case "$1" in |
---|
| 56 | 0) b1=0; b2=0; b3=0; b4=0 ;; |
---|
| 57 | 1) b1=1; b2=0; b3=0; b4=0 ;; |
---|
| 58 | 2) b1=2; b2=0; b3=0; b4=0 ;; |
---|
| 59 | 3) b1=3; b2=0; b3=0; b4=0 ;; |
---|
| 60 | 4) b1=4; b2=0; b3=0; b4=0 ;; |
---|
| 61 | 5) b1=5; b2=0; b3=0; b4=0 ;; |
---|
| 62 | 6) b1=6; b2=0; b3=0; b4=0 ;; |
---|
| 63 | 7) b1=7; b2=0; b3=0; b4=0 ;; |
---|
| 64 | 8) b1=8; b2=0; b3=0; b4=0 ;; |
---|
| 65 | 9) b1=8; b2=1; b3=0; b4=0 ;; |
---|
| 66 | 10) b1=8; b2=2; b3=0; b4=0 ;; |
---|
| 67 | 11) b1=8; b2=3; b3=0; b4=0 ;; |
---|
| 68 | 12) b1=8; b2=4; b3=0; b4=0 ;; |
---|
| 69 | 13) b1=8; b2=5; b3=0; b4=0 ;; |
---|
| 70 | 14) b1=8; b2=6; b3=0; b4=0 ;; |
---|
| 71 | 15) b1=8; b2=7; b3=0; b4=0 ;; |
---|
| 72 | 16) b1=8; b2=8; b3=0; b4=0 ;; |
---|
| 73 | 17) b1=8; b2=8; b3=1; b4=0 ;; |
---|
| 74 | 18) b1=8; b2=8; b3=2; b4=0 ;; |
---|
| 75 | 19) b1=8; b2=8; b3=3; b4=0 ;; |
---|
| 76 | 20) b1=8; b2=8; b3=4; b4=0 ;; |
---|
| 77 | 21) b1=8; b2=8; b3=5; b4=0 ;; |
---|
| 78 | 22) b1=8; b2=8; b3=6; b4=0 ;; |
---|
| 79 | 23) b1=8; b2=8; b3=7; b4=0 ;; |
---|
| 80 | 24) b1=8; b2=8; b3=8; b4=0 ;; |
---|
| 81 | 25) b1=8; b2=8; b3=8; b4=1 ;; |
---|
| 82 | 26) b1=8; b2=8; b3=8; b4=2 ;; |
---|
| 83 | 27) b1=8; b2=8; b3=8; b4=3 ;; |
---|
| 84 | 28) b1=8; b2=8; b3=8; b4=4 ;; |
---|
| 85 | 29) b1=8; b2=8; b3=8; b4=5 ;; |
---|
| 86 | 30) b1=8; b2=8; b3=8; b4=6 ;; |
---|
| 87 | 31) b1=8; b2=8; b3=8; b4=7 ;; |
---|
| 88 | 32) b1=8; b2=8; b3=8; b4=8 ;; |
---|
| 89 | esac |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | # mask8 <o> <b> sets a8 to the first <b> bits of <o>. |
---|
| 93 | mask8() { |
---|
| 94 | case "$2" in |
---|
| 95 | 0) a8=0 ;; |
---|
| 96 | 1) a8=`expr "$1" - "$1" % 128` ;; |
---|
| 97 | 2) a8=`expr "$1" - "$1" % 64` ;; |
---|
| 98 | 3) a8=`expr "$1" - "$1" % 32` ;; |
---|
| 99 | 4) a8=`expr "$1" - "$1" % 16` ;; |
---|
| 100 | 5) a8=`expr "$1" - "$1" % 8` ;; |
---|
| 101 | 6) a8=`expr "$1" - "$1" % 4` ;; |
---|
| 102 | 7) a8=`expr "$1" - "$1" % 2` ;; |
---|
| 103 | 8) a8=$1 ;; |
---|
| 104 | esac |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | # fill8 <o> <b> sets a8 to <o> with the last 8-<b> bits set to 1. |
---|
| 108 | fill8() { |
---|
| 109 | case "$2" in |
---|
| 110 | 0) a8=255 ;; |
---|
| 111 | 1) a8=`expr "$1" - "$1" % 128 + 127` ;; |
---|
| 112 | 2) a8=`expr "$1" - "$1" % 64 + 63` ;; |
---|
| 113 | 3) a8=`expr "$1" - "$1" % 32 + 31` ;; |
---|
| 114 | 4) a8=`expr "$1" - "$1" % 16 + 15` ;; |
---|
| 115 | 5) a8=`expr "$1" - "$1" % 8 + 7` ;; |
---|
| 116 | 6) a8=`expr "$1" - "$1" % 4 + 3` ;; |
---|
| 117 | 7) a8=`expr "$1" - "$1" % 2 + 1` ;; |
---|
| 118 | 8) a8=$1 ;; |
---|
| 119 | esac |
---|
| 120 | } |
---|
| 121 | |
---|
| 122 | # mask <ip address> <n> sets a to the first <n> bits of <ip address>. |
---|
| 123 | # If a third parameter is given, add 1 to the last octet (to get the |
---|
| 124 | # gateway address). |
---|
| 125 | mask() { |
---|
| 126 | a="" |
---|
| 127 | octets "$1" |
---|
| 128 | octetbits "$2" |
---|
| 129 | mask8 "$o1" "$b1" |
---|
| 130 | a=$a8 |
---|
| 131 | mask8 "$o2" "$b2" |
---|
| 132 | a=$a.$a8 |
---|
| 133 | mask8 "$o3" "$b3" |
---|
| 134 | a=$a.$a8 |
---|
| 135 | mask8 "$o4" "$b4" |
---|
| 136 | if [ -n "$3" ]; then |
---|
| 137 | a8=`expr "$a8" + 1` |
---|
| 138 | fi |
---|
| 139 | a=$a.$a8 |
---|
| 140 | } |
---|
| 141 | |
---|
| 142 | # fill <ip address> <n> sets a to <ip address> with the last 32-<n> bits |
---|
| 143 | # set to 1. |
---|
| 144 | fill() { |
---|
| 145 | a="" |
---|
| 146 | octets "$1" |
---|
| 147 | octetbits "$2" |
---|
| 148 | fill8 "$o1" "$b1" |
---|
| 149 | a=$a8 |
---|
| 150 | fill8 "$o2" "$b2" |
---|
| 151 | a=$a.$a8 |
---|
| 152 | fill8 "$o3" "$b3" |
---|
| 153 | a=$a.$a8 |
---|
| 154 | fill8 "$o4" "$b4" |
---|
| 155 | a=$a.$a8 |
---|
| 156 | } |
---|
| 157 | |
---|
| 158 | # getnetmask <ip address> <file> sets maskbits to the number of netmask |
---|
| 159 | # bits for <ip address> according to <file>. Also sets gateway to the |
---|
| 160 | # gateway field on the matching line, if one was specified. |
---|
| 161 | getnetmask() { |
---|
| 162 | exec < $2 |
---|
| 163 | maskbits="" |
---|
| 164 | while read addr sigbits mbits gw; do |
---|
| 165 | # Ignore blank lines and comments. |
---|
| 166 | if [ -z "$addr" -o `expr "$addr" : '#'` -ne 0 ]; then |
---|
| 167 | continue |
---|
| 168 | fi |
---|
| 169 | |
---|
| 170 | # Make sure the line is in the proper form. |
---|
| 171 | if [ `expr "$addr" : "$ipreg"` -eq 0 \ |
---|
| 172 | -o `expr "$sigbits" : '[0-9][0-9]*$'` -eq 0 \ |
---|
| 173 | -o `expr "$mbits" : '[0-9][0-9]*$'` -eq 0 ]; then |
---|
| 174 | echo "Bad line in $2: $addr $sigbits $mbits $gw" 1>&2 |
---|
| 175 | exit 1 |
---|
| 176 | fi |
---|
| 177 | if [ -n "$gw" -a `expr "$gw" : "$ipreg"` -eq 0 ]; then |
---|
| 178 | echo "Bad gateway in $2: $gw" 1>&2 |
---|
| 179 | exit 1 |
---|
| 180 | fi |
---|
| 181 | |
---|
| 182 | mask "$1" "$sigbits" |
---|
| 183 | if [ "$a" = "$addr" ]; then |
---|
| 184 | maskbits=$mbits |
---|
| 185 | gateway=$gw |
---|
| 186 | break |
---|
| 187 | fi |
---|
| 188 | done |
---|
| 189 | } |
---|
| 190 | |
---|
| 191 | # Process arguments. |
---|
| 192 | defaultbits=24 |
---|
| 193 | errornf=false |
---|
| 194 | maskfile="" |
---|
| 195 | while getopts d:ef: opt; do |
---|
| 196 | case "$opt" in |
---|
| 197 | d) |
---|
| 198 | defaultbits=$OPTARG |
---|
| 199 | ;; |
---|
| 200 | e) |
---|
| 201 | errornf=true |
---|
| 202 | ;; |
---|
| 203 | f) |
---|
| 204 | maskfile=$OPTARG |
---|
| 205 | ;; |
---|
| 206 | \?) |
---|
| 207 | echo "$usage" |
---|
| 208 | exit 1 |
---|
| 209 | ;; |
---|
| 210 | esac |
---|
| 211 | done |
---|
| 212 | shift `expr $OPTIND - 1` |
---|
| 213 | |
---|
| 214 | # Make sure we have some addresses. |
---|
| 215 | if [ $# -eq 0 ]; then |
---|
| 216 | echo "Usage: $0 ip-address ..." 1>&2 |
---|
| 217 | exit 1 |
---|
| 218 | fi |
---|
| 219 | |
---|
| 220 | # Make sure our addresses are in something like the proper format. |
---|
| 221 | for ip in "$@"; do |
---|
| 222 | if [ `expr "$ip" : "$ipreg"` -eq 0 ]; then |
---|
| 223 | echo "Bad address: $ip" 1>&2 |
---|
| 224 | echo "Usage: $0 ip-address ..." 1>&2 |
---|
| 225 | exit 1 |
---|
| 226 | fi |
---|
| 227 | done |
---|
| 228 | |
---|
| 229 | for ip in "$@"; do |
---|
| 230 | if [ -n "$maskfile" ]; then |
---|
| 231 | getnetmask "$ip" "$maskfile" |
---|
| 232 | elif [ -f /etc/athena/masks.local ]; then |
---|
| 233 | getnetmask "$ip" /etc/athena/masks.local |
---|
| 234 | if [ -z "$maskbits" ]; then |
---|
| 235 | getnetmask "$ip" /etc/athena/masks |
---|
| 236 | fi |
---|
| 237 | else |
---|
| 238 | getnetmask "$ip" /etc/athena/masks |
---|
| 239 | fi |
---|
| 240 | if [ -z "$maskbits" ]; then |
---|
| 241 | # Error out if we were told to, or guess. |
---|
| 242 | if [ "$errornf" = true ]; then |
---|
| 243 | echo "$ip not matched." 1>&2 |
---|
| 244 | exit 1 |
---|
| 245 | fi |
---|
| 246 | maskbits=$defaultbits |
---|
| 247 | fi |
---|
| 248 | |
---|
| 249 | mask 255.255.255.255 "$maskbits" |
---|
| 250 | netmask=$a |
---|
| 251 | mask "$ip" "$maskbits" |
---|
| 252 | network=$a |
---|
| 253 | fill "$ip" "$maskbits" |
---|
| 254 | broadcast=$a |
---|
| 255 | if [ -z "$gateway" ]; then |
---|
| 256 | mask "$ip" "$maskbits" 1 |
---|
| 257 | gateway=$a |
---|
| 258 | fi |
---|
| 259 | |
---|
| 260 | echo "$netmask $network $broadcast $gateway $maskbits" |
---|
| 261 | done |
---|