]> git.ipfire.org Git - network.git/commitdiff
Create a basic version of an ISDN dial-in server. isdn
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 16 Dec 2011 23:48:39 +0000 (23:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 16 Dec 2011 23:48:39 +0000 (23:48 +0000)
There is more work needed on the error checking and
the feature did not get very much testing, yet.

functions.auth [new file with mode: 0644]
functions.ipv4
functions.isdn
hooks/zones/isdn-server [new file with mode: 0755]

diff --git a/functions.auth b/functions.auth
new file mode 100644 (file)
index 0000000..5f1742a
--- /dev/null
@@ -0,0 +1,30 @@
+#!/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/>.       #
+#                                                                             #
+###############################################################################
+
+# A list of all supported authentications methods:
+
+#  PPP daemon:
+PPP_ALLOWED_AUTHS="chap pap"
+
+#  ISDN/ippp daemon:
+ISDN_ALLOWED_AUTHS="${PPP_ALLOWED_AUTHS}"
+
+# XXX ADD MODEM AND PPPOE ALLOWED AUTHS
index d074ca940ab35408876d6be8e446d445b5ec20a3..65cdcf7370315aac06761da89303051e2a366ab6 100644 (file)
@@ -42,6 +42,9 @@ function ipv4_detect_duplicate() {
        assert isset device
        assert device_exists ${device}
 
+       # Don't check on PPP devices.
+       device_is_ppp ${device} && return ${EXIT_ERROR}
+
        if ! arping -q -c 2 -w 3 -D -I ${device} ${address}; then
                log DEBUG "Detected duplicate address '${address}' on device '${device}'."
                return ${EXIT_OK}
@@ -54,6 +57,9 @@ function ipv4_update_neighbours() {
        local device=${1}
        local address=${2}
 
+       # Don't do anything on PPP devices.
+       device_is_ppp ${device} && return ${EXIT_OK}
+
        arping -q -A -c 1 -I ${device} ${address}
        ( sleep 2; arping -q -U -c 1 -I ${device} ${address} ) >/dev/null 2>&1 </dev/null &
 }
@@ -73,3 +79,21 @@ function ipv4_get_netaddress() {
 
        return ${EXIT_OK}
 }
+
+function ipv4_prefix2netmask() {
+       local prefix=${1}
+       shift
+
+       assert isinteger prefix
+
+       # XXX this function is a stub
+
+       case "${prefix}" in
+               24)
+                       echo "255.255.255.0"
+                       ;;
+               *)
+                       assert false NOT IMPLEMENTED
+                       ;;
+       esac
+}
index 673d9ccc71f2d6c0290c1705a998be8687d8538a..e8f3d417af0f3ad625aa826b984fae3994200fc1 100644 (file)
@@ -302,7 +302,7 @@ function isdn_hangup() {
 }
 
 function ipppd_start() {
-       local device=${device}
+       local device=${1}
        shift
 
        assert device_exists ${device}
@@ -317,13 +317,27 @@ 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=}
                                ;;
@@ -336,6 +350,29 @@ function ipppd_write_config() {
                        --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}"
                                ;;
@@ -343,21 +380,38 @@ function ipppd_write_config() {
                shift
        done
 
-       assert isset auth
+       # 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} <<EOF
+### Common section
+
 # XXX find a solution for this
 /dev/${device}
 
-# Authentication
-user ${user}
-+${auth}
-
-# Get remote DNS servers
-ms-get-dns
+# Never change the default route
+-defaultroute
 
 # Link properties
 mru ${mtu}
@@ -370,7 +424,38 @@ noipdefault
 -vj -vjccomp
 
 debug
+
 EOF
+
+       case "${mode}" in
+               client)
+                       cat >>${config} <<EOF
+### Client section
+
+# Authentication
+user ${user}
++${auth}
+
+# Get remote DNS servers
+ms-get-dns
+
+EOF
+                       ;;
+
+
+               server)
+                       cat >>${config} <<EOF
+### Server section
+
+${local_address}:${remote_address}
+netmask ${netmask}
+
+# Add DNS servers
+$(for value in ${dns_servers}; do echo "ms-dns ${value}"; done)
+
+EOF
+                       ;;
+       esac
 }
 
 function ipppd_stop() {
diff --git a/hooks/zones/isdn-server b/hooks/zones/isdn-server
new file mode 100755 (executable)
index 0000000..b8691e1
--- /dev/null
@@ -0,0 +1,234 @@
+#!/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 LOCAL_ADDRESS REMOTE_ADDRESS MSN MTU MRU"
+HOOK_SETTINGS="${HOOK_SETTINGS} L2PROTO L3PROTO ENCAP"
+
+# The peer address of the ISDN server.
+LOCAL_ADDRESS=
+REMOTE_ADDRESS=
+
+AUTH=
+ENCAP="syncppp"
+L2PROTO="hdlc"
+L3PROTO="trans"
+LINKNAME="$(uuid)"
+MSN=
+MTU=1500
+TIMEOUT=10
+
+MODE="persistent"
+
+function _check() {
+       assert isset LOCAL_ADDRESS
+       assert isset REMOTE_ADDRESS
+
+       assert isset LINKNAME
+       assert isset TIMEOUT
+
+       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
+                       --local-address=*)
+                               LOCAL_ADDRESS=${1#--local-address=}
+                               ;;
+                       --remote-address=*)
+                               REMOTE_ADDRESS=${1#--remote-address=}
+                               ;;
+                       --subnet=*)
+                               SUBNET=${1#--subnet=}
+                               ;;
+                       --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 ))
+
+       # Set our ip address.
+       ip_address_add ${zone} ${LOCAL_ADDRESS}
+       device_set_up ${zone}
+
+       # Start ipppd in server mode and make it listening for
+       # incoming connections:
+       local options
+
+       # Get a list of all DNS servers.
+       local dns_server
+       for dns_server in ${dns_servers}; do
+               options="${options} --dns-server=${dns_server}"
+       done
+
+       # Convert netmask.
+       local prefix=$(ip_get_prefix ${LOCAL_ADDRESS})
+       local netmask=$(ipv4_prefix2netmask ${prefix})
+
+       # Split prefix from LOCAL_ADDRESS.
+       local local_address=$(ip_split_prefix ${LOCAL_ADDRESS})
+
+       ipppd_start ${zone} \
+               --mode="server" \
+               --local-address="${local_address}" \
+               --remote-address="${REMOTE_ADDRESS}" \
+               --netmask="${netmask}" \
+               --mtu=${MTU} \
+               ${options}
+
+       exit ${EXIT_OK}
+}
+
+function _down() {
+       local zone=${1}
+       shift
+
+       # Kill ipppd service.
+       ipppd_stop ${zone}
+
+       # Bring down ISDN interface.
+       device_set_down ${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 $@