ISDN mit isdn4linux

Grundlagen

Zuerst brauchen wir einen Kernel mit ISDN-Unterstützung. Im ISDN-Subsystem-Menü zur Kernelkonfiguration wählen wir folgendes aus:

[*] ISDN subsystem
[*] Support synchronous PPP
[*] User VJ-compression with synchronous PPP
[*] Support generic MP (RFC 1717)
[m] HiSax SiemensChipSet driver support
[*] HiSax Unterstützung für EURO/DSS1
[*] HiSax Unterstützung für die Niccy PnP/PCI Karte

Alle anderen Optionen können ausgeschaltet werden. Der HiSax-Treiber muß als Modul geladen werden, da wir eine ISA-PnP-Karte haben. Liegt die ISDN-Karte in der PCI-Version vor, so kann der Treiber auch fest in den Kernel eingebaut werden.

 

Im Netzwerkartentreiber-Menü muss noch das PPP-Protokoll aktiviert werden.

*] PPP (point-to-point) support

ISA-PnP-Karten

ISA-PnP-Karten müssen unter Linux per Hand installiert werden. Zuerst führt root folgenden Befehl aus.

krypton:~ # pnpdump > /etc/isapnp.conf
krypton:~ # cat /etc/isapnp.conf
# $Id: pnpdump.c,v 1.19 1999/10/16 15:17:17 fox Exp $
IRQ 0 in use
IRQ 1 in use
IRQ 2 in use
IRQ 4 in use
IRQ 8 in use
IRQ 9 in use
IRQ 13 in use
IRQ 14 in use
IRQ 15 in use
# Trying port address 0273
# Board 1 has serial identifier 51 00 a0 47 75 50 01 81 4c

# (DEBUG)
(READPORT 0x0273)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING

# Card 1: (serial identifier 51 00 a0 47 75 50 01 81 4c)
# Vendor Id SDA0150, Serial Number 10504053, checksum 0x51.
# Version 1.0, Vendor version 0.0
# ANSI string -->ISDN PnP ISA pass. Adaptor DNT2039<--
#
# Logical device id SDA0150
# Device supports I/O range check register
# Device supports vendor reserved register @ 0x38
# Device supports vendor reserved register @ 0x39
# Device supports vendor reserved register @ 0x3b
# Device supports vendor reserved register @ 0x3d
#
# Edit the entries below to uncomment out the configuration required.
# Note that only the first value of any range is given, this may be changed if required
# Don't forget to uncomment the activate (ACT Y) when happy

(CONFIGURE SDA0150/10504053 (LD 0
# Logical device decodes 16 bit IO address lines
# Minimum IO base address 0x0200
# Maximum IO base address 0x03e0
# IO base alignment 2 bytes
# Number of IO addresses required: 2
# (IO 0 (SIZE 2) (BASE 0x0200) (CHECK))
# Logical device decodes 16 bit IO address lines
# Minimum IO base address 0x0200
# Maximum IO base address 0x03e0
# IO base alignment 2 bytes
# Number of IO addresses required: 2
# (IO 1 (SIZE 2) (BASE 0x0200) (CHECK))
# IRQ 3, 4, 5, 9, 10, 11, 12 or 15.
# High true, edge sensitive interrupt
# (INT 0 (IRQ 3 (MODE +E)))
 (NAME "SDA0150/10504053[0]{ISDN PnP ISA pass. Adaptor DNT2039}")
# (ACT Y)
))
# End tag... Checksum 0x00 (OK)

# Returns all cards to the "Wait for Key" state
(WAITFORKEY)

Die Datei /etc/isapnp.conf wird jetzt von Hand bearbeitet. Zuerst wählen wir für IO 0 und IO 1 gültige Werte. Als Interrupt nehmen wir einen noch nicht oben aufgeführten. Zum Schluß entfernen wir das Kommentarzeichen vor (ACT Y).

# (DEBUG)
(READPORT 0x0273)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING

