]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blame - firewall/src/functions.ip
iptables: Remove package
[people/amarx/ipfire-3.x.git] / firewall / src / functions.ip
CommitLineData
8838c71a
MT
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
55function 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
67function 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
82function 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
131function 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
157function _netmask() {
158 local vlsm
159 vlsm=${1#*/}
160 [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) ))
161}
162
163function 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
172function _broadcast() {
173 local x
174 x=$(( 32 - ${1#*/} ))
175 [ $x -eq 32 ] && echo -1 || echo $(( $(( 1 << $x )) - 1 ))
176}
177
178function 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
189function ip_in_subnet() {
190 local netmask
191 netmask=$(_netmask $2)
192 [ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ]
193}
194
195function 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
215function 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}