]> git.ipfire.org Git - people/ms/network.git/blob - hooks/zones/pppoe
Execute hooks faster by sourcing them.
[people/ms/network.git] / hooks / zones / pppoe
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 . /usr/lib/network/header-zone
23
24 # TODO XXX AC name, service name, sync?
25
26 HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MTU"
27
28 AUTH=
29 DEFAULTROUTE=1
30 IPV6=1
31 LINKNAME="$(uuid)"
32 MTU=1492
33 PEERDNS=1
34 SECRET=
35 USER=
36
37 PPPOE_ALLOWED_AUTHS="chap pap"
38 PPPOE_PLUGIN="rp-pppoe.so"
39
40 function pppd_pid() {
41 local zone=${1}
42 shift
43
44 cat /var/run/${zone}.pid 2>/dev/null
45 }
46
47 function _check() {
48 assert isset USER
49 assert isset SECRET
50 assert isset LINKNAME
51 assert isset DEFAULTROUTE
52 assert isset PEERDNS
53 #assert isset DEVICE
54 #assert isset DEVICE_TYPE
55
56 assert isbool DEFAULTROUTE
57 assert isbool IPV6
58 assert isbool PEERDNS
59 #assert ismac DEVICE
60 #assert isoneof DEVICE_TYPE real virtual
61
62 local ports_num=$(listlength ${PORTS})
63 assert isoneof ports_num 0 1
64
65 isset AUTH && assert isoneof AUTH ${PPPOE_ALLOWED_AUTHS}
66 isset DEVICE_ID && assert isinteger DEVICE_VID
67 }
68
69 function _parse_cmdline() {
70 local value
71
72 while [ $# -gt 0 ]; do
73 case "$1" in
74 --user=*)
75 USER=${1#--user=}
76 ;;
77 --secret=*)
78 SECRET=${1#--secret=}
79 ;;
80 --linkname=*)
81 LINKNAME=${1#--name=}
82 ;;
83 --mtu=*)
84 MTU=${1#--mtu=}
85 ;;
86 --defaultroute=*)
87 value=${1#--defaultroute=}
88 if enabled value; then
89 DEFAULTROUTE=1
90 else
91 DEFAULTROUTE=0
92 fi
93 ;;
94 --dns=*)
95 value=${1#--dns=}
96 if enabled value; then
97 PEERDNS=1
98 else
99 PEERDNS=0
100 fi
101 ;;
102 --auth=*)
103 AUTH=${1#--auth=}
104 ;;
105 --ipv6=*)
106 IPV6=${1#--ipv6=}
107 ;;
108 *)
109 echo "Unknown option: $1" >&2
110 exit ${EXIT_ERROR}
111 ;;
112 esac
113 shift
114 done
115 }
116
117 function _up() {
118 local zone=${1}
119 shift
120
121 assert isset zone
122
123 zone_config_read ${zone}
124
125 local port=$(zone_get_ports ${zone})
126
127 assert isset port
128
129 if ! port_exists ${port}; then
130 error_log "Parent device '${port}' does not exist. Cannot bring up zone '${zone}'."
131 exit ${EXIT_ERROR}
132 fi
133
134 # Creating necessary files
135 # XXX must be PPP_RUN
136 [ -d "${RED_RUN}/${LINKNAME}" ] || mkdir -p ${RED_RUN}/${LINKNAME}
137
138 # Setting up the device
139 zone_ports_up ${zone}
140
141 ppp_secret "${USER}" "${SECRET}"
142
143 # XXX AC and service on plugin command line
144
145 cat <<EOF >${RED_RUN}/${LINKNAME}/options
146 # Naming options
147 ifname ${zone}
148 name ${LINKNAME}
149 linkname ${LINKNAME}
150
151 plugin ${PPPOE_PLUGIN} ${port}
152
153 # Enable/disable IPv6
154 $(enabled IPV6 && echo "+" || echo "-")ipv6
155
156 # User configuration
157 user ${USER}
158
159 $(enabled PEERDNS && echo "usepeerdns")
160 $(enabled DEFAULTROUTE && echo "defaultroute")
161
162 noauth
163 $(isset AUTH && echo "require-${AUTH}")
164
165 noipdefault
166
167 # Maximum transmission/receive unit
168 mtu ${MTU}
169 mru ${MTU}
170
171 # Disable the compression
172 noccp noaccomp nodeflate nopcomp novj novjccomp nobsdcomp nomppe
173
174 updetach debug
175 EOF
176
177 pppd_exec file ${RED_RUN}/${LINKNAME}/options
178
179 local ret=$?
180
181 # Get exit code from ppp daemon and handle it:
182 case "${ret}" in
183 0)
184 log DEBUG "pppd detached successfully"
185 exit ${EXIT_OK}
186 ;;
187 19)
188 log ERROR "Authentication failed. Maybe user and/or secret is/are incorrect."
189 exit ${EXIT_ERROR}
190 ;;
191 esac
192
193 error_log "pppd exited with unknown exit code '${ret}'"
194
195 exit ${EXIT_ERROR}
196 }
197
198 function _down() {
199 local zone=${1}
200 shift
201
202 # Kill pppd
203 # XXX very ugly
204 kill $(pppd_pid ${zone}) &>/dev/null
205
206 zone_ports_down ${zone}
207
208 exit ${EXIT_OK}
209 }
210
211 function _discover() {
212 local device=${1}
213
214 if [ "$(device_get_type ${device})" != "real" ]; then
215 exit ${EXIT_ERROR}
216 fi
217
218 local output
219 output=$(pppoe-discovery -I ${device} -U $(uuid) 2>&1)
220
221 # Exit if there was not output
222 [ -z "${output}" ] && exit ${DISCOVER_ERROR}
223
224 # Exit if PADI timed out
225 grep -q "Timeout" <<<${output} && exit ${DISCOVER_ERROR}
226
227 local ac
228 while read line; do
229 case "${line}" in
230 Access-Concentrator:*)
231 ac="${line#Access-Concentrator: }"
232 ;;
233 esac
234 done <<<"${output}"
235
236 echo "ACCESS_CONCENTRATOR=\"$ac\""
237
238 exit ${DISCOVER_OK}
239 }
240
241 function _status() {
242 local zone=${1}
243 assert isset zone
244
245 cli_device_headline ${zone}
246
247 zone_config_read ${zone}
248
249 cli_headline 2 "Configuration"
250 cli_print_fmt1 2 "User" "${USER}"
251 cli_print_fmt1 2 "Secret" "<hidden>"
252 cli_space
253
254 enabled IPV6 &>/dev/null
255 local ipv6_enabled=$?
256 cli_print_fmt1 2 "IPv6?" "$(cli_print_bool ${ipv6_enabled})"
257
258 cli_headline 2 "Ports"
259 zone_ports_status ${zone}
260 if [ -z "$(zone_get_ports ${zone})" ]; then
261 cli_print_warning "No ports attached. Won't be able to start."
262 cli_space
263 fi
264
265 # Exit if zone is down
266 if ! zone_is_up ${zone}; then
267 echo # Empty line
268 exit ${EXIT_ERROR}
269 fi
270
271 # XXX display time since connection started
272
273 cli_headline 2 "Point-to-Point-over-Ethernet protocol"
274 local proto
275 for proto in ${IP_SUPPORTED_PROTOCOLS}; do
276 routing_db_exists ${zone} ${proto} || continue
277
278 local headline
279 case "${proto}" in
280 ipv6)
281 headline="Internet Protocol Version 6"
282 ;;
283 ipv4)
284 headline="Internet Protocol Version 4"
285 ;;
286 *)
287 headline="Unkown protocol"
288 ;;
289 esac
290 cli_headline 3 "${headline}"
291
292 cli_print_fmt1 3 "IP address" "$(routing_db_get ${zone} ${proto} local-ip-address)"
293 cli_print_fmt1 3 "Gateway" "$(routing_db_get ${zone} ${proto} remote-ip-address)"
294 cli_print_fmt1 3 "DNS servers" "$(routing_db_get ${zone} ${proto} dns)"
295 cli_space
296 cli_print_fmt1 3 "MAC-Remote" "$(routing_db_get ${zone} ${proto} remote-address)"
297 cli_space
298 done
299
300 exit ${EXIT_OK}
301 }
302
303 function _port_add() {
304 local zone=${1}
305 local port=${2}
306 shift 2
307
308 if [ $(listlength $(zone_get_ports ${zone})) -ge 1 ]; then
309 error "This hook only supports one port at a time."
310 error "Please remove any existant port(s) and try again."
311 exit ${EXIT_ERROR}
312 fi
313
314 _port_cmd add ${zone} ${port} $@
315
316 exit ${EXIT_OK}
317 }