#!/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 . # # # ############################################################################### ports_get_all() { local port for port in $(list_directory "${NETWORK_PORTS_DIR}"); do if port_exists "${port}"; then print "${port}" fi done } # XXX TO BE REMOVED port_list() { ports_get_all "$@" } port_list_in_use() { local ports_in_use # Collect all ports that are attached to a zone local zone for zone in $(zones_get_all); do list_append ports_in_use $(zone_get_ports "${zone}") done # Collect all ports that are enslaved by an other port local port for port in $(port_list); do list_append ports_in_use $(port_get_slaves "${port}") done list_sort ${ports_in_use} } port_list_free() { local ports_in_use="$(port_list_in_use)" local port for port in $(port_list); do if ! list_match "${port}" ${ports_in_use}; then print "${port}" fi done return ${EXIT_OK} } port_get_hook() { local port=${1} assert isset port config_get_hook $(port_file ${port}) } port_config_dir() { local port=${1} print "${RUN_DIR}/ports/${port}" return ${EXIT_OK} } port_settings_read() { local port="${1}" assert isset port # Save the HOOK variable. local hook="${HOOK}" settings_read "$(port_file "${port}")" ${HOOK_SETTINGS[*]} # Restore hook. HOOK="${hook}" } port_settings_write() { local port="${1}" assert isset port settings_write "$(port_file "${port}")" \ --check="hook_check_settings" HOOK ${HOOK_SETTINGS[*]} } port_file() { local port="${1}" assert isset port echo "${NETWORK_PORTS_DIR}/${port}/settings" } port_exists() { local port=${1} [ -d "${NETWORK_CONFIG_DIR}/ports/${port}" ] } port_get_hook() { local port=${1} assert isset port config_get_hook $(port_file ${port}) } port_is_attached() { local port=${1} shift assert isset port local zone for zone in $(zones_get_all); do if list_match ${port} $(zone_get_ports ${zone}); then echo "${zone}" return ${EXIT_OK} fi done return ${EXIT_ERROR} } port_is_up() { device_is_up "$@" } port_new() { local hook="${1}" shift if ! hook_exists port "${hook}"; then error "Port hook '${hook}' does not exist." return ${EXIT_ERROR} fi hook_exec port "${hook}" new "$@" } port_destroy() { local port=${1} assert isset port # Cannot delete a port that does not exist if ! port_exists ${port}; then error "No such port: ${port}" return ${EXIT_ERROR} fi local attached_zone=$(port_is_attached ${port}) if [ -n "${attached_zone}" ]; then if ! zone_port_detach "${attached_zone}" "${port}"; then error "Could not remove port ${port} from zone ${zone}" return ${EXIT_ERROR} fi fi # Check if the port is linked to any other port and don't allow the user # to delete it. local other_port for other_port in $(ports_get); do [ "${other_port}" = "${port}" ] && continue if list_match ${port} $(port_get_children ${other_port}); then log ERROR "Cannot destroy port '${port}' which is child of port '${other_port}'." return ${EXIT_ERROR} fi done # Shut down the port before destroying it if ! port_remove "${port}"; then return ${EXIT_ERROR} fi if ! rm -rf "${NETWORK_PORTS_DIR}/${port}"; then log ERROR "Could not destroy port ${port}" return ${EXIT_ERROR} fi log INFO "Destroyed port ${port}" return ${EXIT_OK} } port_create() { port_cmd "create" "$@" } port_remove() { local port="${1}" assert isset port if ! port_exists "${port}"; then log ERROR "Port ${port} does not exist" return ${EXIT_ERROR} fi # If the device is still up, we need to bring it down first. if device_is_up "${port}"; then port_down "${port}" fi port_cmd "remove" "${port}" } # Restarts the port by removing it and then re-creating it port_restart() { local port="${1}" assert isset port port_remove "${port}" port_create "${port}" } port_edit() { port_cmd edit "$@" } port_up() { assert [ $# -eq 1 ] local port="${1}" # Check if the port exists if ! device_exists "${port}"; then log ERROR "Could not bring up port ${port} which has not been created" return ${EXIT_ERROR} fi port_cmd up "${port}" } port_down() { port_cmd down "$@" } port_status() { port_cmd status "$@" } port_cmd() { local cmd=${1} local port=${2} shift 2 assert isset cmd assert isset port local hook=$(port_get_hook ${port}) # Abort if we could not find a hook if ! isset hook; then log CRITICAL "Port ${port} does not have a hook associated with it" return ${EXIT_ERROR} fi hook_exec port ${hook} ${cmd} ${port} "$@" } ports_get() { local port for port in $(list_directory "${NETWORK_PORTS_DIR}"); do if port_exists ${port}; then echo "${port}" fi done } port_find_free() { local pattern=${1} assert isset pattern local port local i=0 while [ ${i} -lt 99 ]; do port=${pattern//N/${i}} if ! port_exists ${port} && ! device_exists ${port}; then echo "${port}" return ${EXIT_OK} fi i=$(( ${i} + 1 )) done return ${EXIT_ERROR} } port_get_children() { local port=${1} assert port_exists "${port}" port_cmd "children" "${port}" } port_zone() { # Get name of the zones, this port is configured in. local port=${1} shift assert isset port local zone for zone in $(zones_get_all); do if zone_has_port ${zone} ${port}; then echo "${zone}" return ${EXIT_OK} fi done return ${EXIT_OK} } port_hotplug_event() { local port="${1}" assert isset port hotplug_assert_in_hotplug_event port_cmd "hotplug" "${port}" } port_get_slaves() { local port="${1}" port_settings_read "${port}" \ --ignore-superfluous-settings SLAVES print "${SLAVES}" } port_device_is_slave() { assert [ $# -eq 2 ] local port="${1}" local device="${2}" # Get slaves of port local slaves="$(port_get_slaves "${port}")" # Returns true if device is in slaves list_match "${device}" ${slaves} } port_get_phy() { local port="${1}" port_settings_read "${port}" \ --ignore-superfluous-settings PHY print "${PHY}" } port_uses_phy() { assert [ $# -eq 2 ] local port="${1}" local phy="${2}" # Nothing to do if an empty argument is given if ! isset phy; then return ${EXIT_FALSE} fi phy="$(phy_get_address "${phy}")" local port_phy="$(port_get_phy "${port}")" [ "${port_phy}" = "${phy}" ] } ports_lowest_address() { local address local addresses local port for port in $(port_list); do # Skip all ports that do not exist # any more or are not plugged in device_exists "${port}" || continue # Skip all ports that are not proper ethernet devices device_is_wireless "${port}" && continue device_is_ethernet "${port}" || continue list_append addresses "$(device_get_address "${port}")" done # Sort the list addresses="$(list_sort ${addresses})" # Get the first element which is the lowest MAC address list_head ${addresses} } port_identify() { device_identify "$@" } port_get_color() { # This function return the color of a port assert [ $# -eq 1 ] local name=${1} color_read "port" ${name} } port_get_description_title() { assert [ $# -eq 1 ] local name=${1} description_title_read $(description_format_filename "port" "${name}") }