]> git.ipfire.org Git - people/stevee/network.git/blame - network
Add some minor input validation for configuration settings.
[people/stevee/network.git] / network
CommitLineData
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
23while [ $# -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
34done
35
3647b19f
MT
36. /usr/lib/network/functions
37
9111eb72
MT
38function cli_config() {
39 if cli_help_requested $@; then
40 cli_show_man network-config
41 exit ${EXIT_OK}
42 fi
43
44 if [ -n "${1}" ]; then
45 config_set $@
46 network_config_write
47 else
48 network_config_print
49 fi
50}
51
52function cli_device() {
6c74a64c
MT
53 if cli_help_requested $@; then
54 cli_show_man network-device
55 exit ${EXIT_OK}
56 fi
57
9111eb72
MT
58 local device=${1}
59 local action=${2}
60 shift 2
61
ec63256a
MT
62 if ! isset device; then
63 cli_show_man network-device
9111eb72
MT
64 return ${EXIT_ERROR}
65 fi
66
ec63256a
MT
67 assert device_exists ${device}
68
9111eb72
MT
69 case "${action}" in
70 discover)
9111eb72
MT
71 cli_device_discover ${device} $@
72 ;;
ec63256a
MT
73 status)
74 cli_device_status ${device}
9111eb72 75 ;;
6c74a64c
MT
76 unlock)
77 cli_device_serial_unlock ${device} $@
78 ;;
9111eb72
MT
79 *)
80 cli_show_man network-device
81 ;;
82 esac
ec63256a
MT
83
84 return ${EXIT_OK}
85}
86
87function cli_device_status() {
88 local device=${1}
89 assert device_exists ${device}
90
6c74a64c
MT
91 # Disable debugging output here.
92 local log_disable_stdout=${LOG_DISABLE_STDOUT}
93 LOG_DISABLE_STDOUT="true"
94
ec63256a
MT
95 # Save the type of the device for later.
96 local type=$(device_get_type ${device})
97
98 cli_headline 1 "Device status: ${device}"
99 cli_print_fmt1 1 "Name" "${device}"
100
6c74a64c
MT
101 # Handle serial devices.
102 if [ "${type}" = "serial" ]; then
103 cli_device_status_serial ${device}
104 return $?
105 fi
106
ec63256a
MT
107 # Print the device status.
108 device_is_up ${device} &>/dev/null
109 local status=$?
110
111 case "${status}" in
112 ${EXIT_TRUE})
113 status="${COLOUR_GREEN}UP${COLOUR_NORMAL}"
114 ;;
115 ${EXIT_FALSE})
116 status="${COLOUR_RED}DOWN${COLOUR_NORMAL}"
117 ;;
118 esac
119
120 cli_print_fmt1 1 "Status" "${status}"
121 cli_print_fmt1 1 "Type" "${type}"
122 cli_print_fmt1 1 "Address" "$(device_get_address ${device})"
123 cli_space
124
125 # Print the link speed for ethernet devices.
126 case "${type}" in
127 ethernet)
128 cli_print_fmt1 1 "Link" \
129 "$(device_get_speed ${device}) MBit/s $(device_get_duplex ${device}) duplex"
130 ;;
131 esac
132
133 cli_print_fmt1 1 "MTU" "$(device_get_mtu ${device})"
134 cli_space
135
3cb2fc42
MT
136 # Print device statistics.
137 cli_device_stats 2 ${device}
ec63256a
MT
138
139 # Print some more information.
140 device_has_carrier ${device} &>/dev/null
141 cli_print_fmt1 1 "Has carrier?" "$(cli_print_bool $?)"
142
143 device_is_promisc ${device} &>/dev/null
144 cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)"
145 cli_space
146
147 # Print all virtual devices.
148 local virtuals=$(device_get_virtuals ${device})
149 if [ -n "${virtuals}" ]; then
150 cli_headline 2 "Virtual devices"
151
152 local virtual
153 for virtual in ${virtuals}; do
154 cli_print 2 "* %-6s - %s" "${virtual}" "$(device_get_address ${virtual})"
155 done
156 cli_space
157 fi
158
6c74a64c
MT
159 # Reset the logging level.
160 LOG_DISABLE_STDOUT=${log_disable_stdout}
161}
162
163function cli_device_status_serial() {
164 local device=${1}
165 assert device_is_serial ${device}
166
167 serial_is_locked ${device} &>/dev/null
168 local locked=$?
169
170 cli_print_fmt1 1 "Locked" "$(cli_print_bool ${locked})"
171 cli_space
172
173 # Cannot go on when the device is locked.
174 [ ${locked} -eq ${EXIT_TRUE} ] && return ${EXIT_OK}
175
176 cli_print_fmt1 1 "Manufacturer" \
177 "$(modem_get_manufacturer ${device})"
178 cli_print_fmt1 1 "Model" \
179 "$(modem_get_model ${device})"
180 cli_print_fmt1 1 "Software version" \
181 "$(modem_get_software_version ${device})"
182
183 if modem_is_mobile ${device}; then
184 cli_print_fmt1 1 "IMEI" \
185 "$(modem_get_device_imei ${device})"
186 cli_space
187
188 cli_headline 2 "Network status"
189 modem_sim_status ${device} &>/dev/null
190 local sim_status_code=$?
191
192 local sim_status="unknown"
193 case "${sim_status_code}" in
194 ${EXIT_SIM_READY})
195 sim_status="SIM ready"
196 ;;
197 ${EXIT_SIM_PIN})
198 sim_status="PIN locked"
199 ;;
200 ${EXIT_SIM_PUK})
201 sim_status="PUK locked"
202 ;;
203 esac
204 cli_print_fmt1 2 "SIM status" "${sim_status}"
205
206 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
207 cli_print_fmt1 2 "IMSI" \
208 "$(modem_get_sim_imsi ${device})"
209 cli_print_fmt1 2 "Operator" \
210 "$(modem_get_network_operator ${device})"
211 cli_print_fmt1 2 "Mode" \
212 "$(modem_get_network_mode ${device})"
213 cli_print_fmt1 2 "Signal quality" \
214 "$(modem_get_signal_quality ${device}) dBm"
215
216 local ber=$(modem_get_bit_error_rate ${device})
217 isset ber || ber="unknown"
218 cli_print_fmt1 2 "Bit Error Rate" "${ber}"
219 fi
220 fi
221 cli_space
9111eb72
MT
222}
223
224function cli_device_discover() {
225 local device=${1}
226 shift
227
228 local device_type=$(device_get_type ${device})
229 if [ "${device_type}" != "real" ]; then
230 return ${EXIT_OK}
231 fi
232
233 local raw
234
235 while [ $# -gt 0 ]; do
236 case "${1}" in
237 --raw)
238 raw=1
239 ;;
240 esac
241 shift
242 done
243
244 local up
245 device_is_up ${device} && up=1
246 device_set_up ${device}
247
248 enabled raw || echo "${device}"
249
250 local hook
251 local out
252 local ret
253 for hook in $(hook_zone_get_all); do
254 out=$(hook_zone_exec ${hook} discover ${device})
255 ret=$?
256
257 [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue
258
259 if enabled raw; then
260 case "${ret}" in
261 ${DISCOVER_OK})
262 echo "${hook}: OK"
263 local line
264 while read line; do
265 echo "${hook}: ${line}"
266 done <<<"${out}"
267 ;;
268
269 ${DISCOVER_ERROR})
270 echo "${hook}: FAILED"
271 ;;
272 esac
273 else
274 case "${ret}" in
275 ${DISCOVER_OK})
276 echo " ${hook} was successful."
277 local line
278 while read line; do
279 echo " ${line}"
280 done <<<"${out}"
281 ;;
282
283 ${DISCOVER_ERROR})
284 echo " ${hook} failed."
285 ;;
286 esac
287 fi
288 done
289
290 echo # New line
291
292 [ "${up}" = "1" ] || device_set_down ${device}
293}
294
6c74a64c
MT
295function cli_device_serial_unlock() {
296 if cli_help_requested $@; then
297 cli_show_man network-device
298 exit ${EXIT_OK}
299 fi
300
301 local device=${1}
302 assert isset device
303
304 if ! device_is_serial ${device}; then
305 error "${device} is not a serial device."
306 error "Unlocking is only supported for serial devices."
307 exit ${EXIT_ERROR}
308 fi
309
310 # Read the current state of the SIM card.
311 modem_sim_status ${device} &>/dev/null
312 local sim_status_code=$?
313
314 # If the SIM card is already unlocked, we don't need to do anything.
315 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
316 print "The SIM card is already unlocked."
317 exit ${EXIT_OK}
318
319 # If the SIM card is in an unknown state, we cannot do anything.
320 elif [ ${sim_status_code} -eq ${EXIT_SIM_UNKNOWN} ]; then
321 error "The SIM card is in an unknown state."
322 exit ${EXIT_ERROR}
323 fi
324
325 # Ask for the code.
326 local code=${2}
327 local require_new_pin="false"
328 local new_pin
329
330 while ! isinteger code; do
331 local message
332 case "${sim_status_code}" in
333 ${EXIT_SIM_PIN})
334 message="Please enter PIN:"
335 ;;
336 ${EXIT_SIM_PUK})
337 message="Please enter PUK:"
338 require_new_pin="true"
339 ;;
340 esac
341 assert isset message
342
343 echo -n "${message} "
344 read -s code
345 echo # Print newline.
346
347 if enabled require_new_pin; then
348 local i new_pin2
349 for i in 0 1; do
350 case "${i}" in
351 0)
352 message="Please enter a new PIN code:"
353 ;;
354 1)
355 message="Please confirm the new PIN code:"
356 ;;
357 esac
358
359 echo -n "${message} "
360 read -s new_pin2
361 echo # Print newline.
362
363 if [ -n "${new_pin}" ]; then
364 if [ "${new_pin}" != "${new_pin2}" ]; then
365 error "The entered PIN codes did not match."
366 exit ${EXIT_ERROR}
367 fi
368 else
369 new_pin=${new_pin2}
370 fi
371 done
372 fi
373 done
374
375 # Trying to unlock the SIM card.
376 modem_sim_unlock ${device} ${code} ${new_pin}
377
378 exit $?
379}
380
9111eb72
MT
381function cli_hostname() {
382 if cli_help_requested $@; then
383 cli_show_man network
384 exit ${EXIT_OK}
385 fi
386
387 local hostname=${1}
388
389 if [ -n "${hostname}" ]; then
390 config_hostname ${hostname}
391 log INFO "Hostname was set to '${hostname}'."
392 log INFO "Changes do only take affect after reboot."
393 exit ${EXIT_OK}
394 fi
395
396 echo "$(config_hostname)"
397 exit ${EXIT_OK}
398}
399
400function cli_port() {
401 if cli_help_requested $@; then
402 cli_show_man network-port
403 exit ${EXIT_OK}
404 fi
405
406 local action
407 local port
408
409 if port_exists ${1}; then
410 port=${1}
411 action=${2}
412 shift 2
413
414 # Action aliases
415 case "${action}" in
416 start)
417 action="up"
418 ;;
419 stop)
420 action="down"
421 ;;
422 show)
423 action="status"
424 ;;
425 esac
426
427 case "${action}" in
428 edit|up|down|status)
429 port_${action} ${port} $@
430 ;;
431 *)
432 error "Unrecognized argument: ${action}"
433 exit ${EXIT_ERROR}
434 ;;
435 esac
436 else
437 action=${1}
438 shift
439
440 case "${action}" in
441 create|destroy)
442 port_${action} $@
443 ;;
444 *)
445 error "Unrecognized argument: ${action}"
446 exit ${EXIT_ERROR}
447 ;;
448 esac
449 fi
450}
451
452function cli_zone() {
453 if cli_help_requested $@; then
454 cli_show_man network-zone
455 exit ${EXIT_OK}
456 fi
457
458 local action
459 local zone
460
461 if zone_name_is_valid ${1}; then
462 zone=${1}
463 action=${2}
464 shift 2
465
466 # Action aliases
467 case "${action}" in
468 start)
469 action="up"
470 ;;
471 stop)
472 action="down"
473 ;;
474 show)
475 action="status"
476 ;;
477 esac
478
479 case "${action}" in
480 config|down|edit|port|status|up)
481 zone_${action} ${zone} $@
482 ;;
483 *)
484 error "Unrecognized argument: ${action}"
485 cli_show_man network-zone
486 exit ${EXIT_ERROR}
487 ;;
488 esac
489 else
490 action=${1}
491 shift
492
493 case "${action}" in
494 create)
495 zone_${action} $@
496 ;;
497 remove)
498 cli_zone_remove $@
499 ;;
500 list-hooks)
501 cli_list_hooks zone $@
502 ;;
503 ""|*)
504 if [ -n "${action}" ]; then
505 error "Unrecognized argument: '${action}'"
506 echo
507 fi
508
509 cli_show_man network-zone
510 exit ${EXIT_ERROR}
511 ;;
512 esac
513 fi
514}
515
516# Removes a zone either immediately, if it is currently down,
517# or adds a tag that the removal will be done when the zone
518# is brought down the next time.
519function cli_zone_remove() {
520 if cli_help_requested $@; then
521 cli_show_man network-zone
522 exit ${EXIT_OK}
523 fi
524
525 local zone=${1}
526 assert zone_exists ${zone}
527
528 if zone_is_up ${zone}; then
529 echo "Zone '${zone}' is up and will be removed when it goes down the next time."
530 zone_remove ${zone}
531 else
532 echo "Removing zone '${zone}' now..."
533 zone_remove_now ${zone}
534 fi
535
536 exit ${EXIT_OK}
537}
538
539function cli_list_hooks() {
540 local type=${1}
541 shift
542
543 if cli_help_requested $@; then
544 cli_show_man network-zone
545 exit ${EXIT_OK}
546 fi
547
548 local hook_dir=$(hook_dir ${type})
549 local hook
550
551 for hook in ${hook_dir}/*; do
552 hook=$(basename ${hook})
553 if hook_exists ${type} ${hook}; then
554 echo "${hook}"
555 fi
556 done | sort -u
557}
558
559function cli_start() {
560 if cli_help_requested $@; then
561 cli_show_man network
562 exit ${EXIT_OK}
563 fi
564
565 local zones=$(zones_get $@)
566
567 local zone
568 for zone in ${zones}; do
569 zone_start ${zone} &
570 done
571
572 wait # until everything is settled
573}
574
575function cli_stop() {
576 if cli_help_requested $@; then
577 cli_show_man network
578 exit ${EXIT_OK}
579 fi
580
581 local zones=$(zones_get $@)
582
583 local zone
584 for zone in ${zones}; do
585 zone_stop ${zone} &
586 done
587
588 wait # until everything is settled
589}
590
591function cli_restart() {
592 if cli_help_requested $@; then
593 cli_show_man network
594 exit ${EXIT_OK}
595 fi
596
597 cli_stop $@
598
599 # Give the system some time to calm down
600 sleep ${TIMEOUT_RESTART}
601
602 cli_start $@
603}
604
605function cli_status() {
606 if cli_help_requested $@; then
607 cli_show_man network
608 exit ${EXIT_OK}
609 fi
610
611 # When dumping status information, the debug
612 # mode clutters the console which is not what we want.
613 # Logging on the console is disabled for a short time.
614 local log_disable_stdout=${LOG_DISABLE_STDOUT}
615 LOG_DISABLE_STDOUT="true"
616
617 local zones=$(zones_get $@)
618
619 local zone
620 for zone in ${zones}; do
621 zone_status ${zone}
622 done
623
624 # Reset logging.
625 LOG_DISABLE_STDOUT=${log_disable_stdout}
626}
627
628function cli_reset() {
629 if cli_help_requested $@; then
630 cli_show_man network
631 exit ${EXIT_OK}
632 fi
633
634 warning_log "Will reset the whole network configuration!!!"
635
636 # Force mode is disabled by default
637 local force=0
638
639 while [ $# -gt 0 ]; do
640 case "${1}" in
641 --force|-f)
642 force=1
643 ;;
644 esac
645 shift
646 done
647
648 # If we are not running in force mode, we ask the user if he does know
649 # what he is doing.
650 if ! enabled force; then
651 if ! cli_yesno "Do you really want to reset the whole network configuration?"; then
652 exit ${EXIT_ERROR}
653 fi
654 fi
655
656 local zone
657 for zone in $(zones_get --all); do
658 zone_remove ${zone}
659 done
660
661 local port
662 for port in $(ports_get --all); do
663 port_remove ${port}
664 done
665
acc9efd5
MT
666 # Flush all DNS servers.
667 dns_server_flush
668
9111eb72
MT
669 # Re-run the initialization functions
670 init_run
671
672 exit ${EXIT_OK}
673}
674
85afd775
MT
675# Help function: will show the default man page to the user.
676# Optionally, there are two arguments taken, the type of hook
677# and which hook should be shown.
678function cli_help() {
679 local type=${1}
680 local what=${2}
681
682 # Remove unknown types.
683 if ! listmatch ${type} zone port config; then
684 type=""
685 fi
686
687 # If no arguments were given, we will show the default page.
688 if [ -z "${type}" ]; then
689 cli_show_man network
690 return ${EXIT_OK}
691 fi
692
693 if ! hook_exists ${type} ${what}; then
694 error "Hook of type '${type}' and name '${what}' could not be found."
695 exit "${EXIT_ERROR}"
696 fi
697
698 hook_exec ${type} ${what} help
699}
700
acc9efd5
MT
701function cli_dns() {
702 if cli_help_requested $@; then
703 cli_show_man network-dns
704 exit ${EXIT_OK}
705 fi
706
707 # Get the command.
708 local cmd=${1}; shift
709 if [ -z "${cmd}" ]; then
710 cli_show_man network-dns
711 exit ${EXIT_ERROR}
712 fi
713
6f923dac
MT
714 # Get the new server to process (if any).
715 local server=${1}
716 local priority=${2}
717
acc9efd5
MT
718 case "${cmd}" in
719 list)
720 __dns_server_println "SERVER" "PRIORITY"
721 dns_server_list
e5efaa6b 722 exit ${EXIT_OK}
acc9efd5
MT
723 ;;
724 add)
6f923dac
MT
725 log INFO "Adding new DNS server: ${server}"
726 dns_server_add ${server} ${priority}
acc9efd5
MT
727 ;;
728 remove)
6f923dac
MT
729 log INFO "Removing DNS server: ${server}"
730 dns_server_remove ${server} ${priority}
acc9efd5
MT
731 ;;
732 update)
733 # Just run the update afterwards.
734 ;;
735 *)
736 error "No such command: ${cmd}"
737 exit ${EXIT_ERROR}
738 esac
739
740 # Update the local DNS configuration after changes have been made.
741 dns_generate_resolvconf
6f923dac 742 radvd_update
acc9efd5
MT
743
744 exit ${EXIT_OK}
745}
746
1848564d
MT
747# Process the given action
748case "${action}" in
b8357295
MT
749 init)
750 init_run
751 ;;
752
acc9efd5 753 config|hostname|port|device|zone|start|stop|restart|status|reset|dns)
0a79ea02 754 cli_${action} $@
1848564d
MT
755 ;;
756
fe4555b5 757 ""|help|--help|-h)
85afd775 758 cli_help $@
1848564d 759 ;;
fe4555b5 760
1848564d 761 *)
fe4555b5 762 error "Invalid command given: ${action}"
de28a630 763 cli_usage "network help"
1848564d 764 exit ${EXIT_CONF_ERROR}
fe4555b5 765 ;;
1848564d 766esac
85afd775
MT
767
768exit ${EXIT_OK}