#!/bin/sh ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2009 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 . # # # ############################################################################### HOME_DIR=${HOME_DIR-/lib/network} CONFIG_DIR=/etc/sysconfig/networking HOOKS_DIR=${HOME_DIR}/hooks CONFIG_ZONES=${CONFIG_DIR}/zones CONFIG_PORTS=${CONFIG_DIR}/ports COMMON_DEVICE=black+ EXIT_OK=0 EXIT_ERROR=1 EXIT_CONF_ERROR=2 [ -n "${DEBUG}" ] || DEBUG= [ -n "${VERBOSE}" ] || VERBOSE= function is_mac() { egrep -q "^[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]$" <<<$1 } function get_device_by_mac() { local mac local device mac=$1 for device in /sys/class/net/*; do if [ "$(cat $device/address)" = "$mac" ]; then device=${device##*/} # Skip virtual devices if [ -e "/proc/net/vlan/$device" ]; then continue fi # Skip zones if zone_exists ${device}; then continue fi echo ${device} return 0 fi done return 1 } function get_device_by_mac_and_vid() { local mac=$1 local vid=$2 local i local VID local DEVICE if [ -e "/proc/net/vlan/config" ]; then grep '|' /proc/net/vlan/config | sed "s/|//g" | \ while read DEVICE VID PARENT; do if [ "${vid}" = "${VID}" ] && [ "$(macify ${PARENT})" = "${mac}" ]; then echo "${DEVICE}" return 0 fi done fi return 1 } function get_device() { if [ ${#@} -gt 1 ]; then get_device_by_mac_and_vid $@ else get_device_by_mac $@ fi } function get_mac_by_device() { local device device=$1 if [ -d "/sys/class/net/$device" ]; then cat /sys/class/net/$device/address return 0 fi return 1 } function get_mac() { get_mac_by_device $@ } function devicify() { local device=${1} local mac if is_mac ${device}; then mac=${device} device=$(get_device_by_mac ${device}) fi if [ -n "${device}" ]; then echo ${device} return 0 else echo "devicify: Could not find device of $@" >&2 return 1 fi } function macify() { local input=${1} local mac if is_mac ${input}; then mac=${input} else mac=$(get_mac_by_device ${input}) fi echo ${mac} } function device_exists() { ip link show $(devicify ${1}) &>/dev/null } function device_is_up() { ip link show $(devicify ${1}) 2>/dev/null | grep -qE "<.*UP.*>" } function device_rename() { local source=$1 local destination=$2 # Replace + by a valid number if grep -q "+$" <<<${destination}; then local number destination=$(sed -e "s/+//" <<<$destination) number=0 while [ "${number}" -le "100" ]; do if ! device_exists "${destination}${number}"; then destination="${destination}${number}" break fi number=$(($number + 1)) done fi # Check if devices exist if ! device_exists ${source} || device_exists ${destination}; then return 4 fi ip link set ${source} down ip link set ${source} name ${destination} ip link set ${destination} up return $? } function hook_exists() { [ -x "${HOOKS_DIR}/${1}" ] } function port_exists() { device_exists $@ } function port_is_up() { port_exists $@ && device_is_up $@ } function zone_exists() { [ -e "$CONFIG_ZONES/${1}" ] } function zone_is_up() { zone_exists $@ && device_is_up $@ } function bridge_devices() { local bridge=$1 [ -z "${bridge}" ] && return 2 brctl show | grep "^${bridge}" | awk '{ print $NF }' | grep -v "^interfaces$" } function zone_add_port() { local zone=${1} local port=${2} brctl addif ${zone} ${port} } function zone_del_port() { local zone=${1} local port=${2} brctl delif ${zone} ${port} } function zone_list() { local zone for zone in $(find ${CONFIG_ZONES}/* 2>/dev/null); do [ -d "${zone}" ] && echo ${zone} done } function run_hooks() { local action=${1} local dir=${2} local failed local hook local hooks shift 2 if [ -z "${action}" ] || [ -z "${dir}" ]; then echo "Not enough parameters given." >&2 return 1 fi for hook in $(find ${dir} -type f); do ( . ${hook} if [ -n "${HOOK}" ] && hook_exists ${HOOK}; then /lib/network/hooks/${HOOK} --config=${hook} $@ ${action} RET=$? else echo -e "${FAILURE}Unable to process ${hook}. Either" echo -e "${FAILURE}the HOOK variable was not set," echo -e "${FAILURE}or the specified hook cannot be executed." message="" log_failure_msg fi exit ${RET} ) || failed=1 done return ${failed} } function hook_type() { local hook=${1} ( . $(hook_run ${hook} info) echo "${HOOK_TYPE}" ) } function config_get_hook() { local config=${1} if [ ! -e "${config}" ]; then log_failure_msg "Config file \"${config}\" does not exist." return ${EXIT_ERROR} fi ( . ${config}; echo ${HOOK} ) } function hook_run() { local hook=${1} shift if ! hook_exists ${hook}; then log_failure_msg "Hook ${hook} cannot be found or is not executeable." return ${EXIT_ERROR} fi decho "Running hook: ${hook} $@" DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOOKS_DIR}/${hook} $@ return $? } function hook_run_multiple() { local zone local config local hook local hook_type2 local type while [ "$#" -gt "0" ]; do case "${1}" in --type=*) type=${1#--type=} ;; *) zone=${1} break ;; esac shift done if ! zone_exists ${zone}; then return ${EXIT_ERROR} fi for config in $(find ${CONFIG_ZONES}/${zone} 2>/dev/null); do hook=$(config_get_hook ${config}) if [ -n "${type}" ]; then hook_type2=$(hook_type ${hook}) if [ "${type}" != "${hook_type2}" ]; then continue fi fi hook_run ${hook} $@ done } function zone_run() { local zone=${1} shift if ! zone_exists ${zone}; then log_failure_msg "Zone ${zone} does not exist." exit ${EXIT_ERROR} fi decho "Running zone: ${zone} $@" DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOME_DIR}/zone --zone=${zone} $@ return $? }