]> git.ipfire.org Git - people/arne_f/network.git/blob - functions.ipv6
network: Add some initialization handlers.
[people/arne_f/network.git] / functions.ipv6
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
22 function ipv6_device_autoconf_enable() {
23 local device=${1}
24
25 if ! device_exists ${device}; then
26 error "Device '${device}' does not exist."
27 return ${EXIT_ERROR}
28 fi
29
30 echo 1 > /proc/sys/net/ipv6/conf/${device}/autoconf
31 }
32
33 function ipv6_device_autoconf_disable() {
34 local device=${1}
35
36 if ! device_exists ${device}; then
37 error "Device '${device}' does not exist."
38 return ${EXIT_ERROR}
39 fi
40
41 echo 0 > /proc/sys/net/ipv6/conf/${device}/autoconf
42 }
43
44 function ipv6_is_valid() {
45 local address=${1}
46
47 # Check length
48 [ ${#address} -gt 39 ] && return ${EXIT_ERROR}
49
50 # XXX find :: twice?
51 # XXX check for documentation prefix?
52
53 # Check for bad characters
54 local char
55 for char in 0 1 2 3 4 5 6 7 8 9 a b c d e f :; do
56 address=${address//${char}/}
57 done
58 [ -n "${address}" ] && return ${EXIT_ERROR}
59
60 return ${EXIT_OK}
61 }
62
63 function ipv6_implode() {
64 local address=${1}
65
66 if ! ipv6_is_valid ${address}; then
67 error "IPv6 address is invalid: ${address}"
68 return ${EXIT_ERROR}
69 fi
70
71 # Make proper address in exploded format
72 address=$(ipv6_explode ${address})
73
74 local block
75 local char
76 local i
77
78 local address_new
79 local block_new
80
81 for block in ${address//:/\ }; do
82 block_new=
83 for i in $(seq 0 ${#block}); do
84 char="${block:${i}:1}"
85
86 [ -z "${char}" ] && continue
87
88 if [ -z "${block_new}" ] && [ "${char}" = "0" ]; then
89 continue
90 fi
91
92 block_new="${block_new}${char}"
93 done
94
95 [ -z "${block_new}" ] && block_new="0"
96
97 address_new="${address_new}:${block_new}"
98 done
99
100 # Cut first colon (:)
101 address="${address_new:1:${#address_new}}"
102
103 local match
104 local matches=()
105 local pattern
106 local pos_start
107 local pos_next
108 for pos_start in $(seq 0 ${#address}); do
109 matches["${pos_start}"]=0
110
111 for pos_next in $(seq ${pos_start} 2 ${#address}); do
112 case "${pos_start}" in
113 0)
114 match="${address:${pos_next}:2}"
115 pattern="0:"
116 ;;
117 *)
118 match="${address:${pos_next}:2}"
119 pattern=":0"
120 ;;
121 esac
122
123 [ -z "${match}" ] && continue
124
125 if [ "${match}" = "${pattern}" ]; then
126 matches[${pos_start}]=$(( matches[${pos_start}] + 1))
127 else
128 break
129 fi
130 done
131 done
132
133 local pos_best
134 local pos_best_val=0
135 for i in $(seq 0 ${#matches[@]}); do
136 [ -z "${matches[${i}]}" ] && continue
137
138 if [ ${matches[${i}]} -gt ${pos_best_val} ]; then
139 pos_best=${i}
140 pos_best_val=${matches[${i}]}
141 fi
142 done
143
144 if [ -n "${pos_best}" ]; then
145 address_new="${address:0:${pos_best}}::"
146
147 local pos_end=$(( ${pos_best_val} * 2 + ${pos_best} + 1))
148
149 if [ "${pos_best}" = "0" ]; then
150 pos_end=$(( ${pos_end} - 1 ))
151 fi
152
153 address="${address_new}${address:${pos_end}:${#address}}"
154 fi
155
156 assert ipv6_is_valid ${address}
157
158 echo "${address}"
159 }
160
161 function ipv6_explode() {
162 local address=${1}
163
164 if [ ${#address} -eq 39 ]; then
165 echo "${address}"
166 return ${EXIT_OK}
167 fi
168
169 address=${address//::/:X:}
170
171 local block
172 local block_count=0
173 local block_id
174 local block_max=8
175 local blocks=()
176
177 for block in ${address//:/\ }; do
178 blocks[${block_count}]=${block}
179
180 block_count=$(( ${block_count} + 1 ))
181 done
182
183 if [ ${#blocks[@]} -lt ${block_max} ]; then
184 for block_id in $(seq ${#blocks[@]} -1 0); do
185 block=${blocks[${block_id}]}
186
187 [ -z "${block}" ] && continue
188
189 if [ "${block}" = "X" ]; then
190 blocks[${block_id}]="0000"
191 break
192 fi
193
194 blocks[$(( ${block_max} - ${block_count} + ${block_id} ))]=${block}
195 blocks[${block_id}]="0000"
196 done
197 fi
198
199 for block_id in $(seq 0 ${#blocks[@]}); do
200 block=${blocks[${block_id}]}
201
202 [ -z "${block}" ] && block="0000"
203
204 while [ "${#block}" -lt 4 ]; do
205 block="0${block}"
206 done
207
208 blocks[${block_id}]=${block}
209 done
210
211 address=
212 for block in ${blocks[@]}; do
213 address="${address}:${block}"
214 done
215 address=${address:1:39}
216
217 assert ipv6_is_valid ${address}
218
219 echo "${address}"
220 }
221
222 function ipv6_hash() {
223 local address=${1}
224
225 # Explode address
226 address=$(ipv6_explode ${address})
227
228 echo "${address//:/}"
229 }