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 # A list of supported versions of the IP protocol
23 IP_SUPPORTED_PROTOCOLS
=""
36 # Break if no prefix is provided
37 [[ ${address} =~ \
/ ]] ||
return ${EXIT_OK}
42 ip_detect_protocol
() {
46 # Remove prefix so that we can handle subnet, too
47 address
=$
(ip_split_prefix
${address})
50 for protocol
in ${IP_SUPPORTED_PROTOCOLS}; do
51 if ${protocol}_is_valid
"${address}"; then
60 ip_protocol_is_supported
() {
65 list_match
${proto} ${IP_SUPPORTED_PROTOCOLS}
68 # Returns true if all IP addresses are of the same protocol
73 # Get protocol of the first address
74 local protocol
="$(ip_detect_protocol "${address}")"
76 # Check if all other addresses match the protocol
78 local p
="$(ip_detect_protocol "${address}")"
80 if [ "${p}" != "${protocol}" ]; then
93 for protocol
in ${IP_SUPPORTED_PROTOCOLS}; do
94 if ${protocol}_is_valid
"${address}"; then
107 for protocol
in ${IP_SUPPORTED_PROTOCOLS}; do
108 if ${protocol}_net_is_valid
"${network}"; then
116 ip_prefix_is_valid
() {
124 ipv4_prefix_is_valid
${prefix}
128 ipv6_prefix_is_valid
${prefix}
133 assert ip_protocol_is_supported
${proto}
137 inetcalc
-n "$@" && return ${EXIT_OK} ||
return ${EXIT_ERROR}
140 ip_network_is_subset_of
() {
143 inetcalc
-s "$@" && return ${EXIT_TRUE} ||
return ${EXIT_FALSE}
151 assert device_exists
${device}
153 local prefix
=$
(ip_get_prefix
${address})
154 address
=$
(ip_split_prefix
${address})
159 echo "ADDRESS = $address"
161 # Detect the protocol version
162 local protocol
=$
(ip_detect_protocol
"${address}")
163 assert ip_protocol_is_supported
"${protocol}"
165 case "${protocol}" in
167 assert ipv6_prefix_is_valid
"${prefix}"
170 assert ipv4_prefix_is_valid
"${prefix}"
174 case "${protocol}" in
176 if ipv4_detect_duplicate
${device} ${address}; then
177 error_log
"Duplicate address detected on zone '${device}' (${address})."
178 error_log
"Cannot continue."
184 if ! device_has_ip
${device} ${address}/${prefix}; then
185 assert ip addr add
${address}/${prefix} dev ${device}
187 log DEBUG
"IP address '${address}' (${protocol}) was successfully configured on device '${device}'."
189 case "${protocol}" in
191 # Announce our new address to the neighbours
192 ipv4_update_neighbours
${device} ${address}
196 log DEBUG
"IP address '${address}' (${protocol}) was already configured on device '${device}'."
207 assert device_exists
${device}
209 local prefix
=$
(ip_get_prefix
${address})
210 address
=$
(ip_split_prefix
${address})
214 # Detect the protocol version
215 local protocol
=$
(ip_detect_protocol
"${address}")
216 assert ip_protocol_is_supported
"${protocol}"
218 if device_has_ip
${device} ${address}/${prefix}; then
219 assert ip addr del
${address}/${prefix} dev ${device}
221 log DEBUG
"IP address '${address}' (${protocol}) was successfully removed from device '${device}'."
223 log DEBUG
"IP address '${address}' (${protocol}) was not configured on device '${device}'."
229 # Get all currently assigned addresse for a given network
230 ip_get_assigned_addresses_from_net
() {
235 if ! ip_net_is_valid
${net}; then
236 log ERROR
"IP net ${net} is invalid"
243 # We read the output of $(ip addr show to ${net} ${args})
244 while read -r line
; do
245 # We are only interested in lines which start with inet or inet6
246 [[ "${line}" =~ ^
(inet6 |inet
) ]] ||
continue
248 # We need the second word the line
250 list_append
"addresses" "$(ip_split_prefix "${line[1]}")"
251 done <<< "$(ip addr show to "${net}" ${args})"
253 # We sort the list to get the lowest IP as first item
254 list_sort
${addresses}