(CONFIGURE SDA0150/10504053 (LD 0
(IO 0 (SIZE 2) (BASE 0x0208))
(IO 1 (SIZE 2) (BASE 0x020A))
(INT 0 (IRQ 11 (MODE +E)))
 (NAME "SDA0150/10504053[0]{ISDN PnP ISA pass. Adaptor DNT2039}")
(ACT Y)
))
(WAITFORKEY)

Nun kann die Karte mit dem Befehl

isapnp /etc/isapnp.conf

aktiviert werden. Eine erfolgreiche Initialisierung sieht in etwa so aus.

krypton:~ # isapnp /etc/isapnp.conf
IRQ 0 in use
IRQ 1 in use
IRQ 2 in use
IRQ 4 in use
IRQ 8 in use
IRQ 9 in use
IRQ 13 in use
IRQ 14 in use
IRQ 15 in use
Board 1 has Identity 51 00 a0 47 75 50 01 81 4c:SDA0150 Serial No 10504053 [checksum 51]
SDA0150/10504053[0]{ISDN PnP ISA pass. Adaptor DNT2039}: Ports 0x208 0x20A; IRQ11 --- Enabled OK

HiSax- und ISDN-Treiber

Der HiSax-Treiber stellt die Verbindung zwischen Hardware und Kernel her. Eine händische Initialisierung läuft folgendermassen ab:

Das (CHECK) bei den IO-Ports sollte man entfernen, wenn es nicht funktioniert. Bei Problemen ist es hilfreich, den Debugmodus einzuschalten, indem man in der Datei die Raute "#" vor (DEBUG) entfernt.

insmod hisax id=Niccy type=24 protocol=2 io0=0x208 io1=0x20A irq=11

#prüfen mit lsmod, ob das Hisax Modul erfolgreich geladen wurde
#sonst schlagen die nachfolgenden Befehle fehl
hisaxctrl Niccy 1 4

#mehr Informationen in den Logfiles
isdnctrl verbose 3

#ISDN-Device einrichten, das sollte keine Fehlermeldung liefern, andernfalls
#ist vorher etwas nicht korrekt verlaufen
isdnctrl addif ippp0

#Nummern festlegen
LOCAL_MSN="110"
#nach wieviel Sekunden Inaktivität aufgelegt werden soll
HUPTIMEOUT="60"
#Anzahl der Wählversuche
DIALMAX="10"
#Wahlmodus
DIALMODE="manual"

isdnctrl eaz        ippp0 $LOCAL_MSN
isdnctrl dialmode   ippp0 $DIALMODE
isdnctrl l2_prot    ippp0 hdlc
isdnctrl l3_prot    ippp0 trans
isdnctrl encap      ippp0 syncppp
isdnctrl secure     ippp0 on
isdnctrl huptimeout ippp0 $HUPTIMEOUT
isdnctrl chargehup  ippp0 off
isdnctrl ihup       ippp0 off
isdnctrl dialmax    ippp0 $DIALMAX
isdnctrl callback   ippp0 off
isdnctrl cbdelay    ippp0 1
isdnctrl cbhup      ippp0 off
isdnctrl addslave   ippp0 ippp1
isdnctrl eaz        ippp1 $LOCAL_MSN
isdnctrl dialmode   ippp1 $DIALMODE
isdnctrl l2_prot    ippp1 hdlc
isdnctrl l3_prot    ippp1 trans
isdnctrl encap      ippp1 syncppp
isdnctrl secure     ippp1 on
isdnctrl huptimeout ippp1 $HUPTIMEOUT
isdnctrl chargehup  ippp1 off
isdnctrl ihup       ippp1 off
isdnctrl dialmax    ippp1 $DIALMAX
isdnctrl callback   ippp1 off
isdnctrl cbdelay    ippp1 1
isdnctrl cbhup      ippp1 off

#Netzinterface bereitstellen
ifconfig ippp0 192.168.0.1 pointopoint 192.168.0.99 up

Für die eigene Konfiguration sind nur noch die MSN, eventuell die Anzahl der Wählversuche anzupassen und dem HiSax-Treiber die richtigen Daten übergeben werden.

 

