#!/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 . # # # ############################################################################### IDENT=" " cli_help_requested() { local argument="${1}" if [ -n "${argument}" ]; then if list_match ${argument} help -h --help; then return ${EXIT_TRUE} fi fi return ${EXIT_FALSE} } cli_run_help() { local command="$@" print "Run \"${command} help\" to get more information." return ${EXIT_OK} } 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 local enabled zone_is_enabled "${device}" case "$?" in ${EXIT_TRUE}) enabled="enabled" ;; ${EXIT_FALSE}) enabled="disabled" ;; esac local hook="$(zone_get_hook "${device}")" headline_prefix="${headline_prefix} (${enabled}, ${hook})" 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}" # Print the description title of the device. case "${type}" in port) cli_print_fmt1 1 "Description" "$(port_get_description_title ${device})" ;; zone) cli_print_fmt1 1 "Description" "$(zone_get_description_title ${device})" ;; esac # Print the color of the device. case "${type}" in port) cli_print_fmt1 1 "Color" "$(cli_color_bar $(port_get_color ${device}))" ;; zone) cli_print_fmt1 1 "Color" "$(cli_color_bar $(zone_get_color ${device}))" ;; esac 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 } 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 } 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 } 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 } 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 } cli_device_show_queues() { assert [ $# -eq 2 ] local level=${1} local device=${2} cli_headline ${level} "Queues" cli_print_fmt1 ${level} "Queue" "Processors" local processors=$(system_get_processors) local queue for queue in $(device_get_queues ${device}); do local smp_affinity=$(device_queue_get_smp_affinity ${device} ${queue}) local processor s="" for (( processor = 0; processor < ${processors}; processor++ )); do if ! isset smp_affinity || list_match ${processor} ${smp_affinity}; then list_append s ${processor} fi done cli_print_fmt1 ${level} "${queue}" "$(list_join s ", ")" done cli_space } cli_headline() { local level=${1} local format=${2} shift 2 local ident=$(cli_ident ${level}) local out printf -v out "${ident}${FONT_BOLD}${format}${FONT_RESET}\n" "$@" printf "${out}" } cli_statusline() { local level=${1} shift local head=${1} shift cli_print $(( ${level} - 1 )) "%-12s %s" "${head}" "$@" } 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}" } cli_print_fmt1() { local level=${1} shift local space=$(( 34 - (${level} * ${#IDENT}) )) local format="%-${space}s %s" cli_print ${level} "${format}" "$@" } cli_print_bool() { if [ "${1}" = "${EXIT_TRUE}" ]; then echo "true" else echo "false" fi } cli_print_yesno() { if [ "${1}" = "${EXIT_TRUE}" ]; then echo "yes" else echo "false" fi } cli_print_enabled() { enabled ${1} cli_print_bool $? } cli_print_warning() { local level=${1} shift cli_print ${level} "${CLR_YELLOW_B}%s${CLR_RESET}" "$@" } cli_space() { printf "\n" } cli_ident() { local level=${1} assert isinteger level local ident="" while [ ${level} -gt 1 ]; do ident="${ident}${IDENT}" level=$(( ${level} - 1 )) done print "${ident}" } cli_yesno() { local message="$@ [y/n] " local yesno while true; do printf "\n${message}" read yesno # Check for "yes". if list_match ${yesno} y Y yes YES Yes; then return ${EXIT_TRUE} # Check for "no". elif list_match ${yesno} n N no NO No; then return ${EXIT_FALSE} fi done } cli_get_key() { local key="${1%%=*}" echo "${key/--/}" } cli_get_val() { echo "${@#*=}" } cli_get_bool() { local value="$(cli_get_val "$@")" if enabled value; then print "true" return ${EXIT_TRUE} fi print "false" return ${EXIT_FALSE} } 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 } 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} } cli_set_color() { #Function to set the back and foreground color at once. local fg=${1} local bg=${2} local i for i in fg bg; do # Skip if color is empty [ -n "${!i}" ] || continue # Skip for dash [ "${!i}" = "-" ] && continue color_set_shell ${i} ${!i} done } cli_reset_color() { #Reset the shell color. printf "\e[0m" } cli_color_bar() { # This function return some colored space assert [ $# -eq 1 ] local color=${1} echo "$(cli_set_color - ${color}) ${CLR_RESET}" }