]>
Commit | Line | Data |
---|---|---|
1848564d MT |
1 | #!/bin/bash |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
97cb552e | 5 | # Copyright (C) 2012 IPFire Network Development Team # |
1848564d MT |
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 | ||
f41fa3d7 | 22 | . /usr/lib/network/header-zone |
1848564d | 23 | |
d389e96b MT |
24 | HOOK_SETTINGS=( |
25 | "ACCESS_CONCENTRATOR" | |
26 | "AUTH" | |
27 | "USERNAME" | |
28 | "PASSWORD" | |
29 | "SERVICE_NAME" | |
30 | "MTU" | |
31 | "IPV6" | |
32 | "PREFIX_DELEGATION" | |
33 | ) | |
1848564d | 34 | |
97cb552e | 35 | # This hook can work with all authentication methods supported by pppd. |
3a829636 | 36 | PPPOE_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}" |
1848564d MT |
37 | PPPOE_PLUGIN="rp-pppoe.so" |
38 | ||
69e93b3c | 39 | # Request an IPv6 address. |
53e764a7 | 40 | DEFAULT_IPV6="true" |
69e93b3c | 41 | |
08e40c8c | 42 | # Use IPv6 prefix delegation. |
53e764a7 | 43 | DEFAULT_PREFIX_DELEGATION="true" |
08e40c8c | 44 | |
1c6a4e30 | 45 | hook_check_settings() { |
97cb552e MT |
46 | assert isset USERNAME |
47 | assert isset PASSWORD | |
261132f9 | 48 | |
3a829636 | 49 | isset AUTH && assert isoneof AUTH ${PPPOE_SUPPORTED_AUTH_METHODS} |
261132f9 | 50 | |
69e93b3c | 51 | assert isset IPV6 |
08e40c8c | 52 | assert isset PREFIX_DELEGATION |
1848564d MT |
53 | } |
54 | ||
1c6a4e30 | 55 | hook_parse_cmdline() { |
1848564d | 56 | while [ $# -gt 0 ]; do |
97cb552e MT |
57 | case "${1}" in |
58 | --access-concentrator=*) | |
2212045f | 59 | ACCESS_CONCENTRATOR=$(cli_get_val "${1}") |
1848564d | 60 | ;; |
97cb552e | 61 | --auth=*) |
2212045f | 62 | AUTH=$(cli_get_val "${1}") |
1848564d | 63 | ;; |
69e93b3c MT |
64 | --ipv6=*) |
65 | local value="$(cli_get_val "${1}")" | |
66 | if enabled value; then | |
67 | IPV6="true" | |
68 | else | |
69 | IPV6="false" | |
70 | fi | |
71 | ;; | |
1848564d | 72 | --mtu=*) |
2212045f | 73 | MTU=$(cli_get_val "${1}") |
1848564d | 74 | ;; |
97cb552e | 75 | --password=*) |
2212045f | 76 | PASSWORD=$(cli_get_val "${1}") |
1848564d | 77 | ;; |
08e40c8c MT |
78 | --prefix-delegation=*) |
79 | PREFIX_DELEGATION="$(cli_get_bool "${1}")" | |
80 | ;; | |
97cb552e | 81 | --service-name=*) |
2212045f | 82 | SERVICE_NAME=$(cli_get_val "${1}") |
1848564d | 83 | ;; |
97cb552e | 84 | --username=*) |
2212045f | 85 | USERNAME=$(cli_get_val "${1}") |
201b7dff | 86 | ;; |
1848564d | 87 | *) |
97cb552e | 88 | warning "Unknown argument: ${1}" >&2 |
1848564d MT |
89 | ;; |
90 | esac | |
91 | shift | |
92 | done | |
1848564d MT |
93 | } |
94 | ||
1c6a4e30 | 95 | hook_up() { |
1848564d | 96 | local zone=${1} |
711ffac1 MT |
97 | assert isset zone |
98 | ||
ac694a6a MT |
99 | # If this zone's port is not set, we will return |
100 | # with EXIT_OK so that this zone will remain active, | |
101 | # but we cannot start pppd. | |
102 | local port=$(__hook_get_port "${zone}") | |
103 | if ! isset port || ! port_exists "${port}"; then | |
104 | log WARNING "Could not bring up zone '${zone}' because no port is attached" | |
105 | exit ${EXIT_OK} | |
106 | fi | |
107 | ||
1e6f187e | 108 | zone_settings_read "${zone}" |
2044f591 | 109 | |
3ab3292c SS |
110 | # Load the pppoe kernel module |
111 | module_load "pppoe" | |
112 | ||
2044f591 | 113 | # Bring up the port. |
529141df | 114 | port_up "${port}" |
2044f591 | 115 | |
97cb552e MT |
116 | # Start the ppp daemon. |
117 | pppd_start ${zone} | |
da453c33 | 118 | |
97cb552e | 119 | exit ${EXIT_OK} |
1848564d MT |
120 | } |
121 | ||
1c6a4e30 | 122 | hook_down() { |
1848564d | 123 | local zone=${1} |
97cb552e | 124 | assert isset zone |
1848564d | 125 | |
1e6f187e | 126 | zone_settings_read "${zone}" |
2044f591 | 127 | |
97cb552e MT |
128 | # Stop the ppp daemon. |
129 | pppd_stop ${zone} | |
1848564d | 130 | |
2044f591 | 131 | # Bring down the port. |
ebd29545 SS |
132 | local port=$(__hook_get_port "${zone}") |
133 | if isset port; then | |
134 | log DEBUG "Bringing down port '${port}'" | |
135 | port_down "${port}" | |
136 | fi | |
2044f591 | 137 | |
1848564d MT |
138 | exit ${EXIT_OK} |
139 | } | |
140 | ||
1c6a4e30 | 141 | hook_hotplug() { |
0994996d MT |
142 | local zone="${1}" |
143 | ||
144 | case "$(hotplug_action)" in | |
145 | add) | |
146 | if hotplug_event_interface_is_port_of_zone "${zone}"; then | |
147 | # Bring up the zone if it is enabled but not active, yet. | |
148 | zone_start_auto "${zone}" | |
149 | ||
150 | exit ${EXIT_OK} | |
151 | fi | |
152 | ;; | |
153 | remove) | |
154 | # PPPoE cannot work if the ethernet device has been removed | |
155 | if hotplug_event_interface_is_port_of_zone "${zone}"; then | |
156 | if zone_is_active "${zone}"; then | |
157 | zone_stop "${zone}" | |
158 | fi | |
159 | ||
160 | exit ${EXIT_OK} | |
161 | fi | |
162 | ;; | |
163 | esac | |
164 | ||
165 | exit ${EXIT_NOT_HANDLED} | |
166 | } | |
167 | ||
1c6a4e30 | 168 | hook_discover() { |
1848564d MT |
169 | local device=${1} |
170 | ||
5dfc94a8 MT |
171 | # This obviously only works on ethernet (or compatible) devices |
172 | if ! device_is_ethernet_compatible "${device}"; then | |
5b20e43a | 173 | exit ${EXIT_ERROR} |
1848564d MT |
174 | fi |
175 | ||
176 | local output | |
177 | output=$(pppoe-discovery -I ${device} -U $(uuid) 2>&1) | |
178 | ||
179 | # Exit if there was not output | |
180 | [ -z "${output}" ] && exit ${DISCOVER_ERROR} | |
181 | ||
182 | # Exit if PADI timed out | |
183 | grep -q "Timeout" <<<${output} && exit ${DISCOVER_ERROR} | |
184 | ||
185 | local ac | |
186 | while read line; do | |
187 | case "${line}" in | |
188 | Access-Concentrator:*) | |
189 | ac="${line#Access-Concentrator: }" | |
190 | ;; | |
191 | esac | |
192 | done <<<"${output}" | |
193 | ||
194 | echo "ACCESS_CONCENTRATOR=\"$ac\"" | |
195 | ||
196 | exit ${DISCOVER_OK} | |
197 | } | |
5b20e43a | 198 | |
1c6a4e30 | 199 | hook_status() { |
8eadf1da | 200 | local zone=${1} |
711ffac1 MT |
201 | assert isset zone |
202 | ||
3cb2fc42 | 203 | cli_device_headline ${zone} |
8eadf1da | 204 | |
1e6f187e | 205 | zone_settings_read "${zone}" |
711ffac1 | 206 | |
3cb2fc42 | 207 | cli_headline 2 "Configuration" |
97cb552e MT |
208 | cli_print_fmt1 2 "Username" "${USERNAME}" |
209 | cli_print_fmt1 2 "Password" "<hidden>" | |
529141df MT |
210 | |
211 | local port=$(__hook_get_port "${zone}") | |
212 | if isset port; then | |
213 | cli_print_fmt1 2 "Port" "${port}" | |
214 | fi | |
3cb2fc42 MT |
215 | cli_space |
216 | ||
8eadf1da MT |
217 | # Exit if zone is down |
218 | if ! zone_is_up ${zone}; then | |
219 | echo # Empty line | |
220 | exit ${EXIT_ERROR} | |
221 | fi | |
222 | ||
711ffac1 MT |
223 | # XXX display time since connection started |
224 | ||
3cb2fc42 | 225 | cli_headline 2 "Point-to-Point-over-Ethernet protocol" |
39cd231c SS |
226 | cli_print_fmt1 2 "MAC-Remote" "$(db_get "${zone}/remote-address")" |
227 | cli_space | |
228 | ||
201b7dff MT |
229 | local proto |
230 | for proto in ${IP_SUPPORTED_PROTOCOLS}; do | |
c041b631 | 231 | db_exists "${zone}/${proto}" || continue |
3cb2fc42 MT |
232 | |
233 | local headline | |
234 | case "${proto}" in | |
235 | ipv6) | |
236 | headline="Internet Protocol Version 6" | |
237 | ;; | |
238 | ipv4) | |
239 | headline="Internet Protocol Version 4" | |
240 | ;; | |
241 | *) | |
242 | headline="Unkown protocol" | |
243 | ;; | |
244 | esac | |
245 | cli_headline 3 "${headline}" | |
246 | ||
c041b631 MT |
247 | cli_print_fmt1 3 "IP address" "$(db_get "${zone}/${proto}/local-ip-address")" |
248 | cli_print_fmt1 3 "Gateway" "$(db_get "${zone}/${proto}/remote-ip-address")" | |
d64f0511 | 249 | cli_print_fmt1 3 "DNS servers" "$(db_get "${zone}/${proto}/domain-name-servers")" |
3cb2fc42 | 250 | cli_space |
201b7dff | 251 | done |
3cb2fc42 | 252 | |
8eadf1da MT |
253 | exit ${EXIT_OK} |
254 | } | |
255 | ||
1c6a4e30 | 256 | hook_ppp_write_config() { |
97cb552e MT |
257 | local zone=${1} |
258 | assert isset zone | |
259 | ||
260 | local file=${2} | |
261 | assert isset file | |
262 | ||
263 | # Read in the configuration files. | |
1e6f187e | 264 | zone_settings_read "${zone}" |
97cb552e | 265 | |
529141df MT |
266 | # A port has to be assigned for this action |
267 | local port=$(__hook_get_port "${zone}") | |
268 | if ! isset port; then | |
269 | error "No port assigned to pppoe hook of zone '${zone}'" | |
270 | exit ${EXIT_ERROR} | |
271 | fi | |
272 | ||
97cb552e MT |
273 | # Prepare the command line options for the pppoe plugin. |
274 | local plugin_options | |
275 | ||
276 | # Add the access concentrator (if any). | |
277 | if isset ACCESS_CONCENTRATOR; then | |
278 | plugin_options="${plugin_options} rp_pppoe_ac '${ACCESS_CONCENTRATOR}'" | |
711ffac1 MT |
279 | fi |
280 | ||
97cb552e MT |
281 | # Add the service name (if any). |
282 | if isset SERVICE_NAME; then | |
283 | plugin_options="${plugin_options} rp_pppoe_service '${SERVICE_NAME}'" | |
284 | fi | |
711ffac1 | 285 | |
97cb552e | 286 | # The last argument must be the interface. |
529141df | 287 | plugin_options="${plugin_options} ${port}" |
97cb552e MT |
288 | |
289 | pppd_write_config ${file} \ | |
290 | --interface="${zone}" \ | |
6c74a64c MT |
291 | --username="${USERNAME}" \ |
292 | --password="${PASSWORD}" \ | |
97cb552e MT |
293 | --mtu="${MTU}" \ |
294 | --auth="${AUTH}" \ | |
69e93b3c | 295 | --ipv6="${IPV6}" \ |
97cb552e MT |
296 | \ |
297 | --plugin="${PPPOE_PLUGIN}" \ | |
298 | --plugin-options="${plugin_options}" | |
299 | ||
6c74a64c | 300 | exit ${EXIT_OK} |
711ffac1 | 301 | } |
529141df | 302 | |
1c6a4e30 | 303 | __hook_get_port() { |
529141df MT |
304 | local zone="${1}" |
305 | ||
306 | local port | |
307 | for port in $(zone_get_ports "${zone}"); do | |
308 | echo "${port}" | |
309 | return ${EXIT_OK} | |
310 | done | |
311 | ||
312 | return ${EXIT_ERROR} | |
313 | } | |
314 | ||
1c6a4e30 | 315 | hook_port_attach() { |
529141df MT |
316 | # Excepting at least two arguments here |
317 | assert [ $# -ge 2 ] | |
318 | ||
319 | local zone="${1}" | |
320 | local port="${2}" | |
321 | shift 2 | |
322 | ||
323 | # PPPoE can only use one port | |
324 | local ports_num="$(zone_get_ports_num "${zone}")" | |
325 | if [ ${ports_num} -ge 1 ]; then | |
ac694a6a | 326 | local ports="$(zone_get_ports "${zone}")" |
529141df | 327 | error "The pppoe zone hook only supports assigning one port" |
ac694a6a | 328 | error " port '${ports}' has already been assigned to zone '${zone}'" |
529141df MT |
329 | return ${EXIT_ERROR} |
330 | fi | |
331 | ||
ac694a6a MT |
332 | if ! zone_port_settings_write "${zone}" "${port}"; then |
333 | exit ${EXIT_ERROR} | |
334 | fi | |
529141df MT |
335 | |
336 | exit ${EXIT_OK} | |
337 | } | |
338 | ||
1c6a4e30 | 339 | hook_port_detach() { |
529141df MT |
340 | assert [ $# -eq 2 ] |
341 | ||
342 | local zone="${1}" | |
343 | local port="${2}" | |
344 | ||
ac694a6a MT |
345 | # Shut down the entire zone here, because it cannot |
346 | # run without a port any way and removing the port would | |
347 | # create a hotplug event which will be processed after the | |
348 | # port has already been detached... | |
349 | zone_stop "${zone}" | |
529141df | 350 | |
ac694a6a MT |
351 | if ! zone_port_settings_remove "${zone}" "${port}"; then |
352 | exit ${EXIT_ERROR} | |
353 | fi | |
529141df MT |
354 | |
355 | exit ${EXIT_OK} | |
356 | } | |
4cee7a5d | 357 | |
82cd8617 MT |
358 | hook_port_up() { |
359 | assert [ $# -eq 2 ] | |
360 | ||
361 | local zone="${1}" | |
362 | local port="${2}" | |
363 | ||
364 | # Try bringing up the port if it has not been brought up before | |
365 | if ! device_exists "${port}"; then | |
366 | port_create "${port}" | |
367 | fi | |
368 | ||
369 | # Make sure that the port is up | |
370 | port_up "${port}" | |
371 | ||
372 | exit ${EXIT_OK} | |
373 | } | |
374 | ||
375 | hook_port_down() { | |
376 | assert [ $# -eq 2 ] | |
377 | ||
378 | local zone="${1}" | |
379 | local port="${2}" | |
380 | ||
381 | if device_exists "${port}"; then | |
382 | port_down "${port}" | |
383 | fi | |
384 | ||
385 | exit ${EXIT_OK} | |
386 | } | |
387 | ||
1c6a4e30 | 388 | hook_ppp_ipv6_up() { |
4cee7a5d MT |
389 | local zone="${1}" |
390 | ||
391 | ppp_common_ipv6_up "${zone}" | |
392 | ||
393 | # Read configuration | |
394 | zone_settings_read "${zone}" | |
395 | ||
396 | if enabled PREFIX_DELEGATION; then | |
397 | dhclient_start "${zone}" ipv6 | |
398 | fi | |
399 | ||
400 | exit ${EXIT_OK} | |
401 | } | |
402 | ||
1c6a4e30 | 403 | hook_ppp_ipv6_down() { |
4cee7a5d MT |
404 | local zone="${1}" |
405 | ||
406 | ppp_common_ipv6_down "${zone}" | |
407 | ||
408 | # Read configuration | |
409 | zone_settings_read "${zone}" | |
410 | ||
411 | if enabled PREFIX_DELEGATION; then | |
412 | dhclient_stop "${zone}" ipv6 | |
413 | fi | |
414 | ||
415 | exit ${EXIT_OK} | |
416 | } |