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}"
132 # Ethernet-compatible?
133 device_is_ethernet_compatible
"${device}" &>/dev
/null
134 cli_print_fmt1
1 "Ethernet-compatible" "$(cli_print_bool $?)"
136 cli_print_fmt1
1 "Address" "$(device_get_address ${device})"
139 # Print the link speed for ethernet devices.
140 if device_is_up
${device} &>/dev
/null
; then
141 local link
="$(device_get_link_string "${device}")"
143 cli_print_fmt1
1 "Link" "${link}"
147 cli_print_fmt1
1 "MTU" "$(device_get_mtu ${device})"
150 # Print device statistics.
151 cli_device_stats
2 ${device}
153 # Print some more information.
154 device_has_carrier
${device} &>/dev
/null
155 cli_print_fmt1
1 "Has carrier?" "$(cli_print_bool $?)"
157 device_is_promisc
${device} &>/dev
/null
158 cli_print_fmt1
1 "Promisc" "$(cli_print_bool $?)"
161 # Print all vlan devices.
162 local vlans
=$
(device_get_vlans
${device})
163 if [ -n "${vlans}" ]; then
164 cli_headline
2 "VLAN devices"
167 for vlan
in ${vlans}; do
168 cli_print
2 "* %-6s - %s" "${vlan}" "$(device_get_address ${vlan})"
173 # Reset the logging level.
174 LOG_DISABLE_STDOUT
=${log_disable_stdout}
177 function cli_device_status_serial
() {
179 assert device_is_serial
${device}
181 serial_is_locked
${device} &>/dev
/null
184 cli_print_fmt1
1 "Locked" "$(cli_print_bool ${locked})"
187 # Cannot go on when the device is locked.
188 [ ${locked} -eq ${EXIT_TRUE} ] && return ${EXIT_OK}
190 cli_print_fmt1
1 "Manufacturer" \
191 "$(modem_get_manufacturer ${device})"
192 cli_print_fmt1
1 "Model" \
193 "$(modem_get_model ${device})"
194 cli_print_fmt1
1 "Software version" \
195 "$(modem_get_software_version ${device})"
197 if modem_is_mobile
${device}; then
198 cli_print_fmt1
1 "IMEI" \
199 "$(modem_get_device_imei ${device})"
202 cli_headline
2 "Network status"
203 modem_sim_status
${device} &>/dev
/null
204 local sim_status_code
=$?
206 local sim_status
="unknown"
207 case "${sim_status_code}" in
209 sim_status
="SIM ready"
212 sim_status
="PIN locked"
215 sim_status
="PUK locked"
218 cli_print_fmt1
2 "SIM status" "${sim_status}"
220 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
221 cli_print_fmt1
2 "IMSI" \
222 "$(modem_get_sim_imsi ${device})"
223 cli_print_fmt1
2 "Operator" \
224 "$(modem_get_network_operator ${device})"
225 cli_print_fmt1
2 "Mode" \
226 "$(modem_get_network_mode ${device})"
227 cli_print_fmt1
2 "Signal quality" \
228 "$(modem_get_signal_quality ${device}) dBm"
230 local ber
=$
(modem_get_bit_error_rate
${device})
231 isset ber || ber
="unknown"
232 cli_print_fmt1
2 "Bit Error Rate" "${ber}"
238 function cli_device_discover
() {
242 local device_type
=$
(device_get_type
${device})
243 if [ "${device_type}" != "real" ]; then
249 while [ $# -gt 0 ]; do
259 device_is_up
${device} && up
=1
260 device_set_up
${device}
262 enabled raw ||
echo "${device}"
267 for hook
in $
(hook_zone_get_all
); do
268 out
=$
(hook_zone_exec
${hook} discover
${device})
271 [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue
279 echo "${hook}: ${line}"
284 echo "${hook}: FAILED"
290 echo " ${hook} was successful."
298 echo " ${hook} failed."
306 [ "${up}" = "1" ] || device_set_down
${device}
309 function cli_device_serial_unlock
() {
310 if cli_help_requested $@
; then
311 cli_show_man network-device
318 if ! device_is_serial
${device}; then
319 error
"${device} is not a serial device."
320 error
"Unlocking is only supported for serial devices."
324 # Read the current state of the SIM card.
325 modem_sim_status
${device} &>/dev
/null
326 local sim_status_code
=$?
328 # If the SIM card is already unlocked, we don't need to do anything.
329 if [ ${sim_status_code} -eq ${EXIT_SIM_READY} ]; then
330 print
"The SIM card is already unlocked."
333 # If the SIM card is in an unknown state, we cannot do anything.
334 elif [ ${sim_status_code} -eq ${EXIT_SIM_UNKNOWN} ]; then
335 error
"The SIM card is in an unknown state."
341 local require_new_pin
="false"
344 while ! isinteger code
; do
346 case "${sim_status_code}" in
348 message
="Please enter PIN:"
351 message
="Please enter PUK:"
352 require_new_pin
="true"
357 echo -n "${message} "
359 echo # Print newline.
361 if enabled require_new_pin
; then
366 message
="Please enter a new PIN code:"
369 message
="Please confirm the new PIN code:"
373 echo -n "${message} "
375 echo # Print newline.
377 if [ -n "${new_pin}" ]; then
378 if [ "${new_pin}" != "${new_pin2}" ]; then
379 error
"The entered PIN codes did not match."
389 # Trying to unlock the SIM card.
390 modem_sim_unlock
${device} ${code} ${new_pin}
395 function cli_device_send_ussd_command
() {
403 while [ $# -gt 0 ]; do
406 timeout
="$(cli_get_val "${1}")"
409 if isset
command; then
410 warning
"Unrecognized argument: ${1}"
419 assert device_is_serial
"${device}"
422 if isset timeout
; then
423 args
="${args} --timeout=${timeout}"
426 modem_ussd_send_command
"${device}" "${command}" ${args}
430 function cli_device_monitor() {
434 if ! device_is_wireless "${device}"; then
435 error "This action only works with wireless devices. Exiting.
"
439 wireless_monitor "${device}"
443 function cli_hostname() {
444 if cli_help_requested $@; then
451 if [ -n "${hostname}" ]; then
452 config_hostname ${hostname}
453 log INFO "Hostname was
set to
'${hostname}'.
"
454 log INFO "Changes
do only take affect after reboot.
"
458 echo "$
(config_hostname
)"
462 function cli_port() {
463 if cli_help_requested $@; then
464 cli_show_man network-port
471 if port_exists ${1}; then
477 edit|create|remove|up|down|status)
478 port_${action} "${port}" $@
481 error "Unrecognized argument
: ${action}"
494 error "Unrecognized argument
: ${action}"
501 function cli_zone() {
502 if cli_help_requested $@; then
503 cli_show_man network-zone
510 if zone_name_is_valid ${1}; then
529 config|disable|down|edit|enable|port|status|up)
530 zone_${action} ${zone} $@
533 error "Unrecognized argument
: ${action}"
534 cli_show_man network-zone
550 cli_list_hooks zone $@
553 if [ -n "${action}" ]; then
554 error "Unrecognized argument
: '${action}'"
558 cli_show_man network-zone
565 # Removes a zone either immediately, if it is currently down,
566 # or adds a tag that the removal will be done when the zone
567 # is brought down the next time.
568 function cli_zone_remove() {
569 if cli_help_requested $@; then
570 cli_show_man network-zone
575 assert zone_exists ${zone}
577 if zone_is_up ${zone}; then
578 echo "Zone
'${zone}' is up and will be removed when it goes down the next
time.
"
581 echo "Removing zone
'${zone}' now...
"
582 zone_remove_now ${zone}
588 function cli_list_hooks() {
592 if cli_help_requested $@; then
593 cli_show_man network-zone
597 local hook_dir=$(hook_dir ${type})
600 for hook in ${hook_dir}/*; do
601 hook=$(basename ${hook})
602 if hook_exists ${type} ${hook}; then
608 function cli_route() {
609 if cli_help_requested $@; then
610 cli_show_man network-route
622 # Remove an existing route.
632 error "Unrecognized action
: ${action}"
633 cli_run_help network route
639 # Applying all routes.
645 function cli_dhcpd() {
649 if cli_help_requested $@; then
650 cli_show_man network-dhcp
659 dhcpd_edit ${proto} $@
668 dhcpd_reload ${proto}
671 cli_dhcpd_subnet ${proto} $@
674 cli_dhcpd_show ${proto} $@
677 error "Unrecognized action
: ${action}"
678 cli_run_help network dhcpvN
687 function cli_dhcpd_show() {
691 local settings=$(dhcpd_settings ${proto})
692 assert isset settings
695 dhcpd_global_settings_read ${proto}
697 cli_headline 1 "Dynamic Host Configuration Protocol Daemon
for ${proto/ip/IP}"
701 cli_headline 2 "Lease
times"
702 if isinteger VALID_LIFETIME; then
703 cli_print_fmt1 2 "Valid lifetime
" "${VALID_LIFETIME}s
"
706 if isinteger PREFERRED_LIFETIME; then
707 cli_print_fmt1 2 "Preferred lifetime
" "${PREFERRED_LIFETIME}s
"
713 cli_print_fmt1 1 "Authoritative
" $(cli_print_enabled AUTHORITATIVE)
716 cli_headline 2 "Lease
times"
717 cli_print_fmt1 2 "Default lease
time" "${DEFAULT_LEASE_TIME}s
"
718 cli_print_fmt1 2 "Max. lease
time" "${MAX_LEASE_TIME}s
"
720 if isset MIN_LEASE_TIME; then
721 cli_print_fmt1 2 "Min. lease
time" "${MIN_LEASE_TIME}s
"
730 dhcpd_global_options_read ${proto} ${subnet_id}
732 # Print the options if any.
733 if [ ${#options[*]} -gt 0 ]; then
734 cli_headline 2 "Options
"
737 for option in $(dhcpd_options ${proto}); do
738 [ -n "${options[${option}]}" ] || continue
741 "${option}" "${options[${option}]}"
747 local subnets=$(dhcpd_subnet_list ${proto})
748 if [ -n "${subnets}" ]; then
749 cli_headline 2 "Subnets
"
751 for subnet_id in ${subnets}; do
752 cli_dhcpd_subnet_show ${proto} ${subnet_id} 2
757 function cli_dhcpd_subnet() {
761 if cli_help_requested $@; then
762 cli_show_man network-dhcp-subnet
771 dhcpd_subnet_new ${proto} $@
774 dhcpd_subnet_remove ${proto} $@
777 local subnet_id=${action}
779 if ! dhcpd_subnet_exists ${proto} ${subnet_id}; then
780 error "The given subnet with ID
${subnet_id} does not exist.
"
790 dhcpd_subnet_edit ${proto} ${subnet_id} $@
793 if [ ${ret} -eq ${EXIT_OK} ]; then
794 dhcpd_reload ${proto}
799 cli_dhcpd_subnet_range ${proto} ${subnet_id} $@
803 cli_dhcpd_subnet_show ${proto} ${subnet_id} $@
807 cli_dhcpd_subnet_options ${proto} ${subnet_id} $@
811 error "Unrecognized action
: ${action}"
812 cli_run_help network dhcpvN subnet
819 for subnet_id in $(dhcpd_subnet_list ${proto}); do
820 cli_dhcpd_subnet_show ${proto} ${subnet_id}
824 error "Unrecognized action
: ${action}"
825 cli_run_help network dhcpvN subnet
834 function cli_dhcpd_subnet_range() {
840 assert isset subnet_id
848 dhcpd_subnet_range_new ${proto} ${subnet_id} $@
852 dhcpd_subnet_range_remove ${proto} ${subnet_id} $@
856 error "Unrecognized action
: ${action}"
857 cli_run_help network dhcpvN subnet range
863 function cli_dhcpd_subnet_show() {
868 assert isset subnet_id
871 isset level || level=0
873 local $(dhcpd_subnet_settings ${proto})
875 # Read in configuration settings.
876 dhcpd_subnet_read ${proto} ${subnet_id}
878 cli_headline $(( ${level} + 1 )) \
879 "DHCP
${proto/ip/} subnet declaration
#${subnet_id}"
880 cli_print_fmt1 $
(( ${level} + 1 )) \
881 "Subnet" "${ADDRESS}/${PREFIX}"
886 dhcpd_subnet_options_read
${proto} ${subnet_id}
888 # Print the options if any.
889 if [ ${#options[*]} -gt 0 ]; then
890 cli_headline $
(( ${level} + 2 )) "Options"
893 for option
in $
(dhcpd_subnet_options
${proto}); do
894 [ -n "${options[${option}]}" ] ||
continue
896 cli_print_fmt1 $
(( ${level} + 2 )) \
897 "${option}" "${options[${option}]}"
903 cli_headline $
(( ${level} + 2 )) "Ranges"
905 local ranges
=$
(dhcpd_subnet_range_list
${proto} ${subnet_id})
906 if isset ranges
; then
907 local range_id $
(dhcpd_subnet_range_settings
${proto})
908 for range_id
in ${ranges}; do
909 dhcpd_subnet_range_read
${proto} ${subnet_id} ${range_id}
911 cli_print $
(( ${level} + 2 )) \
912 "#%d: %s - %s" ${range_id} ${START} ${END}
915 cli_print $
(( ${level} + 2 )) "No ranges have been defined."
921 function cli_dhcpd_options
() {
927 assert isset subnet_id
930 local valid_options
=$
(dhcpd_subnet_options
${proto})
933 while [ $# -gt 0 ]; do
936 key
=$
(cli_get_key
${1})
937 val
=$
(cli_get_val
${1})
939 dhcpd_subnet_option_set
${proto} ${subnet_id} ${key} ${val}
944 function cli_start
() {
945 if cli_help_requested $@
; then
950 local zones
=$
(zones_get $@
)
953 for zone
in ${zones}; do
957 wait # until everything is settled
960 function cli_stop
() {
961 if cli_help_requested $@
; then
966 local zones
=$
(zones_get $@
)
969 for zone
in ${zones}; do
973 wait # until everything is settled
976 function cli_restart
() {
977 if cli_help_requested $@
; then
984 # Give the system some time to calm down
985 sleep ${TIMEOUT_RESTART}
990 function cli_status
() {
991 if cli_help_requested $@
; then
996 # When dumping status information, the debug
997 # mode clutters the console which is not what we want.
998 # Logging on the console is disabled for a short time.
999 local log_disable_stdout
=${LOG_DISABLE_STDOUT}
1000 LOG_DISABLE_STDOUT
="true"
1002 local zones
=$
(zones_get $@
)
1005 for zone
in ${zones}; do
1010 LOG_DISABLE_STDOUT
=${log_disable_stdout}
1013 function cli_reset
() {
1014 if cli_help_requested $@
; then
1015 cli_show_man network
1019 warning_log
"Will reset the whole network configuration!!!"
1021 # Force mode is disabled by default
1024 while [ $# -gt 0 ]; do
1033 # If we are not running in force mode, we ask the user if he does know
1035 if ! enabled force
; then
1036 if ! cli_yesno
"Do you really want to reset the whole network configuration?"; then
1042 for zone
in $
(zones_get
--all); do
1047 for port
in $
(ports_get
--all); do
1048 port_destroy
"${port}"
1051 # Flush all DNS servers.
1054 # Re-run the initialization functions
1060 # Help function: will show the default man page to the user.
1061 # Optionally, there are two arguments taken, the type of hook
1062 # and which hook should be shown.
1063 function cli_help
() {
1067 # Remove unknown types.
1068 if ! listmatch
${type} zone port config
; then
1072 # If no arguments were given, we will show the default page.
1073 if [ -z "${type}" ]; then
1074 cli_show_man network
1078 if ! hook_exists
${type} ${what}; then
1079 error
"Hook of type '${type}' and name '${what}' could not be found."
1080 exit "${EXIT_ERROR}"
1083 hook_exec
${type} ${what} help
1086 function cli_dns_server
() {
1087 if cli_help_requested $@
; then
1088 cli_show_man network-dns-server
1093 local cmd
=${1}; shift
1094 if [ -z "${cmd}" ]; then
1095 cli_show_man network-dns-server
1099 # Get the new server to process (if any).
1109 if dns_server_exists
${server}; then
1110 error
"DNS server '${server}' already exists!"
1114 log INFO
"Adding new DNS server: ${server}"
1115 dns_server_add
${server} ${priority}
1118 if ! dns_server_exists
${server}; then
1119 error
"DNS server '${server}' does not exist!"
1123 log INFO
"Removing DNS server: ${server}"
1124 dns_server_remove
${server} ${priority}
1127 # Just run the update afterwards.
1130 error
"No such command: ${cmd}"
1134 # Update the local DNS configuration after changes have been made.
1135 dns_generate_resolvconf
1141 # Process the given action
1147 settings|hostname|port|device|zone|start|stop|restart|status|
reset|route
)
1151 # DHCP server configuration (automatically detects which protocol to use).
1153 cli_dhcpd
${action/dhcp/ip} $@
1156 # DNS server configuration.
1166 error
"Invalid command given: ${action}"
1167 cli_usage
"network help"
1168 exit ${EXIT_CONF_ERROR}