2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
22 # Parse the command line
23 while [ $# -gt 0 ]; do
33 [ -n "${action}" ] && break
36 .
/usr
/lib
/network
/functions
38 # Read network settings
41 function cli_settings
() {
42 if cli_help_requested $@
; then
43 cli_show_man network-settings
47 if [ -n "${1}" ]; then
49 network_settings_write
51 network_settings_print
55 function cli_device
() {
56 if cli_help_requested $@
; then
57 cli_show_man network-device
65 if ! isset device
; then
66 cli_show_man network-device
70 assert device_exists
${device}
74 cli_device_discover
${device} $@
77 cli_device_monitor
"${device}" $@
80 cli_device_status
${device}
83 cli_device_serial_unlock
${device} $@
86 cli_device_send_ussd_command
"${device}" $@
89 cli_show_man network-device
96 function cli_device_status
() {
98 assert device_exists
${device}
100 # Disable debugging output here.
101 local log_disable_stdout
=${LOG_DISABLE_STDOUT}
102 LOG_DISABLE_STDOUT
="true"
104 # Save the type of the device for later.
105 local type=$
(device_get_type
${device})
107 cli_headline
1 "Device status: ${device}"
108 cli_print_fmt1
1 "Name" "${device}"
110 # Handle serial devices.
111 if [ "${type}" = "serial" ]; then
112 cli_device_status_serial
${device}
116 # Print the device status.
117 device_is_up
${device} &>/dev
/null
122 status
="${CLR_GREEN_B}UP${CLR_RESET}"
125 status
="${CLR_RED_B}DOWN${CLR_RESET}"
129 cli_print_fmt1
1 "Status" "${status}"
130 cli_print_fmt1
1 "Type" "${type}"
131 cli_print_fmt1
1 "Address" "$(device_get_address ${device})"
134 # Print the link speed for ethernet devices.
135 if device_is_up
${device} &>/dev
/null
; then
136 local link
="$(device_get_link_string "${device}")"
138 cli_print_fmt1
1 "Link" "${link}"
142 cli_print_fmt1
1 "MTU" "$(device_get_mtu ${device})"
145 # Print device statistics.
146 cli_device_stats
2 ${device}
148 # Print some more information.
149 device_has_carrier
${device} &>/dev
/null
150 cli_print_fmt1
1 "Has carrier?" "$(cli_print_bool $?)"
152 device_is_promisc
${device} &>/dev
/null
153 cli_print_fmt1
1 "Promisc" "$(cli_print_bool $?)"
156 # Print all vlan devices.
157 local vlans
=$
(device_get_vlans
${device})
158 if [ -n "${vlans}" ]; then
159 cli_headline
2 "VLAN devices"
162 for vlan
in ${vlans}; do
163 cli_print
2 "* %-6s - %s" "${vlan}" "$(device_get_address ${vlan})"
168 # Reset the logging level.
169 LOG_DISABLE_STDOUT
=${log_disable_stdout}
172 function cli_device_status_serial
() {
174 assert device_is_serial
${device}
176 serial_is_locked
${device} &>/dev
/null
179 cli_print_fmt1
1 "Locked" "$(cli_print_bool ${locked})"
182 # Cannot go on when the device is locked.
183 [ ${locked} -eq ${EXIT_TRUE} ] && return ${EXIT_OK}
185 cli_print_fmt1
1 "Manufacturer" \
186 "$(modem_get_manufacturer ${device})"
187 cli_print_fmt1
1 "Model" \
188 "$(modem_get_model ${device})"
189 cli_print_fmt1
1 "Software version" \
190 "$(modem_get_software_version ${device})"
192 if modem_is_mobile
${device}; then
193 cli_print_fmt1
1 "IMEI" \
194 "$(modem_get_device_imei ${device})"
197 cli_headline
2 "Network status"
198 modem_sim_status
${device} &>/dev
/null
199 local sim_status_code
=$?
201 local sim_status
="unknown"
202 case "${sim_status_code}" in
204 sim_status
="SIM ready"
207 sim_status
="PIN locked"
210 sim_status
="PUK locked"
213 cli_print_fmt1
2 "SIM status" "${sim_status}"
215 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
216 cli_print_fmt1
2 "IMSI" \
217 "$(modem_get_sim_imsi ${device})"
218 cli_print_fmt1
2 "Operator" \
219 "$(modem_get_network_operator ${device})"
220 cli_print_fmt1
2 "Mode" \
221 "$(modem_get_network_mode ${device})"
222 cli_print_fmt1
2 "Signal quality" \
223 "$(modem_get_signal_quality ${device}) dBm"
225 local ber
=$
(modem_get_bit_error_rate
${device})
226 isset ber || ber
="unknown"
227 cli_print_fmt1
2 "Bit Error Rate" "${ber}"
233 function cli_device_discover
() {
237 local device_type
=$
(device_get_type
${device})
238 if [ "${device_type}" != "real" ]; then
244 while [ $# -gt 0 ]; do
254 device_is_up
${device} && up
=1
255 device_set_up
${device}
257 enabled raw ||
echo "${device}"
262 for hook
in $
(hook_zone_get_all
); do
263 out
=$
(hook_zone_exec
${hook} discover
${device})
266 [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue
274 echo "${hook}: ${line}"
279 echo "${hook}: FAILED"
285 echo " ${hook} was successful."
293 echo " ${hook} failed."
301 [ "${up}" = "1" ] || device_set_down
${device}
304 function cli_device_serial_unlock
() {
305 if cli_help_requested $@
; then
306 cli_show_man network-device
313 if ! device_is_serial
${device}; then
314 error
"${device} is not a serial device."
315 error
"Unlocking is only supported for serial devices."
319 # Read the current state of the SIM card.
320 modem_sim_status
${device} &>/dev
/null
321 local sim_status_code
=$?
323 # If the SIM card is already unlocked, we don't need to do anything.
324 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
325 print
"The SIM card is already unlocked."
328 # If the SIM card is in an unknown state, we cannot do anything.
329 elif [ ${sim_status_code} -eq ${EXIT_SIM_UNKNOWN} ]; then
330 error
"The SIM card is in an unknown state."
336 local require_new_pin
="false"
339 while ! isinteger code
; do
341 case "${sim_status_code}" in
343 message
="Please enter PIN:"
346 message
="Please enter PUK:"
347 require_new_pin
="true"
352 echo -n "${message} "
354 echo # Print newline.
356 if enabled require_new_pin
; then
361 message
="Please enter a new PIN code:"
364 message
="Please confirm the new PIN code:"
368 echo -n "${message} "
370 echo # Print newline.
372 if [ -n "${new_pin}" ]; then
373 if [ "${new_pin}" != "${new_pin2}" ]; then
374 error
"The entered PIN codes did not match."
384 # Trying to unlock the SIM card.
385 modem_sim_unlock
${device} ${code} ${new_pin}
390 function cli_device_send_ussd_command
() {
398 while [ $# -gt 0 ]; do
401 timeout
="$(cli_get_val "${1}")"
404 if isset
command; then
405 warning
"Unrecognized argument: ${1}"
414 assert device_is_serial
"${device}"
417 if isset timeout
; then
418 args
="${args} --timeout=${timeout}"
421 modem_ussd_send_command
"${device}" "${command}" ${args}
425 function cli_device_monitor() {
429 if ! device_is_wireless "${device}"; then
430 error "This action only works with wireless devices. Exiting.
"
434 wireless_monitor "${device}"
438 function cli_hostname() {
439 if cli_help_requested $@; then
446 if [ -n "${hostname}" ]; then
447 config_hostname ${hostname}
448 log INFO "Hostname was
set to
'${hostname}'.
"
449 log INFO "Changes
do only take affect after reboot.
"
453 echo "$
(config_hostname
)"
457 function cli_port() {
458 if cli_help_requested $@; then
459 cli_show_man network-port
466 if port_exists ${1}; then
486 port_${action} ${port} $@
489 error "Unrecognized argument
: ${action}"
502 error "Unrecognized argument
: ${action}"
509 function cli_zone() {
510 if cli_help_requested $@; then
511 cli_show_man network-zone
518 if zone_name_is_valid ${1}; then
537 config|disable|down|edit|enable|port|status|up)
538 zone_${action} ${zone} $@
541 error "Unrecognized argument
: ${action}"
542 cli_show_man network-zone
558 cli_list_hooks zone $@
561 if [ -n "${action}" ]; then
562 error "Unrecognized argument
: '${action}'"
566 cli_show_man network-zone
573 # Removes a zone either immediately, if it is currently down,
574 # or adds a tag that the removal will be done when the zone
575 # is brought down the next time.
576 function cli_zone_remove() {
577 if cli_help_requested $@; then
578 cli_show_man network-zone
583 assert zone_exists ${zone}
585 if zone_is_up ${zone}; then
586 echo "Zone
'${zone}' is up and will be removed when it goes down the next
time.
"
589 echo "Removing zone
'${zone}' now...
"
590 zone_remove_now ${zone}
596 function cli_list_hooks() {
600 if cli_help_requested $@; then
601 cli_show_man network-zone
605 local hook_dir=$(hook_dir ${type})
608 for hook in ${hook_dir}/*; do
609 hook=$(basename ${hook})
610 if hook_exists ${type} ${hook}; then
616 function cli_route() {
617 if cli_help_requested $@; then
618 cli_show_man network-route
630 # Remove an existing route.
640 error "Unrecognized action
: ${action}"
641 cli_run_help network route
647 # Applying all routes.
653 function cli_dhcpd() {
657 if cli_help_requested $@; then
658 cli_show_man network-dhcp
667 dhcpd_edit ${proto} $@
676 dhcpd_reload ${proto}
679 cli_dhcpd_subnet ${proto} $@
682 cli_dhcpd_show ${proto} $@
685 error "Unrecognized action
: ${action}"
686 cli_run_help network dhcpvN
695 function cli_dhcpd_show() {
699 local settings=$(dhcpd_settings ${proto})
700 assert isset settings
703 dhcpd_global_settings_read ${proto}
705 cli_headline 1 "Dynamic Host Configuration Protocol Daemon
for ${proto/ip/IP}"
709 cli_headline 2 "Lease
times"
710 if isinteger VALID_LIFETIME; then
711 cli_print_fmt1 2 "Valid lifetime
" "${VALID_LIFETIME}s
"
714 if isinteger PREFERRED_LIFETIME; then
715 cli_print_fmt1 2 "Preferred lifetime
" "${PREFERRED_LIFETIME}s
"
721 cli_print_fmt1 1 "Authoritative
" $(cli_print_enabled AUTHORITATIVE)
724 cli_headline 2 "Lease
times"
725 cli_print_fmt1 2 "Default lease
time" "${DEFAULT_LEASE_TIME}s
"
726 cli_print_fmt1 2 "Max. lease
time" "${MAX_LEASE_TIME}s
"
728 if isset MIN_LEASE_TIME; then
729 cli_print_fmt1 2 "Min. lease
time" "${MIN_LEASE_TIME}s
"
738 dhcpd_global_options_read ${proto} ${subnet_id}
740 # Print the options if any.
741 if [ ${#options[*]} -gt 0 ]; then
742 cli_headline 2 "Options
"
745 for option in $(dhcpd_options ${proto}); do
746 [ -n "${options[${option}]}" ] || continue
749 "${option}" "${options[${option}]}"
755 local subnets=$(dhcpd_subnet_list ${proto})
756 if [ -n "${subnets}" ]; then
757 cli_headline 2 "Subnets
"
759 for subnet_id in ${subnets}; do
760 cli_dhcpd_subnet_show ${proto} ${subnet_id} 2
765 function cli_dhcpd_subnet() {
769 if cli_help_requested $@; then
770 cli_show_man network-dhcp-subnet
779 dhcpd_subnet_new ${proto} $@
782 dhcpd_subnet_remove ${proto} $@
785 local subnet_id=${action}
787 if ! dhcpd_subnet_exists ${proto} ${subnet_id}; then
788 error "The given subnet with ID
${subnet_id} does not exist.
"
798 dhcpd_subnet_edit ${proto} ${subnet_id} $@
801 if [ ${ret} -eq ${EXIT_OK} ]; then
802 dhcpd_reload ${proto}
807 cli_dhcpd_subnet_range ${proto} ${subnet_id} $@
811 cli_dhcpd_subnet_show ${proto} ${subnet_id} $@
815 cli_dhcpd_subnet_options ${proto} ${subnet_id} $@
819 error "Unrecognized action
: ${action}"
820 cli_run_help network dhcpvN subnet
827 for subnet_id in $(dhcpd_subnet_list ${proto}); do
828 cli_dhcpd_subnet_show ${proto} ${subnet_id}
832 error "Unrecognized action
: ${action}"
833 cli_run_help network dhcpvN subnet
842 function cli_dhcpd_subnet_range() {
848 assert isset subnet_id
856 dhcpd_subnet_range_new ${proto} ${subnet_id} $@
860 dhcpd_subnet_range_remove ${proto} ${subnet_id} $@
864 error "Unrecognized action
: ${action}"
865 cli_run_help network dhcpvN subnet range
871 function cli_dhcpd_subnet_show() {
876 assert isset subnet_id
879 isset level || level=0
881 local $(dhcpd_subnet_settings ${proto})
883 # Read in configuration settings.
884 dhcpd_subnet_read ${proto} ${subnet_id}
886 cli_headline $(( ${level} + 1 )) \
887 "DHCP
${proto/ip/} subnet declaration
#${subnet_id}"
888 cli_print_fmt1 $
(( ${level} + 1 )) \
889 "Subnet" "${ADDRESS}/${PREFIX}"
894 dhcpd_subnet_options_read
${proto} ${subnet_id}
896 # Print the options if any.
897 if [ ${#options[*]} -gt 0 ]; then
898 cli_headline $
(( ${level} + 2 )) "Options"
901 for option
in $
(dhcpd_subnet_options
${proto}); do
902 [ -n "${options[${option}]}" ] ||
continue
904 cli_print_fmt1 $
(( ${level} + 2 )) \
905 "${option}" "${options[${option}]}"
911 cli_headline $
(( ${level} + 2 )) "Ranges"
913 local ranges
=$
(dhcpd_subnet_range_list
${proto} ${subnet_id})
914 if isset ranges
; then
915 local range_id $
(dhcpd_subnet_range_settings
${proto})
916 for range_id
in ${ranges}; do
917 dhcpd_subnet_range_read
${proto} ${subnet_id} ${range_id}
919 cli_print $
(( ${level} + 2 )) \
920 "#%d: %s - %s" ${range_id} ${START} ${END}
923 cli_print $
(( ${level} + 2 )) "No ranges have been defined."
929 function cli_dhcpd_options
() {
935 assert isset subnet_id
938 local valid_options
=$
(dhcpd_subnet_options
${proto})
941 while [ $# -gt 0 ]; do
944 key
=$
(cli_get_key
${1})
945 val
=$
(cli_get_val
${1})
947 dhcpd_subnet_option_set
${proto} ${subnet_id} ${key} ${val}
952 function cli_start
() {
953 if cli_help_requested $@
; then
958 local zones
=$
(zones_get $@
)
961 for zone
in ${zones}; do
965 wait # until everything is settled
968 function cli_stop
() {
969 if cli_help_requested $@
; then
974 local zones
=$
(zones_get $@
)
977 for zone
in ${zones}; do
981 wait # until everything is settled
984 function cli_restart
() {
985 if cli_help_requested $@
; then
992 # Give the system some time to calm down
993 sleep ${TIMEOUT_RESTART}
998 function cli_status
() {
999 if cli_help_requested $@
; then
1000 cli_show_man network
1004 # When dumping status information, the debug
1005 # mode clutters the console which is not what we want.
1006 # Logging on the console is disabled for a short time.
1007 local log_disable_stdout
=${LOG_DISABLE_STDOUT}
1008 LOG_DISABLE_STDOUT
="true"
1010 local zones
=$
(zones_get $@
)
1013 for zone
in ${zones}; do
1018 LOG_DISABLE_STDOUT
=${log_disable_stdout}
1021 function cli_reset
() {
1022 if cli_help_requested $@
; then
1023 cli_show_man network
1027 warning_log
"Will reset the whole network configuration!!!"
1029 # Force mode is disabled by default
1032 while [ $# -gt 0 ]; do
1041 # If we are not running in force mode, we ask the user if he does know
1043 if ! enabled force
; then
1044 if ! cli_yesno
"Do you really want to reset the whole network configuration?"; then
1050 for zone
in $
(zones_get
--all); do
1055 for port
in $
(ports_get
--all); do
1059 # Flush all DNS servers.
1062 # Re-run the initialization functions
1068 # Help function: will show the default man page to the user.
1069 # Optionally, there are two arguments taken, the type of hook
1070 # and which hook should be shown.
1071 function cli_help
() {
1075 # Remove unknown types.
1076 if ! listmatch
${type} zone port config
; then
1080 # If no arguments were given, we will show the default page.
1081 if [ -z "${type}" ]; then
1082 cli_show_man network
1086 if ! hook_exists
${type} ${what}; then
1087 error
"Hook of type '${type}' and name '${what}' could not be found."
1088 exit "${EXIT_ERROR}"
1091 hook_exec
${type} ${what} help
1094 function cli_dns_server
() {
1095 if cli_help_requested $@
; then
1096 cli_show_man network-dns-server
1101 local cmd
=${1}; shift
1102 if [ -z "${cmd}" ]; then
1103 cli_show_man network-dns-server
1107 # Get the new server to process (if any).
1117 if dns_server_exists
${server}; then
1118 error
"DNS server '${server}' already exists!"
1122 log INFO
"Adding new DNS server: ${server}"
1123 dns_server_add
${server} ${priority}
1126 if ! dns_server_exists
${server}; then
1127 error
"DNS server '${server}' does not exist!"
1131 log INFO
"Removing DNS server: ${server}"
1132 dns_server_remove
${server} ${priority}
1135 # Just run the update afterwards.
1138 error
"No such command: ${cmd}"
1142 # Update the local DNS configuration after changes have been made.
1143 dns_generate_resolvconf
1149 # Process the given action
1155 settings|hostname|port|device|zone|start|stop|restart|status|
reset|route
)
1159 # DHCP server configuration (automatically detects which protocol to use).
1161 cli_dhcpd
${action/dhcp/ip} $@
1164 # DNS server configuration.
1174 error
"Invalid command given: ${action}"
1175 cli_usage
"network help"
1176 exit ${EXIT_CONF_ERROR}