]> git.ipfire.org Git - people/stevee/network.git/blame - src/functions/functions.ipv4
Rectify config creation
[people/stevee/network.git] / src / functions / functions.ipv4
CommitLineData
05c234a8
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
e617226b
MT
22IP_SUPPORTED_PROTOCOLS="${IP_SUPPORTED_PROTOCOLS} ipv4"
23
05c234a8 24function ipv4_is_valid() {
fa6df98c 25 ipcalc --ipv4 -c $@ >/dev/null 2>&1
05c234a8 26
fa6df98c
MT
27 case "$?" in
28 0)
29 return ${EXIT_OK}
30 ;;
31 *)
38f61548 32 return ${EXIT_ERROR}
fa6df98c
MT
33 ;;
34 esac
05c234a8
MT
35}
36
cb965348
MT
37function ipv4_prefix_is_valid() {
38 local prefix=${1}
ab70371d
MT
39
40 isset prefix || return ${EXIT_FALSE}
cb965348
MT
41
42 [ ${prefix} -le 0 ] && return ${EXIT_FALSE}
43 [ ${prefix} -gt 32 ] && return ${EXIT_FALSE}
44
45 return ${EXIT_TRUE}
46}
47
05c234a8
MT
48function ipv4_detect_duplicate() {
49 local device=${1}
50 local address=${2}
51
52 assert isset address
53 assert isset device
54 assert device_exists ${device}
55
785afa13
MT
56 # Don't check on PPP devices.
57 device_is_ppp ${device} && return ${EXIT_ERROR}
58
05c234a8
MT
59 if ! arping -q -c 2 -w 3 -D -I ${device} ${address}; then
60 log DEBUG "Detected duplicate address '${address}' on device '${device}'."
9eebfc55 61 return ${EXIT_OK}
05c234a8
MT
62 fi
63
9eebfc55 64 return ${EXIT_ERROR}
05c234a8
MT
65}
66
67function ipv4_update_neighbours() {
68 local device=${1}
69 local address=${2}
70
785afa13
MT
71 # Don't do anything on PPP devices.
72 device_is_ppp ${device} && return ${EXIT_OK}
73
05c234a8
MT
74 arping -q -A -c 1 -I ${device} ${address}
75 ( sleep 2; arping -q -U -c 1 -I ${device} ${address} ) >/dev/null 2>&1 </dev/null &
76}
d5bace8d
MT
77
78function ipv4_get_netaddress() {
79 local address=${1}
80 assert isset address
81
82 local prefix=$(ip_get_prefix ${address})
1dbb6df4
MT
83 isset prefix || prefix="32"
84
85 # Assume host-only address if no prefix has been given.
86 if [ "${prefix}" = "32" ]; then
87 echo "${address}/${prefix}"
88 return ${EXIT_OK}
89 fi
d5bace8d
MT
90
91 local NETWORK
92 eval $(ipcalc --network ${address})
93 assert isset NETWORK
94
95 echo "${NETWORK}/${prefix}"
d5bace8d
MT
96 return ${EXIT_OK}
97}
e9ea243e
MT
98
99function ipv4_get_prefix() {
100 local address=${1}
101 local broadcast=${2}
102
103 assert isset address
104 assert isset broadcast
105
106 local PREFIX
107 eval $(ipcalc --prefix ${address} ${broadcast})
108 assert isset PREFIX
109
110 echo "${PREFIX}"
111 return ${EXIT_OK}
112}
113
ab70371d
MT
114function ipv4_get_netmask() {
115 local address=${1}
116 assert isset address
117
118 # Add prefix if none given.
119 local prefix=$(ip_get_prefix ${address})
120 isset prefix || address="${address}/32"
121
122 local NETMASK
123 eval $(ipcalc --netmask ${address})
124 assert isset NETMASK
125
126 print "${NETMASK}"
127 return ${EXIT_OK}
128}
129
e9ea243e
MT
130function ipv4_flush_device() {
131 #
132 # Flushes all routes, addresses from the device
133 # and clears the ARP cache.
134 #
135
136 local device=${1}
137 assert isset device
138
139 ip -4 addr flush dev ${device} >/dev/null 2>&1
140 ip -4 route flush dev ${device} >/dev/null 2>&1
141 ip -4 neigh flush dev ${device} >/dev/null 2>&1
142
143 return 0
c7b93f70 144}
6f49dbac 145
785afa13
MT
146function ipv4_prefix2netmask() {
147 local prefix=${1}
148 shift
149
150 assert isinteger prefix
151
152 # XXX this function is a stub
153
154 case "${prefix}" in
155 24)
156 echo "255.255.255.0"
157 ;;
158 *)
159 assert false NOT IMPLEMENTED
160 ;;
161 esac
e9ea243e 162}
999d659b
MT
163
164function ipv4_get_network() {
ab70371d
MT
165 local network=$(ipv4_get_network $@)
166
167 ipv4_decode ${network}
168}
169
170function ipv4_get_network_encoded() {
999d659b
MT
171 local net=${1}
172
173 local prefix=$(ip_get_prefix ${net})
174 isset prefix || prefix=32
175
176 local mask=0
177 if [ ${prefix} -ne 0 ]; then
178 mask=$(( -1 << $(( 32 - ${prefix} )) ))
179 fi
180
181 local addr=$(ip_split_prefix ${net})
182 addr=$(ipv4_encode ${addr})
183
ab70371d 184 print "%d" $(( ${addr} & ${mask} ))
999d659b
MT
185}
186
187function ipv4_get_broadcast() {
ab70371d
MT
188 local broadcast=$(ipv4_get_broadcast_encoded $@)
189
190 ipv4_decode ${broadcast}
191}
192
193function ipv4_get_broadcast_encoded() {
999d659b
MT
194 local net=${1}
195
196 local prefix=$(ip_get_prefix ${net})
197 assert isset prefix
198
199 prefix=$(( 32 - ${prefix} ))
200
201 local netmask=0
202 local broadcast=-1
203 if [ ${prefix} -eq 32 ]; then
204 :
205 else
206 netmask=$(( -1 << ${prefix} ))
207 broadcast=$(( $(( 1 << ${prefix} )) - 1))
208 fi
209
210 local addr=$(ip_split_prefix ${net})
211 addr=$(ipv4_encode ${addr})
212
ab70371d 213 print "%d" $(( $(( ${addr} & ${netmask} )) | ${broadcast} ))
999d659b
MT
214}
215
216function ipv4_encode() {
217 local addr=${1}
218 local int=0
219
220 local field
221 for field in ${addr//./ }; do
222 int=$(( $(( ${int} << 8 )) | ${field} ))
223 done
224
225 print "${int}"
226}
227
228function ipv4_decode() {
229 local int=${1}
230
231 local addr=$(( ${int} & 255 ))
232
233 local i
234 for i in 1 2 3; do
235 int=$(( ${int} >> 8 ))
236 addr="$(( ${int} & 255 )).${addr}"
237 done
238
239 print "${addr}"
240}
241
ab70371d
MT
242function ipv4_addr_eq() {
243 local addr1=${1}
244 assert isset addr1
245
246 local addr2=${2}
247 assert isset addr2
248
249 [[ "${addr1}" = "${addr2}" ]] \
250 && return ${EXIT_TRUE} || return ${EXIT_FALSE}
251}
252
253function ipv4_addr_gt() {
254 local addr1=${1}
255 assert isset addr1
256
257 local addr2=${2}
258 assert isset addr2
259
260 local addr
261 for addr in addr1 addr2; do
262 printf -v ${addr} "%s" "$(ip_encode ${!addr})"
263 done
264
265 [[ ${addr1} -gt ${addr2} ]] \
266 && return ${EXIT_TRUE} || return ${EXIT_FALSE}
267}
268
999d659b
MT
269function ipv4_range() {
270 local range=${1}
271
272 local first=${1%-*}
273 local last=${1#*-}
274
275 _ipv4_range "$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
276}
277
278function _ipv4_range() {
279 local first=${1}
280 local last=${2}
281
282 if [ ${first} -gt ${last} ]; then
283 local range="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
284
285 error "Invalid IPv4 address range: ${range}"
286 return ${EXIT_ERROR}
287 fi
288
289 last=$(( ${last} + 1 ))
290
291 local prefix
292 local x y z
293 while [ ${last} -gt ${first} ]; do
294 prefix=
295 x=31
296 y=2
297 z=1
298
299 while [ $(( ${first} % ${y} )) -eq 0 ] && [ ${last} -gt $(( ${first} + ${y} )) ]; do
300 prefix="/${x}"
301 x=$(( ${x} - 1 ))
302 z=${y}
303 y=$(( ${y} * 2 ))
304 done
305
306 print "$(ipv4_decode ${first})${prefix}"
307 first=$(( ${first} + ${z} ))
308 done
309}
310
311function ipv4_range_explicit() {
312 local range=${1}
313
314 local first last
315
316 case "${range}" in
317 *.*.*.*-*.*.*.*)
318 first=${range%-*}
319 last=${range#*-}
320 ;;
321 *.*.*.*/*)
322 first=$(ipv4_get_network ${range})
323 last=$(ipv4_get_broadcast ${range})
324 ;;
325 esac
326
327 _ipv4_range_explicit "$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
328}
329
330function _ipv4_range_explicit() {
331 local first=${1}
332 local last=${2}
333
334 if [ ${first} -gt ${last} ]; then
335 local range="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
336
337 error "Invalid IPv4 address range: ${range}"
338 return ${EXIT_ERROR}
339 fi
340
341 while [ ${first} -le ${last} ]; do
342 ipv4_decode ${first}
343 first=$(( ${first} + 1 ))
344 done
345}
ab70371d
MT
346
347function ipv4_in_subnet() {
348 local addr=${1}
349 assert isset addr
350
351 local subnet=${2}
352 assert isset subnet
353
354 local subnet_first=$(ipv4_get_network_encoded ${subnet})
355 local subnet_last=$(ipv4_get_broadcast_encoded ${subnet})
356
357 addr=$(ipv4_encode ${addr})
358
359 if [[ "${addr}" -ge "${subnet_first}" ]] && [[ "${addr}" -le "${subnet_last}" ]]; then
360 return ${EXIT_TRUE}
361 fi
362
363 return ${EXIT_FALSE}
364}
ef953be2
MT
365
366function ipv4_ttl_valid() {
367 local ttl="${1}"
368
369 isinteger ttl || return ${EXIT_FALSE}
370
371 # Must be between 10 and 255.
372 [ "${ttl}" -lt 10 ] && return ${EXIT_FALSE}
373 [ "${ttl}" -gt 255 ] && return ${EXIT_FALSE}
374
375 return ${EXIT_TRUE}
376}