]> git.ipfire.org Git - people/stevee/network.git/blob - src/hooks/zones/pppoe
3882a2b37ffd528af376d7d03e16b71ea7133c8d
[people/stevee/network.git] / src / hooks / zones / pppoe
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2012 IPFire Network Development Team #
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 . /usr/lib/network/header-zone
23
24 HOOK_SETTINGS="HOOK ACCESS_CONCENTRATOR AUTH USERNAME PASSWORD"
25 HOOK_SETTINGS="${HOOK_SETTINGS} SERVICE_NAME MTU IPV6 PREFIX_DELEGATION"
26
27 # User credentials for the dialin.
28 USERNAME=""
29 PASSWORD=""
30
31 # Set the authentication mechanism.
32 AUTH=
33
34 # Access Concentrator.
35 ACCESS_CONCENTRATOR=""
36
37 # Service name.
38 SERVICE_NAME=""
39
40 # Maximum Transmission Unit.
41 # 1492 is a very common value for that.
42 MTU=1492
43
44 # This hook can work with all authentication methods supported by pppd.
45 PPPOE_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}"
46 PPPOE_PLUGIN="rp-pppoe.so"
47
48 # Request an IPv6 address.
49 IPV6="true"
50
51 # Use IPv6 prefix delegation.
52 PREFIX_DELEGATION="false"
53
54 function hook_check() {
55 assert isset USERNAME
56 assert isset PASSWORD
57
58 isset AUTH && assert isoneof AUTH ${PPPOE_SUPPORTED_AUTH_METHODS}
59
60 assert isset IPV6
61 assert isset PREFIX_DELEGATION
62 }
63
64 function hook_parse_cmdline() {
65 while [ $# -gt 0 ]; do
66 case "${1}" in
67 --access-concentrator=*)
68 ACCESS_CONCENTRATOR=$(cli_get_val ${1})
69 ;;
70 --auth=*)
71 AUTH=$(cli_get_val ${1})
72 ;;
73 --ipv6=*)
74 local value="$(cli_get_val "${1}")"
75 if enabled value; then
76 IPV6="true"
77 else
78 IPV6="false"
79 fi
80 ;;
81 --mtu=*)
82 MTU=$(cli_get_val ${1})
83 ;;
84 --password=*)
85 PASSWORD=$(cli_get_val ${1})
86 ;;
87 --prefix-delegation=*)
88 PREFIX_DELEGATION="$(cli_get_bool "${1}")"
89 ;;
90 --service-name=*)
91 SERVICE_NAME=$(cli_get_val ${1})
92 ;;
93 --username=*)
94 USERNAME=$(cli_get_val ${1})
95 ;;
96 *)
97 warning "Unknown argument: ${1}" >&2
98 ;;
99 esac
100 shift
101 done
102 }
103
104 function hook_up() {
105 local zone=${1}
106 assert isset zone
107
108 zone_config_read ${zone}
109
110 # Bring up the port.
111 local port=$(__hook_get_port "${zone}")
112 port_up "${port}"
113
114 # Start the ppp daemon.
115 pppd_start ${zone}
116
117 exit ${EXIT_OK}
118 }
119
120 function hook_down() {
121 local zone=${1}
122 assert isset zone
123
124 zone_config_read ${zone}
125
126 # Stop the ppp daemon.
127 pppd_stop ${zone}
128
129 # Bring down the port.
130 log DEBUG "Bringing down port '${PORT}'."
131 port_down ${PORT}
132
133 exit ${EXIT_OK}
134 }
135
136 function hook_discover() {
137 local device=${1}
138
139 if [ "$(device_get_type ${device})" != "real" ]; then
140 exit ${EXIT_ERROR}
141 fi
142
143 local output
144 output=$(pppoe-discovery -I ${device} -U $(uuid) 2>&1)
145
146 # Exit if there was not output
147 [ -z "${output}" ] && exit ${DISCOVER_ERROR}
148
149 # Exit if PADI timed out
150 grep -q "Timeout" <<<${output} && exit ${DISCOVER_ERROR}
151
152 local ac
153 while read line; do
154 case "${line}" in
155 Access-Concentrator:*)
156 ac="${line#Access-Concentrator: }"
157 ;;
158 esac
159 done <<<"${output}"
160
161 echo "ACCESS_CONCENTRATOR=\"$ac\""
162
163 exit ${DISCOVER_OK}
164 }
165
166 function hook_status() {
167 local zone=${1}
168 assert isset zone
169
170 cli_device_headline ${zone}
171
172 zone_config_read ${zone}
173
174 cli_headline 2 "Configuration"
175 cli_print_fmt1 2 "Username" "${USERNAME}"
176 cli_print_fmt1 2 "Password" "<hidden>"
177
178 local port=$(__hook_get_port "${zone}")
179 if isset port; then
180 cli_print_fmt1 2 "Port" "${port}"
181 fi
182 cli_space
183
184 # Exit if zone is down
185 if ! zone_is_up ${zone}; then
186 echo # Empty line
187 exit ${EXIT_ERROR}
188 fi
189
190 # XXX display time since connection started
191
192 cli_headline 2 "Point-to-Point-over-Ethernet protocol"
193 local proto
194 for proto in ${IP_SUPPORTED_PROTOCOLS}; do
195 routing_db_exists ${zone} ${proto} || continue
196
197 local headline
198 case "${proto}" in
199 ipv6)
200 headline="Internet Protocol Version 6"
201 ;;
202 ipv4)
203 headline="Internet Protocol Version 4"
204 ;;
205 *)
206 headline="Unkown protocol"
207 ;;
208 esac
209 cli_headline 3 "${headline}"
210
211 cli_print_fmt1 3 "IP address" "$(routing_db_get ${zone} ${proto} local-ip-address)"
212 cli_print_fmt1 3 "Gateway" "$(routing_db_get ${zone} ${proto} remote-ip-address)"
213 cli_print_fmt1 3 "DNS servers" "$(routing_db_get ${zone} ${proto} dns)"
214 cli_space
215 cli_print_fmt1 3 "MAC-Remote" "$(routing_db_get ${zone} ${proto} remote-address)"
216 cli_space
217 done
218
219 exit ${EXIT_OK}
220 }
221
222 function hook_ppp_write_config() {
223 local zone=${1}
224 assert isset zone
225
226 local file=${2}
227 assert isset file
228
229 # Read in the configuration files.
230 zone_config_read ${zone}
231
232 # A port has to be assigned for this action
233 local port=$(__hook_get_port "${zone}")
234 if ! isset port; then
235 error "No port assigned to pppoe hook of zone '${zone}'"
236 exit ${EXIT_ERROR}
237 fi
238
239 # Prepare the command line options for the pppoe plugin.
240 local plugin_options
241
242 # Add the access concentrator (if any).
243 if isset ACCESS_CONCENTRATOR; then
244 plugin_options="${plugin_options} rp_pppoe_ac '${ACCESS_CONCENTRATOR}'"
245 fi
246
247 # Add the service name (if any).
248 if isset SERVICE_NAME; then
249 plugin_options="${plugin_options} rp_pppoe_service '${SERVICE_NAME}'"
250 fi
251
252 # The last argument must be the interface.
253 plugin_options="${plugin_options} ${port}"
254
255 pppd_write_config ${file} \
256 --interface="${zone}" \
257 --username="${USERNAME}" \
258 --password="${PASSWORD}" \
259 --mtu="${MTU}" \
260 --auth="${AUTH}" \
261 --ipv6="${IPV6}" \
262 \
263 --plugin="${PPPOE_PLUGIN}" \
264 --plugin-options="${plugin_options}"
265
266 exit ${EXIT_OK}
267 }
268
269 function __hook_get_port() {
270 local zone="${1}"
271
272 local port
273 for port in $(zone_get_ports "${zone}"); do
274 echo "${port}"
275 return ${EXIT_OK}
276 done
277
278 return ${EXIT_ERROR}
279 }
280
281 function hook_port_add() {
282 # Excepting at least two arguments here
283 assert [ $# -ge 2 ]
284
285 local zone="${1}"
286 local port="${2}"
287 shift 2
288
289 # PPPoE can only use one port
290 local ports_num="$(zone_get_ports_num "${zone}")"
291 if [ ${ports_num} -ge 1 ]; then
292 local port=$(__hook_get_port "${zone}")
293 error "The pppoe zone hook only supports assigning one port"
294 error " port '${port}' has already been assigned to zone '${zone}'"
295 return ${EXIT_ERROR}
296 fi
297
298 config_write "$(zone_dir "${zone}")/ports/${port}"
299 log INFO "Port '${port}' has been added to zone '${zone}'"
300
301 exit ${EXIT_OK}
302 }
303
304 function hook_port_remove() {
305 assert [ $# -eq 2 ]
306
307 local zone="${1}"
308 local port="${2}"
309
310 # Shut down the port (if possible)
311 port_down "${port}"
312
313 log INFO "Port '${port}' has been removed from zone '${zone}'"
314 config_remove "$(zone_dir "${zone}")/ports/${port}"
315
316 exit ${EXIT_OK}
317 }