source: trunk/packs/maint/netparams.sh @ 11547

Revision 11547, 6.3 KB checked in by ghudson, 26 years ago (diff)
expr regexps are always anchored on the left. As such, POSIX does not uniquely define the behavior of a regexp starting with a caret. So nuke the carets I had at the beginnings of regexps.
Line 
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.
37ipreg='[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$'
38
39# Usage message
40usage="$0 [-f file] [-d defaultbits] [-e] address ..."
41
42# octet <ip address> sets o1..o4 to the octets of the address.
43octets() {
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.
54octetbits() {
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>.
93mask8() {
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.
108fill8() {
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).
125mask() {
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.
144fill() {
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.
161getnetmask() {
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.
192defaultbits=24
193errornf=false
194maskfile=""
195while 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
211done
212shift `expr $OPTIND - 1`
213
214# Make sure we have some addresses.
215if [ $# -eq 0 ]; then
216        echo "Usage: $0 ip-address ..." 1>&2
217        exit 1
218fi
219
220# Make sure our addresses are in something like the proper format.
221for 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
227done
228
229for 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"
261done
Note: See TracBrowser for help on using the repository browser.