#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2014 Michael Tremer # # # # 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 . # # # ############################################################################### # network(8) completion _network_find_on_cmdline () { local word subcommand c=0 while [ ${c} -lt ${cword} ]; do word="${words[c]}" for subcommand in ${1}; do if [ "${subcommand}" = "${word}" ]; then echo "${subcommand}" return fi done ((c++)) done } _network_complete_hooks() { local type="${1}" COMPREPLY=( $(compgen -W "$(network raw list-hooks "${type}")" -- "${cur}") ) } _network_complete_ports() { COMPREPLY=( $(compgen -W "$(network raw list-ports)" -- "${cur}") ) } _network_complete_zones() { COMPREPLY=( $(compgen -W "$(network raw list-zones)" -- "${cur}") ) } _network_color() { local words=( $@ ) local commands="set reset" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_description() { local words=( $@ ) local commands="edit show" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_device() { local words=( $@ ) local commands="list $(network raw list-devices)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in list) return 0 ;; *) _network_device_subcommand ${args} ;; esac } _network_device_subcommand() { local words=( $@ ) local commands="discover identify monitor status unlock ussd" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in ussd) # TODO ;; esac } _network_dhcpd() { local proto="${1}" shift local words=( $@ ) local commands="edit reload restart show start stop subnet" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in subnet) _network_dhcpd_subnet "${proto}" ${args} ;; esac } _network_dhcpd_subnet() { local proto="${1}" shift local words=( $@ ) local commands="new remove show $(network raw list-dhcpd-subnets "${proto}")" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local subnet="${words[0]}" local args="${words[@]:1}" case "${cmd}" in new) : # TODO ;; remove) : # TODO ;; [0-9]*) _network_dhcpd_subnet_subcommand "${proto}" "${subnet}" ${args} ;; esac } _network_dhcpd_subnet_subcommand() { local proto="${1}" local subnet="${2}" shift 2 local words=( $@ ) local commands="edit options range show" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in edit) : # TODO ;; options) _network_dhcpd_subnet_subcommand_options "${proto}" "${subnet}" ${args} ;; range) _network_dhcpd_subnet_subcommand_range "${proto}" "${subnet}" ${args} ;; esac } _network_dhcpd_subnet_subcommand_options() { local proto="${1}" local subnet="${2}" shift 2 local options option for option in $(network raw list-dhcpd-subnet-options "${proto}"); do options="${options} ${option}=" done COMPREPLY=( $(compgen -W "${options}" -- "${cur}") ) } _network_dhcpd_subnet_subcommand_range() { local proto="${1}" local subnet="${2}" shift 2 local words=( $@ ) local commands="new remove" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in new) COMPREPLY=( $(compgen -W "--end= --start=" -- "${cur}") ) ;; remove) COMPREPLY=( $(compgen -W "$(network raw list-dhcpd-ranges-of-subnet "${proto}" "${subnet}")" \ -- "${cur}") ) ;; esac } _network_dns_server() { local words=( $@ ) local commands="add list remove update" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in remove) COMPREPLY=( $(compgen -W "$(network raw list-dns-servers)" \ -- "${cur}") ) ;; esac } _network_port() { local words=( $@ ) local commands="new destroy $(network raw list-ports)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in new) _network_complete_hooks "port" ;; destroy) _network_complete_ports ;; *) local args="${words[@]:1}" _network_port_subcommand ${args} ;; esac } _network_port_subcommand() { local words=( $@ ) local commands="color create description down edit identify remove status up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in color) _network_color ${args} ;; description) _network_description ${args} ;; esac } _network_route() { local words=( $@ ) local commands="static" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in static) local args="${words[@]}" _network_route_static ${args} ;; esac } _network_route_static() { local words=( $@ ) local commands="add list remove reload" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in add) if [[ "${cur}" = -* ]]; then COMPREPLY=( $(compgen -W "--blackhole --gateway= --mtu= \ --prohibit --unreachable" -- "${cur}") ) fi ;; list) # TODO auto-complete options like --protocol here COMPREPLY=( $(compgen -W "--protocol=" -- "${cur}") ) ;; esac } _network_settings() { local words=( $@ ) local key keys for key in $(network raw list-settings); do keys="${keys} ${key}=" done COMPREPLY=( $(compgen -W "${keys}" -- "${cur}") ) } _network_vpn() { local words=( $@ ) local commands="ipsec security-policies" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in ipsec) _network_vpn_ipsec ${args} ;; security-policies) _network_vpn_security_policies ${args} ;; esac } _network_vpn_ipsec() { local words=( $@ ) local commands="connection" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in connection) _network_vpn_ipsec_connection ${args} ;; esac } _network_vpn_ipsec_connection() { local words=( $@ ) local commands="destroy new $(network raw list-ipsec-connections)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in destroy) : ;; new) : ;; *) if network raw ipsec-connection-exists ${cmd}; then _network_vpn_ipsec_connection_subcommands ${cmd} ${args} fi ;; esac } _network_vpn_ipsec_connection_subcommands() { local connection=${1} shift local words=( $@ ) local commands="authentication color description down inactivity-timeout local mode peer remote security-policy show up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in authentication) _network_vpn_ipsec_connection_subcommands_authentication ${connection} ${args} ;; color) _network_color ${args} ;; description) _network_description ${args} ;; local) _network_vpn_ipsec_connection_subcommands_local_remote ${connection} "local" ${args} ;; mode) _network_vpn_ipsec_connection_subcommands_mode ${args} ;; remote) _network_vpn_ipsec_connection_subcommands_local_remote ${connection} "remote" ${args} ;; security-policy) _network_vpn_ipsec_connection_subcommands_security_policy ${args} ;; esac } _network_vpn_ipsec_connection_subcommands_authentication() { local connection=${1} shift local words=( $@ ) local commands="mode pre-shared-key" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in mode) _network_vpn_ipsec_connection_subcommands_authentication_mode ${connection} ${args} ;; esac } _network_vpn_ipsec_connection_subcommands_local_remote() { local connection=${1} local type=${2} shift 2 local words=( $@ ) local commands="id prefix" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in prefix) _network_vpn_ipsec_connection_subcommands_prefix "${connection}" "${type}" ${args} ;; esac } _network_vpn_ipsec_connection_subcommands_prefix() { : } _network_vpn_ipsec_connection_subcommands_authentication_mode() { local connection=${1} shift local words=( $@ ) local commands="PSK" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_vpn_ipsec_connection_subcommands_mode() { local words=( $@ ) local commands="gre-transport tunnel vti" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_vpn_ipsec_connection_subcommands_security_policy() { local words=( $@ ) local commands="$(network raw list-vpn-security-policies-all)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_vpn_security_policies() { local words=( $@ ) local commands="destroy new $(network raw list-vpn-security-policies-all)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in destroy) : ;; new) : ;; *) if network raw vpn-security-policy-exists ${cmd}; then _network_vpn_security_policies_subcommands ${cmd} ${args} fi ;; esac } _network_vpn_security_policies_subcommands() { local policy=${1} shift local words=( $@ ) local commands="ciphers compression group-types integrity key-exchange lifetime pfs pseudo-random-functions show" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in ciphers) _network_vpn_security_policies_subcommands_ciphers ${policy} ${args} ;; compression) _network_vpn_security_policies_subcommands_compression ${policy} ${args} ;; group-types) _network_vpn_security_policies_subcommands_group_types ${policy} ${args} ;; integrity) _network_vpn_security_policies_subcommands_integrity ${policy} ${args} ;; pseudo-random-functions) _network_vpn_security_policies_subcommands_pseudo_random_functions ${policy} ${args} ;; key-exchange) _network_vpn_security_policies_subcommands_key_exchange ${policy} ${args} ;; pfs) _network_vpn_security_policies_subcommands_pfs ${policy} ${args} ;; esac } _network_vpn_security_policies_subcommands_ciphers() { : } _network_vpn_security_policies_subcommands_compression() { : } _network_vpn_security_policies_subcommands_group_types() { : } _network_vpn_security_policies_subcommands_integrity() { : } _network_vpn_security_policies_subcommands_pseudo_random_functions() { : } _network_vpn_security_policies_subcommands_key_exchange() { : } _network_vpn_security_policies_subcommands_pfs() { : } _network_zone() { local words=( $@ ) local commands="new destroy $(network raw list-zones)" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in new) _network_zone_new ${args} ;; destroy) _network_complete_zones ;; *) local zone="${cmd}" local args="${words[@]:1}" _network_zone_subcommand "${zone}" ${args} ;; esac } _network_zone_new() { local words=( $@ ) local cmd=${words[@]:0:1} # Suggest useful zone names if [[ -z "${cmd}" ]]; then local commands="$(network raw list-next-free-zones)" COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) # If a valid zone name was entered, we can move on elif network raw zone-name-is-valid ${cmd}; then local args="${words[@]:1}" _network_complete_hooks zone ${args} fi return 0 } _network_zone_subcommand() { local zone="${1}" shift local words=( $@ ) local commands="color config description disable down edit enable identify port rename status up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in config) _network_zone_subcommand_config "${zone}" ${args} ;; port) _network_zone_subcommand_port "${zone}" ${args} ;; color) _network_color ${args} ;; description) _network_description ${args} ;; esac } _network_zone_subcommand_config() { local zone="${1}" shift local words=( $@ ) local commands="destroy list new $(network raw list-zone-config-hids ${zone})" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local args="${words[@]:1}" case "${cmd}" in new) _network_complete_hooks "config" ;; destroy) _network_zone_subcommand_config_destroy ${zone} ${args} ;; *) if network raw zone-config-id-is-valid ${zone} ${cmd} || network raw zone-config-hid-is-valid ${zone} ${cmd}; then _network_zone_subcommand_config_subcommand ${zone} ${args} fi ;; esac } _network_zone_subcommand_config_subcommand() { local zone="${1}" shift local words=( $@ ) local commands="edit" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_zone_subcommand_config_destroy() { local zone="${1}" shift local words=( $@ ) local commands="$(network raw list-zone-config-ids ${zone})" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_zone_subcommand_port() { local zone="${1}" shift local words=( $@ ) local commands="attach detach $(network raw list-ports-of-zone "${zone}")" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in attach) COMPREPLY=( $(compgen -W "$(network raw list-free-ports "${zone}")" \ -- "${cur}") ) ;; detach) COMPREPLY=( $(compgen -W "$(network raw list-ports-of-zone "${zone}")" \ -- "${cur}") ) ;; *) local port="${cmd}" local args="${words[@]:1}" _network_zone_subcommand_port_subcommand "${zone}" "${port}" ${args} ;; esac } _network_zone_subcommand_port_subcommand() { local zone="${1}" local port="${2}" shift 2 local words=( $@ ) local commands="edit" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in edit) # TODO auto-complete the zone-port hook ;; esac } _network() { local cur prev words cword _init_completion || return local cmd i for (( i=1; i < ${#words[@]} - 1; i++ )); do [[ "${words[i]}" = -* ]] && continue cmd="${words[i]}" && break done if [[ -z "${cmd}" ]]; then case "${cur}" in -*) COMPREPLY=( $(compgen -W "--debug" -- "${cur}") ) ;; *) COMPREPLY=( $(compgen -W "device dhcpv4 dhcpv6 dns-server \ help hostname port reset route settings status vpn zone" \ -- "${cur}") ) ;; esac return 0 fi local args="${words[@]:i+1}" case "${cmd}" in device) _network_device ${args} ;; dhcpv[64]) _network_dhcpd "${cmd/dhcpv/ipv}" ${args} ;; dns-server) _network_dns_server ${args} ;; port) _network_port ${args} ;; route) _network_route ${args} ;; settings) _network_settings ${args} ;; start|stop|status) # start, stop and status optionally take a zone _network_complete_zones ;; vpn) _network_vpn ${args} ;; zone) _network_zone ${args} ;; esac } && complete -F _network network