#!/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 . # # # ############################################################################### . /usr/lib/network/header-config HOOK_SETTINGS=( "ADDRESS" "PREFIX" "GATEWAY" ) hook_check_config_settings() { local protocol="$(ip_detect_protocol "${ADDRESS}")" case "${protocol}" in ipv6) assert ipv6_is_valid "${ADDRESS}" assert ipv6_prefix_is_valid "${PREFIX}" isset GATEWAY && assert ipv6_is_valid "${GATEWAY}" ;; ipv4) assert ipv4_is_valid "${ADDRESS}" assert ipv4_prefix_is_valid "${PREFIX}" isset GATEWAY && assert ipv4_is_valid "${GATEWAY}" ;; *) error "Could not determine protocol: ${protocol}" return ${EXIT_CONF_ERROR} ;; esac return ${EXIT_OK} } hook_parse_cmdline() { local protocol local id="${1}" shift while [ $# -gt 0 ]; do case "${1}" in # IPv6 *:*/*) protocol="ipv6" ADDRESS="$(ip_split_prefix "${1}")" PREFIX="$(ip_get_prefix "${1}")" # Validate address if ! ipv6_is_valid "${ADDRESS}"; then error "Invalid IP address: ${ADDRESS}" return ${EXIT_CONF_ERROR} fi # Validate prefix if ! ipv6_prefix_is_valid "${PREFIX}"; then error "Invalid prefix: ${PREFIX}" return ${EXIT_CONF_ERROR} fi # Store the IPv6 address in its shortest format ADDRESS="$(ipv6_format "${ADDRESS}")" ;; # IPv4 *.*.*.*/*) protocol="ipv4" ADDRESS="$(ip_split_prefix "${1}")" PREFIX="$(ip_get_prefix "${1}")" # Validate address if ! ipv4_is_valid "${ADDRESS}"; then error "Invalid IP address: ${ADDRESS}" return ${EXIT_CONF_ERROR} fi # Validate prefix if ! ipv4_prefix_is_valid "${PREFIX}"; then # This might be a netmask instead local prefix_from_netmask="$(ipv4_netmask2prefix "${PREFIX}")" if ! ipv4_prefix_is_valid "${prefix_from_netmask}"; then PREFIX="${prefix_from_netmask}" else error "Invalid prefix or netmask: ${PREFIX}" return ${EXIT_CONF_ERROR} fi fi ;; # Gateway --gateway=*) GATEWAY="$(cli_get_val "${1}")" # Validate input if isset GATEWAY && ! ip_is_valid "${GATEWAY}"; then error "Invalid gateway IP address: ${GATEWAY}" return ${EXIT_CONF_ERROR} fi ;; *) error "Invalid argument: ${1}" return ${EXIT_CONF_ERROR} ;; esac shift done # Check if an address has been set if ! isset ADDRESS; then error "No IP address provided" return ${EXIT_CONF_ERROR} fi # Check if a prefix has been set if ! isset PREFIX; then error "No prefix provided" return ${EXIT_CONF_ERROR} fi # More gateway validation if isset GATEWAY; then local gateway_protocol="$(ip_detect_protocol "${GATEWAY}")" # Make sure that the prefix is of the same protocol version if [ "${gateway_protocol}" != "${protocol}" ]; then error "The gateway is of a wrong protocol: ${GATEWAY}" return ${EXIT_CONF_ERROR} fi # Make IP address as short as possible if [ "${gateway_protocol}" = "ipv6" ]; then GATEWAY="$(ipv6_format "${GATEWAY}")" fi fi # Check any conflicts if zone_config_check_same_setting "${zone}" "static" "${id}" "ADDRESS" "${ADDRESS}"; then error "A static configuration with the same address is already configured" return ${EXIT_CONF_ERROR} fi } hook_new() { local zone="${1}" shift local id=$(zone_config_get_new_id ${zone}) log DEBUG "ID for the config is: ${id}" if ! hook_parse_cmdline "${id}" "$@"; then # Return an error if the parsing of the cmd line fails return ${EXIT_ERROR} fi zone_config_settings_write "${zone}" "${HOOK}" "${id}" exit ${EXIT_OK} } hook_up() { local zone="${1}" local config="${2}" shift 2 # Check if the device exists if ! device_exists ${zone}; then error "Zone ${zone} doesn't exist" return ${EXIT_ERROR} fi # Read configuration if ! zone_config_settings_read "${zone}" "${config}"; then error "Could not read configuration for ${zone} ${config}" return ${EXIT_ERROR} fi # Add IP address to the interface if ! ip_address_add "${zone}" "${ADDRESS}/${PREFIX}"; then return ${EXIT_ERROR} fi local protocol="$(ip_detect_protocol "${ADDRESS}")" assert isset protocol db_set "${zone}/${protocol}/type" "${HOOK}" db_set "${zone}/${protocol}/local-ip-address" "${ADDRESS}/${PREFIX}" db_set "${zone}/${protocol}/remote-ip-address" "${GATEWAY}" db_set "${zone}/${protocol}/active" 1 # Update routing tables routing_update "${zone}" "${protocol}" routing_default_update exit ${EXIT_OK} } hook_down() { local zone=${1} local config=${2} shift 2 if ! device_exists ${zone}; then error "Zone ${zone} doesn't exist" exit ${EXIT_ERROR} fi # Read configuration if ! zone_config_settings_read "${zone}" "${config}"; then return ${EXIT_ERRO} fi # Remove routing information from database local protocol="$(ip_detect_protocol "${ADDRESS}")" assert isset protocol db_delete "${zone}/${protocol}" # Remove the IP address ip_address_del "${zone}" "${ADDRESS}/${PREFIX}" # Update routing tables routing_update "${zone}" "${protocol}" routing_default_update return ${EXIT_OK} } hook_status() { local zone=${1} local config=${2} shift 2 if ! device_exists ${zone}; then error "Zone ${zone} doesn't exist" exit ${EXIT_ERROR} fi # Read configuration if ! zone_config_settings_read "${zone}" "${config}"; then return ${EXIT_ERROR} fi local status=${MSG_HOOK_UP} if ! zone_has_ip "${zone}" "${ADDRESS}/${PREFIX}"; then status=${MSG_HOOK_DOWN} fi cli_statusline 3 "${HOOK}" "${status}" cli_print_fmt1 3 "IP Address" "${ADDRESS}/${PREFIX}" if [ -n "${GATEWAY}" ]; then cli_print_fmt1 3 "Gateway" "${GATEWAY}" fi cli_space return ${EXIT_OK} }