#!/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
# Modems support all authentication methods, that pppd does support.
MODEM_ALLOWED_AUTH_METHODS="${PPP_ALLOWED_AUTH_METHODS}"
HOOK_SETTINGS="HOOK"
# Access Point Name.
APN=
HOOK_SETTINGS="${HOOK_SETTINGS} APN"
# Sets the authentication algortihm that must be used.
AUTH=
HOOK_SETTINGS="${HOOK_SETTINGS} AUTH"
# Baudrate.
BAUDRATE=921600
HOOK_SETTINGS="${HOOK_SETTINGS} BAUDRATE"
# The device name of the serial device.
# XXX how can we make sure that this does not change all the time?
DEVICE=
HOOK_SETTINGS="${HOOK_SETTINGS} DEVICE"
# A monitor device.
# Send AT commands to this device, when the primary device is
# connected.
MONITOR_DEVICE=
HOOK_SETTINGS="${HOOK_SETTINGS} MONITOR_DEVICE"
# Maximum transmission unit.
MTU=1492
HOOK_SETTINGS="${HOOK_SETTINGS} MTU"
# User credentials.
USERNAME=
PASSWORD=
HOOK_SETTINGS="${HOOK_SETTINGS} USERNAME PASSWORD"
# PIN code.
PIN=
HOOK_SETTINGS="${HOOK_SETTINGS} PIN"
# Phone number.
PHONE_NUMBER=
HOOK_SETTINGS="${HOOK_SETTINGS} PHONE_NUMBER"
# IMSI
IMSI=
HOOK_SETTINGS="${HOOK_SETTINGS} IMSI"
function hook_check() {
assert isset DEVICE
assert isset PHONE_NUMBER
# Make sure the PIN code is an integer, when set.
if isset PIN; then
assert isinteger PIN
assert [ ${#PIN} -ge 4 ]
assert [ ${#PIN} -le 8 ]
fi
assert isoneof BAUDRATE ${SERIAL_BAUDRATES}
isset AUTH && assert isoneof AUTH ${MODEM_ALLOWED_AUTH_METHODS}
}
function hook_parse_cmdline() {
local value
while [ $# -gt 0 ]; do
case "${1}" in
--apn=*)
APN=$(cli_get_val ${1})
;;
--auth=*)
AUTH=$(cli_get_val ${1})
;;
--baudrate=*)
BAUDRATE=$(cli_get_val ${1})
assert isoneif "${BAUDRATE}" ${SERIAL_BAUDRATES}
;;
--device=*)
DEVICE=$(cli_get_val ${1})
;;
--imsi=*)
IMSI="$(cli_get_val "${1}")"
;;
--monitor-device=*)
MONITOR_DEVICE=$(cli_get_val ${1})
;;
--mtu=*)
MTU=$(cli_get_val ${1})
assert isinteger ${MTU}
;;
--password=*)
PASSWORD=$(cli_get_val ${1})
;;
--phone-number=*)
PHONE_NUMBER=$(cli_get_val ${1})
;;
--pin=*)
PIN=$(cli_get_val ${1})
;;
--username=*)
USERNAME=$(cli_get_val ${1})
;;
*)
echo "Unknown argument: ${1}" >&2
exit ${EXIT_ERROR}
;;
esac
shift
done
}
function hook_up() {
local zone=${1}
assert isset zone
# Load configuration file.
zone_config_read ${zone}
# If we have got a PIN, we try to unlock the device first.
if isset PIN; then
if ! modem_sim_auto_unlock "${DEVICE}" "${PIN}"; then
# Reset the PIN setting.
PIN=""
config_write $(zone_dir ${zone})/settings ${HOOK_SETTINGS}
error "Could not unlock the SIM card. Removing PIN from settings."
fi
# For mobile devices, check if a PIN is required although none is set.
elif modem_is_mobile ${DEVICE} && modem_sim_locked ${DEVICE}; then
error "The SIM card is locked. Please configure the PIN code."
exit ${EXIT_ERROR}
fi
# Start the PPP daemon.
pppd_start ${zone}
exit ${EXIT_OK}
}
function hook_down() {
local zone=${1}
assert isset zone
# Stop the PPP daemon.
pppd_stop ${zone}
exit ${EXIT_OK}
}
function hook_status() {
local zone=${1}
assert isset zone
cli_device_headline ${zone}
zone_config_read ${zone}
cli_headline 2 "Configuration"
cli_print_fmt1 2 "Username" "${USERNAME}"
cli_print_fmt1 2 "Password" ""
cli_space
cli_headline 2 "Device settings"
cli_print_fmt1 2 "Device" "${DEVICE}"
if isset MONITOR_DEVICE; then
cli_print_fmt1 2 "Monitor device" "${MONITOR_DEVICE}"
fi
cli_print_fmt1 2 "Baudrate" "${BAUDRATE}"
cli_print_fmt1 2 "MTU/MRU" "${MTU}"
cli_space
# Exit if zone is down
if ! zone_is_up ${zone}; then
echo # Empty line
exit ${EXIT_ERROR}
fi
cli_headline 2 "Carrier network"
# If the device and the monitor device are both locked,
# we cannot show any carrier information.
local device dev
for dev in ${DEVICE} ${MONITOR_DEVICE}; do
if ! serial_exists ${dev}; then
continue
fi
if serial_is_locked ${dev}; then
continue
fi
device=${dev}
done
if isset device; then
cli_print_fmt1 2 "Operator" \
"$(modem_get_network_operator ${device})"
cli_print_fmt1 2 "SIM IMSI" \
"$(modem_get_sim_imsi ${device})"
cli_print_fmt1 2 "Mode" \
"$(modem_get_network_mode ${device})"
cli_print_fmt1 2 "Signal strength" \
"$(modem_get_signal_quality ${device}) dBm"
local ber=$(modem_get_bit_error_rate ${device})
isset ber || ber="unknown"
cli_print_fmt1 2 "Bit error rate" "${ber}"
else
cli_print 2 "Device is locked."
fi
cli_space
# XXX display time since connection started
cli_headline 2 "Point-to-Point-over-Ethernet protocol"
local proto
for proto in ${IP_SUPPORTED_PROTOCOLS}; do
routing_db_exists ${zone} ${proto} || continue
local headline
case "${proto}" in
ipv6)
headline="Internet Protocol Version 6"
;;
ipv4)
headline="Internet Protocol Version 4"
;;
*)
headline="Unkown protocol"
;;
esac
cli_headline 3 "${headline}"
cli_print_fmt1 3 "IP address" "$(routing_db_get ${zone} ${proto} local-ip-address)"
cli_print_fmt1 3 "Gateway" "$(routing_db_get ${zone} ${proto} remote-ip-address)"
cli_print_fmt1 3 "DNS servers" "$(routing_db_get ${zone} ${proto} dns)"
cli_space
done
exit ${EXIT_OK}
}
function hook_ppp_write_config() {
local zone=${1}
assert isset zone
local file=${2}
assert isset file
# Read in the configuration files.
zone_config_read ${zone}
pppd_write_config ${file} \
--interface="${zone}" \
--username="${USERNAME}" \
--password="${PASSWORD}" \
--mtu="${MTU}" \
--auth="${AUTH}" \
\
--serial="true" \
--serial-device="${DEVICE}" \
--baudrate="${BAUDRATE}" \
--connect-command="/usr/lib/network/dialer ${zone}"
exit ${EXIT_OK}
}