Sollte das Laden des HiSax-Treibers scheitern, so kann man in den Logfiles nachschauen, wo die Ursache liegt. Damit wäre der hardwarseitige Teil der ISDN-Konfiguration beendet. ISDN bietet aber eine Menge von Zusatzfunktionen, sei es, den Anrufer festzustellen, oder die Rufdauer zu protokollieren. Für all diese Funktionen ist das Programm isdnlog zuständig, dessen Konfiguration in den nächsten Absätzen behandelt werden soll.

Konfiguration

Zuerst legt man wichtige globale Einstellungen fest. Dazu zählen die Länder- und Ortsvorwahl. Anhand dieser Angaben kann isdnlog z.B. unterscheiden, ob es ein Orts- oder Ferngespräch ist und die Gebühren dementsprechend berechnen. Diese Optionen werden in der Datei /etc/isdn/isdn.conf im [GLOBAL]-Block definiert. Die anderen Angaben sollte man möglichst nicht verändern und sind normalerweise sinnvoll vorbelegt.

# exapmle of /etc/isdn/isdn.conf
# copy this file to /etc/isdn/isdn.conf and edit
#
# More information: /usr/doc/packages/i4l/isdnlog/README


[GLOBAL]
COUNTRYPREFIX = +
COUNTRYCODE   = 49
AREAPREFIX    = 0

AREACODE      = 30
AREADIFF      = /usr/lib/isdn/vorwahl.dat

[VARIABLES]

[ISDNLOG]
LOGFILE        = /var/log/isdn.log
ILABEL         = %b %e %T %ICall to tei %t from %N2 on %n2
OLABEL         = %b %e %T %Itei %t calling %N2 with %n2
REPFMTWWW      = "%X %D %17.17H %T %-17.17F %-20.20l SI: %S %9u %U %I %O"
REPFMTSHORT    = "%X%D %8.8H %T %-14.14F%U%I %O"
REPFMT         = "  %X %D %15.15H %T %-15.15F %7u %U %I %O"
CHARGEMAX      = 20.00
RATEFILE       = /usr/lib/isdn/rate-de.dat
RATECONF       = /etc/isdn/rate.conf
HOLIDAYS       = /usr/lib/isdn/holiday-de.dat
COUNTRYFILE    = /usr/lib/isdn/country-de.dat
SPECIALNUMBERS = /usr/lib/isdn/sonderrufnummern.dat
ZONEFILE       = /usr/lib/isdn/zone-de-%s.gdbm

Die Datei /etc/isdn/isdnlog.isdnctrl0.options ist für die erste ISDN-Karte zuständig. Die Einstellungen sind so gewählt, dass die die wichtigen Meldungen protokolliert werden, dass überwacht wird und welche MSN wie lange angerufen wird.

Die Datei /etc/isdn/callerid.conf legt fest, wie auf welche Aktion reagiert werden soll. Isdnlog ist in der Lage, anhand verschiedener Zustände Skripte zu starten. So kann man z.B. bei einem eingehenden Anruf ein Skript aufrufen, dass die Nummer auf dem Monitor ausgibt oder einfach nur speichert, falls man zurückrufen möchte.

Die ersten Blöcke definieren die eigenen Nummern. Pro Nummer sollte ein Block in der Datei auftauchen. Die beiden letzten Blöcke definieren die Zugänge zu zwei Providern. "xxx" und "yyy" müssen durch die Nummern des jeweiligen Anbieters ersetzt werden. Der Alias dient dazu, sie Anrufe bei der Protokollierung zu benennen. SI bedeutet Service-Indikator. Eine 7 steht für ISDN-, eine 1 für Sprachverbindungen.

[MSN]
NUMBER = 110
SI     = 1
ALIAS  = unsere eigene Nummer
ZONE   = 1
START  = {
  [FLAG]
  FLAGS     = IO|CBHR|U
  INTERVALL = 120
  PROGRAM   = /usr/local/sbin/mailme $1 "\$3" "\$20" "\$2" "\$19" "\$6"
}

[MSN]
NUMBER = 112
SI     = 1
ALIAS  = noch eine Nummer von uns
ZONE   = 1
START  = {
  [FLAG]
  FLAGS     = IO|CBHR|U
  INTERVALL = 120
  PROGRAM   = /usr/local/sbin/mailme $1 "\$3" "\$20" "\$2" "\$19" "\$6"
}

