Project: IPFire
Code Location: git://git.ipfire.org/network.gitmaster
Browse
/
Download File
functions.cli
#!/bin/bash
###############################################################################
#                                                                             #
# IPFire.org - A linux based firewall                                         #
# Copyright (C) 2010  Michael Tremer & Christian Schmidt                      #
#                                                                             #
# This program is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU General Public License as published by        #
# the Free Software Foundation, either version 3 of the License, or           #
# (at your option) any later version.                                         #
#                                                                             #
# This program is distributed in the hope that it will be useful,             #
# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
# GNU General Public License for more details.                                #
#                                                                             #
# You should have received a copy of the GNU General Public License           #
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################

IDENT="  "

function cli_help_requested() {
	local argument="${1}"

	if [ -n "${argument}" ]; then
		if listmatch ${argument} help -h --help; then
			return ${EXIT_OK}
		fi
	fi

	return ${EXIT_ERROR}
}

function cli_run_help() {
	local command="$@"

	print "Run \"${command} help\" to get more information."
	return ${EXIT_OK}
}

function cli_device_headline() {
	local device=${1}
	assert isset device

	local long=0
	shift
	while [ $# -gt 0 ]; do
		case "${1}" in
			--long)
				long=1
				;;
		esac
		shift
	done

	local type
	if zone_exists ${device}; then
		type="zone"
	elif port_exists ${device}; then
		type="port"
	else
		type="unknown"
	fi

	local headline_prefix
	case "${type}" in
		zone)
			headline_prefix="Zone ${device}"
			;;
		port)
			headline_prefix="Port ${device} ($(device_get_type ${device}))"
			;;
		*)
			headline_prefix="Device ${device} ($(device_get_type ${device}))"
			;;
	esac

	# Print the hook for all zones.
	if [ "${type}" = "zone" ]; then
		headline_prefix="${headline_prefix} ($(zone_get_hook ${device}))"
	fi
	cli_headline 1 "${headline_prefix}"

	# Print the device status.
	local status
	case "$(device_get_status ${device})" in
		${STATUS_UP})
			status=${MSG_DEVICE_STATUS_UP}
			;;
		${STATUS_DOWN})
			status=${MSG_DEVICE_STATUS_DOWN}
			;;
		${STATUS_NOCARRIER})
			status=${MSG_DEVICE_STATUS_NOCARRIER}
			;;
		*)
			status=${MSG_DEVICE_STATUS_UNKNOWN}
			;;
	esac
	cli_print_fmt1 1 "Status" "${status}"
	if enabled long; then
		cli_print_fmt1 1 "Address" "$(device_get_address ${device})"
	fi
	if device_is_up ${device}; then
		cli_print_fmt1 1 "MTU" "$(device_get_mtu ${device})"
	fi
	if enabled long; then
		device_is_promisc ${device} &>/dev/null
		cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)"
	fi

	cli_space

	# Print the device stats.
	device_is_up ${device} && cli_device_stats 2 ${device}

	if enabled long; then
		# Virtual devices.
		device_is_vlan ${device} && cli_device_vlan ${device}

		# Bonded devices.
		device_is_bonded ${device} && cli_device_bonded ${device}

		# Bonding devices.
		device_is_bonding ${device} && cli_device_bonding ${device}
	fi
}

function cli_device_stats() {
	local level=${1}
	local device=${2}

	# This section will print statistical data from the device.
	local packets bytes errors

	cli_headline ${level} "Statistics"
	local format="%-10s %9d packets %6s (%d errors)"

	# RX
	packets=$(device_get_rx_packets ${device})
	bytes=$(device_get_rx_bytes ${device})
	errors=$(device_get_rx_errors ${device})

	cli_print ${level} "${format}" "Received" "${packets}" "$(beautify_bytes ${bytes})" "${errors}"

	# TX
	packets=$(device_get_tx_packets ${device})
	bytes=$(device_get_tx_bytes ${device})
	errors=$(device_get_tx_errors ${device})

	cli_print ${level} "${format}" "Sent"     "${packets}" "$(beautify_bytes ${bytes})" "${errors}"
	cli_space
}

function cli_device_vlan() {
	local device=${1}

	cli_headline 2 "VLAN"

	cli_print_fmt1 2 "Parent" "$(vlan_get_parent ${device})"
	cli_print_fmt1 2 "VID" "$(vlan_get_id ${device})"
	cli_space
}

function cli_device_bonded() {
	local device=${1}

	cli_headline 2 "Bonding information"

	local master=$(bonding_slave_get_master ${port})
	cli_print_fmt1 2 "Master" "${master}"

	local mode=$(bonding_get_mode ${master})
	if [ "${mode}" = "active-backup" ]; then
		local active_slaves=$(bonding_get_slaves ${master} --active)
		local active="false"
		if list_match "${device}" ${active_slaves}; then
			active="true"
		fi
		cli_print_fmt1 2 "Active slave" "$(cli_print_yesno ${active})"
	fi

	cli_space
}

