2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
22 IP_SUPPORTED_PROTOCOLS
="${IP_SUPPORTED_PROTOCOLS} ipv4"
24 function ipv4_is_valid
() {
25 ipcalc
--ipv4 -c $@
>/dev
/null
2>&1
37 function ipv4_prefix_is_valid
() {
40 isset prefix ||
return ${EXIT_FALSE}
42 [ ${prefix} -le 0 ] && return ${EXIT_FALSE}
43 [ ${prefix} -gt 32 ] && return ${EXIT_FALSE}
48 function ipv4_detect_duplicate
() {
54 assert device_exists
${device}
56 # Don't check on PPP devices.
57 device_is_ppp
${device} && return ${EXIT_ERROR}
59 if ! arping
-q -c 2 -w 3 -D -I ${device} ${address}; then
60 log DEBUG
"Detected duplicate address '${address}' on device '${device}'."
67 function ipv4_update_neighbours
() {
71 # Don't do anything on PPP devices.
72 device_is_ppp
${device} && return ${EXIT_OK}
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
&
78 function ipv4_get_netaddress
() {
82 local prefix
=$
(ip_get_prefix
${address})
83 isset prefix || prefix
="32"
85 # Assume host-only address if no prefix has been given.
86 if [ "${prefix}" = "32" ]; then
87 echo "${address}/${prefix}"
92 eval $
(ipcalc
--network ${address})
95 echo "${NETWORK}/${prefix}"
99 function ipv4_get_prefix
() {
104 assert isset broadcast
107 eval $
(ipcalc
--prefix ${address} ${broadcast})
114 function ipv4_get_netmask
() {
118 # Add prefix if none given.
119 local prefix
=$
(ip_get_prefix
${address})
120 isset prefix || address
="${address}/32"
123 eval $
(ipcalc
--netmask ${address})
130 function ipv4_flush_device
() {
132 # Flushes all routes, addresses from the device
133 # and clears the ARP cache.
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
146 function ipv4_prefix2netmask
() {
150 assert isinteger prefix
152 # XXX this function is a stub
159 assert false NOT IMPLEMENTED
164 function ipv4_get_network
() {
165 local network
=$
(ipv4_get_network $@
)
167 ipv4_decode
${network}
170 function ipv4_get_network_encoded
() {
173 local prefix
=$
(ip_get_prefix
${net})
174 isset prefix || prefix
=32
177 if [ ${prefix} -ne 0 ]; then
178 mask
=$
(( -1 << $
(( 32 - ${prefix} )) ))
181 local addr
=$
(ip_split_prefix
${net})
182 addr
=$
(ipv4_encode
${addr})
184 print
"%d" $
(( ${addr} & ${mask} ))
187 function ipv4_get_broadcast
() {
188 local broadcast
=$
(ipv4_get_broadcast_encoded $@
)
190 ipv4_decode
${broadcast}
193 function ipv4_get_broadcast_encoded
() {
196 local prefix
=$
(ip_get_prefix
${net})
199 prefix
=$
(( 32 - ${prefix} ))
203 if [ ${prefix} -eq 32 ]; then
206 netmask
=$
(( -1 << ${prefix} ))
207 broadcast
=$
(( $
(( 1 << ${prefix} )) - 1))
210 local addr
=$
(ip_split_prefix
${net})
211 addr
=$
(ipv4_encode
${addr})
213 print
"%d" $
(( $
(( ${addr} & ${netmask} )) | ${broadcast} ))
216 function ipv4_encode
() {
221 for field
in ${addr//./ }; do
222 int
=$
(( $
(( ${int} << 8 )) | ${field} ))
228 function ipv4_decode() {
231 local addr=$(( ${int} & 255 ))
235 int=$(( ${int} >> 8 ))
236 addr
="$(( ${int} & 255 )).${addr}"
242 function ipv4_addr_eq
() {
249 [[ "${addr1}" = "${addr2}" ]] \
250 && return ${EXIT_TRUE} ||
return ${EXIT_FALSE}
253 function ipv4_addr_gt
() {
261 for addr
in addr1 addr2
; do
262 printf -v ${addr} "%s" "$(ip_encode ${!addr})"
265 [[ ${addr1} -gt ${addr2} ]] \
266 && return ${EXIT_TRUE} ||
return ${EXIT_FALSE}
269 function ipv4_range
() {
275 _ipv4_range
"$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
278 function _ipv4_range
() {
282 if [ ${first} -gt ${last} ]; then
283 local range
="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
285 error
"Invalid IPv4 address range: ${range}"
289 last
=$
(( ${last} + 1 ))
293 while [ ${last} -gt ${first} ]; do
299 while [ $
(( ${first} % ${y} )) -eq 0 ] && [ ${last} -gt $(( ${first} + ${y} )) ]; do
306 print
"$(ipv4_decode ${first})${prefix}"
307 first
=$
(( ${first} + ${z} ))
311 function ipv4_range_explicit
() {
322 first
=$
(ipv4_get_network
${range})
323 last
=$
(ipv4_get_broadcast
${range})
327 _ipv4_range_explicit
"$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
330 function _ipv4_range_explicit
() {
334 if [ ${first} -gt ${last} ]; then
335 local range
="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
337 error
"Invalid IPv4 address range: ${range}"
341 while [ ${first} -le ${last} ]; do
343 first
=$
(( ${first} + 1 ))
347 function ipv4_in_subnet
() {
354 local subnet_first
=$
(ipv4_get_network_encoded
${subnet})
355 local subnet_last
=$
(ipv4_get_broadcast_encoded
${subnet})
357 addr
=$
(ipv4_encode
${addr})
359 if [[ "${addr}" -ge "${subnet_first}" ]] && [[ "${addr}" -le "${subnet_last}" ]]; then