[NUMBER]
NUMBER    = Nummer des Providers xxx
ALIAS     = Provider xxx
ZONE      = 1
INTERFACE = ippp0

[NUMBER]
NUMBER    = Nummer des Providers yyy
ALIAS     = Provider yyy
ZONE      = 1
INTERFACE = ippp0

Die Bedeutung des Zonen-Parameters erklärt die Tabelle.

Bedeutung des Zonen-Parameters
Zone Bedeutung
0 Verbindung am internen S0-Bus
1 Ortsgespräch
2 Region 50
3 Region 200
4 Ferngespräch
5 Vis-'a-vis

Die Bedeutung des Flags entnimmt man der folgenden Tabelle. Anhand der gesetzten Flags kann man entscheiden, was passieren soll. Die Sektionen sind durch das Pipesymbol "|" getrennt.

Bedeutung des FLAGS-Parameters Sektion 1
Flag (Sektion 1) Bedeutung
I Eingehender Ruf
O Ausgehender Ruf
Bedeutung des FLAGS-Parameters Sektion 2
Flag (Sektion 2) Bedeutung
A Zeitsignal erkannt
B Anschluß ist besetzt
C angerufene Person nimmt ab
E Fehler
H Teilnehmer legt auf
R Telefon klingelt
Bedeutung des FLAGS-Parameters Sektion 3
Flag (Sektion 3) Bedeutung
K stoppe das Programm nach dem Ende des Intervalls
L starte das Programm neu, sobald es beendet wurde
U starte das Programm nur einmal im Intervall

Dem aufgerufenen Skript gibt isdnlog diverse Parameter mit, deren Bedeutung die folgende Tabelle erläutert.

Bedeutung der Skriptparameter
Skript-Parameter Bedeutung
\$1 enthält die ersten beiden Sektionen des Flags
\$2 komplette Nummer des Anrufers (mit Vorwahl)
\$3 komplette Nummer des Angerufenen (mit Vorwahl)
\$4 Startzeit des Gesprächs (nicht verfügbar bei RING)
\$5 bisherige Dauer des Gesprächs
\$6 Zeitpunkt, wann das Gesprächs beendet wurde
\$7 Anzahl der eingegangenen Bytes
\$8 Anzahl der gesendeten Bytes
\$9 eingegangenen Bytes pro Sekunde
\$9 eingegangenen Bytes pro Sekunde
\$10 ausgehende Bytes pro Sekunde
\$11 Service Indikator
\$12 Entgelt
\$13 Ländercode des Anrufers
\$14 Ländercode des Angerufenen
\$15 Areacode des Anrufers
\$16 Areacode des Angerufenen
\$17 Stadt des Anrufers
\$18 Stadt des Angerufenen
\$19 Alias des Anrufers
\$20 Alias des Angerufenen

Beispielhaft ist noch das Skript /usr/local/sbin/mailme angeführt, was anhand der verschiedenen Zustände Nachrichten an den Admin sendet. Als Gerüst für eigene Experimente ist es sicherlich gut zu gebrauchen.

#!/bin/sh

case "$1" in
IR)     Header="`date`: $4 ruft $2 ($3) an, läutet"
        ;;
IC)     Header="`date`: $4 ruft $2 ($3) an, abgenommen"
        ;;
IH)     Header="`date`: $4 ruft $2 ($3) an, aufgelegt"
        ;;
OR)     Header="`date`: $2 ($3) ruft $4 an, läutet"
        ;;
OC)     Header="`date`: $2 ($3) ruft $4 an, abgenommen"
        ;;
OR)     Header="`date`: $2 ($3) ruft $4 an, beendet, Dauer=$5"
        ;;
*)      Header="`date`: unbekannt, $1 $2 $3 $4 $5 $6"
        ;;
esac

/bin/echo "." | /usr/bin/mail -s "$Header" root@localhost

Nachdem die Konfiguration abgeschlossen ist, kann man den isdnlog starten, und prüfen, ob alles wie gewünscht funktioniert. Man findet zusätzliche Hinweise in /var/log/isdn.log bzw. in der dem i4l-Paket beiliegenden Dokumentation.