function cli_device_bonding() {
	local device=${1}
	assert isset device

	cli_headline 2 "Bonding information"

	local mode=$(bonding_get_mode ${device})

	cli_print_fmt1 2 "Mode" "${mode}"
	if [ "${mode}" = "802.3ad" ]; then
		local lacp_rate=$(bonding_get_lacp_rate ${device})
		cli_print_fmt1 2 "LACP rate" "${lacp_rate}"
	fi
	cli_space

	local slave slave_suffix
	local active_slaves=$(bonding_get_slaves ${device} --active)
	for slave in $(bonding_get_slaves ${device}); do
		# Print the device status.
		local status
		case "$(device_get_status ${slave})" in
			${STATUS_UP})
				status=${MSG_DEVICE_STATUS_UP}
				;;
			${STATUS_DOWN})
				status=${MSG_DEVICE_STATUS_DOWN}
				;;
			${STATUS_NOCARRIER})
				status=${MSG_DEVICE_STATUS_NOCARRIER}
				;;
			*)
				status=${MSG_DEVICE_STATUS_UNKNOWN}
				;;
		esac

		if list_match "${slave}" ${active_slaves}; then
			slave_suffix="(active)"
		else
			slave_suffix=""
		fi
		cli_print_fmt1 2 "Slave ${slave}" "${status} ${slave_suffix}"
	done
	cli_space
}

function cli_headline() {
	local level=${1}
	local format=${2}
	shift 2

	local ident=$(cli_ident ${level})

	local out
	printf -v out "${ident}${CLR_BLACK_B}${format}${CLR_RESET}\n" "$@"
	printf "${out}"
}

function cli_statusline() {
	local level=${1}
	shift

	local head=${1}
	shift

	cli_print $(( ${level} - 1 )) "%-12s %s" "${head}" "$@"
}

function cli_print() {
	local level=${1}
	local format=${2}
	shift 2

	local ident=$(cli_ident $(( ${level} + 1 )))

	local out
	printf -v out "${ident}${format}\n" "$@"
	printf "${out}"
}

function cli_print_fmt1() {
	local level=${1}
	shift

	local space=$(( 34 - (${level} * ${#IDENT}) ))
	local format="%-${space}s %s"

	cli_print ${level} "${format}" "$@"
}

function cli_print_bool() {
	if [ "${1}" = "${EXIT_TRUE}" ]; then
		echo "true"
	else
		echo "false"
	fi
}

function cli_print_yesno() {
	if [ "${1}" = "${EXIT_TRUE}" ]; then
		echo "yes"
	else
		echo "false"
	fi
}

function cli_print_enabled() {
	enabled ${1}

	cli_print_bool $?
}

function cli_print_warning() {
	local level=${1}
	shift

	cli_print ${level} "${CLR_YELLOW_B}%s${CLR_RESET}" "$@"
}

function cli_space() {
	printf "\n"
}

function cli_ident() {
	local level=${1}
	assert isinteger level

	local ident=""
	while [ ${level} -gt 1 ]; do
		ident="${ident}${IDENT}"
		level=$(( ${level} - 1 ))
	done

	print "${ident}"
}

function cli_yesno() {
	local message="$@ [y/n] "
	local yesno

	while true; do
		printf "\n${message}"
		read yesno

		# Check for "yes".
		if listmatch ${yesno} y Y yes YES Yes; then
			return ${EXIT_TRUE}

		# Check for "no".
		elif listmatch ${yesno} n N no NO No; then
			return ${EXIT_FALSE}
		fi
	done
}

function cli_get_key() {
	local key="${1%%=*}"
	echo "${key/--/}"
}

function cli_get_val() {
	echo "${@#*=}"
}

function cli_get_bool() {
	local value="$(cli_get_val "$@")"

	if enabled value; then
		print "true"
		return ${EXIT_TRUE}
	fi

	print "false"
	return ${EXIT_FALSE}
}

function cli_usage() {
	local command="$@"
	local basename="$(basename ${0})"

	if ! isset command; then
		command="${basename} help"
	fi

	echo "The given command was not understood by ${basename}." >&2
	echo "Please run '${command}' for detailed help." >&2
}

function cli_show_man() {
	local manpage=${1}
	assert isset manpage

	if ! binary_exists man; then
		error "The man package is not installed on this system."
		error "Please install 'man' in order to view the help."
		exit ${EXIT_ERROR}
	fi

	man ${manpage}
}