]> git.ipfire.org Git - people/stevee/network.git/commitdiff
isdn: Initial commit of ISDN code.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 12 Nov 2011 16:04:37 +0000 (16:04 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 12 Nov 2011 16:04:37 +0000 (16:04 +0000)
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.

functions.isdn [new file with mode: 0644]
hooks/zones/isdn [new file with mode: 0755]

diff --git a/functions.isdn b/functions.isdn
new file mode 100644 (file)
index 0000000..673d9cc
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+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} <<EOF
+# XXX find a solution for this
+/dev/${device}
+
+# Authentication
+user ${user}
++${auth}
+
+# Get remote DNS servers
+ms-get-dns
+
+# Link properties
+mru ${mtu}
+mtu ${mtu}
+
+lock
+noipdefault
+
+# Disable compression
+-vj -vjccomp
+
+debug
+EOF
+}
+
+function ipppd_stop() {
+       local device=${1}
+
+       # Stop service.
+       service_stop "ipppd@${device}"
+
+       # Remove configuration file.
+       rm -f $(isdn_config_dir ${device})/config
+}
+
+function ibod_start() {
+       local device=${1}
+
+       assert device_exists ${device}
+
+       # Create ibod configuration file first.
+       ibod_write_config $@
+
+       # Start the daemon.
+       log INFO "Starting ibod service on device ${device}."
+       service_start "ibod@${device}"
+}
+
+function ibod_config_file() {
+       assert [ -n "$@" ]
+
+       echo "$(isdn_config_dir $@)/ibod.cf"
+}
+
+function ibod_write_config() {
+       local device=${1}
+
+       log DEBUG "Writing ibod.cf for device ${device}."
+
+       # Create path to configuration file.
+       local config=$(ibod_config_file ${device})
+
+       # Empty configuration file.
+       : > ${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 (executable)
index 0000000..82d066f
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+. /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:" "<hidden>"
+       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 $@