From 1848564d3b83c8d55ef908c3c8dde2d12d9e491c Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 3 Jun 2010 16:53:02 +0200 Subject: [PATCH] network: Update codebase. --- functions | 680 +------------------------------ functions.cli | 218 ++++++++++ functions.colors | 28 ++ functions.constants | 52 +++ functions.device | 536 ++++++++++++++++++++++++ functions.events | 28 ++ functions.hook | 141 +++++++ functions.logging | 21 + functions.ppp | 25 +- functions.util | 198 +++++++++ functions.zone | 417 +++++++++++++++++++ zone => header-port | 78 +--- header-zone | 254 ++++++++++++ hook-header | 38 -- hooks/README | 86 ---- hooks/bonding | 177 -------- hooks/bridge | 152 +++++++ hooks/bridge.configs/ipv4-static | 135 ++++++ hooks/bridge.ports/ethernet | 95 +++++ hooks/bridge.ports/virtual | 127 ++++++ hooks/ethernet | 137 ------- hooks/ipv4-dhcp | 84 ---- hooks/ipv4-static | 169 -------- hooks/ipv4-static-route | 141 ------- hooks/mtu | 85 ---- hooks/pppoe | 376 +++++++++-------- hooks/pppoe.helper | 73 ---- hooks/stp | 97 ----- hooks/vlan | 120 ------ network | 634 +++------------------------- ppp/ip-updown | 27 +- 31 files changed, 2705 insertions(+), 2724 deletions(-) create mode 100644 functions.cli create mode 100644 functions.colors create mode 100644 functions.constants create mode 100644 functions.device create mode 100644 functions.events create mode 100644 functions.hook create mode 100644 functions.logging create mode 100644 functions.util create mode 100644 functions.zone rename zone => header-port (50%) mode change 100755 => 100644 create mode 100644 header-zone delete mode 100644 hook-header delete mode 100644 hooks/README delete mode 100755 hooks/bonding create mode 100755 hooks/bridge create mode 100755 hooks/bridge.configs/ipv4-static create mode 100755 hooks/bridge.ports/ethernet create mode 100755 hooks/bridge.ports/virtual delete mode 100755 hooks/ethernet delete mode 100755 hooks/ipv4-dhcp delete mode 100755 hooks/ipv4-static delete mode 100755 hooks/ipv4-static-route delete mode 100755 hooks/mtu delete mode 100755 hooks/pppoe.helper delete mode 100755 hooks/stp delete mode 100755 hooks/vlan mode change 100644 => 100755 network mode change 100644 => 100755 ppp/ip-updown diff --git a/functions b/functions index f4a7fa1c..5c5372d9 100644 --- a/functions +++ b/functions @@ -1,678 +1,8 @@ -#!/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 . # -# # -############################################################################### +#!/bin/bash -HOME_DIR=${HOME_DIR-/lib/network} -CONFIG_DIR=/etc/network -HOOKS_DIR=${HOME_DIR}/hooks -LOG_DIR=/var/log/network - -CONNECTIONS_FILE=/var/log/network/connections.db - -CONFIG_ZONES=${CONFIG_DIR}/zones -CONFIG_PORTS=${CONFIG_DIR}/ports -CONFIG_HOOKS=${CONFIG_DIR}/hooks -CONFIG_PPP=${CONFIG_DIR}/ppp -CONFIG_UUIDS=${CONFIG_DIR}/uuids - -# Create config directories -for dir in ${CONFIG_ZONES} ${CONFIG_PORTS} ${CONFIG_HOOKS} ${CONFIG_PPP} ${CONFIG_UUIDS}; do - [ -d "${dir}" ] && continue - mkdir -p "${dir}" +for file in /lib/network/functions.*; do + . ${file} done -COMMON_DEVICE=port+ - -EXIT_OK=0 -EXIT_ERROR=1 -EXIT_CONF_ERROR=2 - -VALID_ZONES="green orange red grey" - -[ -n "${DEBUG}" ] || DEBUG= -[ -n "${VERBOSE}" ] || VERBOSE= - -function is_mac() { - [[ $1 =~ ^[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]$ ]] -} - -function is_uuid() { - local string=${1} - - # Length must be 37 characters - if [ ${#string} -eq 36 ] \ - && [ "${string:8:1}" = "-" ] \ - && [ "${string:13:1}" = "-" ] \ - && [ "${string:18:1}" = "-" ] \ - && [ "${string:23:1}" = "-" ]; then - return ${EXIT_OK} - fi - return ${EXIT_ERROR} -} - -function get_device_by_mac() { - local mac=${1} - local device - - for device in /sys/class/net/*; do - [ -d "${device}" ] || continue - 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 - - [ -n "${device}" ] || return 1 - - 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() { - [ -n "${1}" ] || return ${EXIT_ERROR} - local device=$(devicify ${1}) - [ -n "${device}" ] || return ${EXIT_ERROR} - ip link show ${device} &>/dev/null -} - -function device_is_bonding() { - [ -d "/sys/class/net/${1}/bonding" ] -} - -function device_is_bonded() { - local dev - for dev in /sys/class/net/*; do - # Skip crappy files - [ -d "${dev}" ] || continue - - # Continue if not a bonding device - device_is_bonding "${dev##*/}" || continue - - if grep -q "\<${1}\>" ${dev}/bonding/slaves; then - return 0 - fi - done - return 1 -} - -function device_is_bridge() { - [ -d "/sys/class/net/${1}/bridge" ] -} - -function device_is_up() { - ip link show $(devicify ${1}) 2>/dev/null | grep -qE "<.*UP.*>" -} - -function device_is_vlan() { - if [ ! -e "/proc/net/vlan/config" ]; then - return 1 - fi - grep -q "^${1}" /proc/net/vlan/config -} - -function device_is_ppp() { - # XXX need something better - [ "${1:0:3}" = "ppp" ] -} - -function device_is_loopback() { - local device=$(devicify ${1}) - [ "${device}" = "lo" ] -} - -function device_is_real() { - local device=${1} - - device_is_loopback ${device} && \ - return ${EXIT_ERROR} - - device_is_bonding ${device} && \ - return ${EXIT_ERROR} - - device_is_bridge ${device} && \ - return ${EXIT_ERROR} - - device_is_ppp ${device} && \ - return ${EXIT_ERROR} - - device_is_vlan ${device} && \ - return ${EXIT_ERROR} - - return ${EXIT_OK} -} - -function device_type() { - local device=$(devicify ${1}) - - if device_is_vlan ${device}; then - echo "vlan" - - elif device_is_bonding ${device}; then - echo "bonding" - - elif device_is_bridge ${device}; then - echo "bridge" - - elif device_is_ppp ${device}; then - echo "ppp" - - elif device_is_loopback ${device}; then - echo "loopback" - - elif device_is_real ${device}; then - echo "real" - - else - echo "unknown" - fi -} - -function device_has_vlans() { - if [ ! -e "/proc/net/vlan/config" ]; then - return 1 - fi - grep -q "${1}$" /proc/net/vlan/config -} - -function device_has_carrier() { - local device=$(devicify ${1}) - [ "$(/dev/null); do - [ -d "${zone}" ] && echo ${zone} - done -} - -function zone_is_red() { - local zone=${1} - [ "${zone#red}" != "${zone}" ] -} - -function _run_hooks() { - local action - local type - - while [ $# -gt 0 ]; do - case "${1}" in - --type=*) - type=${1#--type=} - ;; - *) - action="${1}" - shift; break - ;; - esac - shift - done - - local dir=${1}; shift - local failed - local hook - local hooks - - if [ -z "${action}" ] || [ -z "${dir}" ]; then - echo "Not enough parameters given." >&2 - return 1 - fi - - for hook in $(find ${dir}); do - # Skip dirs - [ -d "${hook}" ] && continue - - ( - . ${hook} - # Skip hooks that are not of the given type - if [ -n "${type}" ] && [ "$(hook_type ${HOOK})" != "${type}" ]; then - continue - fi - if [ -n "${HOOK}" ]; then - hook_run ${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 hooks_run_all() { - _run_hooks $@ -} - -function hooks_run_ports() { - _run_hooks --type="port" $@ -} - -function hooks_run_zones() { - _run_hooks --type="zone" $@ -} - -function hook_type() { - local hook=${1} - ( - eval $(${HOOKS_DIR}/${hook} info) - echo "${HOOK_TYPE}" - ) -} - -function hook_list() { - local type=${1} - local hook - for hook in ${HOOKS_DIR}/*; do - [ -x "${hook}" ] || continue - - hook=${hook##*/} - - [[ ${hook} =~ helper$ ]] && continue - - if [ -n "${type}" ] && [ "$(hook_type ${hook})" != "${type}" ]; then - continue - fi - echo "${hook}" - done -} - -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 - [ -n "${DEBUG}" ] && echo "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} $@ -} - -function zone_valid_name() { - local zone=${1} - local match - - local i - for i in ${VALID_ZONES}; do - match="${match}|${i}[0-9]{1,5}" - done - [[ ${zone} =~ ${match:1:${#match}} ]] -} - -function isset() { - local key=${1} - [ -n "${!key}" ] && return - if [[ ${key} =~ port|zone ]]; then - echo "ERROR: The --${key} flag is not set." >&2 - else - echo "ERROR: The \"${key}\" variable is not set properly." >&2 - fi - return 1 -} - -# Test if device is attached to the given bridge -function zone_has_device_attached () { - local zone=${1} - local device=${2} - - [ -d "/sys/class/net/${zone}/brif/${device}" ] -} - -function device_has_ipv4() { - local device=${1} - local ip=${2} - ip addr show ${device} | grep inet | fgrep -q ${ip} -} - -function check_config() { - local failed - local i - - for i in $@; do - isset ${i} || failed=1 - done - if [ "${failed}" = "1" ]; then - echo "Exiting..." - exit ${EXIT_ERROR} - fi -} - -function mac_generate() { - local mac="00" - while [ "${#mac}" -lt 15 ]; do - mac="${mac}:$(cut -c 1-2 /proc/sys/kernel/random/uuid)" - done - echo "${mac}" -} - -function connection() { - local action - - local dns - local interface - local iplocal - local ipremote - local name - local status - local weight - local zone - - while [ $# -gt 0 ]; do - case "${1}" in - --up) - action="up" - ;; - --down) - action="down" - ;; - --starting) - action="starting" - ;; - --stopping) - action="stopping" - ;; - --name=*) - name=${1#--name=} - ;; - --zone=*) - zone=${1#--zone=} - zone_is_red ${zone} || return 0 - ;; - --interface=*) - interface=${1#--interface=} - ;; - --iplocal=*) - iplocal=${1#--iplocal=} - ;; - --ipremote=*) - ipremote=${1#--ipremote=} - ;; - --weight=*) - weight=${1#--weight=} - ;; - --dns=*) - dns=${1#--dns=} - ;; - esac - shift - done - - if [ ! -e "${CONNECTIONS_FILE}" ]; then - sqlite3 -batch ${CONNECTIONS_FILE} <. # +# # +############################################################################### + +function cli_config() { + if [ -n "${1}" ]; then + network_config_set $@ + else + network_config_print + fi +} + +function cli_device() { + local action=${1} + shift + + local device + local devices=$@ + + if [ -z "${devices}" ]; then + devices=$(devices_get_all) + fi + + case "${action}" in + discover) + echo "# XXX need to implement --raw here" + for device in ${devices}; do + cli_device_discover ${device} $@ + done + ;; + + show|"") + for device in ${devices}; do + cli_device_print ${device} + done + ;; + *) + cli_usage device + ;; + esac +} + +function cli_device_print() { + local device=${1} + + if ! device_exists ${device}; then + error "Device '${device}' does not exist." + return ${EXIT_ERROR} + fi + + echo "${device}" + echo " Type: $(device_get_type ${device})" + echo " Addr: $(device_get_address ${device})" + echo +} + +function cli_device_discover() { + local device=${1} + shift + + local device_type=$(device_get_type ${device}) + if [ "${device_type}" != "real" ]; then + return ${EXIT_OK} + fi + + local raw + + while [ $# -gt 0 ]; do + case "${1}" in + --raw) + raw=1 + ;; + esac + shift + done + + local up + device_is_up ${device} && up=1 + device_set_up ${device} + + enabled raw || echo "${device}" + + local hook + local out + local ret + for hook in $(hooks_get_all); do + out=$(hook_exec ${hook} discover ${device}) + ret=$? + + [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue + + if enabled raw; then + case "${ret}" in + ${DISCOVER_OK}) + echo "${hook}: OK" + local line + while read line; do + echo "${hook}: ${line}" + done <<<"${out}" + ;; + + ${DISCOVER_ERROR}) + echo "${hook}: FAILED" + ;; + esac + else + case "${ret}" in + ${DISCOVER_OK}) + echo " ${hook} was successful." + local line + while read line; do + echo " ${line}" + done <<<"${out}" + ;; + + ${DISCOVER_ERROR}) + echo " ${hook} failed." + ;; + esac + fi + done + + echo # New line + + [ "${up}" = "1" ] || device_set_down ${device} +} + +function cli_zone() { + local action + local zone + + if zone_name_is_valid ${1}; then + zone=${1} + action=${2} + shift 2 + + case "${action}" in + config|down|edit|port|show|status|up) + zone_${action} ${zone} $@ + ;; + esac + else + action=${1} + shift + + case "${action}" in + create|remove) + zone_${action} $@ + ;; + *) + error "Unrecognized argument: '${action}'" + ;; + esac + fi +} + +function cli_start() { + local zones=$(zones_get $@) + + local zone + for zone in ${zones}; do + zone_up ${zone} + done +} + +function cli_stop() { + local zones=$(zones_get $@) + + local zone + for zone in ${zones}; do + zone_down ${zone} + done +} + +function cli_usage() { + local what=${1} + + case "${what}" in + root) + echo "${0}: [command] " + echo + echo " start - ..." + echo " stop - ..." + echo + echo " config - ..." + echo + echo " device - ..." + echo " show - ???" + echo " zone - ..." + echo + ;; + usage) + echo + echo " Run '${0} help' to get information how to use this tool." + echo + ;; + *) + error "No help available for this command '${what}'." + ;; + esac +} diff --git a/functions.colors b/functions.colors new file mode 100644 index 00000000..19685bb5 --- /dev/null +++ b/functions.colors @@ -0,0 +1,28 @@ +#!/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 . # +# # +############################################################################### + +# Define color for messages +BOLD="\\033[1;39m" +DONE="\\033[1;32m" +SKIP="\\033[1;34m" +WARN="\\033[1;35m" +FAIL="\\033[1;31m" +NORMAL="\\033[0;39m" diff --git a/functions.constants b/functions.constants new file mode 100644 index 00000000..7521e6e8 --- /dev/null +++ b/functions.constants @@ -0,0 +1,52 @@ +#!/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 . # +# # +############################################################################### + +# Enable colors by default +COLORS=1 + +BASE_DIR=/lib/network +CONFIG_DIR=/etc/network +HOOKS_DIR=${BASE_DIR}/hooks +RUN_DIR=/var/run/network +ZONE_DIR=${CONFIG_DIR} + +RED_RUN=/var/run/network/red +PPP_SECRETS=/etc/ppp/secrets + +CONFIG_FILE=${CONFIG_DIR}/network_config +CONFIG_FILE_PARAMS="COLORS DEBUG SHELL" + +# Proper error codes +EXIT_OK=0 +EXIT_ERROR=1 +EXIT_CONF_ERROR=2 + +STATUS_UP=0 +STATUS_DOWN=1 + +DISCOVER_OK=0 +DISCOVER_ERROR=1 +DISCOVER_NOT_SUPPORTED=2 + +# The user is able to create zones that begin with these names +VALID_ZONES="green orange red grey" + +SYS_CLASS_NET="/sys/class/net" diff --git a/functions.device b/functions.device new file mode 100644 index 00000000..2063a83c --- /dev/null +++ b/functions.device @@ -0,0 +1,536 @@ +#!/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 . # +# # +############################################################################### + +function devicify() { + local device=${1} + + if device_exists ${device}; then + echo "${device}" + return ${EXIT_OK} + fi + + local d + for d in $(devices_get_all); do + if [ "$(device_get_address ${d})" = "${device}" ]; then + echo "${d}" + return ${EXIT_OK} + fi + done + + return ${EXIT_ERROR} +} + +function macify() { + local device=${1} + + if mac_is_valid ${device}; then + echo "${device}" + return ${EXIT_OK} + fi + + if device_exists ${device}; then + device_get_address ${device} + return ${EXIT_OK} + fi + + return ${EXIT_ERROR} +} + +# Check if the device exists +function device_exists() { + local device=${1} + + # If device name was not found, exit. + [ -n "${device}" ] || return ${EXIT_ERROR} + + [ -d "${SYS_CLASS_NET}/${device}" ] +} + +# Check if the device is up +function device_is_up() { + local device=${1} + + device_exists ${device} || return ${EXIT_ERROR} + + ip link show ${device} 2>/dev/null | grep -qE "<.*UP.*>" +} + +# Check if the device is a bonding device +function device_is_bonding() { + [ -d "/sys/class/net/${1}/bonding" ] +} + +# Check if the device bonded in a bonding device +function device_is_bonded() { + local dev + for dev in /sys/class/net/*; do + # Skip crappy files + [ -d "${dev}" ] || continue + + # Continue if not a bonding device + device_is_bonding "${dev##*/}" || continue + + if grep -q "\<${1}\>" ${dev}/bonding/slaves; then + return 0 + fi + done + + return 1 +} + +# Check if the device is a bridge +function device_is_bridge() { + [ -d "/sys/class/net/${1}/bridge" ] +} + +# Check if the device is a virtual device +function device_is_virtual() { + local device=${1} + + [ -e "/proc/net/vlan/${device}" ] +} + +# Check if the device has virtual devices +function device_has_virtuals() { + if [ ! -e "/proc/net/vlan/config" ]; then + return 1 + fi + grep -q "${1}$" /proc/net/vlan/config +} + +function device_is_vlan() { # XXX Compat function + log DEBUG "Deprecated function device_is_vlan() was used." + + device_is_virtual $@ +} + +# Check if the device is a ppp device +function device_is_ppp() { + local device=${1} + + ip link show ${device} 2>/dev/null | grep -qE "<.*POINTOPOINT.*>" +} + +# Check if the device is a loopback device +function device_is_loopback() { + local device=$(devicify ${1}) + [ "${device}" = "lo" ] +} + +# Check if the device is a physical network interface +function device_is_real() { + local device=${1} + + device_is_loopback ${device} && \ + return ${EXIT_ERROR} + + device_is_bonding ${device} && \ + return ${EXIT_ERROR} + + device_is_bridge ${device} && \ + return ${EXIT_ERROR} + + device_is_ppp ${device} && \ + return ${EXIT_ERROR} + + device_is_virtual ${device} && \ + return ${EXIT_ERROR} + + return ${EXIT_OK} +} + +# Get the device type +function device_get_type() { + local device=$(devicify ${1}) + + if device_is_vlan ${device}; then + echo "vlan" + + elif device_is_bonding ${device}; then + echo "bonding" + + elif device_is_bridge ${device}; then + echo "bridge" + + elif device_is_ppp ${device}; then + echo "ppp" + + elif device_is_loopback ${device}; then + echo "loopback" + + elif device_is_real ${device}; then + echo "real" + + else + echo "unknown" + fi +} + +function device_get_address() { + local device=${1} + + cat ${SYS_CLASS_NET}/${device}/address 2>/dev/null +} + +function device_set_address() { + device_set_mac $@ +} + +function devices_get_all() { + local device + for device in ${SYS_CLASS_NET}/*; do + echo "$(basename ${device})" + done | sort +} + +# Check if a device has a cable plugged in +function device_has_carrier() { + local device=$(devicify ${1}) + [ "$(<${SYS_CLASS_NET}/${device}/carrier)" = "1" ] +} + +# Check if the device is free +function device_is_free() { + local device=${1} + + device_is_used ${device} && \ + return ${EXIT_ERROR} + + return ${EXIT_OK} +} + +# Check if the device is used +function device_is_used() { + local device=$(devicify ${1}) + + device_has_vlans ${device} && \ + return ${EXIT_ERROR} + device_is_bonded ${device} && \ + return ${EXIT_ERROR} + + return ${EXIT_OK} +} + +# XXX to be removed I think +function device_get_free() { + local destination=${1} + + # Replace + by a valid number + if grep -q "+$" <<<${destination}; then + local number=0 + destination=$(sed -e "s/+//" <<<$destination) + while [ "${number}" -le "100" ]; do + if ! device_exists "${destination}${number}"; then + destination="${destination}${number}" + break + fi + number=$(($number + 1)) + done + fi + echo "${destination}" +} + +# Should be renamed to device_set_name at some time +function device_rename() { + local source=$1 + local destination=$(device_get_free ${2}) + + # Check if devices exists + if ! device_exists ${source} || device_exists ${destination}; then + return 4 + fi + + local up + if device_is_up ${source}; then + ip link set ${source} down + up=1 + fi + + ip link set ${source} name ${destination} + + if [ "${up}" = "1" ]; then + ip link set ${destination} up + fi +} + +function device_hash() { + local device=${1} + + macify ${device} | tr -d ':' +} + +# Give the device a new name +function device_set_name() { + device_rename $@ +} + +# Set device up +function device_set_up() { + local device=$(devicify ${1}) + + # Do nothing if device is already up + device_is_up ${device} && return ${EXIT_OK} + + log DEBUG "Setting up device $@" + ip link set ${device} up +} + +# Set device down +function device_set_down() { + local device=$(devicify ${1}) + + # Do nothing if device is not up + device_is_up ${device} || return ${EXIT_OK} + + log DEBUG "Tearing down device $@" + ip link set ${device} down +} + +# Set new address to a device +function device_set_mac() { + local port=${1} + local mac=${2} + + local up + if device_is_up ${port}; then + device_set_down ${port} + up=1 + fi + + ip link set ${port} address ${mac} + local ret=$? + + if [ "${up}" = "1" ]; then + device_set_up ${port} + fi + + return ${ret} +} + +function device_get_mtu() { + local device=${1} + + if ! device_exists ${device}; then + error "Device '${device}' does not exist." + return ${EXIT_ERROR} + fi + + cat ${SYS_CLASS_NET}/${device}/mtu +} + +# Set mtu to a device +function device_set_mtu() { + local port=${1} + local mtu=${2} + + local up + if device_is_up ${port}; then + device_set_down ${port} + up=1 + fi + + ip link set ${port} mtu ${mtu} + local ret=$? + + if [ "${up}" = "1" ]; then + device_set_up ${port} + fi + + return ${ret} +} + +function device_discover() { + local device=${1} + + local hook + for hook in $(hooks_get_all); do + hook_exec ${hook} discover ${device} + done +} + +function device_create_virtual() { + log WARN "Called deprecated function device_create_virtual" + device_virtual_create $@ +} + +function device_virtual_create() { + local port=$(devicify ${1}) + local vid=${2} + local mac=${3} + local newport=${port}v${vid} + + if [ -z "${mac}" ]; then + mac=$(mac_generate) + fi + + # Bring up the parent device + # XXX Do we need this here? + #device_set_up ${port} + + vconfig set_name_type DEV_PLUS_VID_NO_PAD >/dev/null + vconfig add ${port} ${vid} >/dev/null + [ $? -ne 0 ] && return ${EXIT_ERROR} + + # The device is expected to be named like ${port}.${vid} + # and will be renamed to the virtual schema + device_set_name ${port}.${vid} ${newport} + + # Setting new mac address + device_set_address ${newport} ${mac} + + # Bring up the new device + device_set_up ${newport} + + log DEBUG "Created virtual device ${newport} (${mac})" + return ${EXIT_OK} +} + +function device_virtual_remove() { + local device=$(devicify ${1}) + + device_set_down ${device} + + vconfig rem ${device} >/dev/null + [ $? -ne 0 ] && return ${EXIT_ERROR} + + log DEBUG "Removed virtual device ${device}" + return ${EXIT_OK} +} + +function device_bonding_create() { + local device=${1} + local mac=${2} + + [ -z "${mac}" ] && mac=$(mac_generate) + + echo "+${device}" > /sys/class/net/bonding_masters + device_set_mac ${mac} + device_set_up ${device} +} + +function device_bonding_remove() { + local device=$(devicify ${1}) + + device_set_down ${device} + echo "-${device}" > /sys/class/net/bonding_masters +} + +function bonding_set_mode() { + local device=${1} + local mode=${2} + + echo "${mode}" > /sys/class/net/${device}/bonding/mode +} + +function bonding_enslave_device() { + local device=$(devicify ${1}) + local slave=$(devicify ${2}) + + device_set_down ${slave} + echo "+${slave}" > /sys/class/net/${device}/bonding/slaves +} + +function bridge_attach_device() { + local bridge=${1} + local device=${2} + + if ! device_exists ${bridge}; then + error "Bridge '${bridge}' does not exist." + return ${EXIT_ERROR} + fi + + if ! device_exists ${device}; then + error "Device '${device}' does not exist." + return ${EXIT_ERROR} + fi + + # XXX device_set_up ${device} # Do we need this here? + + brctl addif ${bridge} ${device} +} + +function bridge_detach_device() { + local bridge=${1} + local device=${2} + + if ! device_exists ${bridge}; then + error "Bridge '${bridge}' does not exist." + return ${EXIT_ERROR} + fi + + if ! device_exists ${device}; then + error "Device '${device}' does not exist." + return ${EXIT_ERROR} + fi + + brctl delif ${zone} ${device} + + device_set_down ${device} +} + +function bridge_is_forwarding() { + local seconds=45 + local zone=${1} + + bridge_has_carrier ${zone} || return ${EXIT_ERROR} + + local device + while [ ${seconds} -gt 0 ]; do + for device in ${SYS_CLASS_NET}/${zone}/brif/*; do + [ -e "${device}/state" ] || continue + if [ "$(<${device}/state)" = "3" ]; then + return ${EXIT_OK} + fi + done + sleep 1 + seconds=$((${seconds} - 1)) + done + + return ${EXIT_ERROR} +} + +function bridge_has_carrier() { + local zone=${1} + + local has_carrier=${EXIT_ERROR} + + local device + for device in ${SYS_CLASS_NET}/${zone}/brif/*; do + device=$(basename ${device}) + device_exists ${device} || continue + + device_has_carrier ${device} && has_carrier=${EXIT_OK} + done + + return ${has_carrier} +} + +function device_has_ipv4() { + local device=${1} + local addr=${2} + + if ! device_exists ${device}; then + error "Device '${device}' does not exist." + return ${EXIT_ERROR} + fi + + ip addr show ${device} | grep -q -e "inet " -e "${addr}" +} diff --git a/functions.events b/functions.events new file mode 100644 index 00000000..1dd98a53 --- /dev/null +++ b/functions.events @@ -0,0 +1,28 @@ +#!/bin/bash + +function event_emit() { + local event=${1} + shift + + log DEBUG "Emitting event '${event}' ($@)" + + initctl emit ${event} $@ +} + +function event_firewall_reload() { + event_emit firewall-reload +} + +# XXX dunno what this does. +function event_interface_up() { + local iface=${1} + + event_emit network-interface-up IFACE=${iface} +} + +# XXX dunno what this does. +function event_interface_down() { + local iface=${1} + + event_emit network-interface-down IFACE=${iface} +} diff --git a/functions.hook b/functions.hook new file mode 100644 index 00000000..970e43b1 --- /dev/null +++ b/functions.hook @@ -0,0 +1,141 @@ +#!/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 . # +# # +############################################################################### + +function hook_exists() { + local hook=${1} + + [ -d "${HOOKS_DIR}/${hook}" ] && return ${EXIT_ERROR} + + [ -x "${HOOKS_DIR}/${hook}" ] +} + +function hook_port_exists() { + local hook_zone=${1} + local hook_port=${2} + + hook_exists ${hook_zone} || return ${EXIT_ERROR} + + [ -x "${HOOKS_DIR}/${hook_zone}.ports/${hook_port}" ] +} + +function hook_config_exists() { + local hook_zone=${1} + local hook_config=${2} + + hook_exists ${hook_zone} || return ${EXIT_ERROR} + + [ -x "${HOOKS_DIR}/${hook_zone}.configs/${hook_config}" ] +} + +function hook_has_ports() { + local hook=${1} + + [ -d "${HOOKS_DIR}/${hook}.ports" ] +} + +function hook_has_configs() { + local hook=${1} + + [ -d "${HOOKS_DIR}/${hook}.configs" ] +} + +function hook_exec() { + local hook=${1} + shift + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + ${SHELL} ${HOOKS_DIR}/${hook} $@ +} + +function hook_port_exec() { + local hook_zone=${1} + local hook_port=${2} + shift 2 + + if ! hook_exists ${hook_zone}; then + error "Hook '${hook_zone}' does not exist." + return ${EXIT_ERROR} + fi + + if ! hook_port_exists ${hook_zone} ${hook_port}; then + error "Port hook '${hook_port}' does not exist." + return ${EXIT_ERROR} + fi + + ${SHELL} ${HOOKS_DIR}/${hook_zone}.ports/${hook_port} $@ +} + +function hook_config_exec() { + local hook_zone=${1} + local hook_config=${2} + shift 2 + + if ! hook_exists ${hook_zone}; then + error "Hook '${hook_zone}' does not exist." + return ${EXIT_ERROR} + fi + + if ! hook_config_exists ${hook_zone} ${hook_config}; then + error "Config hook '${hook_config}' does not exist." + return ${EXIT_ERROR} + fi + + ${SHELL} ${HOOKS_DIR}/${hook_zone}.configs/${hook_config} $@ +} + +function hooks_get_all() { + local type=${1} + + local hook + for hook in ${HOOKS_DIR}/*; do + hook=$(basename ${hook}) + hook_exists ${hook} && echo "${hook}" + done | sort +} + +function hook_ports_get_all() { + local hook=${1} + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + local hook + for hook in ${HOOKS_DIR}/${zone}.ports/*; do + hook=$(basename ${hook}) + ## XXX executeable? + echo "${hook}" + done | sort +} + +function config_get_hook() { + local config=${1} + + ( + . ${config} + echo "${HOOK}" + ) +} diff --git a/functions.logging b/functions.logging new file mode 100644 index 00000000..db5c8efa --- /dev/null +++ b/functions.logging @@ -0,0 +1,21 @@ +#!/bin/bash + +LOG_FACILITY="network" +LOG_LEVEL="DEBUG" + +function log() { + local level=${1} + shift + local message="$@" + + if [ -z "${DEBUG}" ] && [ "${level}" = "DEBUG" ]; then + return + fi + + # Set a prefix if we are in a hook. + if [ -n "${HOOK}" ]; then + message="${HOOK}: ${message}" + fi + + logger -t ${LOG_FACILITY} "${message}" +} diff --git a/functions.ppp b/functions.ppp index 7598f0ba..82038512 100644 --- a/functions.ppp +++ b/functions.ppp @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# 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 # @@ -19,26 +19,28 @@ # # ############################################################################### -RED_RUN=/var/run/network/red -PPP_SECRETS=/etc/ppp/secrets - function ppp_pre_up() { # Load the ppp_generic module if not already done - grep -q ^ppp_generic /proc/modules || modprobe ppp_generic + if ! grep -q ^ppp_generic /proc/modules; then + modprobe -q ppp_generic + fi - connection --starting --zone=${zone} + #connection --starting --zone=${zone} } function ppp_post_up() { - : #connection --up --zone=${zone} + : + #connection --up --zone=${zone} } function ppp_pre_down() { - connection --stopping --zone=${zone} + : + # connection --stopping --zone=${zone} } function ppp_post_down() { - : #connection --down --zone=${zone} + : + #connection --down --zone=${zone} } function ppp_secret() { @@ -83,13 +85,14 @@ function ppp_linkname_get() { local config=${1} ( . ${config} - echo "${LINKNAME}" + echo "${NAME}" ) } function red_defaultroute_update() { local command="ip route replace default" + local uplink for uplink in ${RED_RUN}/*; do [ -d "${uplink}" ] || continue @@ -102,7 +105,7 @@ function red_defaultroute_update() { fi done $command - ip route flush cache + #ip route flush cache } function red_dns_update() { diff --git a/functions.util b/functions.util new file mode 100644 index 00000000..9eb5afe3 --- /dev/null +++ b/functions.util @@ -0,0 +1,198 @@ +#!/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 . # +# # +############################################################################### + +# Print a pretty error message +function error() { + echo -e " ${FAIL}ERROR${NORMAL} : $@" >&2 +} + +# Print a pretty warn message +function warning() { + echo -e " ${WARN}WARNING${NORMAL}: $@" >&2 +} + +function listsort() { + local i + for i in $@; do + echo "${i}" + done | sort | tr "\n" " " +} + +function config_read() { + local config_file=${1} + + if [ -e "${config_file}" ]; then + . ${config_file} + config_check + fi +} + +function config_write() { + local config_file=${1} + shift + + # Check if all values to be written are sane + config_check + + > ${config_file} + + local param + for param in $(listsort $@); do + echo "${param}=\"${!param}\"" >> ${config_file} + done +} + +function config_print() { + local param + + for param in $(listsort $@); do + printf "%-16s = %s\n" "${param}" "${!param}" + done +} + +function config_check() { + # If there is a function defined that is called __check + # we call that function + [ -n "$(type -t _check)" ] && _check +} + +function network_config_set() { + while [ $# -gt 0 ]; do + case "${1}" in + *=*) + eval ${1} + ;; + *) + warning "Invalid parameter given: ${1}" + ;; + esac + shift + done + + # Write configuration to disk + network_config_write +} + +function network_config_read() { + config_read ${CONFIG_FILE} +} + +function network_config_write() { + config_write ${CONFIG_FILE} ${CONFIG_FILE_PARAMS} +} + +function network_config_print() { + config_print ${CONFIG_FILE_PARAMS} +} + +# Speedup function to avoid a call of the basename binary +function basename() { + echo "${1##*/}" +} + +function enabled() { + local param=${1} + + [ "${!param}" = "yes" ] || [ "${!param}" = "on" ] || [ "${!param}" = "1" ] +} + +function mac_generate() { + local mac=() + for i in $(seq 0 5); do + mac[i]="0x$(uuid | cut -c 1-2)" + done + + # Remove multicast bit + # and set address is software assigned + # XXX must doublecheck if this works + mac[0]=$((mac[0] & 0xfe)) + mac[0]=$((mac[0] | 0x02)) + + local output + for i in ${mac[*]}; do + if [ -n "${output}" ]; then + output="${output}:" + fi + + output="${output}$(printf "%02x" ${i})" + done + + # Check if output is valid + assert mac_is_valid ${output} + + echo ${output} +} + +function mac_is_valid() { + local mac=${1} + + [[ ${mac} =~ ^([0-9a-f]{2}\:){5}[0-9a-f]{2}$ ]] +} + +function uuid() { + cat /proc/sys/kernel/random/uuid +} + +function isset() { + local var=${1} + + [ -n "${!var}" ] +} + +function isoneof() { + local var=${!1} + shift + + for i in $@; do + [ "${var}" = "${i}" ] && return ${EXIT_OK} + done + + return ${EXIT_ERROR} +} + +function isbool() { + local var=${1} + + isoneof ${var} 0 1 no yes on off +} + +function isinteger() { + local var=${!1} + + [[ ${var} =~ ^[0-9]+$ ]] +} + +function ismac() { + local mac=${!1} + + mac_is_valid ${mac} +} + +function assert() { + local assertion="$@" + + if ! ${assertion}; then + error "Assertion '${assertion}' failed." + exit ${EXIT_ERROR} + fi + + return ${EXIT_OK} +} diff --git a/functions.zone b/functions.zone new file mode 100644 index 00000000..268993ae --- /dev/null +++ b/functions.zone @@ -0,0 +1,417 @@ +#!/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 . # +# # +############################################################################### + +function zone_dir() { + local zone=${1} + + echo "${ZONE_DIR}/${zone}" +} + +function zone_exists() { + local zone=${1} + + [ -d "$(zone_dir ${zone})" ] +} + +function zone_match() { + local match + + local i + for i in ${VALID_ZONES}; do + match="${match}|${i}[0-9]{1,5}" + done + + echo "${match:1:${#match}}" +} + +function zone_name_is_valid() { + local zone=${1} + + [[ ${zone} =~ $(zone_match) ]] +} + +function zone_is_local() { + local zone=${1} + + if [[ ${zone} =~ ^red[0-9]{1,5} ]]; then + return ${EXIT_ERROR} + fi + return ${EXIT_OK} +} + +function zone_get_hook() { + local zone=${1} + + config_get_hook $(zone_dir ${zone})/settings +} + +function zone_create() { + local zone=${1} + local hook=${2} + shift 2 + + if ! zone_name_is_valid ${zone}; then + error "Zone name '${zone}' is not valid." + return ${EXIT_ERROR} + fi + + if zone_exists ${zone}; then + error "Zone '${zone}' does already exist." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + mkdir -p $(zone_dir ${zone}) + + hook_exec ${hook} create ${zone} $@ + local ret=$? + + # Maybe the zone create hook did not exit correctly. + # If this is the case we remove the created zone immediately. + if [ "${ret}" = "${EXIT_ERROR}" ]; then + zone_remove ${zone} + fi +} + +function zone_edit() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} edit ${zone} $@ +} + +function zone_remove() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + # XXX Tear this down here? + + rm -rf $(zone_dir ${zone}) +} + +function zone_up() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} up ${zone} $@ +} + +function zone_down() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} down ${zone} $@ +} + +function zone_status() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} status ${zone} $@ +} + +function zone_port() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} port ${zone} $@ +} + +function zone_config() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + error "Zone '${zone}' does not exist." + return ${EXIT_ERROR} + fi + + local hook=$(config_get_hook $(zone_dir ${zone})/settings) + + if [ -z "${hook}" ]; then + error "Config file did not provide any hook." + return ${EXIT_ERROR} + fi + + if ! hook_exists ${hook}; then + error "Hook '${hook}' does not exist." + return ${EXIT_ERROR} + fi + + hook_exec ${hook} config ${zone} $@ +} + +function zone_show() { + local zone=${1} + + echo "${zone}" + echo " Type: $(zone_get_hook ${zone})" + echo +} + +function zones_show() { + local zone + + for zone in $(zones_get $@); do + zone_show ${zone} + done +} + +function zones_get_all() { + local zone + for zone in ${ZONE_DIR}/*; do + zone=$(basename ${zone}) + zone_exists ${zone} || continue + + echo "${zone}" + done | sort +} + +function zones_get_local() { + local zone + for zone in $(zones_get_all); do + zone_is_local ${zone} && echo "${zone}" + done +} + +function zones_get_nonlocal() { + local zone + for zone in $(zones_get_all); do + zone_is_local ${zone} || echo "${zone}" + done +} + +function zones_get() { + local local=1 + local remote=1 + + local zones + + while [ $# -gt 0 ]; do + case "${1}" in + --local-only) + local=1 + remote=0 + ;; + --remote-only) + local=0 + remote=1 + ;; + --all) + local=1 + remote=1 + ;; + *) + if zone_name_is_valid ${1}; then + zones="${zones} ${1}" + else + warning "Unrecognized argument '${1}'" + fi + ;; + esac + shift + done + + if [ -n "${zones}" ]; then + local zone + for zone in ${zones}; do + zone_exists ${zone} && echo "${zone}" + done + exit ${EXIT_OK} + fi + + if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then + zones_get_all + elif [ ${local} -eq 1 ]; then + zones_get_local + elif [ ${remote} -eq 1 ]; then + zones_get_nonlocal + fi +} + +function zone_ports_list() { + local zone=${1} + + local port + for port in $(zone_dir ${zone})/port.*; do + [ -e "${port}" ] || continue + + echo $(basename ${port}) + done | sort +} + +function zone_ports_cmd() { + local cmd=${1} + local zone=${2} + shift 2 + + local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings) + + local hook_port + local port + for port in $(zone_ports_list ${zone}); do + hook_port=$(config_get_hook $(zone_dir ${zone})/${port}) + + hook_port_exec ${hook_zone} ${hook_port} ${cmd} ${zone} ${port} $@ + done +} + +function zone_ports_up() { + zone_ports_cmd up $@ +} + +function zone_ports_down() { + zone_ports_cmd down $@ +} + +function zone_configs_list() { + local zone=${1} + + local config + for config in $(zone_dir ${zone})/config.*; do + [ -e "${config}" ] || continue + + echo $(basename ${config}) + done | sort +} + +function zone_configs_cmd() { + local cmd=${1} + local zone=${2} + shift 2 + + local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings) + + local hook_config + local config + for config in $(zone_configs_list ${zone}); do + hook_config=$(config_get_hook $(zone_dir ${zone})/${config}) + + hook_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} ${config} $@ + done +} + +function zone_configs_up() { + zone_configs_cmd up $@ +} + +function zone_configs_down() { + zone_configs_cmd down $@ +} + +function zone_has_ipv4() { + device_has_ipv4 $@ +} + diff --git a/zone b/header-port old mode 100755 new mode 100644 similarity index 50% rename from zone rename to header-port index 0f5b355d..4f22adc4 --- a/zone +++ b/header-port @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# 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 # @@ -19,75 +19,31 @@ # # ############################################################################### -. /etc/init/functions . /lib/network/functions -while [ "$#" -gt "0" ]; do +HOOK=$(basename ${0}) + +while [ $# -gt 0 ]; do case "${1}" in - --zone=*) - zone=${1#--zone=} + -*) + error "Unrecognized option: ${1}" + exit ${EXIT_ERROR} ;; *) action=${1} - break - ;; + ;; esac shift + [ -n "${action}" ] && break done -if [ -z "${zone}" ] || [ -z "${action}" ]; then - log_failure_msg "Wrong number of arguments." - exit ${EXIT_ERROR} -fi +function run() { + case "${action}" in + create|rem|up|down) + _${action} $@ + ;; + esac -if ! zone_exists ${zone}; then - echo "Zone ${zone} does not exist." + error "Port hook '${HOOK}' didn't exit properly." exit ${EXIT_ERROR} -fi - -case "$action" in - start|up|reload) - message="Bringing up zone ${zone}..." - - hooks_run_all pre-up ${CONFIG_ZONES}/${zone} --zone=${zone} - - if ! zone_is_up ${zone}; then - # Create and bring up the zone - brctl addbr ${zone} || failed=1 - brctl stp ${zone} on || failed=1 - brctl setfd ${zone} 0 || failed=1 - ip link set ${zone} up || failed=1 - (exit ${failed}) - evaluate_retval standard - fi - - # First bring up the ports to be able to start something like - # a dhcp client that needs a running interface. - hooks_run_ports post-up ${CONFIG_ZONES}/${zone} --zone=${zone} - hooks_run_zones post-up ${CONFIG_ZONES}/${zone} --zone=${zone} - ;; - - stop|down) - message="Bringing down zone ${zone}..." - - if zone_is_up ${zone}; then - hooks_run_zones pre-down ${CONFIG_ZONES}/${zone} --zone=${zone} - hooks_run_ports pre-down ${CONFIG_ZONES}/${zone} --zone=${zone} - - # Bring down the zone and delete it - ip link set ${zone} down || failed=1 - brctl delbr ${zone} || failed=1 - (exit ${failed}) - evaluate_retval standard - - hooks_run_all post-down ${CONFIG_ZONES}/${zone} --zone=${zone} - else - log_warning_msg ${message} - log_warning_msg "Zone ${zone} does not exist." - fi - ;; - - *) - exit 1 - ;; -esac +} diff --git a/header-zone b/header-zone new file mode 100644 index 00000000..30cb5f27 --- /dev/null +++ b/header-zone @@ -0,0 +1,254 @@ +#!/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 . # +# # +############################################################################### +# +# Notes: +# - All functions in this scope must start with an underline (_) to not +# conflict with any functions that were defined somewhere else. +# + +. /lib/network/functions + +HOOK=$(basename ${0}) + +while [ $# -gt 0 ]; do + case "${1}" in + -*) + error "Unrecognized option: ${1}" + exit ${EXIT_ERROR} + ;; + *) + action=${1} + ;; + esac + shift + + # If action argument was given, we will exit. + [ -n "${action}" ] && break +done + +# _notimplemented +# Returns a soft error if a function was not implemented, yet. +# +function _notimplemented() { + warning "'$@' was not implemented." + exit ${EXIT_CONF_ERROR} +} + +function _info() { + echo "HOOK=\"${HOOK}\"" +} + +function _create() { + local zone=${1} + shift + + config_read ${ZONE_DIR}/${zone}/settings + + _parse_cmdline $@ + + config_write ${ZONE_DIR}/${zone}/settings ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _edit() { + _create $@ +} + +function _rem() { + _notimplemented _rem +} + +function _status() { + local zone=${1} + + if device_is_up ${zone}; then + exit ${STATUS_UP} + fi + + exit ${STATUS_DOWN} +} + +function _up() { + _notimplemented _up +} + +function _down() { + _notimplemented _down +} + +function _discover() { + # This hook does not support a discovery + exit ${DISCOVER_NOT_SUPPORTED} +} + +# Do nothing +function _parse_cmdline() { + return ${EXIT_OK} +} + +function _port() { + local zone=${1} + local action=${2} + shift 2 + + local ret + + case "${action}" in + create|edit|rem|show) + _port_${action} ${zone} $@ + ret=$? + ;; + *) + error "Unrecognized argument: '${action}'" + exit ${EXIT_ERROR} + ;; + esac + + exit ${ret} +} + +# This function is not a public one +function __portcmd() { + local cmd=${1} + local zone=${2} + local hook_port=${3} + shift 3 + + local hook_zone=$(zone_get_hook ${zone}) + + if ! hook_exists ${hook_zone}; then + error "Hook '${hook}' does not exist." + exit ${EXIT_ERROR} + fi + + if ! hook_port_exists ${hook_zone} ${hook_port}; then + error "Hook '${hook_port}' is not supported for zone '${zone}'." + exit ${EXIT_ERROR} + fi + + hook_port_exec ${hook_zone} ${hook_port} ${cmd} ${zone} $@ +} + +function _port_create() { + __portcmd create $@ +} + +function _port_edit() { + __portcmd edit $@ +} + +function _port_rem() { + _notimplemented _port_rem +} + +function _port_show() { + _notimplemented _port_show +} + +function _config() { + local zone=${1} + local action=${2} + shift 2 + + local ret + + case "${action}" in + create|edit|rem|show) + _config_${action} ${zone} $@ + ret=$? + ;; + *) + error "Unrecognized argument: '${action}'" + exit ${EXIT_ERROR} + ;; + esac + + exit ${ret} +} + +# This function is not a public one +function __configcmd() { + local cmd=${1} + local zone=${2} + local hook_config=${3} + shift 3 + + local hook_zone=$(zone_get_hook ${zone}) + + if ! hook_exists ${hook_zone}; then + error "Hook '${hook}' does not exist." + exit ${EXIT_ERROR} + fi + + if ! hook_config_exists ${hook_zone} ${hook_config}; then + error "Hook '${hook_config}' is not supported for zone '${zone}'." + exit ${EXIT_ERROR} + fi + + hook_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} $@ +} + +function _config_create() { + __configcmd create $@ +} + +function _config_edit() { + __configcmd edit $@ +} + +function _config_rem() { + _notimplemented _config_rem +} + +function _config_show() { + _notimplemented _config_show +} + +function run() { + case "${action}" in + create|discover|down|edit|info|rem|status|up) + _${action} $@ + ;; + + port) + if ! hook_has_ports ${HOOK}; then + error "Hook '${HOOK}' does not support ports." + exit ${EXIT_ERROR} + fi + + _port $@ + ;; + + config) + if ! hook_has_configs ${HOOK}; then + error "Hook '${HOOK}' does not support configurations." + exit ${EXIT_ERROR} + fi + + _config $@ + ;; + + esac + + error "Hook did not exit properly." + exit ${EXIT_ERROR} +} diff --git a/hook-header b/hook-header deleted file mode 100644 index b2693b89..00000000 --- a/hook-header +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -. /etc/init/functions -. /lib/network/functions - -INDENT=" " - -HOOK_PRIO=100 - -# Parse the command line -action= -port= -zone= - -while [ $# -gt 0 ]; do - case "${1}" in - --zone=*) - zone=${1#--zone=} - ;; - --config=*) - . ${1#--config=} - ;; - --port=*) - port=${1#--port=} - ;; - -*) - log_failure_msg "Unrecognized option: ${1}" - exit ${EXIT_ERROR} - ;; - *) - action=${1} - shift - break - ;; - esac - shift -done - diff --git a/hooks/README b/hooks/README deleted file mode 100644 index 09ca2307..00000000 --- a/hooks/README +++ /dev/null @@ -1,86 +0,0 @@ -HOOKS README - -A hook is file that can configure a specific network connection (e.g. ethernet) -or protocol (e.g. ipv4-static). - -They are expandable and standalone. Means, when you call a file, you will -run it and pass some options and an action to it. - - /lib/network/hooks/HOOOK [options] [options to action] - -There are two types of hooks: - zone - These hooks applies to a zone and does configuration on it. - Mainly, it configures the IP protocol or something else. - - port - These hooks add ports to zones. - -DEFINES: - So, to know what type of hook this is, we have to define some variables - in the header of the file. - - HOOK_NAME - The name of the hook. This is normally the file name. - - HOOK_TYPE - zone or port. See section above. - - -INLCUDES: - These files get included in the header. - - /lib/lsb/init-functions - For pretty messages - - /lib/network/functions - Our networking funktions. - - -OPTIONS: - Options have at least to be for zone file: - - --config=CONFIG - Includes the given config file CONFIG. - If there is an error when loading the config file or the parameters are - wrong or invalid, the script will pass an error with code ${EXIT_CONF_ERROR}! - - --port=PORT - Takes a port (either as device (eth0) or as mac (00:11:22:33:44:55)). - - --zone=ZONE - Takes the name of a zone. - - -ACTION: - Actions that always have to be defined: - help - Gives the user a short help how to use the command and its arguments. - - info - Gives some information about the hook (mainly for internal use of the scripts). - See below. - - status - Gives information if the hook is active or not. - - config - This is the command that creates the configuration for each hook. - It will accept some more arguments in the command line - and return either ${EXIT_OK} or ${EXIT_ERROR}. - - Actions that have to be defined for a zone hook: - pre-up - This gets runned before the zone gets up. - - pre-down. - This is runned before the zone is set down. - - post-up - After setting up the zone, this command will be executed. - - post-down - After the zone has vanished, this part of the script is called. - - All these actions will return ${EXIT_OK} when everything went fine. - If not, they will return ${EXIT_ERROR}. diff --git a/hooks/bonding b/hooks/bonding deleted file mode 100755 index 03f0a70b..00000000 --- a/hooks/bonding +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/bonding -# -# Description : Bonding Script -# -# Authors : Michael Tremer - michael.tremer@ipfire.org -# -# Version : 00.00 -# -# Notes : This script adds bonding support. -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=bonding -HOOK_TYPE=port -HOOK_PRIO=50 - -DEFAULT_MODE= - -function port_name() { - echo "${zone}t+" -} - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=${HOOK_NAME}" - echo "HOOK_TYPE=${HOOK_TYPE}" - ;; - - pre-up) - if ! grep -q ^bonding /proc/modules; then - modprobe bonding - echo "-bond0" > /sys/class/net/bonding_masters - fi - - if device_exists ${MAC}; then - device=$(devicify ${MAC}) - if ! device_is_bonding ${device}; then - log_failure_msg "Device \"${device}\" is up, but not a bonding device." - exit ${EXIT_ERR} - fi - exit ${EXIT_OK} - fi - - device=$(device_get_free $(port_name)) - echo "+${device}" > /sys/class/net/bonding_masters - ip link set ${device} address ${MAC} - - [ -n "${MODE}" ] && \ - echo "${MODE}" > /sys/class/net/${device}/bonding/mode - - echo "${MIIMON-100}" > /sys/class/net/${device}/bonding/miimon - - for slave in ${SLAVES}; do - if device_exists ${slave}; then - if device_is_up ${slave}; then - log_warning_msg "Cannot enslave device \"${slave}\"." - continue - fi - device_rename "$(devicify ${slave})" "${device}s+" - echo "+$(devicify ${slave})" > /sys/class/net/${device}/bonding/slaves - else - log_warning_msg "Device ${slave} does not exist." - fi - done - - ip link set ${device} up - - log_success_msg "Setting up trunk ${MAC}..." - ;; - - post-up) - device=$(devicify ${MAC}) - if ! zone_has_device_attached ${zone} ${device}; then - zone_add_port ${zone} ${device} - fi - ;; - - pre-down) - device=$(devicify ${MAC}) - if zone_has_device_attached ${zone} ${device}; then - zone_del_port ${zone} ${device} - fi - ;; - - post-down) - device=$(devicify ${MAC}) - if port_is_up ${device}; then - MESSAGE="Pulling down trunk ${MAC}..." - ip link set ${device} down - evaluate_retval - echo "-${device}" > /sys/class/net/bonding_masters - fi - ;; - - add) - MAC=$(mac_generate) - MODE=${DEFAULT_MODE} - - while [ $# -gt 0 ]; do - case "${1}" in - --mac=*) - MAC=${1#--mac=} - ;; - --mode=*) - MODE=${1#--mode=} - ;; - *) - SLAVES="${SLAVES} $(macify ${1})" - ;; - esac - shift - done - - UUID=$(uuid) - cat < ${CONFIG_UUIDS}/${UUID} -HOOK="${HOOK_NAME}" -MAC="${MAC}" -MODE="${MODE}" -SLAVES="$(echo ${SLAVES})" -EOF - ln -sf ${CONFIG_UUIDS}/${UUID} \ - ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} - - log_success_msg "Configuration successfully saved!" - echo " MAC address : ${MAC}" - echo " Mode : ${MODE}" - echo " Slaves : $(echo ${SLAVES})" - ;; - - rem) - ;; - - status) - DEVICE=$(devicify ${MAC}) - echo -e "# ${CLR_BOLD_CYN}Trunk ${DEVICE} (${MAC})${NORMAL}" - if device_is_up ${MAC}; then - echo -e "# State: ${CLR_BOLD_GRN}up${NORMAL}" - echo "#" - for slave in $(. # +# # +############################################################################### + +. /lib/network/header-zone + +HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE MAC MTU" + +# Default values +MAC=$(mac_generate) +MTU=1500 +STP="on" +STP_FORWARD_DELAY=0 +STP_HELLO=2 +STP_MAXAGE=20 + +function _check() { + assert ismac MAC + assert isbool STP + assert isinteger STP_HELLO + assert isinteger STP_FORWARD_DELAY + assert isinteger MTU +} + +function _parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in + --stp=*) + STP=${1#--stp=} + ;; + --stp-hello=*) + STP_HELLO=${1#--stp-hello=} + ;; + --stp-forward-delay=*) + STP_FORWARD_DELAY=${1#--stp-forward-delay=} + ;; + --mtu=*) + MTU=${1#--mtu=} + ;; + --mac=*) + MAC=${1#--mac=} + ;; + *) + warning "Ignoring unknown option '${1}'" + ;; + esac + shift + done +} + +function _up() { + local zone=${1} + shift + + config_read ${ZONE_DIR}/${zone}/settings + + if ! device_exists ${zone}; then + brctl addbr ${zone} + fi + + [ -n "${MAC}" ] && device_set_mac ${zone} ${MAC} + [ -n "${MTU}" ] && device_set_mtu ${zone} ${MTU} + + # Enable STP + if enabled STP; then + brctl stp ${zone} on + + if [ -n "${STP_FORWARD_DELAY}" ]; then + brctl setfd ${zone} ${STP_FORWARD_DELAY} + fi + + if [ -n "${STP_HELLO}" ]; then + brctl sethello ${zone} ${STP_HELLO} + fi + + if [ -n "${STP_MAXAGE}" ]; then + brctl setmaxage ${zone} ${STP_MAXAGE} + fi + else + brctl stp ${zone} off + fi + + device_set_up ${zone} + + # Bring all ports up + zone_ports_up ${zone} + + # XXX Do we need this? + # Wait until bridge is forwarding + # which is needed by dhcp client + #if enabled STP; then + # bridge_is_forwarding ${zone} + #fi + + zone_configs_up ${zone} + + event_interface_up ${zone} + + exit $? +} + +function _down() { + local zone=${1} + shift + + if ! device_is_up ${zone}; then + warning "Zone '${zone}' is not up" + exit ${EXIT_OK} + fi + + event_interface_down ${zone} + + zone_configs_down ${zone} + zone_ports_down ${zone} + + device_set_down ${zone} + brctl delbr ${zone} + + exit $? +} + +function _addport() { + local zone=${1} + local hook=${2} + shift 2 + + if ! hook_exists port ${hook}; then + error "Hook does not exist '${hook}'" + exit ${EXIT_ERROR} + fi + + port_hook ${hook} add ${zone} +} + +run $@ diff --git a/hooks/bridge.configs/ipv4-static b/hooks/bridge.configs/ipv4-static new file mode 100755 index 00000000..733a43f1 --- /dev/null +++ b/hooks/bridge.configs/ipv4-static @@ -0,0 +1,135 @@ +#!/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 . # +# # +############################################################################### + +. /lib/network/header-port + +HOOK_SETTINGS="HOOK ADDRESS PREFIX GATEWAY" + +function _check() { + assert isset ADDRESS + assert isinteger PREFIX + + if [ ${PREFIX} -gt 30 ]; then + error "PREFIX is greater than 30." + exit ${EXIT_ERROR} + fi +} + +function _create() { + local zone=${1} + shift + + while [ $# -gt 0 ]; do + case "${1}" in + --address=*) + ADDRESS=${1#--address=} + ;; + --netmask=*) + NETMASK=${1#--netmask=} + ;; + --prefix=*) + PREFIX=${1#--prefix=} + ;; + --gateway=*) + GATEWAY=${1#--gateway=} + ;; + esac + shift + done + + if [ -z "${PREFIX}" -a -n "${NETMASK}" ]; then + PREFIX=$(ipv4_mask_to_cidr ${NETMASK}) + fi + + config_write $(zone_dir ${zone})/config.${HOOK}.$(uuid) ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _up() { + local zone=${1} + local config=${2} + shift 2 + + if ! device_exists ${zone}; then + error "Zone '${zone}' doesn't exist." + exit ${EXIT_ERROR} + fi + + config_read $(zone_dir ${zone})/${config} + + if ! zone_has_ipv4 ${zone} ${ADDRESS}/${PREFIX}; then + ip addr add ${ADDRESS}/${PREFIX} dev ${zone} + else + warning "Do not set IPv4 address '${ADDRESS}/${PREFIX}' because it was already configured on zone '${zone}'." + fi + + warning "XXX Gateway stuff has to be done." + if [ -n "${GATEWAY}" ]; then + : # What do we do with the gateway? + fi + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + local config=${2} + shift 2 + + if ! device_exists ${zone}; then + error "Zone '${zone}' doesn't exist." + exit ${EXIT_ERROR} + fi + + config_read $(zone_dir ${zone})/${config} + + if zone_has_ipv4 ${zone} ${ADDRESS}/${PREFIX}; then + ip addr del ${ADDRESS}/${PREFIX} dev ${zone} + fi + + exit ${EXIT_OK} +} + +function ipv4_mask_to_cidr() { + local mask=0 + + local field + for field in $(tr '.' ' ' <<<${1}); do + mask=$(( $(( ${mask} << 8 )) | ${field} )) + done + + local cidr=0 + local x=$(( 128 << 24 )) # 0x80000000 + + while [ $(( ${x} & ${mask} )) -ne 0 ]; do + [ ${mask} -eq ${x} ] && mask=0 || mask=$(( ${mask} << 1 )) + cidr=$((${cidr} + 1)) + done + + if [ $(( ${mask} & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff + echo "Invalid net mask: $1" >&2 + else + echo ${cidr} + fi +} + +run $@ diff --git a/hooks/bridge.ports/ethernet b/hooks/bridge.ports/ethernet new file mode 100755 index 00000000..6428ef31 --- /dev/null +++ b/hooks/bridge.ports/ethernet @@ -0,0 +1,95 @@ +#!/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 . # +# # +############################################################################### + +. /lib/network/header-port + +HOOK_SETTINGS="HOOK DEVICE" + +function _check() { + assert isset DEVICE + assert ismac DEVICE +} + +function _create() { + local zone=${1} + local device=${2} + shift 2 + + if [ -z "${device}" ]; then + error "No device given." + exit ${EXIT_ERROR} + fi + + if ! device_exists ${device}; then + warning "Device does not exist." + fi + + DEVICE=$(macify ${device}) + + config_write $(zone_dir ${zone})/port.${HOOK}.$(device_hash ${device}) ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _up() { + local zone=${1} + local port=${2} + + config_read $(zone_dir ${zone})/${port} + + local device=$(devicify ${DEVICE}) + + if ! device_exists ${device}; then + warning "Device '${DEVICE}' does not exist." + exit ${EXIT_ERROR} + fi + + # Set same MTU to device that the bridge has got + device_set_mtu ${device} $(device_get_mtu ${zone}) + + device_set_up ${device} + + bridge_attach_device ${zone} ${device} + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + local port=${2} + + config_read $(zone_dir ${zone})/${port} + + local device=$(devicify ${DEVICE}) + + if ! device_exists ${device}; then + warning "Device '${DEVICE}' does not exist." + exit ${EXIT_ERROR} + fi + + bridge_detach_device ${zone} ${device} + + device_set_down ${device} + + exit ${EXIT_OK} +} + +run $@ diff --git a/hooks/bridge.ports/virtual b/hooks/bridge.ports/virtual new file mode 100755 index 00000000..46b1088d --- /dev/null +++ b/hooks/bridge.ports/virtual @@ -0,0 +1,127 @@ +#!/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 . # +# # +############################################################################### + +. /lib/network/header-port + +HOOK_SETTINGS="HOOK DEVICE DEVICE_MAC DEVICE_VID" + +DEVICE_MAC=$(mac_generate) + +function _check() { + assert ismac DEVICE + assert ismac DEVICE_MAC + + assert isinteger DEVICE_VID + + if [ ${DEVICE_VID} -gt 4096 ]; then + error "DEVICE_VID is greater than 4096." + exit ${EXIT_ERROR} + fi + + local reserved + for reserved in 0 4095; do + if [ "${DEVICE_VID}" = "${reserved}" ]; then + error "DEVICE_VID=${reserved} is reserved." + exit ${EXIT_ERROR} + fi + done +} + +function _add() { + local zone=${1} + local device=${2} + shift 2 + + while [ $# -gt 0 ]; do + case "${1}" in + --mac=*) + DEVICE_MAC=${1#--mac=} + ;; + --id=*) + DEVICE_VID=${1#--id=} + ;; + *) + warning "Unknown argument '${1}'" + ;; + esac + shift + done + + DEVICE=$(macify ${device}) + + _check + + config_write $(zone_dir ${zone})/port.${HOOK}.$(device_hash ${device}).${DEVICE_VID} ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _edit() { + local zone=${1} + + error "TODO - edit mac addres" + + exit ${EXIT_ERROR} +} + +function _up() { + local zone=${1} + local port=${2} + + config_read $(zone_dir ${zone})/${port} + + if ! device_exists $(devicify ${DEVICE_MAC}); then + device_virtual_create ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC} + fi + + local device=$(devicify ${DEVICE_MAC}) + + # Set same MTU to device that the bridge has got + device_set_mtu ${device} $(device_get_mtu ${zone}) + + device_set_up ${device} + + bridge_attach_device ${zone} ${device} + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + local port=${2} + + config_read $(zone_dir ${zone})/${port} + + local device=$(devicify ${DEVICE_MAC}) + + if ! device_exists ${device}; then + error "Device '${DEVICE_MAC}' does not exist." + exit ${EXIT_ERROR} + fi + + bridge_detach_device ${zone} ${device} + + device_virtual_remove ${device} + + exit ${EXIT_OK} +} + +run $@ diff --git a/hooks/ethernet b/hooks/ethernet deleted file mode 100755 index e6e364ff..00000000 --- a/hooks/ethernet +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/ethernet -# -# Description : Ethernet Script -# -# Authors : Michael Tremer - michael.tremer@ipfire.org -# -# Version : 00.00 -# -# Notes : This script adds ethernet support. -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=ethernet -HOOK_TYPE=port - -function port_name() { - echo ${zone}p+ -} - -case "${action}" in - help) - echo -e "${BOLD}Hook (${HOOK_NAME}) help:" - echo - echo -e " ${BOLD}Summary:${NORMAL}" - echo " The ethernet-hook controls connection via ethernet." - echo " You will need this to access your local lan." - echo - echo -e " ${BOLD}Usage:${NORMAL}" - #echo " --config=" - #echo " Includes a config file." - #echo " Example: --config=/etc/sysconfig/network/green0/port-00:11:22:33:44:55" - #echo " --port=" - #echo " Passes the port to the script." - #echo " Example: --port=port0 or --port=00:11:22:33:44:55" - #echo " --zone=" - #echo " Passes the zone to the script." - #echo " Example: --zone=green0" - #echo - #echo -e " ${BOLD}Commands:${NORMAL}" - #echo - echo " This hook only needs the name of the network device" - echo " that should be attached to the zone." - echo " The device identifier can either be a mac address or" - echo " a device name." - echo - echo " Example: network zone addport green0 ethernet port0" - echo " network zone addport green0 ethernet 00:11:22:33:44:55" - echo - ;; - - info) - echo "HOOK_NAME=${HOOK_NAME}" - echo "HOOK_TYPE=${HOOK_TYPE}" - ;; - - pre-up) - device_is_up ${MAC} || ip link set $(devicify ${MAC}) up - ;; - - post-up) - if zone_has_device_attached ${zone} $(get_device ${MAC}); then - # Device is already attached to the bridge - exit ${EXIT_OK} - fi - message="Attaching ethernet port ${MAC}..." - device_rename $(get_device ${MAC}) $(port_name) - zone_add_port ${zone} $(get_device_by_mac ${MAC}) - evaluate_retval - ;; - - pre-down) - if zone_has_device_attached ${zone} $(get_device ${MAC}); then - message="Detatching ethernet port ${MAC}..." - zone_del_port ${zone} $(get_device_by_mac ${MAC}) - device_rename $(get_device_by_mac ${MAC}) ${COMMON_DEVICE} - evaluate_retval - fi - ;; - - post-down) - ## Possibly pull down the device (if there are no more vlan devices up...) - ;; - - add) - ### XXX error handling - - for dev in $@; do - MAC=$(macify ${dev}) - UUID=$(uuid) - cat < ${CONFIG_UUIDS}/${UUID} -HOOK="${HOOK_NAME}" -MAC="${MAC}" -EOF - ln -sf ${CONFIG_UUIDS}/${UUID} \ - ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} - - log_success_msg "Configuration successfully saved!" - echo " Device : $(devicify ${MAC})" - echo " MAC address : ${MAC}" - done - ;; - - rem) - # XXX to be done - ;; - - status) - echo -e "# ${CLR_BOLD_CYN}Ethernet port $(devicify ${MAC}) (${MAC})${NORMAL}" - echo -n "# State: " - if device_is_up ${MAC}; then - echo -e "${CLR_BOLD_GRN}up${NORMAL}" - else - echo -e "${CLR_BOLD_RED}down${NORMAL}" - fi - echo -n "# Link : " - if device_has_carrier ${MAC}; then - echo -e "${CLR_BOLD_GRN}yes${NORMAL}" - else - echo -e "${CLR_BOLD_RED}no${NORMAL}" - fi - echo "#" - - device_is_up ${MAC} - exit ${?} - ;; - - *) - echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}" - exit 1 - ;; -esac - -# End $NETWORK_DEVICES/services/ethernet diff --git a/hooks/ipv4-dhcp b/hooks/ipv4-dhcp deleted file mode 100755 index 43c44199..00000000 --- a/hooks/ipv4-dhcp +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -. /lib/network/hook-header - -HOOK_NAME="ipv4-dhcp" -HOOK_TYPE="zone" - -MESSAGE="DHCP Daemon..." -EXECUTEABLE="/sbin/dhclient" - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=$HOOK_NAME" - echo "HOOK_TYPE=$HOOK_TYPE" - ;; - - status) - check_config zone - pidfile="/var/run/dhclient_${zone}.pid" - pidofproc -p ${pidfile} ${EXECUTEABLE} &>/dev/null - exit $? - ;; - - pre-up) - ;; - - post-up) - check_config zone - pidfile="/var/run/dhclient_${zone}.pid" - if [ -e "${pidfile}" ]; then - kill $(<${pidfile}) &>/dev/null - sleep 1 - fi - ${EXECUTEABLE} -pf ${pidfile} ${zone} - evaluate_retval start - ;; - - pre-down) - check_config zone - pidfile="/var/run/dhclient_${zone}.pid" - killproc -p ${pidfile} ${EXECUTEABLE} - evaluate_retval stop - ;; - - post-down) - ;; - - add) - while [ $# -gt 0 ]; do - case "$1" in - --hostname=*) - HOSTNAME=${1#--hostname=} - ;; - *) - echo "Unknown option: $1" >&2 - exit 1 - ;; - esac - shift - done - cat <${CONFIG_ZONES}/${zone}/ipv4-dhcp -HOOK="${HOOK_NAME}" -HOSTNAME="${HOSTNAME}" -EOF - [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} - ;; - - rem) - ;; - - discover) - exit ${EXIT_ERROR} - ;; - - *) - echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" - exit ${EXIT_ERROR} - ;; -esac - -# End $NETWORK_DEVICES/services/ipv4-dhcp diff --git a/hooks/ipv4-static b/hooks/ipv4-static deleted file mode 100755 index 34af5572..00000000 --- a/hooks/ipv4-static +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/ipv4-static -# -# Description : IPV4 Static Boot Script -# -# Authors : Nathan Coulson - nathan@linuxfromscratch.org -# Kevin P. Fleming - kpfleming@linuxfromscratch.org -# -# Version : 00.00 -# -# Notes : -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME="ipv4-static" -HOOK_TYPE="zone" - -function check_config() { - args= - if [ -z "${IP}" ]; then - log_failure_msg "IP variable missing, cannot continue." - exit ${EXIT_CONF_ERROR} - fi - - if [ -z "${PREFIX}" -a -z "${PEER}" ]; then - log_warning_msg "PREFIX variable missing, assuming 24." - PREFIX=24 - args="${args} ${IP}/${PREFIX}" - elif [ -n "${PREFIX}" -a -n "${PEER}" ]; then - log_failure_msg "PREFIX and PEER both specified, cannot continue." - exit ${EXIT_CONF_ERROR} - elif [ -n "${PREFIX}" ]; then - args="${args} ${IP}/${PREFIX}" - elif [ -n "${PEER}" ]; then - args="${args} ${IP} peer ${PEER}" - fi - - if [ -n "${BROADCAST}" ]; then - args="${args} broadcast ${BROADCAST}" - fi - - if [ -n "${SOURCE}" ]; then - args="${args} src ${SOURCE}" - fi -} - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=$HOOK_NAME" - echo "HOOK_TYPE=$HOOK_TYPE" - ;; - - status) - check_config - echo -e "# ${CLR_BOLD_CYN}IPv4 static: ${IP}/${PREFIX}${NORMAL}" - if [ -n "${GATEWAY}" ]; then - echo "# Gateway: ${GATEWAY}" - echo -n "# Reachable: " - if ping -c1 -w1 -I ${zone} ${GATEWAY} &>/dev/null; then - echo -e "${CLR_BOLD_GRN}yes${NORMAL}" - else - echo -e "${CLR_BOLD_RED}no${NORMAL}" - fi - fi - ip addr show ${zone} | grep "inet " | fgrep -q "${IP}/${PREFIX}" - exit ${?} - ;; - - pre-up) - ;; - - post-up) - check_config - if ! device_has_ipv4 ${zone} ${IP}; then - MESSAGE="Adding IPv4 address ${IP} to zone ${zone} interface..." - ip addr add ${args} dev ${zone} - evaluate_retval - fi - - if [ -n "${GATEWAY}" ]; then - if ip route | grep -q default; then - log_warning_msg "Gateway already setup; skipping." ${WARNING} - else - MESSAGE="Setting up default gateway..." - ip route add default via ${GATEWAY} dev ${zone} - evaluate_retval - fi - fi - ;; - - pre-down) - check_config - if [ -n "${GATEWAY}" ]; then - MESSAGE="Removing default gateway..." - ip route del default - evaluate_retval - fi - - if device_has_ipv4 ${zone} ${IP}; then - MESSAGE="Removing IPv4 address ${IP} from zone ${zone}..." - ip addr del ${args} dev ${zone} - evaluate_retval - fi - ;; - - post-down) - ;; - - add) - while [ $# -gt 0 ]; do - case "$1" in - --ip=*) - IP=${1#--ip=} - ;; - --prefix=*) - PREFIX=${1#--prefix=} - ;; - --peer=*) - PEER=${1#--peer=} - ;; - --broadcast=*) - BROADCAST=${1#--broadcast=} - ;; - --source=*) - SOURCE=${1#--source=} - ;; - --gateway=*) - GATEWAY=${1#--gateway=} - ;; - *) - echo "Unknown option: $1" >&2 - exit 1 - ;; - esac - shift - done - #check_config - cat <${CONFIG_ZONES}/${zone}/ipv4-static_$IP -HOOK="${HOOK_NAME}" -IP="${IP}" -PREFIX="${PREFIX}" -PEER="${PEER}" -BROADCAST="${BROADCAST}" -SOURCE="${SOURCE}" -GATEWAY="${GATEWAY}" -EOF - [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} - ;; - - rem) - ;; - - discover) - exit ${EXIT_ERROR} - ;; - - *) - echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" - exit ${EXIT_ERROR} - ;; -esac - -# End $NETWORK_DEVICES/services/ipv4-static diff --git a/hooks/ipv4-static-route b/hooks/ipv4-static-route deleted file mode 100755 index 9e389864..00000000 --- a/hooks/ipv4-static-route +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/ipv4-static-route -# -# Description : IPV4 Static Route Script -# -# Authors : Kevin P. Fleming - kpfleming@linuxfromscratch.org -# -# Version : 00.00 -# -# Notes : -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=ipv4-static-route -HOOK_TYPE=zone - -function check_config() { - args= - case "${TYPE}" in - ""|network) - need_ip=1 - need_gateway=1 - ;; - - default) - need_gateway=1 - args="${args} default" - desc="default" - ;; - - host) - need_ip=1 - ;; - - unreachable) - need_ip=1 - args="${args} unreachable" - desc="unreachable" - ;; - - *) - log_failure_msg "Unknown route type (${TYPE}) in ${CONFIG}, cannot continue." - exit ${EXIT_CONF_ERROR} - ;; - esac - - if [ -n "${need_ip}" ]; then - if [ -z "${IP}" ]; then - log_failure_msg "IP variable missing from ${CONFIG}, cannot continue." - exit ${EXIT_CONF_ERROR} - fi - - if [ -z "${PREFIX}" ]; then - log_failure_msg "PREFIX variable missing from ${CONFIG}, cannot continue." - exit ${EXIT_CONF_ERROR} - fi - - args="${args} ${IP}/${PREFIX}" - desc="${desc}${IP}/${PREFIX}" - fi - - if [ -n "${need_gateway}" ]; then - if [ -z "${GATEWAY}" ]; then - log_failure_msg "GATEWAY variable missing from ${CONFIG}, cannot continue." - exit ${EXIT_CONF_ERROR} - fi - args="${args} via ${GATEWAY}" - fi -} - -case "${action}" in - add) - while [ $# -gt 0 ]; do - case "${1}" in - --ip=*) - IP=${1#--ip=} - ;; - --gateway=*) - GATEWAY=${1#--gateway=} - ;; - --prefix=*) - PREFIX=${1#--prefix=} - ;; - --type=*) - TYPE=${1#--type=} - ;; - esac - shift - done - check_config - cat <${CONFIG_ZONES}/${zone}/${HOOK_NAME}_${IP-${GATEWAY}} -HOOK="${HOOK_NAME}" -IP="${IP}" -GATEWAY="${GATEWAY}" -PREFIX="${PREFIX}" -TYPE="${TYPE}" -EOF - [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} - ;; - - help) - ;; - - info) - echo "HOOK_NAME=${HOOK_NAME}" - echo "HOOK_TYPE=${HOOK_TYPE}" - ;; - - pre-up) - ;; - - post-up) - boot_mesg "Adding '${desc}' route to zone ${zone}..." - ip route add ${args} dev ${zone} - evaluate_retval - ;; - - pre-down) - boot_mesg "Removing '${desc}' route from zone ${zone}..." - ip route del ${args} dev ${zone} - evaluate_retval - ;; - - post-down) - ;; - - discover) - - exit ${EXIT_ERROR} - ;; - - *) - echo "Usage: ${0} [interface] {up|down}" - exit 1 - ;; -esac - -# End $NETWORK_DEVICES/services/ipv4-static-route diff --git a/hooks/mtu b/hooks/mtu deleted file mode 100755 index 707345a6..00000000 --- a/hooks/mtu +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/mtu -# -# Description : Sets MTU per interface -# -# Authors : Nathan Coulson - nathan@linuxfromscratch.org -# Jim Gifford - jim@linuxfromscratch.org -# -# Version : 00.00 -# -# Notes : This sets the maximum amount of bytes that can be -# transmitted within a packet. By default, this -# value is set to 1500. -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=mtu -HOOK_TYPE=zone - -DEFAULT_MTU=1500 - -function usage() { - echo "Usage: ${0} {pre-up|post-up|pre-down|post-down|config} [interface]" -} - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=$HOOK_NAME" - echo "HOOK_TYPE=$HOOK_TYPE" - ;; - - status) - check_config zone MTU - mtu=$(cat /sys/class/net/${zone}/mtu 2>/dev/null) - [ "$MTU" = "$mtu" ] - exit $? - ;; - - pre-up) - ;; - - post-up) - check_config zone MTU - message="Setting the MTU for ${zone} to ${MTU}..." - echo "${MTU}" > "/sys/class/net/${zone}/mtu" - evaluate_retval standard - ;; - - pre-down) - check_config zone MTU - message="Resetting MTU for ${zone} to 1500..." - echo ${DEFAULT_MTU} > "/sys/class/net/${zone}/mtu" - evaluate_retval standard - ;; - - post-down) - ;; - - config) - MTU=$1 - check_config zone MTU - cat << EOF >> ${CONFIG_ZONES}/${zone}/${HOOK_NAME} -HOOK="${HOOK_NAME}" -MTU="${MTU}" -EOF - exit $? - ;; - - discover) - exit ${EXIT_ERROR} - ;; - - *) - usage - exit 1 - ;; -esac - -# End $NETWORK_DEVICES/services/mtu diff --git a/hooks/pppoe b/hooks/pppoe index d27a5177..60460c92 100755 --- a/hooks/pppoe +++ b/hooks/pppoe @@ -1,72 +1,159 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/ipv4-static -# -# Description : IPV4 Static Boot Script -# -# Authors : Nathan Coulson - nathan@linuxfromscratch.org -# Kevin P. Fleming - kpfleming@linuxfromscratch.org -# -# Version : 00.00 -# -# Notes : -# -######################################################################## - -. /lib/network/hook-header -. /lib/network/functions.ppp - -HOOK_NAME="pppoe" -HOOK_TYPE="zone" - -PPPOE_PLUGIN=rp-pppoe.so - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=$HOOK_NAME" - echo "HOOK_TYPE=$HOOK_TYPE" - ;; - - status) - echo -e "# ${CLR_BOLD_CYN}PPPoE: ${NAME}${NORMAL}" - echo -n "# pppd's PID: " - pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null) - if [ -n "${pid}" ] && [ -d "/proc/${pid}" ]; then - echo -e "${CLR_BOLD_GRN}${pid}${NORMAL}" - exit ${EXIT_OK} - else - echo -e "${CLR_BOLD_RED}${pid-off}${NORMAL}" - exit ${EXIT_OK} - fi - ;; - - pre-up) - ppp_pre_up - - check_config NAME - # Creating necessary files - [ -d "${RED_RUN}/${NAME}" ] || mkdir -p ${RED_RUN}/${NAME} - - ppp_secret "${USER}" "${SECRET}" - - cat <${RED_RUN}/${NAME}/options +#!/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 . # +# # +############################################################################### + +. /lib/network/header-zone + +# TODO AC name, service name, sync? + +HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MTU" +HOOK_SETTINGS="${HOOK_SETTINGS} DEVICE DEVICE_VID DEVICE_TYPE" + +AUTH= +DEFAULTROUTE=1 +LINKNAME="$(uuid)" +MTU=1492 +PEERDNS=1 +SECRET= +USER= + +PPPOE_ALLOWED_AUTHS="chap pap" +PPPOE_PLUGIN="rp-pppoe.so" + +function _pppoe_real_device() { + local device + if [ -n "${DEVICE_VID}" ]; then + device="${DEVICE_MAC}" + else + device="${DEVICE}" + fi + + devicify ${device} +} + +function _check() { + assert isset USER + assert isset SECRET + assert isset LINKNAME + assert isset DEFAULTROUTE + assert isset PEERDNS + assert isset DEVICE + assert isset DEVICE_TYPE + + assert isbool DEFAULTROUTE + assert isbool PEERDNS + assert ismac DEVICE + assert isoneof DEVICE_TYPE real virtual + + isset AUTH && assert isoneof AUTH ${PPPOE_ALLOWED_AUTHS} + isset DEVICE_ID && assert isinteger DEVICE_VID +} + +function _parse_cmdline() { + while [ $# -gt 0 ]; do + case "$1" in + --user=*) + USER=${1#--user=} + ;; + --secret=*) + SECRET=${1#--secret=} + ;; + --linkname=*) + LINKNAME=${1#--name=} + ;; + --mtu=*) + MTU=${1#--mtu=} + ;; + --no-defaultroute) + DEFAULTROUTE=0 + ;; + --no-dns) + PEERDNS=0 + ;; + --auth=*) + AUTH=${1#--auth=} + ;; + --device=*) + DEVICE=${1#--device=} + ;; + --device-vid=*) + DEVICE_VID=${1#--device-vid=} + ;; + *) + echo "Unknown option: $1" >&2 + exit ${EXIT_ERROR} + ;; + esac + shift + done + + if ! device_exists $(devicify ${DEVICE}); then + error "Device '${DEVICE}' does not exist." + exit ${EXIT_ERROR} + fi + + DEVICE=$(macify ${DEVICE}) + + if isset DEVICE_VID; then + DEVICE_TYPE="virtual" + else + DEVICE_TYPE="real" + fi +} + +function _up() { + local zone=${1} + shift + + config_read ${ZONE_DIR}/${zone}/settings + + ppp_pre_up + + # Creating necessary files + [ -d "${RED_RUN}/${LINKNAME}" ] || mkdir -p ${RED_RUN}/${LINKNAME} + + # Setting up the device + if [ -n "${DEVICE_VID}" ]; then + device_create_virtual ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC} + else + device_set_up ${DEVICE} + fi + + ppp_secret "${USER}" "${SECRET}" + + cat <${RED_RUN}/${LINKNAME}/options # Naming options -name ${NAME} -linkname ${NAME} +ifname ${zone} +name ${LINKNAME} +linkname ${LINKNAME} -plugin ${PPPOE_PLUGIN} ${zone} +plugin ${PPPOE_PLUGIN} $(_pppoe_real_device) # User configuration user ${USER} -$([ "${PEERDNS}" = "1" ] && echo "usepeerdns") -$([ "${DEFAULTROUTE}" = "1" ] && echo "defaultroute") +$(enabled PEERDNS && echo "usepeerdns") +$(enabled DEFAULTROUTE && echo "defaultroute") noauth -$([ -n "${AUTH}" ] && echo "require-${AUTH}") +$(isset AUTH && echo "require-${AUTH}") noipdefault @@ -75,117 +162,68 @@ mtu ${MTU} mru ${MTU} # Disable the compression -noaccomp nodeflate nopcomp novj novjccomp nobsdcomp +noccp noaccomp nodeflate nopcomp novj novjccomp nobsdcomp nomppe debug EOF - ;; - - post-up) - check_config zone NAME - MESSAGE="Starting PPP Daemon on interface ${zone}..." - if zone_is_forwarding ${zone}; then - pppd file ${RED_RUN}/${NAME}/options >/dev/null - evaluate_retval - else - log_failure_msg "Zone ${zone} is not forwaring any traffic..." - exit ${EXIT_ERROR} - fi - - ppp_post_up - ;; - - pre-down) - ppp_pre_down - - MESSAGE="Stopping PPP Daemon on interface ${zone}..." - pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null) - if [ -n "${pid}" ]; then - kill ${pid} &>/dev/null - evaluate_retval - fi - ;; - - post-down) - ppp_post_down - ;; - - add) - # A pregenerated connection name - NAME=$(&2 - exit 1 - ;; - esac - shift - done - - UUID=$(uuid) - cat <${CONFIG_UUIDS}/${UUID} -HOOK="${HOOK_NAME}" -USER="${USER}" -SECRET="${SECRET}" -NAME="${NAME}" -MTU="${MTU}" -DEFAULTROUTE="${DEFAULTROUTE}" -PEERDNS="${PEERDNS}" -AUTH="${AUTH}" -EOF - ln -sf ${CONFIG_UUIDS}/${UUID} \ - ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} - - exit ${EXIT_OK} - ;; - - discover) - output=$(pppoe-discovery -I ${zone} \ - -U $(&1) - if grep -q "Timeout" <<<${output}; then - echo "${HOOK_NAME}: FAILED" - exit ${EXIT_ERROR} - else - echo "${HOOK_NAME}: OK" - echo "${output}" | while read line; do - [ "${line:0:1}" = "A" ] || continue - echo "${HOOK_NAME}: ${line}" - done - exit ${EXIT_OK} - fi - ;; - - *) - echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" + pppd file ${RED_RUN}/${LINKNAME}/options >/dev/null + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + shift + + config_read ${ZONE_DIR}/${zone}/settings + + ppp_pre_down + + # Kill pppd + pid=$(cat /var/run/${zone}.pid 2>/dev/null) + if [ -n "${pid}" ]; then + kill ${pid} &>/dev/null + fi + + # Pull down device or remove virtual one + if [ -n "${DEVICE_VID}" ]; then + device_remove_virtual ${DEVICE_MAC} + else + device_set_down ${DEVICE} + fi + + exit ${EXIT_OK} +} + +function _discover() { + local device=${1} + + if [ "$(device_get_type ${device})" != "real" ]; then exit ${EXIT_ERROR} - ;; -esac + fi + + local output + output=$(pppoe-discovery -I ${device} -U $(uuid) 2>&1) + + # Exit if there was not output + [ -z "${output}" ] && exit ${DISCOVER_ERROR} + + # Exit if PADI timed out + grep -q "Timeout" <<<${output} && exit ${DISCOVER_ERROR} + + local ac + while read line; do + case "${line}" in + Access-Concentrator:*) + ac="${line#Access-Concentrator: }" + ;; + esac + done <<<"${output}" + + echo "ACCESS_CONCENTRATOR=\"$ac\"" + + exit ${DISCOVER_OK} +} -# End $NETWORK_DEVICES/services/ipv4-static +run $@ diff --git a/hooks/pppoe.helper b/hooks/pppoe.helper deleted file mode 100755 index 693ba3de..00000000 --- a/hooks/pppoe.helper +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -. /lib/network/functions -. /lib/network/functions.ppp - -while [ $# -gt 0 ]; do - case "${1}" in - --config=*) - . ${1#--config=} - ;; - *) - action=${1} - break - ;; - esac - shift -done - -zone=${DEVICE} - -DIR=${RED_RUN}/${LINKNAME} - -case "${action}" in - ip-up) - mkdir -p ${DIR} 2>/dev/null - - echo "${IPREMOTE}" > ${DIR}/remote-ip-address - echo "${IPLOCAL}" > ${DIR}/local-ip-address - - # Update firewall with new IP address(es) - - # Prepare main routing table - ip route add ${IPREMOTE}/32 dev ${IFNAME} src ${IPLOCAL} - - # Configure our own routing table - ip route add table ${zone} default via ${IPREMOTE} dev ${IFNAME} - - if [ "${DEFAULTROUTE}" = "1" ]; then - ln -sf remote-ip-address ${DIR}/gateway - [ -n "${WEIGHT}" ] && \ - echo "${WEIGHT}" > ${DIR}/weight - - red_defaultroute_update - fi - - if [ "${PEERDNS}" = "1" ]; then - echo "${DNS1}" > ${DIR}/dns - if [ -n "${DNS2}" ] && [ "${DNS1}" != "${DNS2}" ]; then - echo "${DNS2}" > ${DIR}/dns - fi - red_dns_update - fi - ;; - - ip-down) - # Flush firewall - - if [ "${DEFAULTROUTE}" = "1" ]; then - : - fi - - ip route flush table ${zone} - - if [ "${PEERDNS}" = "1" ]; then - : - fi - - # Save statistics - ppp_stat "${NAME}" "${CONNECT_TIME}" "${BYTES_RCVD}" "${BYTES_SENT}" - ;; -esac - -exit 0 diff --git a/hooks/stp b/hooks/stp deleted file mode 100755 index 9e1c465e..00000000 --- a/hooks/stp +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/stp -# -# Description : Spanning Tree Protocol Script -# -# Authors : Michael Tremer - michael.tremer@ipfire.org -# -# Version : 00.00 -# -# Notes : This script adds stp support to a bridge. -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=stp -HOOK_TYPE=zone - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=$HOOK_NAME" - echo "HOOK_TYPE=$HOOK_TYPE" - ;; - - pre-up) - ;; - - post-up) - MESSAGE="Enabling Spanning Tree Protocol on zone ${zone}..." - brctl stp ${zone} on - evaluate_retval - ;; - - pre-down) - MESSAGE="Disabling Spanning Tree Protocol on zone ${zone}..." - brctl stp ${zone} off - evaluate_retval - ;; - - post-down) - ;; - - add) - shift 2 - while [ $# -gt 0 ]; do - case "$1" in - --ageing=*) - AGEING=${1#--ageing=} - ;; - --priority=*) - PRIORITY=${1#--priority=} - ;; - --delay=*) - DELAY=${1#--delay=} - ;; - --hello=*) - HELLO=${1#--hello=} - ;; - --maxage=*) - MAXAGE=${1#--maxage=} - ;; - *) - echo "Unknown option: $1" >&2 - exit 1 - ;; - esac - shift - done - cat <${CONFIG_ZONES}/${zone}/${HOOK_NAME} -HOOK="${HOOK_NAME}" -AGEING="${AGEING}" -PRIORITY="${PRIORITY}" -DELAY="${DELAY}" -HELLO="${HELLO}" -MAXAGE="${MAXAGE}" -EOF - exit $? - ;; - - rem) - ;; - - discover) - exit ${EXIT_ERROR} - ;; - - *) - echo "Usage: ${0} {pre-up|post-up|pre-down|post-down|config} [interface]" - exit 1 - ;; -esac - -# End $NETWORK_DEVICES/services/stp diff --git a/hooks/vlan b/hooks/vlan deleted file mode 100755 index e4d99e64..00000000 --- a/hooks/vlan +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/sh -######################################################################## -# Begin $NETWORK_DEVICES/services/vlan -# -# Description : VLAN Script -# -# Authors : Michael Tremer - michael.tremer@ipfire.org -# -# Version : 00.00 -# -# Notes : This script adds vlan support. -# -######################################################################## - -. /lib/network/hook-header - -HOOK_NAME=vlan -HOOK_TYPE=port - -function port_name() { - echo "${zone}v${ID}" -} - -case "${action}" in - help) - ;; - - info) - echo "HOOK_NAME=${HOOK_NAME}" - echo "HOOK_TYPE=${HOOK_TYPE}" - ;; - - pre-up) - # Load the kernel module - grep -q ^8021q /proc/modules || modprobe 8021q - - if ! port_is_up $(port_name); then - MESSAGE="Adding VLAN ${ID} to port ${MAC}..." - - if ! device_is_up $(devicify ${MAC}); then - ip link set $(devicify ${MAC}) up - fi - vconfig add $(devicify ${MAC}) ${ID} >/dev/null - evaluate_retval - - device_rename $(get_device_by_mac_and_vid ${MAC} ${ID}) $(port_name) - ip link set $(port_name) up - - ebtables -t broute -A BROUTING -p 802_1Q --vlan-id=${ID} -j DROP - fi - ;; - - post-up) - if ! zone_has_device_attached ${zone} $(port_name); then - zone_add_port ${zone} $(get_device ${MAC} ${ID}) - fi - ;; - - pre-down) - if zone_has_device_attached ${zone} $(port_name); then - zone_del_port ${zone} $(get_device_by_mac_and_vid ${MAC} ${ID}) - fi - ;; - - post-down) - if port_is_up $(port_name); then - MESSAGE="Removing VLAN ${ID} from port ${MAC}..." - - vconfig rem $(get_device_by_mac_and_vid ${MAC} ${ID}) >/dev/null - evaluate_retval - - ebtables -t broute -D BROUTING -p 802_1Q --vlan-id=${ID} -j DROP - fi - ;; - - add) - MAC=$(macify ${1}) - ID=${2} # Must be integer between 1 and 4096 - - UUID=$(uuid) - cat < ${CONFIG_UUIDS}/${UUID} -HOOK="${HOOK_NAME}" -ID="${ID}" -MAC="${MAC}" -EOF - ln -sf ${CONFIG_UUIDS}/${UUID} \ - ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} - - log_success_msg "Configuration successfully saved!" - echo " Device : $(devicify ${MAC})" - echo " MAC address : ${MAC}" - echo " VLAN tag : ${ID}" - ;; - - rem) - # XXX to be done - ;; - - status) - echo -e "# ${CLR_BOLD_CYN}VLAN port $(port_name)${NORMAL}" - echo -n "# State: " - if device_is_up $(port_name); then - echo -e "${CLR_BOLD_GRN}up${NORMAL}" - RET=${EXIT_OK} - else - echo -e "${CLR_BOLD_RED}down${NORMAL}" - RET=${EXIT_ERROR} - fi - echo "# ID : ${ID}" - echo "#" - exit ${RET} - ;; - - *) - echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}" - exit 1 - ;; -esac - -# End $NETWORK_DEVICES/services/vlan diff --git a/network b/network old mode 100644 new mode 100755 index 2bcbbe1c..0a2cfdaa --- a/network +++ b/network @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# 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 # @@ -19,597 +19,55 @@ # # ############################################################################### -BOLD="\\033[1;39m" -NORMAL="\\033[0;39m" -ERROR="\\033[1;31m" +. /lib/network/functions -. /etc/init/functions - -if [ -e "/lib/network/functions" ]; then - . /lib/network/functions -elif [ -e "lib/functions" ]; then - HOME_DIR="lib" - . lib/functions -else - echo "Cannot find functions library. Exiting." >&2 - exit 1 -fi - -function usage() { - echo -e "${BOLD}Usage $0${NORMAL}:\n" - case "$1" in - main|"") - echo "This script will help you configuring your network." - echo - echo "You should know that there are three different things:" - echo - echo " hook: A script to control connections and protocols." - echo " port: A physical connection to somewhere." - echo " zone: A group of ports." - echo - echo " $0 [global flags] ... or" - echo " $0 [global flags] " - echo - echo -e "${BOLD}Global flags:${NORMAL}" - echo " --verbose -v - Turn on verbose mode." - echo " --debug -d - Turn on debug mode." - echo - echo -e "${BOLD}Command line options:${NORMAL}" - echo " help - Prints this help message." - echo " start - Starts the whole network." - echo " stop - Stops the whole network." - echo " restart - Restarts the whole network." - echo " reload - Reloads the whole network." - echo - echo " hook - Run \"$0 hook help\" for more information." - echo " port - Run \"$0 port help\" for more information." - echo " zone - Run \"$0 zone help\" for more information." - echo - ;; - hook*) - echo -e "${BOLD}Hook configuration:${NORMAL}" - echo - echo " ${0} [global options] hook " - echo - echo -e "${BOLD}1st level commands:${NORMAL}" - echo -e " ${BOLD}list:${NORMAL}" - echo " Returns a list of all available hooks." - echo - echo - echo " ${0} [global options] hook " - echo - echo -e "${BOLD}2nd level commands:${NORMAL}" - echo -e " ${BOLD}help:${NORMAL}" - echo " Displays some help about the given hook." - echo - echo " Example: $0 hook ethernet help" - echo +# Parse the command line +while [ $# -gt 0 ]; do + case "${1}" in + -d|--debug) + DEBUG=1 + log DEBUG "Enabled debugging mode" ;; - port) - echo -e "${BOLD}Port Configuration:${NORMAL}" - echo - echo " $0 [global options] port ..." - echo - echo -e "${BOLD}Commands:${NORMAL}" - echo -e " ${BOLD}show:${NORMAL}" - echo " Displays information about a given port." - echo - echo " Requires a \"port\"." - echo " Example: $0 port show 00:11:22:33:44:55" - echo " $0 port show port0" - echo + *) + action=${1} ;; - zone) - echo -e "${BOLD}Zone Configuration:${NORMAL}" - echo - echo " $0 [global options] zone ..." - echo - echo -e "${BOLD}Commands:${NORMAL}" - echo -e " ${BOLD}show:${NORMAL}" - echo " Displays information about a given zone." - echo - echo " Requires a \"zone\"." - echo " Example: $0 zone show green0" - echo - echo -e " ${BOLD}add:${NORMAL}" - echo " Adds a new zone." - echo - echo " Requires a \"zone\"." - echo " Example: $0 zone add green0" - echo - echo -e " ${BOLD}del:${NORMAL}" - echo " Deletes a zone." - echo - echo " Requires a \"zone\"." - echo " Example: $0 zone del green0" - echo - echo -e " ${BOLD}addport:${NORMAL}" - echo " Adds a port to a zone." - echo - echo " Requires a \"zone\" and \"port\"." - echo " Example: $0 zone addport green0 port0" - echo - echo " You may also pass a hook and its parameters:" - echo " $0 zone addport green0 port0 vlan 10" - echo - echo -e " ${BOLD}delport:${NORMAL}" - echo " Deletes a port from a zone." - echo - echo " Requires a \"zone\" and \"port\"." - echo " Example: $0 zone delport green0" - echo - echo " You may also pass a hook and its parameters:" - echo " $0 zone delport green0 port0 vlan 10" - echo esac - _exit ${2-1} -} - -function debug() { - if [ -n "$1" ]; then - DEBUG=$1 - verbose $1 - return - else - if [ "$DEBUG" = "1" ]; then - return 0 - else - return 1 - fi - fi -} - -function verbose() { - if [ -n "$1" ]; then - VERBOSE=$1 - return - else - if [ "$VERBOSE" = "1" ]; then - return 0 - else - return 1 - fi - fi -} - -function decho() { - debug && echo -e "${ERROR}$@${NORMAL}" >&2 -} - -function vecho() { - verbose && echo -e "$@" >&2 -} - -function error() { - echo -e "${ERROR}ERROR${NORMAL}: $@" >&2 - _exit 1 -} - -function _exit() { - local code - local reload - - while [ $# -gt 0 ]; do - case "$1" in - --reload) - reload=1 - ;; - [0-9]*) - code=$1 - ;; - *) - error "Unrecognized argument: $1" - ;; - esac - shift - done - - if [ "${reload}" = "1" ]; then - # Reloading network to apply changes immediately - vecho "Reloading network settings..." - cmd $0 reload - - # Reload firewall, too - firewall=$(which firewall 2>/dev/null) - if [ -n "${firewall}" ]; then - vecho "Reloading firewall..." - cmd ${firewall} reload - fi - fi - - decho "Exiting with code ${code}." - exit ${code} -} - -function cmd() { - decho "Running command: $@" - if debug; then - DEBUG=${DEBUG} VERBOSE=${VERBOSE} $@ - else - DEBUG=${DEBUG} VERBOSE=${VERBOSE} $@ >/dev/null - fi -} - -function size() { - local size=${1} - - local units - units[0]="Bytes " - units[1]="kBytes" - units[2]="MBytes" - units[3]="GBytes" - units[4]="TBytes" - - local count=${#units} - while [ ${count} -gt 0 ]; do - if [ ${size} -lt 1024 ]; then - break - fi - size=$((${size} / 1024)) - count=$((${count} - 1)) - done - printf "%4d %s\n" "${size}" "${units[$((${#units} - ${count}))]}" -} - -function port_show() { - local port - if [ $# -eq 0 ]; then - for port in /sys/class/net/*; do - port=${port##*/} - device_is_real ${port} || continue - port_show ${port} - done - return - fi - - port=$(devicify $1) - - echo "##################################################" - echo "#" - echo -e "# Port ${CLR_BOLD_BLU}${port}${NORMAL}" - echo "# ------------------------------------------------" - - echo -n "# State: " - if device_is_up ${port}; then - echo -e "${CLR_BOLD_GRN}up${NORMAL}" - else - echo -e "${CLR_BOLD_RED}down${NORMAL}" - fi - - echo -n "# Link : " - if device_has_carrier ${port}; then - echo -e "${CLR_BOLD_GRN}yes${NORMAL}" - else - echo -e "${CLR_BOLD_RED}no${NORMAL}" - fi - - if device_is_up ${port}; then - echo "#" - echo "# Statistics:" - echo -n "# RX: $(size $(/dev/null - if hook_exists ${hook}; then - /lib/network/hooks/${hook} --zone=${zone} add $@ - RET=$? - if [ "$RET" -eq "0" ]; then - vecho "Successfully added port to ${BOLD}${zone}${NORMAL}." - else - error "Hook ${BOLD}${hook}${NORMAL} exited with $RET." - return $RET - fi - else - error "Hook ${BOLD}${hook}${NORMAL} does not exist or is not executeable." - return 1 - fi -} - -function port_del() { - local config - local hook - local uuid - - local zone=${1} shift - - if is_uuid ${1}; then - uuid=${1} - config="${CONFIG_UUIDS}/${uuid}" - - if [ -e "${config}" ]; then - hook=$(config_get_hook ${config}) - else - error "Given config file does not exist: ${config}." - return 1 - fi - fi - - hook_run --config=${config} pre-down - hook_run --config=${config} post-down - hook_run --config=${config} rem -} - -function zone_discover() { - local zone=${1} - - for hook in $(hook_list zone); do - hook_run ${hook} --zone=${zone} discover - done -} - -function zone_show() { - local zone - zone=$1 - - if [ -z "$zone" ]; then - for zone in ${CONFIG_ZONES}/*; do - zone_show $(basename $zone) - done - return - fi - - if ! zone_exists ${zone}; then - error "Zone ${BOLD}${zone}${NORMAL} does not exist." - return 2 - fi - - echo "##################################################" - echo "#" - echo -e "# Zone ${CLR_BOLD_BLU}${zone}${NORMAL}" - echo "# ------------------------------------------------" - - # Up or down? - if zone_is_up ${zone}; then - echo -e "# Status: ${CLR_BOLD_GRN}up${NORMAL}" - else - echo -e "# Status: ${CLR_BOLD_RED}down${NORMAL}" - fi - echo "#" - - # Ports - echo -e "# ${CLR_BOLD_BLU}Ports:${NORMAL}" - hooks_run_ports status ${CONFIG_ZONES}/${zone} --zone=${zone} - - echo "#" - echo -e "# ${CLR_BOLD_BLU}Zone configurations:${NORMAL}" - hooks_run_zones status ${CONFIG_ZONES}/${zone} --zone=${zone} - echo "#" - -} - -function zone_raw() { - local zone - if [ $# -eq 0 ]; then - for zone in $(zone_list); do - zone_raw ${zone##*/} - done - return - fi - - zone=${1} - -cat <