]>
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 | ||
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 | } |