From: Michael Tremer Date: Sat, 12 Nov 2011 16:04:37 +0000 (+0000) Subject: isdn: Initial commit of ISDN code. X-Git-Tag: 004~86^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6402343833acd8aa04872c4e4cb6de1530c435b;p=network.git isdn: Initial commit of ISDN code. This may be quite non-function but gives a limited way to create an ISDN dialup connection. It's to be decided if we will support that in future. --- diff --git a/functions.isdn b/functions.isdn new file mode 100644 index 00000000..673d9ccc --- /dev/null +++ b/functions.isdn @@ -0,0 +1,434 @@ +#!/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=${device} + shift + + assert device_exists ${device} + + ipppd_write_config ${device} $@ + + # Actually run the service. + service_start "ipppd@${device}" +} + +function ipppd_write_config() { + local device=${1} + shift + + local auth="chap" + local user + local mppe="on" + local mtu="1500" + + while [ $# -gt 0 ]; do + case "${1}" in + --auth=*) + auth=${1#--auth=} + ;; + --user=*) + user=${1#--user=} + ;; + --mppe=*) + mppe=${1#--mppe=} + ;; + --mtu=*) + mtu=${1#--mtu=} + ;; + *) + log WARN "Unknown argument given: ${1}" + ;; + esac + shift + done + + assert isset auth + assert isinteger mtu + + local config="$(isdn_config_dir ${device})/config" + + cat >${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}" + + # Remove ibod configuration file. + rm -f $(ibod_config_file ${device}) +} diff --git a/hooks/zones/isdn b/hooks/zones/isdn new file mode 100755 index 00000000..82d066fb --- /dev/null +++ b/hooks/zones/isdn @@ -0,0 +1,218 @@ +#!/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 + +HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MSN MTU" +HOOK_SETTINGS="${HOOK_SETTINGS} L2PROTO L3PROTO ENCAP PHONE" + +AUTH= +CHANNELS="auto" +DEFAULTROUTE=1 +ENCAP="syncppp" +L2PROTO="hdlc" +L3PROTO="trans" +LINKNAME="$(uuid)" +MSN= +MTU=1500 +PEERDNS=1 +TIMEOUT=10 +SECRET= +USER= +PHONE= + +MODE="persistent" + +ISDN_ALLOWED_AUTHS="chap pap" + +function _check() { + assert isset USER + assert isset SECRET + assert isset LINKNAME + assert isset DEFAULTROUTE + assert isset PEERDNS + assert isset TIMEOUT + assert isset PHONE + + assert isbool DEFAULTROUTE + assert isbool PEERDNS + assert isinteger MSN + assert isinteger TIMEOUT + + isset AUTH && assert isoneof AUTH ${ISDN_ALLOWED_AUTHS} +} + +function _parse_cmdline() { + local value + + while [ $# -gt 0 ]; do + case "$1" in + --user=*) + USER=${1#--user=} + ;; + --secret=*) + SECRET=${1#--secret=} + ;; + --linkname=*) + LINKNAME=${1#--name=} + ;; + --mtu=*) + MTU=${1#--mtu=} + ;; + --defaultroute=*) + value=${1#--defaultroute=} + if enabled value; then + DEFAULTROUTE=1 + else + DEFAULTROUTE=0 + fi + ;; + --dns=*) + value=${1#--dns=} + if enabled value; then + PEERDNS=1 + else + PEERDNS=0 + fi + ;; + --auth=*) + AUTH=${1#--auth=} + ;; + --device=*) + DEVICE=${1#--device=} + ;; + --msn=*) + MSN=${1#--msn=} + ;; + --timeout=*) + TIMEOUT=${1#--timeout=} + ;; + --phone=*) + PHONE="${PHONE} ${1#--phone=}" + ;; + *) + echo "Unknown option: $1" >&2 + exit ${EXIT_ERROR} + ;; + esac + shift + done +} + +function _up() { + local zone=${1} + shift + + assert isset zone + + zone_config_read ${zone} + + assert [ -e "/dev/${DEVICE}" ] + + # Creating necessary files + # XXX must be PPP_RUN + [ -d "${RED_RUN}/${LINKNAME}" ] || mkdir -p ${RED_RUN}/${LINKNAME} + + # Create device node. + isdn_create_device ${zone} + + # Apply configuration to the ISDN stack. + isdn_set_l2proto ${zone} ${L2PROTO} + isdn_set_l3proto ${zone} ${L3PROTO} + isdn_set_encap ${zone} ${ENCAP} + + isdn_set_eaz ${zone} ${MSN} + isdn_set_huptimeout ${zone} $(( ${TIMEOUT} * 60 )) + isdn_addphone ${zone} out ${PHONE} + + # Updating PPP credentials. + ppp_secret "${USER}" "${SECRET}" + + # Bring up connection. + isdn_dial ${zone} \ + --mode=${MODE} \ + --channels=${CHANNELS} \ + --user=${USER} \ + --mtu=${MTU} + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + shift + + # Bring down ISDN interface. + isdn_hangup ${zone} + + # Remove ISDN device. + isdn_remove_device ${zone} + + exit ${EXIT_OK} +} + +function _status() { + local zone=${1} + + assert isset zone + + cli_status_headline ${zone} + + zone_config_read ${zone} + + cli_headline " Configuration:" + printf "${DEVICE_PRINT_LINE1}" "User:" "${USER}" + printf "${DEVICE_PRINT_LINE1}" "Secret:" "" + echo + printf "${DEVICE_PRINT_LINE1}" "MTU:" "${MTU}" + printf "${DEVICE_PRINT_LINE1}" "Use default route?" "$(enabled DEFAULTROUTE && echo "enabled" || echo "disabled")" + printf "${DEVICE_PRINT_LINE1}" "Use peer DNS?" "$(enabled PEERDNS && echo "enabled" || echo "disabled")" + echo + + if device_exists ${zone}; then + cli_headline " ISDN information:" + printf "${DEVICE_PRINT_LINE1}" "L2 protocol:" "$(isdn_get_l2proto ${zone})" + printf "${DEVICE_PRINT_LINE1}" "L3 protocol:" "$(isdn_get_l3proto ${zone})" + printf "${DEVICE_PRINT_LINE1}" "Encapsulation:" "$(isdn_get_encap ${zone})" + echo + fi + + # Exit if zone is down + if ! zone_is_up ${zone}; then + echo # Empty line + exit ${EXIT_ERROR} + fi + + # XXX display time since connection started + + cli_headline " Point-to-Point-over-Ethernet protocol:" + echo " IP-Address : $(routing_db_get ${zone} local-ip-address)" + echo " Gateway : $(routing_db_get ${zone} remote-ip-address)" + echo " DNS-Server : $(routing_db_get ${zone} dns)" + echo + echo " MAC-Remote : $(routing_db_get ${zone} remote-address)" + echo + echo " MTU : $(device_get_mtu ${zone})" + echo # Empty line + exit ${EXIT_OK} +} + +run $@