]>
Commit | Line | Data |
---|---|---|
5b20e43a MT |
1 | #!/bin/bash |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
1848564d | 5 | # Copyright (C) 2010 Michael Tremer & Christian Schmidt # |
5b20e43a 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 | ||
1848564d MT |
22 | # Parse the command line |
23 | while [ $# -gt 0 ]; do | |
24 | case "${1}" in | |
25 | -d|--debug) | |
26 | DEBUG=1 | |
5b20e43a | 27 | ;; |
1848564d MT |
28 | *) |
29 | action=${1} | |
5b20e43a | 30 | ;; |
5b20e43a | 31 | esac |
5b20e43a | 32 | shift |
1848564d | 33 | [ -n "${action}" ] && break |
5b20e43a MT |
34 | done |
35 | ||
3647b19f MT |
36 | . /usr/lib/network/functions |
37 | ||
e9df08ad MT |
38 | # Read network settings |
39 | network_settings_read | |
fe52c5e0 | 40 | |
e9df08ad | 41 | function cli_settings() { |
9111eb72 | 42 | if cli_help_requested $@; then |
e9df08ad | 43 | cli_show_man network-settings |
9111eb72 MT |
44 | exit ${EXIT_OK} |
45 | fi | |
46 | ||
47 | if [ -n "${1}" ]; then | |
e9df08ad MT |
48 | settings_set $@ |
49 | network_settings_write | |
9111eb72 | 50 | else |
e9df08ad | 51 | network_settings_print |
9111eb72 MT |
52 | fi |
53 | } | |
54 | ||
55 | function cli_device() { | |
6c74a64c MT |
56 | if cli_help_requested $@; then |
57 | cli_show_man network-device | |
58 | exit ${EXIT_OK} | |
59 | fi | |
60 | ||
9111eb72 MT |
61 | local device=${1} |
62 | local action=${2} | |
63 | shift 2 | |
64 | ||
ec63256a MT |
65 | if ! isset device; then |
66 | cli_show_man network-device | |
9111eb72 MT |
67 | return ${EXIT_ERROR} |
68 | fi | |
69 | ||
ec63256a MT |
70 | assert device_exists ${device} |
71 | ||
9111eb72 MT |
72 | case "${action}" in |
73 | discover) | |
9111eb72 MT |
74 | cli_device_discover ${device} $@ |
75 | ;; | |
5a38ea84 MT |
76 | monitor) |
77 | cli_device_monitor "${device}" $@ | |
78 | ;; | |
ec63256a MT |
79 | status) |
80 | cli_device_status ${device} | |
9111eb72 | 81 | ;; |
6c74a64c MT |
82 | unlock) |
83 | cli_device_serial_unlock ${device} $@ | |
84 | ;; | |
5cf0edf9 MT |
85 | ussd) |
86 | cli_device_send_ussd_command "${device}" $@ | |
87 | ;; | |
9111eb72 MT |
88 | *) |
89 | cli_show_man network-device | |
90 | ;; | |
91 | esac | |
ec63256a MT |
92 | |
93 | return ${EXIT_OK} | |
94 | } | |
95 | ||
96 | function cli_device_status() { | |
97 | local device=${1} | |
98 | assert device_exists ${device} | |
99 | ||
6c74a64c MT |
100 | # Disable debugging output here. |
101 | local log_disable_stdout=${LOG_DISABLE_STDOUT} | |
102 | LOG_DISABLE_STDOUT="true" | |
103 | ||
ec63256a MT |
104 | # Save the type of the device for later. |
105 | local type=$(device_get_type ${device}) | |
106 | ||
107 | cli_headline 1 "Device status: ${device}" | |
108 | cli_print_fmt1 1 "Name" "${device}" | |
109 | ||
6c74a64c MT |
110 | # Handle serial devices. |
111 | if [ "${type}" = "serial" ]; then | |
112 | cli_device_status_serial ${device} | |
113 | return $? | |
114 | fi | |
115 | ||
ec63256a MT |
116 | # Print the device status. |
117 | device_is_up ${device} &>/dev/null | |
118 | local status=$? | |
119 | ||
120 | case "${status}" in | |
121 | ${EXIT_TRUE}) | |
fcbf6823 | 122 | status="${CLR_GREEN_B}UP${CLR_RESET}" |
ec63256a MT |
123 | ;; |
124 | ${EXIT_FALSE}) | |
fcbf6823 | 125 | status="${CLR_RED_B}DOWN${CLR_RESET}" |
ec63256a MT |
126 | ;; |
127 | esac | |
128 | ||
129 | cli_print_fmt1 1 "Status" "${status}" | |
130 | cli_print_fmt1 1 "Type" "${type}" | |
131 | cli_print_fmt1 1 "Address" "$(device_get_address ${device})" | |
132 | cli_space | |
133 | ||
134 | # Print the link speed for ethernet devices. | |
245dffc9 MT |
135 | if device_is_up ${device} &>/dev/null; then |
136 | case "${type}" in | |
137 | ethernet) | |
138 | cli_print_fmt1 1 "Link" \ | |
139 | "$(device_get_speed ${device}) MBit/s $(device_get_duplex ${device}) duplex" | |
140 | ;; | |
141 | esac | |
142 | fi | |
ec63256a MT |
143 | |
144 | cli_print_fmt1 1 "MTU" "$(device_get_mtu ${device})" | |
145 | cli_space | |
146 | ||
3cb2fc42 MT |
147 | # Print device statistics. |
148 | cli_device_stats 2 ${device} | |
ec63256a MT |
149 | |
150 | # Print some more information. | |
151 | device_has_carrier ${device} &>/dev/null | |
152 | cli_print_fmt1 1 "Has carrier?" "$(cli_print_bool $?)" | |
153 | ||
154 | device_is_promisc ${device} &>/dev/null | |
155 | cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)" | |
156 | cli_space | |
157 | ||
7951525a MT |
158 | # Print all vlan devices. |
159 | local vlans=$(device_get_vlans ${device}) | |
160 | if [ -n "${vlans}" ]; then | |
161 | cli_headline 2 "VLAN devices" | |
162 | ||
163 | local vlan | |
164 | for vlan in ${vlans}; do | |
165 | cli_print 2 "* %-6s - %s" "${vlan}" "$(device_get_address ${vlan})" | |
ec63256a MT |
166 | done |
167 | cli_space | |
168 | fi | |
169 | ||
6c74a64c MT |
170 | # Reset the logging level. |
171 | LOG_DISABLE_STDOUT=${log_disable_stdout} | |
172 | } | |
173 | ||
174 | function cli_device_status_serial() { | |
175 | local device=${1} | |
176 | assert device_is_serial ${device} | |
177 | ||
178 | serial_is_locked ${device} &>/dev/null | |
179 | local locked=$? | |
180 | ||
181 | cli_print_fmt1 1 "Locked" "$(cli_print_bool ${locked})" | |
182 | cli_space | |
183 | ||
184 | # Cannot go on when the device is locked. | |
185 | [ ${locked} -eq ${EXIT_TRUE} ] && return ${EXIT_OK} | |
186 | ||
187 | cli_print_fmt1 1 "Manufacturer" \ | |
188 | "$(modem_get_manufacturer ${device})" | |
189 | cli_print_fmt1 1 "Model" \ | |
190 | "$(modem_get_model ${device})" | |
191 | cli_print_fmt1 1 "Software version" \ | |
192 | "$(modem_get_software_version ${device})" | |
193 | ||
194 | if modem_is_mobile ${device}; then | |
195 | cli_print_fmt1 1 "IMEI" \ | |
196 | "$(modem_get_device_imei ${device})" | |
197 | cli_space | |
198 | ||
199 | cli_headline 2 "Network status" | |
200 | modem_sim_status ${device} &>/dev/null | |
201 | local sim_status_code=$? | |
202 | ||
203 | local sim_status="unknown" | |
204 | case "${sim_status_code}" in | |
205 | ${EXIT_SIM_READY}) | |
206 | sim_status="SIM ready" | |
207 | ;; | |
208 | ${EXIT_SIM_PIN}) | |
209 | sim_status="PIN locked" | |
210 | ;; | |
211 | ${EXIT_SIM_PUK}) | |
212 | sim_status="PUK locked" | |
213 | ;; | |
214 | esac | |
215 | cli_print_fmt1 2 "SIM status" "${sim_status}" | |
216 | ||
217 | if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then | |
218 | cli_print_fmt1 2 "IMSI" \ | |
219 | "$(modem_get_sim_imsi ${device})" | |
220 | cli_print_fmt1 2 "Operator" \ | |
221 | "$(modem_get_network_operator ${device})" | |
222 | cli_print_fmt1 2 "Mode" \ | |
223 | "$(modem_get_network_mode ${device})" | |
224 | cli_print_fmt1 2 "Signal quality" \ | |
225 | "$(modem_get_signal_quality ${device}) dBm" | |
226 | ||
227 | local ber=$(modem_get_bit_error_rate ${device}) | |
228 | isset ber || ber="unknown" | |
229 | cli_print_fmt1 2 "Bit Error Rate" "${ber}" | |
230 | fi | |
231 | fi | |
232 | cli_space | |
9111eb72 MT |
233 | } |
234 | ||
235 | function cli_device_discover() { | |
236 | local device=${1} | |
237 | shift | |
238 | ||
239 | local device_type=$(device_get_type ${device}) | |
240 | if [ "${device_type}" != "real" ]; then | |
241 | return ${EXIT_OK} | |
242 | fi | |
243 | ||
244 | local raw | |
245 | ||
246 | while [ $# -gt 0 ]; do | |
247 | case "${1}" in | |
248 | --raw) | |
249 | raw=1 | |
250 | ;; | |
251 | esac | |
252 | shift | |
253 | done | |
254 | ||
255 | local up | |
256 | device_is_up ${device} && up=1 | |
257 | device_set_up ${device} | |
258 | ||
259 | enabled raw || echo "${device}" | |
260 | ||
261 | local hook | |
262 | local out | |
263 | local ret | |
264 | for hook in $(hook_zone_get_all); do | |
265 | out=$(hook_zone_exec ${hook} discover ${device}) | |
266 | ret=$? | |
267 | ||
268 | [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue | |
269 | ||
270 | if enabled raw; then | |
271 | case "${ret}" in | |
272 | ${DISCOVER_OK}) | |
273 | echo "${hook}: OK" | |
274 | local line | |
275 | while read line; do | |
276 | echo "${hook}: ${line}" | |
277 | done <<<"${out}" | |
278 | ;; | |
279 | ||
280 | ${DISCOVER_ERROR}) | |
281 | echo "${hook}: FAILED" | |
282 | ;; | |
283 | esac | |
284 | else | |
285 | case "${ret}" in | |
286 | ${DISCOVER_OK}) | |
287 | echo " ${hook} was successful." | |
288 | local line | |
289 | while read line; do | |
290 | echo " ${line}" | |
291 | done <<<"${out}" | |
292 | ;; | |
293 | ||
294 | ${DISCOVER_ERROR}) | |
295 | echo " ${hook} failed." | |
296 | ;; | |
297 | esac | |
298 | fi | |
299 | done | |
300 | ||
301 | echo # New line | |
302 | ||
303 | [ "${up}" = "1" ] || device_set_down ${device} | |
304 | } | |
305 | ||
6c74a64c MT |
306 | function cli_device_serial_unlock() { |
307 | if cli_help_requested $@; then | |
308 | cli_show_man network-device | |
309 | exit ${EXIT_OK} | |
310 | fi | |
311 | ||
312 | local device=${1} | |
313 | assert isset device | |
314 | ||
315 | if ! device_is_serial ${device}; then | |
316 | error "${device} is not a serial device." | |
317 | error "Unlocking is only supported for serial devices." | |
318 | exit ${EXIT_ERROR} | |
319 | fi | |
320 | ||
321 | # Read the current state of the SIM card. | |
322 | modem_sim_status ${device} &>/dev/null | |
323 | local sim_status_code=$? | |
324 | ||
325 | # If the SIM card is already unlocked, we don't need to do anything. | |
326 | if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then | |
327 | print "The SIM card is already unlocked." | |
328 | exit ${EXIT_OK} | |
329 | ||
330 | # If the SIM card is in an unknown state, we cannot do anything. | |
331 | elif [ ${sim_status_code} -eq ${EXIT_SIM_UNKNOWN} ]; then | |
332 | error "The SIM card is in an unknown state." | |
333 | exit ${EXIT_ERROR} | |
334 | fi | |
335 | ||
336 | # Ask for the code. | |
337 | local code=${2} | |
338 | local require_new_pin="false" | |
339 | local new_pin | |
340 | ||
341 | while ! isinteger code; do | |
342 | local message | |
343 | case "${sim_status_code}" in | |
344 | ${EXIT_SIM_PIN}) | |
345 | message="Please enter PIN:" | |
346 | ;; | |
347 | ${EXIT_SIM_PUK}) | |
348 | message="Please enter PUK:" | |
349 | require_new_pin="true" | |
350 | ;; | |
351 | esac | |
352 | assert isset message | |
353 | ||
354 | echo -n "${message} " | |
355 | read -s code | |
356 | echo # Print newline. | |
357 | ||
358 | if enabled require_new_pin; then | |
359 | local i new_pin2 | |
360 | for i in 0 1; do | |
361 | case "${i}" in | |
362 | 0) | |
363 | message="Please enter a new PIN code:" | |
364 | ;; | |
365 | 1) | |
366 | message="Please confirm the new PIN code:" | |
367 | ;; | |
368 | esac | |
369 | ||
370 | echo -n "${message} " | |
371 | read -s new_pin2 | |
372 | echo # Print newline. | |
373 | ||
374 | if [ -n "${new_pin}" ]; then | |
375 | if [ "${new_pin}" != "${new_pin2}" ]; then | |
376 | error "The entered PIN codes did not match." | |
377 | exit ${EXIT_ERROR} | |
378 | fi | |
379 | else | |
380 | new_pin=${new_pin2} | |
381 | fi | |
382 | done | |
383 | fi | |
384 | done | |
385 | ||
386 | # Trying to unlock the SIM card. | |
387 | modem_sim_unlock ${device} ${code} ${new_pin} | |
388 | ||
389 | exit $? | |
390 | } | |
391 | ||
5cf0edf9 MT |
392 | function cli_device_send_ussd_command() { |
393 | local device="${1}" | |
394 | assert isset device | |
395 | shift | |
396 | ||
397 | local command | |
398 | local timeout | |
399 | ||
400 | while [ $# -gt 0 ]; do | |
401 | case "${1}" in | |
402 | --timeout=*) | |
403 | timeout="$(cli_get_val "${1}")" | |
404 | ;; | |
405 | *) | |
406 | if isset command; then | |
407 | warning "Unrecognized argument: ${1}" | |
408 | else | |
409 | command="${1}" | |
410 | fi | |
411 | ;; | |
412 | esac | |
413 | shift | |
414 | done | |
415 | ||
416 | assert device_is_serial "${device}" | |
417 | ||
418 | local args | |
419 | if isset timeout; then | |
420 | args="${args} --timeout=${timeout}" | |
421 | fi | |
422 | ||
423 | modem_ussd_send_command "${device}" "${command}" ${args} | |
424 | exit $? | |
425 | } | |
426 | ||
5a38ea84 MT |
427 | function cli_device_monitor() { |
428 | local device="${1}" | |
429 | assert isset device | |
430 | ||
431 | if ! device_is_wireless "${device}"; then | |
432 | error "This action only works with wireless devices. Exiting." | |
433 | exit ${EXIT_ERROR} | |
434 | fi | |
435 | ||
436 | wireless_monitor "${device}" | |
437 | exit $? | |
438 | } | |
439 | ||
9111eb72 MT |
440 | function cli_hostname() { |
441 | if cli_help_requested $@; then | |
442 | cli_show_man network | |
443 | exit ${EXIT_OK} | |
444 | fi | |
445 | ||
446 | local hostname=${1} | |
447 | ||
448 | if [ -n "${hostname}" ]; then | |
449 | config_hostname ${hostname} | |
450 | log INFO "Hostname was set to '${hostname}'." | |
451 | log INFO "Changes do only take affect after reboot." | |
452 | exit ${EXIT_OK} | |
453 | fi | |
454 | ||
455 | echo "$(config_hostname)" | |
456 | exit ${EXIT_OK} | |
457 | } | |
458 | ||
459 | function cli_port() { | |
460 | if cli_help_requested $@; then | |
461 | cli_show_man network-port | |
462 | exit ${EXIT_OK} | |
463 | fi | |
464 | ||
465 | local action | |
466 | local port | |
467 | ||
468 | if port_exists ${1}; then | |
469 | port=${1} | |
470 | action=${2} | |
471 | shift 2 | |
472 | ||
473 | # Action aliases | |
474 | case "${action}" in | |
475 | start) | |
476 | action="up" | |
477 | ;; | |
478 | stop) | |
479 | action="down" | |
480 | ;; | |
481 | show) | |
482 | action="status" | |
483 | ;; | |
484 | esac | |
485 | ||
486 | case "${action}" in | |
487 | edit|up|down|status) | |
488 | port_${action} ${port} $@ | |
489 | ;; | |
490 | *) | |
491 | error "Unrecognized argument: ${action}" | |
492 | exit ${EXIT_ERROR} | |
493 | ;; | |
494 | esac | |
495 | else | |
496 | action=${1} | |
497 | shift | |
498 | ||
499 | case "${action}" in | |
500 | create|destroy) | |
501 | port_${action} $@ | |
502 | ;; | |
503 | *) | |
504 | error "Unrecognized argument: ${action}" | |
505 | exit ${EXIT_ERROR} | |
506 | ;; | |
507 | esac | |
508 | fi | |
509 | } | |
510 | ||
511 | function cli_zone() { | |
512 | if cli_help_requested $@; then | |
513 | cli_show_man network-zone | |
514 | exit ${EXIT_OK} | |
515 | fi | |
516 | ||
517 | local action | |
518 | local zone | |
519 | ||
520 | if zone_name_is_valid ${1}; then | |
521 | zone=${1} | |
522 | action=${2} | |
523 | shift 2 | |
524 | ||
525 | # Action aliases | |
526 | case "${action}" in | |
527 | start) | |
528 | action="up" | |
529 | ;; | |
530 | stop) | |
531 | action="down" | |
532 | ;; | |
533 | show) | |
534 | action="status" | |
535 | ;; | |
536 | esac | |
537 | ||
538 | case "${action}" in | |
5c5b8e36 | 539 | config|disable|down|edit|enable|port|status|up) |
9111eb72 MT |
540 | zone_${action} ${zone} $@ |
541 | ;; | |
542 | *) | |
543 | error "Unrecognized argument: ${action}" | |
544 | cli_show_man network-zone | |
545 | exit ${EXIT_ERROR} | |
546 | ;; | |
547 | esac | |
548 | else | |
549 | action=${1} | |
550 | shift | |
551 | ||
552 | case "${action}" in | |
553 | create) | |
554 | zone_${action} $@ | |
555 | ;; | |
556 | remove) | |
557 | cli_zone_remove $@ | |
558 | ;; | |
559 | list-hooks) | |
560 | cli_list_hooks zone $@ | |
561 | ;; | |
562 | ""|*) | |
563 | if [ -n "${action}" ]; then | |
564 | error "Unrecognized argument: '${action}'" | |
565 | echo | |
566 | fi | |
567 | ||
568 | cli_show_man network-zone | |
569 | exit ${EXIT_ERROR} | |
570 | ;; | |
571 | esac | |
572 | fi | |
573 | } | |
574 | ||
575 | # Removes a zone either immediately, if it is currently down, | |
576 | # or adds a tag that the removal will be done when the zone | |
577 | # is brought down the next time. | |
578 | function cli_zone_remove() { | |
579 | if cli_help_requested $@; then | |
580 | cli_show_man network-zone | |
581 | exit ${EXIT_OK} | |
582 | fi | |
583 | ||
584 | local zone=${1} | |
585 | assert zone_exists ${zone} | |
586 | ||
587 | if zone_is_up ${zone}; then | |
588 | echo "Zone '${zone}' is up and will be removed when it goes down the next time." | |
589 | zone_remove ${zone} | |
590 | else | |
591 | echo "Removing zone '${zone}' now..." | |
592 | zone_remove_now ${zone} | |
593 | fi | |
594 | ||
595 | exit ${EXIT_OK} | |
596 | } | |
597 | ||
598 | function cli_list_hooks() { | |
599 | local type=${1} | |
600 | shift | |
601 | ||
602 | if cli_help_requested $@; then | |
603 | cli_show_man network-zone | |
604 | exit ${EXIT_OK} | |
605 | fi | |
606 | ||
607 | local hook_dir=$(hook_dir ${type}) | |
608 | local hook | |
609 | ||
610 | for hook in ${hook_dir}/*; do | |
611 | hook=$(basename ${hook}) | |
612 | if hook_exists ${type} ${hook}; then | |
613 | echo "${hook}" | |
614 | fi | |
615 | done | sort -u | |
616 | } | |
617 | ||
cb965348 MT |
618 | function cli_route() { |
619 | if cli_help_requested $@; then | |
620 | cli_show_man network-route | |
621 | exit ${EXIT_OK} | |
622 | fi | |
623 | ||
624 | local action=${1} | |
625 | shift | |
626 | ||
627 | case "${action}" in | |
628 | # Add a new route. | |
629 | add) | |
630 | route_add $@ | |
631 | ;; | |
632 | # Remove an existing route. | |
633 | remove) | |
634 | route_remove $@ | |
635 | ;; | |
636 | # List all routes. | |
637 | list) | |
638 | route_list $@ | |
d2021e87 | 639 | return ${EXIT_OK} |
cb965348 MT |
640 | ;; |
641 | *) | |
642 | error "Unrecognized action: ${action}" | |
643 | cli_run_help network route | |
644 | ||
645 | exit ${EXIT_ERROR} | |
646 | ;; | |
647 | esac | |
648 | ||
d2021e87 MT |
649 | # Applying all routes. |
650 | route_apply | |
651 | ||
cb965348 MT |
652 | exit ${EXIT_OK} |
653 | } | |
654 | ||
6c07160e MT |
655 | function cli_dhcpd() { |
656 | local proto=${1} | |
657 | shift | |
658 | ||
659 | if cli_help_requested $@; then | |
660 | cli_show_man network-dhcp | |
661 | exit ${EXIT_OK} | |
662 | fi | |
663 | ||
664 | local action=${1} | |
665 | shift | |
666 | ||
667 | case "${action}" in | |
668 | edit) | |
669 | dhcpd_edit ${proto} $@ | |
670 | ;; | |
671 | start) | |
672 | dhcpd_start ${proto} | |
673 | ;; | |
674 | stop) | |
675 | dhcpd_stop ${proto} | |
676 | ;; | |
677 | restart|reload) | |
678 | dhcpd_reload ${proto} | |
679 | ;; | |
680 | subnet) | |
681 | cli_dhcpd_subnet ${proto} $@ | |
682 | ;; | |
683 | show|"") | |
684 | cli_dhcpd_show ${proto} $@ | |
685 | ;; | |
686 | *) | |
687 | error "Unrecognized action: ${action}" | |
688 | cli_run_help network dhcpvN | |
689 | ||
690 | exit ${EXIT_ERROR} | |
691 | ;; | |
692 | esac | |
693 | ||
694 | exit ${EXIT_OK} | |
695 | } | |
696 | ||
697 | function cli_dhcpd_show() { | |
698 | local proto=${1} | |
699 | assert isset proto | |
700 | ||
701 | local settings=$(dhcpd_settings ${proto}) | |
702 | assert isset settings | |
703 | ||
704 | local ${settings} | |
705 | dhcpd_global_settings_read ${proto} | |
706 | ||
707 | cli_headline 1 "Dynamic Host Configuration Protocol Daemon for ${proto/ip/IP}" | |
708 | ||
709 | case "${proto}" in | |
710 | ipv6) | |
711 | cli_headline 2 "Lease times" | |
712 | if isinteger VALID_LIFETIME; then | |
713 | cli_print_fmt1 2 "Valid lifetime" "${VALID_LIFETIME}s" | |
714 | fi | |
715 | ||
716 | if isinteger PREFERRED_LIFETIME; then | |
717 | cli_print_fmt1 2 "Preferred lifetime" "${PREFERRED_LIFETIME}s" | |
718 | fi | |
719 | ||
720 | cli_space | |
721 | ;; | |
722 | ipv4) | |
723 | cli_print_fmt1 1 "Authoritative" $(cli_print_enabled AUTHORITATIVE) | |
724 | cli_space | |
725 | ||
726 | cli_headline 2 "Lease times" | |
727 | cli_print_fmt1 2 "Default lease time" "${DEFAULT_LEASE_TIME}s" | |
728 | cli_print_fmt1 2 "Max. lease time" "${MAX_LEASE_TIME}s" | |
729 | ||
730 | if isset MIN_LEASE_TIME; then | |
731 | cli_print_fmt1 2 "Min. lease time" "${MIN_LEASE_TIME}s" | |
732 | fi | |
733 | ||
734 | cli_space | |
735 | ;; | |
736 | esac | |
737 | ||
738 | # Read the options. | |
739 | local -A options | |
740 | dhcpd_global_options_read ${proto} ${subnet_id} | |
741 | ||
742 | # Print the options if any. | |
743 | if [ ${#options[*]} -gt 0 ]; then | |
744 | cli_headline 2 "Options" | |
745 | ||
746 | local option | |
747 | for option in $(dhcpd_options ${proto}); do | |
748 | [ -n "${options[${option}]}" ] || continue | |
749 | ||
750 | cli_print_fmt1 2 \ | |
751 | "${option}" "${options[${option}]}" | |
752 | done | |
753 | cli_space | |
754 | fi | |
755 | ||
756 | # Subnets. | |
757 | local subnets=$(dhcpd_subnet_list ${proto}) | |
758 | if [ -n "${subnets}" ]; then | |
759 | cli_headline 2 "Subnets" | |
760 | local subnet_id | |
761 | for subnet_id in ${subnets}; do | |
762 | cli_dhcpd_subnet_show ${proto} ${subnet_id} 2 | |
763 | done | |
764 | fi | |
765 | } | |
766 | ||
767 | function cli_dhcpd_subnet() { | |
768 | local proto=${1} | |
769 | shift | |
770 | ||
771 | if cli_help_requested $@; then | |
772 | cli_show_man network-dhcp-subnet | |
773 | exit ${EXIT_OK} | |
774 | fi | |
775 | ||
776 | local action=${1} | |
777 | shift | |
778 | ||
779 | case "${action}" in | |
780 | new) | |
781 | dhcpd_subnet_new ${proto} $@ | |
782 | ;; | |
783 | remove) | |
784 | dhcpd_subnet_remove ${proto} $@ | |
785 | ;; | |
786 | [0-9]*) | |
787 | local subnet_id=${action} | |
788 | ||
789 | if ! dhcpd_subnet_exists ${proto} ${subnet_id}; then | |
790 | error "The given subnet with ID ${subnet_id} does not exist." | |
791 | return ${EXIT_ERROR} | |
792 | fi | |
793 | ||
794 | # Update the action. | |
795 | action=${1} | |
796 | shift | |
797 | ||
798 | case "${action}" in | |
799 | edit) | |
800 | dhcpd_subnet_edit ${proto} ${subnet_id} $@ | |
801 | local ret=$? | |
802 | ||
803 | if [ ${ret} -eq ${EXIT_OK} ]; then | |
804 | dhcpd_reload ${proto} | |
805 | fi | |
806 | exit ${ret} | |
807 | ;; | |
808 | range) | |
809 | cli_dhcpd_subnet_range ${proto} ${subnet_id} $@ | |
810 | exit $? | |
811 | ;; | |
812 | show) | |
813 | cli_dhcpd_subnet_show ${proto} ${subnet_id} $@ | |
814 | exit $? | |
815 | ;; | |
816 | options) | |
817 | cli_dhcpd_subnet_options ${proto} ${subnet_id} $@ | |
818 | exit $? | |
819 | ;; | |
820 | *) | |
821 | error "Unrecognized action: ${action}" | |
822 | cli_run_help network dhcpvN subnet | |
823 | exit ${EXIT_ERROR} | |
824 | ;; | |
825 | esac | |
826 | ;; | |
827 | show) | |
828 | local subnet_id | |
829 | for subnet_id in $(dhcpd_subnet_list ${proto}); do | |
830 | cli_dhcpd_subnet_show ${proto} ${subnet_id} | |
831 | done | |
832 | ;; | |
833 | *) | |
834 | error "Unrecognized action: ${action}" | |
835 | cli_run_help network dhcpvN subnet | |
836 | ||
837 | exit ${EXIT_ERROR} | |
838 | ;; | |
839 | esac | |
840 | ||
841 | exit ${EXIT_OK} | |
842 | } | |
843 | ||
844 | function cli_dhcpd_subnet_range() { | |
845 | local proto=${1} | |
846 | assert isset proto | |
847 | shift | |
848 | ||
849 | local subnet_id=${1} | |
850 | assert isset subnet_id | |
851 | shift | |
852 | ||
853 | local action=${1} | |
854 | shift | |
855 | ||
856 | case "${action}" in | |
857 | new) | |
858 | dhcpd_subnet_range_new ${proto} ${subnet_id} $@ | |
859 | exit $? | |
860 | ;; | |
861 | remove) | |
862 | dhcpd_subnet_range_remove ${proto} ${subnet_id} $@ | |
863 | exit $? | |
864 | ;; | |
865 | *) | |
866 | error "Unrecognized action: ${action}" | |
867 | cli_run_help network dhcpvN subnet range | |
868 | exit ${EXIT_ERROR} | |
869 | ;; | |
870 | esac | |
871 | } | |
872 | ||
873 | function cli_dhcpd_subnet_show() { | |
874 | local proto=${1} | |
875 | assert isset proto | |
876 | ||
877 | local subnet_id=${2} | |
878 | assert isset subnet_id | |
879 | ||
880 | local level=${3} | |
881 | isset level || level=0 | |
882 | ||
883 | local $(dhcpd_subnet_settings ${proto}) | |
884 | ||
885 | # Read in configuration settings. | |
886 | dhcpd_subnet_read ${proto} ${subnet_id} | |
887 | ||
888 | cli_headline $(( ${level} + 1 )) \ | |
889 | "DHCP${proto/ip/} subnet declaration #${subnet_id}" | |
890 | cli_print_fmt1 $(( ${level} + 1 )) \ | |
891 | "Subnet" "${ADDRESS}/${PREFIX}" | |
892 | cli_space | |
893 | ||
894 | # Read the options. | |
895 | local -A options | |
896 | dhcpd_subnet_options_read ${proto} ${subnet_id} | |
897 | ||
898 | # Print the options if any. | |
899 | if [ ${#options[*]} -gt 0 ]; then | |
900 | cli_headline $(( ${level} + 2 )) "Options" | |
901 | ||
902 | local option | |
903 | for option in $(dhcpd_subnet_options ${proto}); do | |
904 | [ -n "${options[${option}]}" ] || continue | |
905 | ||
906 | cli_print_fmt1 $(( ${level} + 2 )) \ | |
907 | "${option}" "${options[${option}]}" | |
908 | done | |
909 | cli_space | |
910 | fi | |
911 | ||
912 | # Ranges. | |
913 | cli_headline $(( ${level} + 2 )) "Ranges" | |
914 | ||
915 | local ranges=$(dhcpd_subnet_range_list ${proto} ${subnet_id}) | |
916 | if isset ranges; then | |
917 | local range_id $(dhcpd_subnet_range_settings ${proto}) | |
918 | for range_id in ${ranges}; do | |
919 | dhcpd_subnet_range_read ${proto} ${subnet_id} ${range_id} | |
920 | ||
921 | cli_print $(( ${level} + 2 )) \ | |
922 | "#%d: %s - %s" ${range_id} ${START} ${END} | |
923 | done | |
924 | else | |
925 | cli_print $(( ${level} + 2 )) "No ranges have been defined." | |
926 | fi | |
927 | ||
928 | cli_space | |
929 | } | |
930 | ||
931 | function cli_dhcpd_options() { | |
932 | local proto=${1} | |
933 | assert isset proto | |
934 | shift | |
935 | ||
936 | local subnet_id=${1} | |
937 | assert isset subnet_id | |
938 | shift | |
939 | ||
940 | local valid_options=$(dhcpd_subnet_options ${proto}) | |
941 | ||
942 | local key val | |
943 | while [ $# -gt 0 ]; do | |
944 | case "${1}" in | |
945 | *=*) | |
946 | key=$(cli_get_key ${1}) | |
947 | val=$(cli_get_val ${1}) | |
948 | ||
949 | dhcpd_subnet_option_set ${proto} ${subnet_id} ${key} ${val} | |
950 | esac | |
951 | done | |
952 | } | |
953 | ||
9111eb72 MT |
954 | function cli_start() { |
955 | if cli_help_requested $@; then | |
956 | cli_show_man network | |
957 | exit ${EXIT_OK} | |
958 | fi | |
959 | ||
960 | local zones=$(zones_get $@) | |
961 | ||
962 | local zone | |
963 | for zone in ${zones}; do | |
964 | zone_start ${zone} & | |
965 | done | |
966 | ||
967 | wait # until everything is settled | |
968 | } | |
969 | ||
970 | function cli_stop() { | |
971 | if cli_help_requested $@; then | |
972 | cli_show_man network | |
973 | exit ${EXIT_OK} | |
974 | fi | |
975 | ||
976 | local zones=$(zones_get $@) | |
977 | ||
978 | local zone | |
979 | for zone in ${zones}; do | |
980 | zone_stop ${zone} & | |
981 | done | |
982 | ||
983 | wait # until everything is settled | |
984 | } | |
985 | ||
986 | function cli_restart() { | |
987 | if cli_help_requested $@; then | |
988 | cli_show_man network | |
989 | exit ${EXIT_OK} | |
990 | fi | |
991 | ||
992 | cli_stop $@ | |
993 | ||
994 | # Give the system some time to calm down | |
995 | sleep ${TIMEOUT_RESTART} | |
996 | ||
997 | cli_start $@ | |
998 | } | |
999 | ||
1000 | function cli_status() { | |
1001 | if cli_help_requested $@; then | |
1002 | cli_show_man network | |
1003 | exit ${EXIT_OK} | |
1004 | fi | |
1005 | ||
1006 | # When dumping status information, the debug | |
1007 | # mode clutters the console which is not what we want. | |
1008 | # Logging on the console is disabled for a short time. | |
1009 | local log_disable_stdout=${LOG_DISABLE_STDOUT} | |
1010 | LOG_DISABLE_STDOUT="true" | |
1011 | ||
1012 | local zones=$(zones_get $@) | |
1013 | ||
1014 | local zone | |
1015 | for zone in ${zones}; do | |
1016 | zone_status ${zone} | |
1017 | done | |
1018 | ||
1019 | # Reset logging. | |
1020 | LOG_DISABLE_STDOUT=${log_disable_stdout} | |
1021 | } | |
1022 | ||
1023 | function cli_reset() { | |
1024 | if cli_help_requested $@; then | |
1025 | cli_show_man network | |
1026 | exit ${EXIT_OK} | |
1027 | fi | |
1028 | ||
1029 | warning_log "Will reset the whole network configuration!!!" | |
1030 | ||
1031 | # Force mode is disabled by default | |
1032 | local force=0 | |
1033 | ||
1034 | while [ $# -gt 0 ]; do | |
1035 | case "${1}" in | |
1036 | --force|-f) | |
1037 | force=1 | |
1038 | ;; | |
1039 | esac | |
1040 | shift | |
1041 | done | |
1042 | ||
1043 | # If we are not running in force mode, we ask the user if he does know | |
1044 | # what he is doing. | |
1045 | if ! enabled force; then | |
1046 | if ! cli_yesno "Do you really want to reset the whole network configuration?"; then | |
1047 | exit ${EXIT_ERROR} | |
1048 | fi | |
1049 | fi | |
1050 | ||
1051 | local zone | |
1052 | for zone in $(zones_get --all); do | |
1053 | zone_remove ${zone} | |
1054 | done | |
1055 | ||
1056 | local port | |
1057 | for port in $(ports_get --all); do | |
1058 | port_remove ${port} | |
1059 | done | |
1060 | ||
acc9efd5 MT |
1061 | # Flush all DNS servers. |
1062 | dns_server_flush | |
1063 | ||
9111eb72 MT |
1064 | # Re-run the initialization functions |
1065 | init_run | |
1066 | ||
1067 | exit ${EXIT_OK} | |
1068 | } | |
1069 | ||
85afd775 MT |
1070 | # Help function: will show the default man page to the user. |
1071 | # Optionally, there are two arguments taken, the type of hook | |
1072 | # and which hook should be shown. | |
1073 | function cli_help() { | |
1074 | local type=${1} | |
1075 | local what=${2} | |
1076 | ||
1077 | # Remove unknown types. | |
1078 | if ! listmatch ${type} zone port config; then | |
1079 | type="" | |
1080 | fi | |
1081 | ||
1082 | # If no arguments were given, we will show the default page. | |
1083 | if [ -z "${type}" ]; then | |
1084 | cli_show_man network | |
1085 | return ${EXIT_OK} | |
1086 | fi | |
1087 | ||
1088 | if ! hook_exists ${type} ${what}; then | |
1089 | error "Hook of type '${type}' and name '${what}' could not be found." | |
1090 | exit "${EXIT_ERROR}" | |
1091 | fi | |
1092 | ||
1093 | hook_exec ${type} ${what} help | |
1094 | } | |
1095 | ||
6b34112f | 1096 | function cli_dns_server() { |
acc9efd5 | 1097 | if cli_help_requested $@; then |
6b34112f | 1098 | cli_show_man network-dns-server |
acc9efd5 MT |
1099 | exit ${EXIT_OK} |
1100 | fi | |
1101 | ||
1102 | # Get the command. | |
1103 | local cmd=${1}; shift | |
1104 | if [ -z "${cmd}" ]; then | |
6b34112f | 1105 | cli_show_man network-dns-server |
acc9efd5 MT |
1106 | exit ${EXIT_ERROR} |
1107 | fi | |
1108 | ||
6f923dac MT |
1109 | # Get the new server to process (if any). |
1110 | local server=${1} | |
1111 | local priority=${2} | |
1112 | ||
acc9efd5 MT |
1113 | case "${cmd}" in |
1114 | list) | |
acc9efd5 | 1115 | dns_server_list |
e5efaa6b | 1116 | exit ${EXIT_OK} |
acc9efd5 MT |
1117 | ;; |
1118 | add) | |
e5651e17 MT |
1119 | if dns_server_exists ${server}; then |
1120 | error "DNS server '${server}' already exists!" | |
1121 | exit ${EXIT_ERROR} | |
1122 | fi | |
1123 | ||
6f923dac MT |
1124 | log INFO "Adding new DNS server: ${server}" |
1125 | dns_server_add ${server} ${priority} | |
acc9efd5 MT |
1126 | ;; |
1127 | remove) | |
e5651e17 MT |
1128 | if ! dns_server_exists ${server}; then |
1129 | error "DNS server '${server}' does not exist!" | |
1130 | exit ${EXIT_ERROR} | |
1131 | fi | |
1132 | ||
6f923dac MT |
1133 | log INFO "Removing DNS server: ${server}" |
1134 | dns_server_remove ${server} ${priority} | |
acc9efd5 MT |
1135 | ;; |
1136 | update) | |
1137 | # Just run the update afterwards. | |
1138 | ;; | |
1139 | *) | |
1140 | error "No such command: ${cmd}" | |
1141 | exit ${EXIT_ERROR} | |
1142 | esac | |
1143 | ||
1144 | # Update the local DNS configuration after changes have been made. | |
1145 | dns_generate_resolvconf | |
6f923dac | 1146 | radvd_update |
acc9efd5 MT |
1147 | |
1148 | exit ${EXIT_OK} | |
1149 | } | |
1150 | ||
1848564d MT |
1151 | # Process the given action |
1152 | case "${action}" in | |
b8357295 MT |
1153 | init) |
1154 | init_run | |
1155 | ;; | |
1156 | ||
e9df08ad | 1157 | settings|hostname|port|device|zone|start|stop|restart|status|reset|route) |
0a79ea02 | 1158 | cli_${action} $@ |
1848564d MT |
1159 | ;; |
1160 | ||
6c07160e MT |
1161 | # DHCP server configuration (automatically detects which protocol to use). |
1162 | dhcpv6|dhcpv4) | |
1163 | cli_dhcpd ${action/dhcp/ip} $@ | |
1164 | ;; | |
1165 | ||
6b34112f MT |
1166 | # DNS server configuration. |
1167 | dns-server) | |
1168 | cli_dns_server $@ | |
1169 | ;; | |
1170 | ||
fe4555b5 | 1171 | ""|help|--help|-h) |
85afd775 | 1172 | cli_help $@ |
1848564d | 1173 | ;; |
fe4555b5 | 1174 | |
1848564d | 1175 | *) |
fe4555b5 | 1176 | error "Invalid command given: ${action}" |
de28a630 | 1177 | cli_usage "network help" |
1848564d | 1178 | exit ${EXIT_CONF_ERROR} |
fe4555b5 | 1179 | ;; |
1848564d | 1180 | esac |
85afd775 MT |
1181 | |
1182 | exit ${EXIT_OK} |