]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/blob - pkgs/firewall/src/functions.ip
Change file layout of the makefiles.
[people/arne_f/ipfire-3.x.git] / pkgs / firewall / src / functions.ip
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2009 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
22 ###############################################################################
23 # General IP address manipulation functions
24 # ip_encode - Encodes an IP to an integer
25 # Parameters: ip address (e.g. 192.168.0.1)
26 # Returns : integer
27 # ip_decode - Decodes an integer to an IP
28 # Parameters: integer
29 # Returns : ip address
30 # ip_valid - Checks if given IP is valid
31 # Parameters: IP
32 # Returns : boolean
33 #
34 # General subnet functions
35 # ip_range - Enumerates members of an IP range
36 # Parameters: ip range (e.g. 192.168.0.1-192.168.0.128)
37 # Returns : several subnets/IPs
38 # ip_range_explicit - Enumerates ALL IP addresses of an IP range
39 # Parameters: ip range
40 # Returns : several IPs
41 # subnet_network - Calculates the network address of a CIDR
42 # Parameters: CIDR network (e.g. 192.168.0.0/24)
43 # Returns : Network address
44 # subnet_broadcast - Calculates the broadcast address of a CIDR
45 # Parameters: CIDR network
46 # Returns : Broadcast address
47 # ip_in_subnet - Checks if an IP is in given subnet
48 # Parameters: IP address, subnet
49 # Returns : Boolean
50 # mask_to_cidr - Converts a subnet mask to cidr type
51 # Parameters: subnet (e.g. 255.255.255.0)
52 # Returns : CIDR (e.g. 24)
53 #
54
55 function ip_encode() {
56 IFS=$(ifs .)
57
58 local int=0
59 for field in $1; do
60 int=$(( $(( $int << 8 )) | $field ))
61 done
62
63 echo $int
64 IFS=$(ifs)
65 }
66
67 function ip_decode() {
68 addr=$1
69
70 local x
71 local y
72
73 y=$(($addr & 255))
74 for x in 1 2 3; do
75 addr=$(($addr >> 8))
76 y=$(($addr & 255)).$y
77 done
78
79 echo $y
80 }
81
82 function ip_range() {
83 local first
84 local last
85 local l
86 local x
87 local y
88 local z
89 local vlsm
90
91 case "$1" in
92 !*)
93 echo $1
94 return
95 ;;
96 [0-9]*.*.*.*-*.*.*.*)
97 ;;
98 *)
99 echo $1
100 return
101 ;;
102 esac
103
104 first=$(ip_encode ${1%-*})
105 last=$(ip_encode ${1#*-})
106
107 if [ $first -gt $last ]; then
108 error "Invalid IP address range: $1"
109 fi
110
111 l=$(( $last + 1 ))
112
113 while [ $l -gt $first ]; do
114 vlsm=
115 x=31
116 y=2
117 z=1
118
119 while [ $(( $first % $y )) -eq 0 ] && [ $l -gt $(( $first + $y )) ]; do
120 vlsm=/$x
121 x=$(( $x - 1 ))
122 z=$y
123 y=$(( $y * 2 ))
124 done
125
126 echo $(ip_decode $first)$vlsm
127 first=$(($first + $z))
128 done
129 }
130
131 function ip_range_explicit() {
132 local first
133 local last
134
135 case $1 in
136 [0-9]*.*.*.*-*.*.*.*)
137 ;;
138 *)
139 echo $1
140 return
141 ;;
142 esac
143
144 first=$(ip_encode ${1%-*})
145 last=$(ip_encode ${1#*-})
146
147 if [ $first -gt $last ]; then
148 error "Invalid IP address range: $1"
149 fi
150
151 while ! [ $first -gt $last ]; do
152 echo $(ip_decode $first)
153 first=$(($first + 1))
154 done
155 }
156
157 function _netmask() {
158 local vlsm
159 vlsm=${1#*/}
160 [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) ))
161 }
162
163 function subnet_network() {
164 local encodedaddr
165 encodedaddr=$(ip_encode ${1%/*})
166 local netmask
167 netmask=$(_netmask $1)
168
169 echo $(ip_decode $(($encodedaddr & $netmask)))
170 }
171
172 function _broadcast() {
173 local x
174 x=$(( 32 - ${1#*/} ))
175 [ $x -eq 32 ] && echo -1 || echo $(( $(( 1 << $x )) - 1 ))
176 }
177
178 function subnet_broadcast() {
179 local encodedaddr
180 encodedaddr=$(ip_encode ${1%/*})
181 local netmask
182 netmask=$(_netmask $1)
183 local broadcast
184 broadcast=$(_broadcast $1)
185
186 echo $(ip_decode $(( $(($encodedaddr & $netmask)) | $broadcast )))
187 }
188
189 function ip_in_subnet() {
190 local netmask
191 netmask=$(_netmask $2)
192 [ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ]
193 }
194
195 function mask_to_cidr() {
196 local mask
197 mask=$(ip_encode $1)
198 local cidr
199 cidr=0
200 local x
201 x=$(( 128 << 24 )) # 0x80000000
202
203 while [ $(( $x & $mask )) -ne 0 ]; do
204 [ $mask -eq $x ] && mask=0 || mask=$(( $mask << 1 ))
205 cidr=$(($cidr + 1))
206 done
207
208 if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff
209 echo "Invalid net mask: $1" >&2
210 else
211 echo $cidr
212 fi
213 }
214
215 function ip_valid() {
216 local x
217 IFS=$(ifs .)
218 for x in $1; do
219 case $x in
220 [0-9]|[0-9][0-9]|[1-2][0-9][0-9])
221 [ $x -lt 256 ] || { IFS=$(ifs); return 1; }
222 ;;
223 *)
224 IFS=$(ifs)
225 return 1
226 ;;
227 esac
228 done
229 IFS=$(ifs)
230 return 0
231 }