#!/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/>.       #
#                                                                             #
###############################################################################

. /usr/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_device_headline ${zone}

	zone_config_read ${zone}

	cli_headline 2 "Configuration:"
	cli_print_fmt1 2 "User" "${USER}"
	cli_print_fmt1 2 "Secret" "<hidden>"
	cli_space

	if device_exists ${zone}; then
		cli_headline  3 "ISDN information:"
		cli_print_fmt1 3 "L2 protocol" "$(isdn_get_l2proto ${zone})"
		cli_print_fmt1 3 "L3 protocol" "$(isdn_get_l3proto ${zone})"
		cli_print_fmt1 3 "Encapsulation" "$(isdn_get_encap ${zone})"
		cli_space
	fi

	# Exit if zone is down
	zone_is_up ${zone} || exit ${EXIT_ERROR}

	# XXX display time since connection started

	cli_headline 2 "Point-to-Point protocol"
	cli_print_fmt1 2 "IP address"  "$(routing_db_get ${zone} local-ip-address)"
	cli_print_fmt1 2 "Gateway"     "$(routing_db_get ${zone} remote-ip-address)"
	cli_print_fmt1 2 "DNS servers" "$(routing_db_get ${zone} dns)"
	cli_space

	exit ${EXIT_OK}
}
