]>
Commit | Line | Data |
---|---|---|
4231f419 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 | ||
58fb41ee MT |
22 | function ipv6_init() { |
23 | log INFO "Initializing IPv6 networking." | |
24 | ||
25 | # Enable forwarding on all devices | |
26 | ipv6_device_forwarding_disable all | |
27 | ipv6_device_forwarding_disable default | |
28 | ||
29 | # Disable autoconfiguration on all devices per default | |
30 | ipv6_device_autoconf_disable all | |
31 | ipv6_device_autoconf_disable default | |
32 | ||
33 | # XXX do we need this? | |
34 | #local device | |
35 | #for device in $(devices_get_all); do | |
36 | # ipv6_device_forwarding_disable ${device} | |
37 | # ipv6_device_autoconf_disable ${device} | |
38 | #done | |
39 | } | |
40 | ||
41 | init_register ipv6_init | |
42 | ||
4231f419 MT |
43 | function ipv6_device_autoconf_enable() { |
44 | local device=${1} | |
45 | ||
58fb41ee MT |
46 | assert isset device |
47 | ||
48 | # Allow setting default and all settings | |
49 | if ! isoneof device all default; then | |
50 | assert device_exists ${device} | |
4231f419 MT |
51 | fi |
52 | ||
58fb41ee MT |
53 | local val |
54 | for val in accept_ra accept_redirects; do | |
55 | echo 1 > /proc/sys/net/ipv6/conf/${device}/${val} | |
56 | done | |
4231f419 MT |
57 | } |
58 | ||
59 | function ipv6_device_autoconf_disable() { | |
60 | local device=${1} | |
61 | ||
58fb41ee MT |
62 | assert isset device |
63 | ||
64 | # Allow setting default and all settings | |
65 | if ! isoneof device all default; then | |
66 | assert device_exists ${device} | |
67 | fi | |
68 | ||
69 | local val | |
70 | for val in accept_ra accept_redirects; do | |
71 | echo 0 > /proc/sys/net/ipv6/conf/${device}/${val} | |
72 | done | |
73 | } | |
74 | ||
75 | function ipv6_device_forwarding_enable() { | |
76 | local device=${1} | |
77 | ||
78 | assert isset device | |
79 | ||
80 | # Allow setting default and all settings | |
81 | if ! isoneof device all default; then | |
82 | assert device_exists ${device} | |
83 | fi | |
84 | ||
85 | echo 1 > /proc/sys/net/ipv6/conf/${device}/forwarding | |
86 | } | |
87 | ||
88 | function ipv6_device_forwarding_disable() { | |
89 | local device=${1} | |
90 | ||
91 | assert isset device | |
92 | ||
93 | # Allow setting default and all settings | |
94 | if ! isoneof device all default; then | |
95 | assert device_exists ${device} | |
4231f419 MT |
96 | fi |
97 | ||
58fb41ee MT |
98 | echo 0 > /proc/sys/net/ipv6/conf/${device}/forwarding |
99 | } | |
100 | ||
101 | # Enable IPv6 RFC3041 privacy extensions if desired | |
102 | function ipv6_device_privacy_extensions_enable() { | |
103 | local device=${1} | |
104 | local type=${2} | |
105 | ||
106 | assert isset device | |
107 | assert device_exists ${device} | |
108 | ||
109 | # Default value is rfc3041 | |
110 | if [ -z "${type}" ]; then | |
111 | type="rfc3041" | |
112 | fi | |
113 | ||
114 | assert isset type | |
115 | ||
116 | case "${type}" in | |
117 | rfc3041) | |
118 | echo 2 > /proc/sys/net/ipv6/conf/${device}/use_tempaddr | |
119 | ;; | |
120 | *) | |
121 | error_log "Given type '${type}' is not supported." | |
122 | return ${EXIT_ERROR} | |
123 | ;; | |
124 | esac | |
125 | ||
126 | return ${EXIT_OK} | |
127 | } | |
128 | ||
129 | function ipv6_device_privacy_extensions_disable() { | |
130 | local device=${1} | |
131 | ||
132 | assert isset device | |
133 | assert device_exists ${device} | |
134 | ||
135 | echo 0 > /proc/sys/net/ipv6/conf/${device}/use_tempaddr | |
4231f419 MT |
136 | } |
137 | ||
138 | function ipv6_is_valid() { | |
139 | local address=${1} | |
140 | ||
58fb41ee MT |
141 | assert isset address |
142 | ||
4231f419 MT |
143 | # Check length |
144 | [ ${#address} -gt 39 ] && return ${EXIT_ERROR} | |
145 | ||
146 | # XXX find :: twice? | |
147 | # XXX check for documentation prefix? | |
148 | ||
149 | # Check for bad characters | |
150 | local char | |
151 | for char in 0 1 2 3 4 5 6 7 8 9 a b c d e f :; do | |
152 | address=${address//${char}/} | |
153 | done | |
154 | [ -n "${address}" ] && return ${EXIT_ERROR} | |
155 | ||
156 | return ${EXIT_OK} | |
157 | } | |
158 | ||
159 | function ipv6_implode() { | |
160 | local address=${1} | |
161 | ||
58fb41ee MT |
162 | assert isset address |
163 | ||
4231f419 MT |
164 | if ! ipv6_is_valid ${address}; then |
165 | error "IPv6 address is invalid: ${address}" | |
166 | return ${EXIT_ERROR} | |
167 | fi | |
168 | ||
169 | # Make proper address in exploded format | |
170 | address=$(ipv6_explode ${address}) | |
171 | ||
172 | local block | |
173 | local char | |
174 | local i | |
175 | ||
176 | local address_new | |
177 | local block_new | |
178 | ||
179 | for block in ${address//:/\ }; do | |
180 | block_new= | |
181 | for i in $(seq 0 ${#block}); do | |
182 | char="${block:${i}:1}" | |
183 | ||
184 | [ -z "${char}" ] && continue | |
185 | ||
186 | if [ -z "${block_new}" ] && [ "${char}" = "0" ]; then | |
187 | continue | |
188 | fi | |
189 | ||
190 | block_new="${block_new}${char}" | |
191 | done | |
192 | ||
193 | [ -z "${block_new}" ] && block_new="0" | |
194 | ||
195 | address_new="${address_new}:${block_new}" | |
196 | done | |
197 | ||
198 | # Cut first colon (:) | |
199 | address="${address_new:1:${#address_new}}" | |
200 | ||
201 | local match | |
202 | local matches=() | |
203 | local pattern | |
204 | local pos_start | |
205 | local pos_next | |
206 | for pos_start in $(seq 0 ${#address}); do | |
207 | matches["${pos_start}"]=0 | |
208 | ||
209 | for pos_next in $(seq ${pos_start} 2 ${#address}); do | |
210 | case "${pos_start}" in | |
211 | 0) | |
212 | match="${address:${pos_next}:2}" | |
213 | pattern="0:" | |
214 | ;; | |
215 | *) | |
216 | match="${address:${pos_next}:2}" | |
217 | pattern=":0" | |
218 | ;; | |
219 | esac | |
220 | ||
221 | [ -z "${match}" ] && continue | |
222 | ||
223 | if [ "${match}" = "${pattern}" ]; then | |
224 | matches[${pos_start}]=$(( matches[${pos_start}] + 1)) | |
225 | else | |
226 | break | |
227 | fi | |
228 | done | |
229 | done | |
230 | ||
231 | local pos_best | |
232 | local pos_best_val=0 | |
233 | for i in $(seq 0 ${#matches[@]}); do | |
234 | [ -z "${matches[${i}]}" ] && continue | |
235 | ||
236 | if [ ${matches[${i}]} -gt ${pos_best_val} ]; then | |
237 | pos_best=${i} | |
238 | pos_best_val=${matches[${i}]} | |
239 | fi | |
240 | done | |
241 | ||
242 | if [ -n "${pos_best}" ]; then | |
243 | address_new="${address:0:${pos_best}}::" | |
244 | ||
245 | local pos_end=$(( ${pos_best_val} * 2 + ${pos_best} + 1)) | |
246 | ||
247 | if [ "${pos_best}" = "0" ]; then | |
248 | pos_end=$(( ${pos_end} - 1 )) | |
249 | fi | |
250 | ||
251 | address="${address_new}${address:${pos_end}:${#address}}" | |
252 | fi | |
253 | ||
254 | assert ipv6_is_valid ${address} | |
255 | ||
256 | echo "${address}" | |
257 | } | |
258 | ||
259 | function ipv6_explode() { | |
260 | local address=${1} | |
261 | ||
58fb41ee MT |
262 | assert isset address |
263 | ||
4231f419 MT |
264 | if [ ${#address} -eq 39 ]; then |
265 | echo "${address}" | |
266 | return ${EXIT_OK} | |
267 | fi | |
268 | ||
269 | address=${address//::/:X:} | |
270 | ||
271 | local block | |
272 | local block_count=0 | |
273 | local block_id | |
274 | local block_max=8 | |
275 | local blocks=() | |
276 | ||
277 | for block in ${address//:/\ }; do | |
278 | blocks[${block_count}]=${block} | |
279 | ||
280 | block_count=$(( ${block_count} + 1 )) | |
281 | done | |
282 | ||
283 | if [ ${#blocks[@]} -lt ${block_max} ]; then | |
284 | for block_id in $(seq ${#blocks[@]} -1 0); do | |
285 | block=${blocks[${block_id}]} | |
286 | ||
287 | [ -z "${block}" ] && continue | |
288 | ||
289 | if [ "${block}" = "X" ]; then | |
290 | blocks[${block_id}]="0000" | |
291 | break | |
292 | fi | |
293 | ||
294 | blocks[$(( ${block_max} - ${block_count} + ${block_id} ))]=${block} | |
295 | blocks[${block_id}]="0000" | |
296 | done | |
297 | fi | |
298 | ||
299 | for block_id in $(seq 0 ${#blocks[@]}); do | |
300 | block=${blocks[${block_id}]} | |
301 | ||
302 | [ -z "${block}" ] && block="0000" | |
303 | ||
304 | while [ "${#block}" -lt 4 ]; do | |
305 | block="0${block}" | |
306 | done | |
307 | ||
308 | blocks[${block_id}]=${block} | |
309 | done | |
310 | ||
311 | address= | |
312 | for block in ${blocks[@]}; do | |
313 | address="${address}:${block}" | |
314 | done | |
315 | address=${address:1:39} | |
316 | ||
317 | assert ipv6_is_valid ${address} | |
318 | ||
319 | echo "${address}" | |
320 | } | |
321 | ||
322 | function ipv6_hash() { | |
323 | local address=${1} | |
324 | ||
58fb41ee MT |
325 | assert isset address |
326 | ||
4231f419 MT |
327 | # Explode address |
328 | address=$(ipv6_explode ${address}) | |
329 | ||
330 | echo "${address//:/}" | |
331 | } |