--- /dev/null
+#!/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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+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}"
+done
+
+COMMON_DEVICE=port+
+
+EXIT_OK=0
+EXIT_ERROR=1
+EXIT_CONF_ERROR=2
+
+VALID_ZONES="blue 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})
+ [ "$(</sys/class/net/${device}/carrier)" = "1" ]
+}
+
+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}"
+}
+
+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 hook_exists() {
+ [ -x "${HOOKS_DIR}/${1}" ]
+}
+
+function port_exists() {
+ device_exists $@
+}
+
+function port_is_up() {
+ port_exists $@ && device_is_up $@
+}
+
+function zone_exists() {
+ [ -e "$CONFIG_ZONES/${1}" ]
+}
+
+function zone_is_up() {
+ zone_exists $@ && device_is_up $@
+}
+
+function zone_is_forwarding() {
+ local seconds=45
+ local zone=${1}
+
+ 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_devices() {
+ local bridge=$1
+ [ -z "${bridge}" ] && return 2
+ brctl show | grep "^${bridge}" | awk '{ print $NF }' | grep -v "^interfaces$"
+}
+
+function zone_add_port() {
+ local zone=${1}
+ local port=${2}
+
+ brctl addif ${zone} ${port}
+}
+
+function zone_del_port() {
+ local zone=${1}
+ local port=${2}
+
+ brctl delif ${zone} ${port}
+}
+
+function zone_list() {
+ local zone
+ for zone in $(find ${CONFIG_ZONES}/* 2>/dev/null); do
+ [ -d "${zone}" ] && echo ${zone}
+ done
+}
+
+function 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
+ 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} <<EOF
+CREATE TABLE connections(name, zone, interface, iplocal, ipremote, weight, dns, status);
+EOF
+ fi
+
+ if [ -z "${zone}" ]; then
+ return 2
+ fi
+
+ status=${action}
+
+ sqlite3 -batch ${CONNECTIONS_FILE} <<EOF
+DELETE FROM connections WHERE zone = '${zone}';
+INSERT INTO connections(name, zone, interface, iplocal, ipremote, weight, dns, status)
+ VALUES('${name}', '${zone}', '${interface}', '${iplocal}', '${ipremote}', '${weight}', '${dns}', '${status}');
+EOF
+
+}
+
+function uuid() {
+ cat /proc/sys/kernel/random/uuid
+}
--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+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
+
+ connection --starting --zone=${zone}
+}
+
+function ppp_post_up() {
+ : #connection --up --zone=${zone}
+}
+
+function ppp_pre_down() {
+ connection --stopping --zone=${zone}
+}
+
+function ppp_post_down() {
+ : #connection --down --zone=${zone}
+}
+
+function ppp_secret() {
+ local USER=${1}
+ local SECRET=${2}
+ local a
+ local secret
+ local user
+
+ # Updateing secret file
+ > ${PPP_SECRETS}.tmp
+ while read user a secret; do
+ if [ "'${USER}'" != "${user}" ]; then
+ echo "${user} ${a} ${secret}" >> ${PPP_SECRETS}.tmp
+ fi
+ done < ${PPP_SECRETS}
+ echo "'${USER}' * '${SECRET}'" >> ${PPP_SECRETS}.tmp
+ cat ${PPP_SECRETS}.tmp > ${PPP_SECRETS}
+ rm -f ${PPP_SECRETS}.tmp
+}
+
+function ppp_stat() {
+ local name=${1}
+ local time=${2}
+ local rcvd=${3}
+ local sent=${4}
+
+ local file="${LOG_DIR}/ppp_${name}.db"
+ if ! [ -e "${file}" ]; then
+ sqlite3 -batch ${file} <<EOF
+CREATE TABLE connections(date, duration, rcvd, sent);
+EOF
+ fi
+ ppp_stat_init ${file}
+
+ sqlite3 -batch ${file} <<EOF
+INSERT INTO connections(date, duration, rcvd, sent) VALUES('$(date -u '+%s')', '${time}', '${rcvd}', '${sent}');
+EOF
+}
+
+function ppp_linkname_get() {
+ local config=${1}
+ (
+ . ${config}
+ echo "${LINKNAME}"
+ )
+}
+
+function red_defaultroute_update() {
+ local command="ip route replace default"
+
+ for uplink in ${RED_RUN}/*; do
+ [ -d "${uplink}" ] || continue
+
+ # Skip if no gateway given
+ [ -e "${uplink}/gateway" ] || continue
+
+ command="${command} nexthop via $(<${uplink}/gateway)"
+ if [ -e "${uplink}/weight" ]; then
+ command="${command} weight $(<${uplink}/weight)"
+ fi
+ done
+ $command
+ ip route flush cache
+}
+
+function red_dns_update() {
+ : # XXX todo
+}
--- /dev/null
+#!/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
+
--- /dev/null
+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] <action> [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}.
--- /dev/null
+#!/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 <<EOF > ${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 $(</sys/class/net/${DEVICE}/bonding/slaves); do
+ echo -e "# ${CLR_BOLD_CYN}Slave port ${slave}${NORMAL}"
+
+ echo -n "# State: "
+ if device_is_up ${slave}; then
+ echo -e "${CLR_BOLD_GRN}up${NORMAL}"
+ else
+ echo -e "${CLR_BOLD_RED}down${NORMAL}"
+ fi
+
+ echo -n "# Link : "
+ if device_has_carrier ${slave}; then
+ echo -e "${CLR_BOLD_GRN}yes${NORMAL}"
+ else
+ echo -e "${CLR_BOLD_RED}no${NORMAL}"
+ fi
+ done
+ else
+ echo -e "# State: ${CLR_BOLD_RED}down${NORMAL}"
+ fi
+
+ device_is_up ${MAC}
+ exit ${?}
+ ;;
+
+ *)
+ echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}"
+ exit 1
+ ;;
+esac
+
+# End $NETWORK_DEVICES/services/bonding
--- /dev/null
+#!/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=<FILE>"
+ #echo " Includes a config file."
+ #echo " Example: --config=/etc/sysconfig/network/green0/port-00:11:22:33:44:55"
+ #echo " --port=<MAC or Name>"
+ #echo " Passes the port to the script."
+ #echo " Example: --port=port0 or --port=00:11:22:33:44:55"
+ #echo " --zone=<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 <<EOF > ${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
--- /dev/null
+#!/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 <<EOF >${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
--- /dev/null
+#!/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 <<EOF >${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
--- /dev/null
+#!/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 <<EOF >${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
--- /dev/null
+#!/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
--- /dev/null
+#!/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 <<EOF >${RED_RUN}/${NAME}/options
+# Naming options
+name ${NAME}
+linkname ${NAME}
+
+plugin ${PPPOE_PLUGIN} ${zone}
+
+# User configuration
+user ${USER}
+
+$([ "${PEERDNS}" = "1" ] && echo "usepeerdns")
+$([ "${DEFAULTROUTE}" = "1" ] && echo "defaultroute")
+
+noauth
+$([ -n "${AUTH}" ] && echo "require-${AUTH}")
+
+noipdefault
+
+# Maximum transmission/receive unit
+mtu ${MTU}
+mru ${MTU}
+
+# Disable the compression
+noaccomp nodeflate nopcomp novj novjccomp nobsdcomp
+
+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=$(</proc/sys/kernel/random/uuid)
+ DEFAULTROUTE=1
+ PEERDNS=1
+ MTU=1492
+
+ while [ $# -gt 0 ]; do
+ case "$1" in
+ --user=*)
+ USER=${1#--user=}
+ ;;
+ --secret=*)
+ SECRET=${1#--secret=}
+ ;;
+ --name=*)
+ NAME=${1#--name=}
+ ;;
+ --mtu=*)
+ MTU=${1#--mtu=}
+ ;;
+ --no-defaultroute)
+ DEFAULTROUTE=0
+ ;;
+ --no-dns)
+ PEERDNS=0
+ ;;
+ --auth=*)
+ AUTH=${1#--auth=}
+ ;;
+ *)
+ echo "Unknown option: $1" >&2
+ exit 1
+ ;;
+ esac
+ shift
+ done
+
+ UUID=$(uuid)
+ cat <<EOF >${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 $(</proc/sys/kernel/random/uuid) 2>&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]"
+ exit ${EXIT_ERROR}
+ ;;
+esac
+
+# End $NETWORK_DEVICES/services/ipv4-static
--- /dev/null
+#!/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
--- /dev/null
+#!/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 <<EOF >${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
--- /dev/null
+#!/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 <<EOF > ${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
--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+BOLD="\\033[1;39m"
+NORMAL="\\033[0;39m"
+ERROR="\\033[1;31m"
+
+. /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] <hook|port|zone> ... or"
+ echo " $0 [global flags] <cmd line options...>"
+ 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 <command>"
+ 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 <hook> <command>"
+ 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
+ ;;
+ port)
+ echo -e "${BOLD}Port Configuration:${NORMAL}"
+ echo
+ echo " $0 [global options] port <command> ..."
+ 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
+ ;;
+ zone)
+ echo -e "${BOLD}Zone Configuration:${NORMAL}"
+ echo
+ echo " $0 [global options] zone <command> ..."
+ 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 $(</sys/class/net/${port}/statistics/rx_bytes))"
+ echo " ($(</sys/class/net/${port}/statistics/rx_packets) packets)"
+ echo -n "# TX: $(size $(</sys/class/net/${port}/statistics/tx_bytes))"
+ echo " ($(</sys/class/net/${port}/statistics/tx_packets) packets)"
+ fi
+
+ echo "#"
+}
+
+function port_raw() {
+ local port
+ if [ $# -eq 0 ]; then
+ for port in /sys/class/net/*; do
+ port=${port##*/}
+ device_is_real ${port} || continue
+ port_raw ${port}
+ done
+ return
+ fi
+
+ port=$(devicify $1)
+
+ cat <<EOF
+[${port}]
+type=$(device_type ${port})
+mac=$(macify ${port})
+carrier=$(device_has_carrier ${port} && echo "1" || echo "0")
+up=$(device_is_up ${port} && echo "1" || echo "0")
+
+EOF
+}
+
+function port_add() {
+ local zone=${1}
+ local hook=${2}
+ shift 2
+
+ if ! zone_exists ${zone}; then
+ error "Zone ${BOLD}${zone}${NORMAL} does not exist."
+ return 1
+ fi
+
+ mkdir -p ${CONFIG_PORTS}/${port} 2>/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 <<EOF
+[${zone}]
+up=$(zone_is_up ${zone} && echo "1" || echo "0")
+
+EOF
+}
+
+function zone_add() {
+ local zone=$1
+
+ if zone_exists ${zone}; then
+ error "Zone ${BOLD}${zone}${NORMAL} already exists."
+ return 1
+ fi
+
+ if ! zone_valid_name ${zone}; then
+ error "The given zone name is not valid."
+ return 1
+ fi
+
+ mkdir -p ${CONFIG_ZONES}/${zone}
+ vecho "Successfully added zone ${BOLD}${zone}${NORMAL}."
+}
+
+function zone_del() {
+ local zone=$1
+
+ if ! zone_exists ${zone}; then
+ error "Zone ${BOLD}${zone}${NORMAL} does not exist."
+ return 1
+ fi
+
+ cmd /lib/network/zone --zone=${zone} down
+ rm -rf ${CONFIG_ZONES}/${zone}
+ vecho "Successfully removed zone ${BOLD}${zone}${NORMAL}."
+}
+
+# See what to do
+while [ "$#" -gt 0 ]; do
+ arg=$1
+ shift
+
+ case "$arg" in
+ --debug|-d)
+ debug 1
+ decho "Debug mode enabled."
+ ;;
+ --verbose|-v)
+ verbose 1
+ vecho "${BOLD}Verbose mode enabled.${NORMAL}"
+ ;;
+ help|-h|--help)
+ usage main 0
+ ;;
+ start|stop|reload)
+ action=${arg}
+ for zone in $(zone_list); do
+ zone=${zone##*/}
+ decho "Running command: ${HOME_DIR}/zone --zone=${zone} ${action}"
+ DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOME_DIR}/zone --zone=${zone} ${action}
+ done
+ _exit $?
+ ;;
+ restart)
+ DEBUG=${DEBUG} VERBOSE=${VERBOSE} $0 stop $@
+ sleep 1
+ DEBUG=${DEBUG} VERBOSE=${VERBOSE} $0 start $@
+ _exit $?
+ ;;
+ hook|hooks)
+ case "$1" in
+ list)
+ hook_list
+ _exit $?
+ ;;
+ *)
+ if hook_exists ${1}; then
+ hook=${1}
+ else
+ usage hook
+ fi
+ esac
+ shift
+ case "$1" in
+ help|info)
+ if hook_exists ${hook}; then
+ hook_run ${hook} ${1}
+ _exit $?
+ else
+ error "Hook ${hook} does not exist or is not executeable."
+ _exit 1
+ fi
+ ;;
+ *)
+ usage hook
+ ;;
+ esac
+ ;;
+ p*)
+ arg=$1
+ shift
+ case "$arg" in
+ help)
+ usage port 0
+ ;;
+ show)
+ port_show $@
+ _exit $?
+ ;;
+ _raw)
+ port_raw $@
+ _exit $?
+ ;;
+ esac
+ ;;
+ z*)
+ arg=$1
+ shift
+ case "$arg" in
+ add)
+ zone_add $@
+ _exit --reload $?
+ ;;
+ addport)
+ port_add $@
+ _exit --reload $?
+ ;;
+ config)
+ zone=$1; hook=$2; shift 2
+ if [ -z "${zone}" ] || [ -z "${hook}" ]; then
+ usage config
+ fi
+ hook_run ${hook} --zone=${zone} add $@
+ _exit --reload $?
+ ;;
+ del)
+ zone_del $@
+ _exit --reload $?
+ ;;
+ delport)
+ port_del $@
+ _exit --reload $?
+ ;;
+ discover)
+ zone_discover $@
+ _exit $?
+ ;;
+ help)
+ usage zone 0
+ ;;
+ list)
+ zone_list
+ _exit $?
+ ;;
+ show)
+ zone_show $@
+ _exit $?
+ ;;
+ start|stop)
+ zone=$1; shift
+ zone_run --zone=${zone} ${arg} $@
+ ;;
+ _raw)
+ zone_raw $@
+ _exit $?
+ ;;
+ esac
+ ;;
+ show)
+ arg=${1}
+ shift
+ case "${arg}" in
+ ports)
+ port_show $@
+ _exit 0
+ ;;
+ esac
+ ;;
+ -*)
+ error "Option \"$arg\" is not known."
+ ;;
+ esac
+done
+
+usage main
--- /dev/null
+#!/bin/sh
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2007 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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+umask 022
+export PATH=/usr/sbin:/sbin:/usr/bin:/bin
+
+. /lib/network/functions
+. /lib/network/functions.ppp
+
+for config in ${CONFIG_ZONES}/${DEVICE}/*; do
+ if [ "$(ppp_linkname_get ${config})" = "${LINKNAME}" ]; then
+ CONFIG=${config}
+ . ${CONFIG}
+ break
+ fi
+done
+
+if [ -n "${HOOK}" ] && [ -x "${HOOKS_DIR}/${HOOK}.helper" ]; then
+ exec ${HOOKS_DIR}/${HOOK}.helper --config=${CONFIG} \
+ $(basename $0) $@
+fi
+
+exit ${EXIT_ERROR}
--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+. /etc/init/functions
+. /lib/network/functions
+
+while [ "$#" -gt "0" ]; do
+ case "${1}" in
+ --zone=*)
+ zone=${1#--zone=}
+ ;;
+ *)
+ action=${1}
+ break
+ ;;
+ esac
+ shift
+done
+
+if [ -z "${zone}" ] || [ -z "${action}" ]; then
+ log_failure_msg "Wrong number of arguments."
+ exit ${EXIT_ERROR}
+fi
+
+if ! zone_exists ${zone}; then
+ echo "Zone ${zone} does not exist."
+ 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