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" |
---|
261 | done |
---|