]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.ip
device: Refactor check for device type
[people/ms/network.git] / src / functions / functions.ip
CommitLineData
2b5c311d
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
22# A list of supported versions of the IP protocol
23IP_SUPPORTED_PROTOCOLS=""
24
1c6a4e30 25ip_split_prefix() {
2b5c311d 26 local address=${1}
2b5c311d
MT
27 assert isset address
28
29 echo "${address%%/*}"
30}
31
1c6a4e30 32ip_get_prefix() {
2b5c311d 33 local address=${1}
2b5c311d
MT
34 assert isset address
35
38f61548
MT
36 # Break if no prefix is provided
37 [[ ${address} =~ \/ ]] || return ${EXIT_OK}
38
2b5c311d
MT
39 echo "${address##*/}"
40}
41
1c6a4e30 42ip_detect_protocol() {
13a6e69f 43 local address="${1}"
2b5c311d
MT
44 assert isset address
45
0af2168d
JS
46 # Remove prefix so that we can handle subnet, too
47 address=$(ip_split_prefix ${address})
48
2b5c311d 49 local protocol
e617226b 50 for protocol in ${IP_SUPPORTED_PROTOCOLS}; do
13a6e69f 51 if ${protocol}_is_valid "${address}"; then
2b5c311d
MT
52 echo "${protocol}"
53 return ${EXIT_OK}
54 fi
55 done
56
57 return ${EXIT_ERROR}
58}
e617226b 59
1c6a4e30 60ip_protocol_is_supported() {
e617226b
MT
61 local proto=${1}
62
63 assert isset proto
64
8c9205b1 65 list_match ${proto} ${IP_SUPPORTED_PROTOCOLS}
e617226b 66}
38f61548 67
2a588cab
MT
68# Returns true if all IP addresses are of the same protocol
69ip_protocol_match() {
70 local address="${1}"
71 shift
72
73 # Get protocol of the first address
74 local protocol="$(ip_detect_protocol "${address}")"
75
76 # Check if all other addresses match the protocol
77 for address in $@; do
78 local p="$(ip_detect_protocol "${address}")"
79
80 if [ "${p}" != "${protocol}" ]; then
81 return ${EXIT_FALSE}
82 fi
83 done
84
85 return ${EXIT_TRUE}
86}
87
1c6a4e30 88ip_is_valid() {
afb7d704
MT
89 local address=${1}
90 assert isset address
91
b2cb6736
JS
92 local protocol
93 for protocol in ${IP_SUPPORTED_PROTOCOLS}; do
94 if ${protocol}_is_valid "${address}"; then
95 return ${EXIT_TRUE}
96 fi
97 done
98
99 return ${EXIT_FALSE}
afb7d704
MT
100}
101
8b0958b2 102ip_net_is_valid() {
cb965348
MT
103 local network=${1}
104 assert isset network
105
d2bd71e4
JS
106 local protocol
107 for protocol in ${IP_SUPPORTED_PROTOCOLS}; do
108 if ${protocol}_net_is_valid "${network}"; then
109 return ${EXIT_TRUE}
110 fi
111 done
cb965348 112
d2bd71e4 113 return ${EXIT_FALSE}
cb965348
MT
114}
115
1c6a4e30 116ip_prefix_is_valid() {
cb965348
MT
117 local proto=${1}
118 assert isset proto
119
120 local prefix=${2}
121
122 case "${proto}" in
123 ipv4)
124 ipv4_prefix_is_valid ${prefix}
125 return $?
126 ;;
127 ipv6)
128 ipv6_prefix_is_valid ${prefix}
129 return $?
130 ;;
131 esac
132
133 assert ip_protocol_is_supported ${proto}
134}
135
13a6e69f 136ip_get_network() {
2212045f 137 inetcalc -n "$@" && return ${EXIT_OK} || return ${EXIT_ERROR}
13a6e69f
MT
138}
139
4a7c3c02
MT
140ip_network_is_subset_of() {
141 assert [ $# -eq 2 ]
142
2212045f 143 inetcalc -s "$@" && return ${EXIT_TRUE} || return ${EXIT_FALSE}
4a7c3c02
MT
144}
145
1c6a4e30 146ip_address_add() {
38f61548
MT
147 local device=${1}
148 local address=${2}
149
150 assert isset address
151 assert device_exists ${device}
152
153 local prefix=$(ip_get_prefix ${address})
154 address=$(ip_split_prefix ${address})
155
156 assert isset prefix
13a6e69f
MT
157 assert isset address
158
159 echo "ADDRESS = $address"
38f61548
MT
160
161 # Detect the protocol version
13a6e69f
MT
162 local protocol=$(ip_detect_protocol "${address}")
163 assert ip_protocol_is_supported "${protocol}"
164
165 case "${protocol}" in
166 ipv6)
167 assert ipv6_prefix_is_valid "${prefix}"
168 ;;
169 ipv4)
170 assert ipv4_prefix_is_valid "${prefix}"
171 ;;
172 esac
38f61548
MT
173
174 case "${protocol}" in
175 ipv4)
176 if ipv4_detect_duplicate ${device} ${address}; then
177 error_log "Duplicate address detected on zone '${device}' (${address})."
178 error_log "Cannot continue."
179 return ${EXIT_ERROR}
180 fi
181 ;;
182 esac
183
184 if ! device_has_ip ${device} ${address}/${prefix}; then
185 assert ip addr add ${address}/${prefix} dev ${device}
186
187 log DEBUG "IP address '${address}' (${protocol}) was successfully configured on device '${device}'."
188
189 case "${protocol}" in
190 ipv4)
191 # Announce our new address to the neighbours
192 ipv4_update_neighbours ${device} ${address}
193 ;;
194 esac
195 else
196 log DEBUG "IP address '${address}' (${protocol}) was already configured on device '${device}'."
197 fi
198
199 return ${EXIT_OK}
200}
201
1c6a4e30 202ip_address_del() {
38f61548
MT
203 local device=${1}
204 local address=${2}
205
206 assert isset address
207 assert device_exists ${device}
208
209 local prefix=$(ip_get_prefix ${address})
210 address=$(ip_split_prefix ${address})
211
212 assert isset prefix
213
214 # Detect the protocol version
13a6e69f
MT
215 local protocol=$(ip_detect_protocol "${address}")
216 assert ip_protocol_is_supported "${protocol}"
38f61548
MT
217
218 if device_has_ip ${device} ${address}/${prefix}; then
219 assert ip addr del ${address}/${prefix} dev ${device}
220
221 log DEBUG "IP address '${address}' (${protocol}) was successfully removed from device '${device}'."
222 else
223 log DEBUG "IP address '${address}' (${protocol}) was not configured on device '${device}'."
224 fi
225
226 return ${EXIT_OK}
227}
1ad09828
JS
228
229# Get all currently assigned addresse for a given network
230ip_get_assigned_addresses_from_net() {
231 local net=${1}
232 shift
233 local args="$@"
234
235 if ! ip_net_is_valid ${net}; then
236 log ERROR "IP net ${net} is invalid"
237 return ${EXIT_ERROR}
238 fi
239
240 local line
241 local addresses
242
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
247
248 # We need the second word the line
249 line=(${line})
250 list_append "addresses" "$(ip_split_prefix "${line[1]}")"
251 done <<< "$(ip addr show to "${net}" ${args})"
252
253 # We sort the list to get the lowest IP as first item
254 list_sort ${addresses}
255}