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
472 edit|create|remove|up|down|status)
473 port_${action} "${port}" $@
476 error "Unrecognized argument
: ${action}"
489 error "Unrecognized argument
: ${action}"
496 function cli_zone() {
497 if cli_help_requested $@; then
498 cli_show_man network-zone
505 if zone_name_is_valid ${1}; then
524 config|disable|down|edit|enable|port|status|up)
525 zone_${action} ${zone} $@
528 error "Unrecognized argument
: ${action}"
529 cli_show_man network-zone
545 cli_list_hooks zone $@
548 if [ -n "${action}" ]; then
549 error "Unrecognized argument
: '${action}'"
553 cli_show_man network-zone
560 # Removes a zone either immediately, if it is currently down,
561 # or adds a tag that the removal will be done when the zone
562 # is brought down the next time.
563 function cli_zone_remove() {
564 if cli_help_requested $@; then
565 cli_show_man network-zone
570 assert zone_exists ${zone}
572 if zone_is_up ${zone}; then
573 echo "Zone
'${zone}' is up and will be removed when it goes down the next
time.
"
576 echo "Removing zone
'${zone}' now...
"
577 zone_remove_now ${zone}
583 function cli_list_hooks() {
587 if cli_help_requested $@; then
588 cli_show_man network-zone
592 local hook_dir=$(hook_dir ${type})
595 for hook in ${hook_dir}/*; do
596 hook=$(basename ${hook})
597 if hook_exists ${type} ${hook}; then
603 function cli_route() {
604 if cli_help_requested $@; then
605 cli_show_man network-route
617 # Remove an existing route.
627 error "Unrecognized action
: ${action}"
628 cli_run_help network route
634 # Applying all routes.
640 function cli_dhcpd() {
644 if cli_help_requested $@; then
645 cli_show_man network-dhcp
654 dhcpd_edit ${proto} $@
663 dhcpd_reload ${proto}
666 cli_dhcpd_subnet ${proto} $@
669 cli_dhcpd_show ${proto} $@
672 error "Unrecognized action
: ${action}"
673 cli_run_help network dhcpvN
682 function cli_dhcpd_show() {
686 local settings=$(dhcpd_settings ${proto})
687 assert isset settings
690 dhcpd_global_settings_read ${proto}
692 cli_headline 1 "Dynamic Host Configuration Protocol Daemon
for ${proto/ip/IP}"
696 cli_headline 2 "Lease
times"
697 if isinteger VALID_LIFETIME; then
698 cli_print_fmt1 2 "Valid lifetime
" "${VALID_LIFETIME}s
"
701 if isinteger PREFERRED_LIFETIME; then
702 cli_print_fmt1 2 "Preferred lifetime
" "${PREFERRED_LIFETIME}s
"
708 cli_print_fmt1 1 "Authoritative
" $(cli_print_enabled AUTHORITATIVE)
711 cli_headline 2 "Lease
times"
712 cli_print_fmt1 2 "Default lease
time" "${DEFAULT_LEASE_TIME}s
"
713 cli_print_fmt1 2 "Max. lease
time" "${MAX_LEASE_TIME}s
"
715 if isset MIN_LEASE_TIME; then
716 cli_print_fmt1 2 "Min. lease
time" "${MIN_LEASE_TIME}s
"
725 dhcpd_global_options_read ${proto} ${subnet_id}
727 # Print the options if any.
728 if [ ${#options[*]} -gt 0 ]; then
729 cli_headline 2 "Options
"
732 for option in $(dhcpd_options ${proto}); do
733 [ -n "${options[${option}]}" ] || continue
736 "${option}" "${options[${option}]}"
742 local subnets=$(dhcpd_subnet_list ${proto})
743 if [ -n "${subnets}" ]; then
744 cli_headline 2 "Subnets
"
746 for subnet_id in ${subnets}; do
747 cli_dhcpd_subnet_show ${proto} ${subnet_id} 2
752 function cli_dhcpd_subnet() {
756 if cli_help_requested $@; then
757 cli_show_man network-dhcp-subnet
766 dhcpd_subnet_new ${proto} $@
769 dhcpd_subnet_remove ${proto} $@
772 local subnet_id=${action}
774 if ! dhcpd_subnet_exists ${proto} ${subnet_id}; then
775 error "The given subnet with ID
${subnet_id} does not exist.
"
785 dhcpd_subnet_edit ${proto} ${subnet_id} $@
788 if [ ${ret} -eq ${EXIT_OK} ]; then
789 dhcpd_reload ${proto}
794 cli_dhcpd_subnet_range ${proto} ${subnet_id} $@
798 cli_dhcpd_subnet_show ${proto} ${subnet_id} $@
802 cli_dhcpd_subnet_options ${proto} ${subnet_id} $@
806 error "Unrecognized action
: ${action}"
807 cli_run_help network dhcpvN subnet
814 for subnet_id in $(dhcpd_subnet_list ${proto}); do
815 cli_dhcpd_subnet_show ${proto} ${subnet_id}
819 error "Unrecognized action
: ${action}"
820 cli_run_help network dhcpvN subnet
829 function cli_dhcpd_subnet_range() {
835 assert isset subnet_id
843 dhcpd_subnet_range_new ${proto} ${subnet_id} $@
847 dhcpd_subnet_range_remove ${proto} ${subnet_id} $@
851 error "Unrecognized action
: ${action}"
852 cli_run_help network dhcpvN subnet range
858 function cli_dhcpd_subnet_show() {
863 assert isset subnet_id
866 isset level || level=0
868 local $(dhcpd_subnet_settings ${proto})
870 # Read in configuration settings.
871 dhcpd_subnet_read ${proto} ${subnet_id}
873 cli_headline $(( ${level} + 1 )) \
874 "DHCP
${proto/ip/} subnet declaration
#${subnet_id}"
875 cli_print_fmt1 $
(( ${level} + 1 )) \
876 "Subnet" "${ADDRESS}/${PREFIX}"
881 dhcpd_subnet_options_read
${proto} ${subnet_id}
883 # Print the options if any.
884 if [ ${#options[*]} -gt 0 ]; then
885 cli_headline $
(( ${level} + 2 )) "Options"
888 for option
in $
(dhcpd_subnet_options
${proto}); do
889 [ -n "${options[${option}]}" ] ||
continue
891 cli_print_fmt1 $
(( ${level} + 2 )) \
892 "${option}" "${options[${option}]}"
898 cli_headline $
(( ${level} + 2 )) "Ranges"
900 local ranges
=$
(dhcpd_subnet_range_list
${proto} ${subnet_id})
901 if isset ranges
; then
902 local range_id $
(dhcpd_subnet_range_settings
${proto})
903 for range_id
in ${ranges}; do
904 dhcpd_subnet_range_read
${proto} ${subnet_id} ${range_id}
906 cli_print $
(( ${level} + 2 )) \
907 "#%d: %s - %s" ${range_id} ${START} ${END}
910 cli_print $
(( ${level} + 2 )) "No ranges have been defined."
916 function cli_dhcpd_options
() {
922 assert isset subnet_id
925 local valid_options
=$
(dhcpd_subnet_options
${proto})
928 while [ $# -gt 0 ]; do
931 key
=$
(cli_get_key
${1})
932 val
=$
(cli_get_val
${1})
934 dhcpd_subnet_option_set
${proto} ${subnet_id} ${key} ${val}
939 function cli_start
() {
940 if cli_help_requested $@
; then
945 local zones
=$
(zones_get $@
)
948 for zone
in ${zones}; do
952 wait # until everything is settled
955 function cli_stop
() {
956 if cli_help_requested $@
; then
961 local zones
=$
(zones_get $@
)
964 for zone
in ${zones}; do
968 wait # until everything is settled
971 function cli_restart
() {
972 if cli_help_requested $@
; then
979 # Give the system some time to calm down
980 sleep ${TIMEOUT_RESTART}
985 function cli_status
() {
986 if cli_help_requested $@
; then
991 # When dumping status information, the debug
992 # mode clutters the console which is not what we want.
993 # Logging on the console is disabled for a short time.
994 local log_disable_stdout
=${LOG_DISABLE_STDOUT}
995 LOG_DISABLE_STDOUT
="true"
997 local zones
=$
(zones_get $@
)
1000 for zone
in ${zones}; do
1005 LOG_DISABLE_STDOUT
=${log_disable_stdout}
1008 function cli_reset
() {
1009 if cli_help_requested $@
; then
1010 cli_show_man network
1014 warning_log
"Will reset the whole network configuration!!!"
1016 # Force mode is disabled by default
1019 while [ $# -gt 0 ]; do
1028 # If we are not running in force mode, we ask the user if he does know
1030 if ! enabled force
; then
1031 if ! cli_yesno
"Do you really want to reset the whole network configuration?"; then
1037 for zone
in $
(zones_get
--all); do
1042 for port
in $
(ports_get
--all); do
1043 port_destroy
"${port}"
1046 # Flush all DNS servers.
1049 # Re-run the initialization functions
1055 # Help function: will show the default man page to the user.
1056 # Optionally, there are two arguments taken, the type of hook
1057 # and which hook should be shown.
1058 function cli_help
() {
1062 # Remove unknown types.
1063 if ! listmatch
${type} zone port config
; then
1067 # If no arguments were given, we will show the default page.
1068 if [ -z "${type}" ]; then
1069 cli_show_man network
1073 if ! hook_exists
${type} ${what}; then
1074 error
"Hook of type '${type}' and name '${what}' could not be found."
1075 exit "${EXIT_ERROR}"
1078 hook_exec
${type} ${what} help
1081 function cli_dns_server
() {
1082 if cli_help_requested $@
; then
1083 cli_show_man network-dns-server
1088 local cmd
=${1}; shift
1089 if [ -z "${cmd}" ]; then
1090 cli_show_man network-dns-server
1094 # Get the new server to process (if any).
1104 if dns_server_exists
${server}; then
1105 error
"DNS server '${server}' already exists!"
1109 log INFO
"Adding new DNS server: ${server}"
1110 dns_server_add
${server} ${priority}
1113 if ! dns_server_exists
${server}; then
1114 error
"DNS server '${server}' does not exist!"
1118 log INFO
"Removing DNS server: ${server}"
1119 dns_server_remove
${server} ${priority}
1122 # Just run the update afterwards.
1125 error
"No such command: ${cmd}"
1129 # Update the local DNS configuration after changes have been made.
1130 dns_generate_resolvconf
1136 # Process the given action
1142 settings|hostname|port|device|zone|start|stop|restart|status|
reset|route
)
1146 # DHCP server configuration (automatically detects which protocol to use).
1148 cli_dhcpd
${action/dhcp/ip} $@
1151 # DNS server configuration.
1161 error
"Invalid command given: ${action}"
1162 cli_usage
"network help"
1163 exit ${EXIT_CONF_ERROR}