isdnlog -f /etc/isdn/isdnlog.isdnctrl0.options /dev/isdnctrl0

Nun fehlt nur noch die Konfiguration des ipppd-Dämons. Er ist u.a. für die Einwahl und die Authentifizierung beim Provider zuständig. Wir haben hier zwei Provider, und verwalten deshalb zwei Konfigurationsdateien. Welche Konfigurationsdatei dem ipppd übergeben wird, hängt davon ob, welchen Provider wir benutzen möchten. Hier ist nun die Optionsdatei für Provider 1.

/dev/ippp0 /dev/ippp1
+mp

ipcp-accept-local
ipcp-accept-remote
noipdefault
mru 1524
mtu 1500

-ac
-pc
noccp

user "laas"

Die ersten beiden Zeilen geben an, dass wir eventuell Kanalbündelung benutzen wollen. Die Einstellungen im zweiten Block sollte man nicht verändern. Die Bedeutung ist in der Manualpage zu ipppd nachzulesen. Der letzte Block schaltet die Adress/Control compression, die Protocol-Field compression und das CCP (keine Ahnung, was das ist) ab. Da Provider1 VanJacobson-Header, VanJacobson Connection-ID, Predictor-1 und BSD compression unterstützt, lassen wir diese aktiviert. Zu allerletzt wird der Nutzer spezifiziert, mit dem wir uns beim Provider anmelden möchten. Für jeden Nutzer muss in der /etc/ppp/pap-secret ein Eintrag der folgenden Form vorhanden sein, wobei "xxx" durch das entsprechende Passwort ausgetauscht werden muss.

laas * "xxx"

Provider2 nutzt zur Authentifizierung das CHAP-Protokoll zur Authentifizierung. Deshalb wird der Login mit name angegeben und in die Datei /etc/ppp/chap-secret der Login und das Passwort eingetragen. Das Format der Einträge ist identisch mit denen in /etc/ppp/pap-secret, weshalb man bequemerweise die beiden verlinkt und die Daten in nur einer Datei verwaltet.

/dev/ippp0 /dev/ippp1
+mp

ipcp-accept-local
ipcp-accept-remote
noipdefault
mru 296
mtu 296

# disable all header-compression
-vj
-vjccomp
-ac
-pc
-bsdcomp
noccp

name "UserProvider2"

passive
#lcp-restart 2

Hierbei fällt auf, dass die mru- und die mtu-Werte sehr gering sind. Die Verbindung zum Provider2 ist nicht sehr gut, weshalb wir die Paketlänge, die gesendet und empfangen wird, verkleinern. Zusätzlich haben wir den passiven Modus gewählt, so dass der ipppd wartet, bis er eine IP-Adresse vom Provider zugewiesen bekommt. Beide Provider arbeiten mit dynamischen IP-Adressen.

Einwahl

Die Einwahl wird bei mir über ein Web-Interface passieren. Trotzdem möchte ich hierzu noch die händische Variante vorstellen. Nach Auswahl des Providers wird der ipppd mit den entprechenden Optionen gestartet, danach wird die Einwahlnummer des Providers gesetzt und die Einwahl initiiert.

ipppd /etc/ppp/ioptions.ippp0_provider1
isdnctrl addphone ippp0 out <Einwahlnummer>
isdnctrl dial ippp0

Nach erfolgreicher Einwahl wird das Skript /etc/ppp/ip-up aufgerufen. Dieses Skript dient in der Regel dazu, die IP-Adresse zu setzen, DNS Server einzutragen usw. Wir werden in diesem Skript u.a. den Mailversand und -empfang starten. Mehr dazu in einem späteren Kapitel.

Kanalbündelung

ISDN bietet die Möglichkeit, beide Kanäle zusammen zu schalten, um somit höhere Geschwindigkeit zu erreichen. Vorraussetzung ist, dass der erste Kanal bereits online ist, und das der 2. Kanal nicht belegt ist, z.B. durch ein Telefonat.

isdnctrl addlink ippp0
isdnctrl dial ippp1