#!/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 . # # # ############################################################################### port_dir() { echo "${NETWORK_CONFIG_DIR}/ports" } port_list() { local port for port in $(port_dir)/*; do port="$(basename "${port}")" if port_exists "${port}"; then print "${port}" fi done } 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 shift local args if function_exists "hook_check_settings"; then list_append args "--check=\"hook_check_settings\"" fi list_append args ${HOOK_SETTINGS} settings_write "$(port_file "${port}")" ${args} } ports_get_all() { port_list } port_file() { local port="${1}" assert isset port echo "$(port_dir)/${port}" } port_exists() { local port=${1} [ -f "${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 assert isset zone assert zone_exists ${zone} if listmatch ${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 port=${1} #shift # #if port_exists ${port}; then # error "Port '${port}' does already exist." # return ${EXIT_ERROR} #fi local hook=${1} shift if ! hook_exists port ${hook}; then error "Port hook '${hook}' does not exist." return ${EXIT_ERROR} fi #port_edit ${port} ${hook} $@ # #if [ $? -ne ${EXIT_OK} ]; then # port_destroy ${port} #fi hook_exec port ${hook} new $@ } port_destroy() { local port=${1} assert isset port port_exists ${port} || return ${EXIT_OK} # Check if the port is attached to any zone and don't delete it. local ok=${EXIT_OK} local attached_zone=$(port_is_attached ${port}) if [ -n "${attached_zone}" ]; then error_log "Cannot destroy port '${port}' which is attached to zone '${attached_zone}'." ok=${EXIT_ERROR} 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 listmatch ${port} $(port_get_parents ${other_port}); then error_log "Cannot destroy port '${port}' which is a parent port to '${other_port}'." ok=${EXIT_ERROR} fi if listmatch ${port} $(port_get_children ${other_port}); then error_log "Cannot destroy port '${port}' which is child of port '${other_port}'." ok=${EXIT_ERROR} fi done # If ok says we are not okay --> exit if [ ${ok} -ne ${EXIT_OK} ]; then return ${EXIT_ERROR} fi port_remove "${port}" rm -f $(port_file ${port}) } port_create() { port_cmd "create" $@ } port_remove() { local port="${1}" assert isset port # 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}" } port_edit() { port_cmd edit $@ } port_up() { port_cmd up $@ } port_down() { port_cmd down $@ } port_status() { port_cmd status $@ } port_info() { port_cmd info $@ } port_cmd() { local cmd=${1} local port=${2} shift 2 assert isset cmd assert isset port local hook=$(port_get_hook ${port}) assert isset hook hook_exec port ${hook} ${cmd} ${port} $@ } ports_get() { local port for port in $(port_dir)/*; do port=$(basename ${port}) 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_info() { local port=${1} local key=${2} assert isset port assert port_exists ${port} assert isset key ( eval $(port_info ${port}) echo "${!key}" ) } port_get_parents() { local port=${1} port_get_info ${port} PORT_PARENTS } port_get_children() { local port=${1} port_get_info ${port} PORT_CHILDREN } 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} }