#!/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=" " function cli_help_requested() { local argument="${1}" if [ -n "${argument}" ]; then if listmatch ${argument} help -h --help; then return ${EXIT_TRUE} fi fi return ${EXIT_FALSE} } 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 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}" 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} }