#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2011 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 isdn_config_dir() { local device=${1} local dir="${RUN_DIR}/isdn/${device}" [ -d "${dir}" ] || mkdir -p ${dir} echo "${dir}" } function isdn_create_device() { local device=${1} if device_exists ${device}; then return ${EXIT_OK} fi log INFO "Creating ISDN interface ${device}." isdnctrl addif ${device} >/dev/null } function isdn_remove_device() { local device=${1} if ! device_exists ${device}; then return ${EXIT_OK} fi log INFO "Removing ISDN interface ${device}." isdnctrl delif ${device} >/dev/null } function isdn_add_slave() { local device=${1} local slave=${2} assert device_exists ${device} assert isset slave log INFO "Creating ISDN slave interface ${slave} for device ${device}." isdnctrl addslave ${device} ${slave} local ret=$? case "${ret}" in 0) return ${EXIT_OK} ;; 255) log ERROR "Could not create slave device for ${device}." ;; esac return ${EXIT_ERROR} } function isdn_rem_slave() { local device=${1} local slave=${2} assert device_exists ${device} assert isset slave log INFO "Removing ISDN slave interface ${slave}." isdnctrl delslave ${device} ${slave} >/dev/null } function isdn_addlink() { local device=${1} assert device_exists ${device} log INFO "Adding link to ISDN interface ${device}." isdnctrl addlink ${device} >/dev/null } function isdn_get_encap() { local device=${1} assert device_exists ${device} isdnctrl encap ${device} | awk '{ print $NF }' } function isdn_set_encap() { local device=${1} local encap=${2} assert device_exists ${device} assert isset encap case "${encap}" in syncppp) ;; *) log ERROR "Cannot set unknown encapsulation: ${encap}" return ${EXIT_ERROR} ;; esac isdnctrl encap ${device} ${encap} >/dev/null } function isdn_get_l2proto() { local device=${1} assert device_exists ${device} isdnctrl l2_prot ${device} | awk '{ print $NF }' } function isdn_set_l2proto() { local device=${1} local proto=${2} assert device_exists ${device} assert isset proto case "${proto}" in hdlc) ;; *) log ERROR "Cannot set unknown l2 proto: ${proto}" return ${EXIT_ERROR} ;; esac isdnctrl l2_prot ${device} ${proto} >/dev/null } function isdn_get_l3proto() { local device=${1} assert device_exists ${device} isdnctrl l3_prot ${device} | awk '{ print $NF }' } function isdn_set_l3proto() { local device=${1} local proto=${2} assert device_exists ${device} assert isset proto case "${proto}" in trans) ;; *) log ERROR "Cannot set unknown l3 proto: ${proto}" return ${EXIT_ERROR} ;; esac isdnctrl l3_prot ${device} ${proto} >/dev/null } function isdn_set_dialmax() { local device=${1} local dialmax=${2} assert device_exists ${device} assert [ ${dialmax} -gt 0 ] isdnctrl dialmax ${device} ${dialmax} >/dev/null } function isdn_set_eaz() { local device=${1} local eaz=${2} assert device_exists ${device} assert isset eaz isdnctrl eaz ${device} ${eaz} >/dev/null } function isdn_set_dialmode() { local device=${1} local mode=${2} assert device_exists ${device} case "${proto}" in auto) ;; *) log ERROR "Cannot set unknown dialmode: ${mode}" return ${EXIT_ERROR} ;; esac isdnctrl dialmode ${device} ${mode} >/dev/null } function isdn_set_huptimeout() { local device=${1} local timeout=${2} assert device_exists ${device} assert isinteger timeout isdnctrl huptimeout ${device} ${mode} >/dev/null } function isdn_addphone() { local device=${1} local type=${2} local number=${3} assert device_exists ${device} assert isoneof type in out assert isset number isdnctrl addphone ${device} ${type} ${number} >/dev/null } function isdn_dial() { local device=${1} shift assert device_exists ${device} local mode="persistent" local channels="auto" local ipppd_args while [ $# -gt 0 ]; do case "${1}" in --mode=*) mode=${1#--mode=} ;; --channels=*) channels=${1#--channels=} ;; *) ipppd_args="${ipppd_args} ${1}" ;; esac shift done assert isset channels assert isset mode assert isoneof channels 1 2 auto # Start ippp daemon. ipppd_start ${ipppd_args} case "${mode}" in dialondemand) isdn_set_dialmode ${device} auto ;; persistent) case "${channels}" in auto) ibod_start ${device} ;; 1) # Do nothing. ;; 2) isdn_addlink ${device} ;; esac # Establish the connection immediately. isdnctrl dial ${device} >/dev/null ;; *) log ERROR "Unknown dial mode given: ${mode}." return ${EXIT_ERROR} ;; esac } function isdn_hangup() { local device=${1} assert device_exists ${device} # Bring isdn device down. ip link set ${device} down # Kill ippp daemon. ipppd_stop ${device} } function ipppd_start() { local device=${1} shift assert device_exists ${device} ipppd_write_config ${device} $@ # Actually run the service. service_start "ipppd@${device}.service" } function ipppd_write_config() { local device=${1} shift local value local auth="chap" local user local mppe="on" local mtu="1500" local proxyarp="on" local local_address local remote_address local netmask local dns_servers # mode tells us if we are running in server or # client mode. The collection of variables to # be set depends on this. local mode="client" while [ $# -gt 0 ]; do case "${1}" in --mode=*) mode=${1#--mode=} ;; --auth=*) auth=${1#--auth=} ;; --user=*) user=${1#--user=} ;; --mppe=*) mppe=${1#--mppe=} ;; --mtu=*) mtu=${1#--mtu=} ;; --proxyarp=*) value=${1#--proxyarp=} if enabled value; then proxyarp="on" else proxyarp="off" fi ;; --netmask=*) netmask=${1#--netmask=} ;; --local-address=*) local_address=${1#--local-address=} ;; --remote-address=*) remote_address=${1#--remote-address=} ;; --dns-server=*) value=${1#--dns-server=} # XXX check if this is actually an IP address dns_servers="${dns_servers} ${value}" ;; *) log WARN "Unknown argument given: ${1}" ;; esac shift done # Check if all common variables are correctly set. assert isset mtu assert isinteger mtu case "${mode}" in client) # Check if all variables for client mode are set. assert isset auth assert isset user ;; server) assert isset local_address assert isset remote_address assert isset netmask ;; *) log CRITICAL "Invalid mode given: ${mode}" exit ${EXIT_ERROR} ;; esac # Make a configuration file. local config="$(isdn_config_dir ${device})/config" cat >${config} <>${config} <>${config} < ${config} # Set the device to watch. echo "DEVICE ${device}" >> ${config} # We could set some more options here to # configure when ibod is bringing the second # channel up and down. I guess that is not # required at the moment. # See man ibod.cf. } function ibod_stop() { local device=${1} log INFO "Stopping ibod on device ${device}..." service_stop "ibod@${device}.service" # Remove ibod configuration file. rm -f $(ibod_config_file ${device}) }