Linux
Installation and Configuration


The Kernel

Once upon a time there was the 1.2.13 kernel, which was included in the most distributions. This kernel did a goodjob for i4l, when no ISDN drivers existed in the kernel code, but the development stopped at version 0.7.3beta. So i4l users mostly used kernels younger than 1.3.68, the so-called "hacker kernels".

These days you should take a kernel version 1.3.97 or younger (there are kernel internal drivers available since kernel 1.3.69, but this thing only is stable enough since 1.3.97).

Now, while kernel 2.0 is released, we will talk about this kernel. Nowadays it is recommended to use kernel version 2.0.27, which cooperates flawlessly with isdn4k-utils-2.0. You should look for the kernel at your SunSite, e.g. at

  ftp.leo.org/pub/comp/os/linux/Linus/v2.0/
(e.g. linux-2.0.27.tar.gz; this kernel runs at the author's machine since months without any problems). And you also should fetch the new modules package:
  ftp.leo.org/pub/comp/os/linux/Linus/v2.0/modules-2.0.0.tar.gz
Handle the kernel as you are used to - have a look at the kernel-HOWTO:
  ftp.leo.org/pub/comp/os/linux/sunsite/docs/HOWTO/Kernel-HOWTO.gz
You should decompree your modules and install them as described in the Kernel-HOWTO.

If you want to use isdn4linux to drive an ISDN card you don't need to apply any more a patch to this kernel (only kernel 2.0.0 needed the two patches isdn4kernel-2.0-patch1+2). But: Most passive ISDN cards with Siemens chip set (Teles, Creatix, AVM, Elsa, ...) only work, if you use the driver package "HiSax". If you run such a card you must fetch this driver, too, and put it into/usr/src:

  ftp.franken.de/pub/isdn4linux/HiSax/
(e.g. version 1.5; read the README to learn which cards are supported!) Now patch it into the kernel:
  root:# cd /usr/src
  root:# tar zxfv HiSax_1.5.patch_for_2.0.tar.gz
  root:# patch -p <HiSax_1.5.patch_for_2.0
  root:# _
You must set now the following items while "make config" or its graphical relatives "make menuconfig" or "make xconfig" to compile the kernel:
Code maturity level options":
  Prompt for development and/or incomplete code/drivers: No
Section "General Setup":
  Networking support: Yes
Section "Networking options":
  TCP/IP networking: Yes
  all other items are up to you
Section "Network device support":
  Network device support: Yes
  PPP (point-to-point) support: Yes  
  all other items are up to you
Section "ISDN subsystem":
  Only if you need isdn4linux:
  ISDN support: Yes
  Support synchronous PPP: Yes (!)
  Use VJ compression with synchronous PPP: Yes
  Support audio via ISDN: Yes
  Support generic MP (RFC 1717): Yes
  Mark your own PC card here, too.
If this kernel later works properly you could think about defining some of the parts of it to modules instead of using a monolithic kernel.

ISDN Card Driver Software

If you only want to use a modem (analogous modem or ISDN modem) you may skip this section.

If you want to drive an ISDN card you also need the current version of Fritz Elfert's "isdn4kernel utilities". If you have an older version of isdn4linux you must update: the command "isdnctrl pppbind" must exist! Find out - type in isdnctrl and have a look at the available options.

  ftp.franken.de/pub/isdn4linux/isdn4k-utils-2.0.tar.gz
Put it into the /usr/src directory and unpack it by "tar zxfv isdn4k-utils-2.0.tar.gz". Now in the directory
  /usr/src/isdn4k-utils-2.0
you find all the files you need to operate i4l. Some Linux distributions lack of some important links, so you need to change some of the make files. These make files are all in the subdirectory tools. /usr/src/isdn4k-utils-2.0/tools/Makefile remove "isdnbutton-1.1" in the following line, if you don't have Motif - or you will get compiler errors. SUBDIRS=imon imontty-0.3 isdnlog-2.41 isdnbutton-1.1 tcltk [...] /usr/src/isdn4k-utils-2.0/tools/imontty-0.3/Makefile [...] LDFLAGS=-lncurses -lm [...] /usr/src/isdn4k-utils-2.0/tools/isdnlog-2.41/Makefile [...] LIB = -lgdbm [...] At first the programs need to be built. Therefore go into the /usr/src/isdn4k-utils-2.0 directory, compile it by typing in "make", create the ISDN device files by "make devices" and finally install all executables by "make install" in the /sbin directory (also the man pages where they need to be).

You also need to define the card parameters - please read the ISDN4Linux manual

  /usr/src/linux/Documentation/isdn/README
These parameters will be set while booting or while loading the i4l modules.

Configuration

Hint:
There are some large script files following. They are downloadable within this tutorial package - just click onto the script headlines!
Remark for readers who are familiar with my tutorial:
The scripts have changed heavily. There is no longer a command isdn, all things are now handled by a script package named connect. This package can handle now modems, too!

Configuration files

Two central files are used for setup and maintaining connections: The first one is called while machine boot-up, it lays in the startup directory and is named rc.connect. The other one is connect and is responsible for establishing and deleting connections and more.

Eine Reihe weiterer Dateien müssen angelegt werden. So ist für jeden Provider je eine Datei pro Einwahl-Telefonnummer herzustellen, in der alle wichtigen Daten enthalten sind. Die PPP-Dämonen benötigen überdies ein paar weitere Dateien. Das werden wir nun der Reihe nach besprechen.

There are also some more files necessary. So you need one file per provider and per dial-in number. And the PPP daemons need some more files, too. We will discuss this now.

If you did load down this WWW pages as package "leafsite.tar.gz", you find the scripts in the subdirectory "scripts".

Some Pre Work

If you have used the old "isdn" package before, stop the isdn system using
    root:# <startup_path>/i4l stop (or "rc.isdn stop" or whatever)
    root:# _
  
(<startup_path> is the path, where all the system bootup files are located).

Then remove (or save, if you like) some old files:

    root:# rm <startup_path>/i4l (if you use a newer SuSE distribution)
    root:# rm <startup_path>/rc.isdn
    root:# rm /sbin/isdn
    root:# rm /etc/i4l.provider (or /etc/i4l.config, if older "isdn" version)
    root:# rm /etc/i4l.secrets  (or /etc/i4l.param, if older "isdn" version)
    root:# _
  
You have to create some directories for the beginning:
  root:# mkdir /usr/lib/connect
  root:# mkdir /usr/lib/connect/providers
  root:# mkdir /var/lib/connect
  root:# _

Provider Data

In /usr/lib/connect/providers for each provider and each dial-in number is needed. Files for isdn4linux and for modems look slightly different. Here some cutted examples - you can load down some examples, containing more explanations. Name these files as you like, but don't use a connect keyword (on, off, status, help, maxtries, route, device, all).

Beispiel für eine isdn4linux-Datei

  #!/bin/bash
  MODE=i4l
  PHONE=0891234567
  IP_ADDRESS=123.234.210.109
  OPTIONS_FILE=/etc/ppp/options.ipppd
Beispiel für eine Modem-Datei
  #!/bin/bash
  MODE=modem
  IP_ADDRESS=234.123.134.56
  DEVICE=ttyS1
  OPTIONS_FILE=/etc/ppp/options.pppd
  CHAT_SCRIPT="ABORT BUSY ABORT 'NO CARRIER' '' ATZ0 OK ATD0,08912345 CONNECT"
This files define some environment variables, which are used in the scripts described here. MODE tells connect whether it shall call i4l or drive a modem, IP_ADDRESS is the IP address of the remote you want to dial in, OPTIONS_FILE is the (i)pppd options file for this remote. isdn4linux needs the telephone number of the remote (PHONE), and pppd needs a chat script (CHAT_SCRIPT) and the serial port name (DEVICE), where the modem is connected.

You can load down a database with date for several universities and other providers.

By the way: I would be pleased to get the configuration file for your provider - just mail it!

Default Values

Some data are loaded while system startup. Therefore you must write a configuration file. Here is mine:
/usr/lib/connect/base
#!/bin/bash
# (c) 1997 Bernhard Hailer (GNU GPL V.2)

# Edit this file for your needs

# local settings
# ==============

# Fully qualified host name
read MY_HOSTNAME </etc/HOSTNAME                          # read host's name
# MY_HOSTNAME=foo.bar.com

# Host phone number and MSN (EAZ) - replace by your numbers!
MY_PHONE=817890032                                          # no leading zero!
MY_EAZ=90032

# Email address for fetching mail - replace by your address!
MY_EMAIL_ADDRESS=dl4mhk@lrz.uni-muenchen.de


# extra start commands for rc.connect (e.g. module loading)
# ---------------------------------------------------------
function Con_Start()
{
  insmod /lib/modules/`/bin/uname -r`/misc/isdn.o
  insmod /lib/modules/`/bin/uname -r`/misc/hisax.o io=3,2,12,0xd80 HiSax_id=Teles0
  #insmod /lib/modules/`/bin/uname -r`/misc/teles.o io=0,12,0xd80,2 teles_id=Teles0
  #rmmod teles.o
  #insmod /lib/modules/`/bin/uname -r`/misc/teles.o io=0,12,0xd80,2 teles_id=Teles0
  return
}

# extra stop commands for rc.connect (e.g. module unloading)
# ----------------------------------------------------------
function Con_Stop()
{
  rmmod hisax.o  
  #rmmod teles.o
  sleep 1
  rmmod isdn.o
  return
}

# Default remote providers for regular connects
DEFAULT_REMOTES="lrz-d1 lrz-d2"

# default device where your modem is connected - no leading "/dev/"!
DEFAULT_DEVICE="ttyS1"

# Maximum number of dialin attempts
declare -i DEFAULT_MAX_TRIES
DEFAULT_MAX_TRIES=4

# Maximum idle time before hangup (you should use a time of about 300 secs
# here, because it is more expensive to dial often than to hold a line!)
# This only works for isdn4linux connections.
declare -i HUPTIMEOUT
HUPTIMEOUT=300             # 5 min
The shell functions Con_Start() and Con_Stop() are called from the script rc.connect - these functions are very interesting if you load your ISDN subsystem as modules: enter here the commands for loading and unloading the modules. Examples for the Teles and the HiSax driver are printed here (I'm using currently HiSax 1.4 to drive a Teles 16.3 card).

Here also some default values are defined. DEFAULT_REMOTES contains the file names of the remotes which shall be called by default (if you define more than one, "connect" tries to call one after the other until the connection establishes). DEFAULT_MAX_TRIES says how often this should happen. HUPTIMEOUT is valid only for isdn4linux. Enter here after how many idle time isdn4linux shall hang up (modems: read the manual, please). And DEFAULT_DEVICE is the name of the serial interface the modem normally is connected.

We will discuss now this script rc.connect.

What Happens While Booting

There are two possibilities Linux may boot. One is simpleinit (e.g. Slackware), the other one (more complicated, but also more flexible) is sysvinit (S.u.S.E. since 4.0, Debian, Caldera, Red Hat...). These two need different linking of the ISDN startup scripts.

simpleinit

simpleinit has its startup scripts in /etc/rc.d/. There are some single scripts. Important for us are the files rc.M (calls some startup scripts) and rc.6 (reboot script). In this directory we set a new file named rc.isdn, which starts up the ISDN system.

You must create this file. Before this you must add the following to /etc/rc.d/rc.M, because this new file must be known by the booting system:

/etc/rc.d/rc.M, section "# Initialize the NET subsystem."
  . /etc/rc.d/rc.inet1
  . /etc/rc.d/rc.connect    # <-- add this line!
  . /etc/rc.d/rc.inet2

sysvinit

Under sysvinit the start-up is completely different. Here the scripts are in the directory /sbin/init.d/, /etc/init.d or /etc/rc.d/. The scripts do have two functionalities: called with the argument "start" it starts up a part of the system, called with the argument "stop" it shuts down. This whole thing works with so-called "run levels"; level 0 is "system halt", level 1 is "single user mode", level 2 commonly is "multi user mode with network" and level 3 is "with xdm", and finally level 6 is running shutdown. The system calls the first three levels one after the other while startup (using "start"). In run level 6 they are called vice versa (using "stop").

This sequence is a bit "tricky": a "master script" looks into the directory of the run level (./rc1.d, ./rc2.d, ./rc3.d and so on) what to do. Therein are a lot of soft links to the scripts I wrote above. All links are named

  SnnScriptName
or
  KnnScriptName
with a number nn, which tells the master script in which order it has to call these scripts. So if we create a script - let's call it rc.connect again -, we must also set two links in the runlevel 2 directory ./rc2.d:
  root:# cd /sbin/init.d/rc2.d  # (please verify path!!)
  root:# ln -s ../rc.connect K20rc.connect
  root:# ln -s ../rc.connect S20rc.connect
  root:# _
Remark for S.u.S.E. users (version 4 and newer): A similar file exists here, named i4l, also there may exist a file i4l_hardware. These files must be removed, and also their calling scripts in /sbin/init.d/rc2.d. Of course so the I4L_* entries in the S.u.S.E. configuration file /etc/rc.config are obsolete now.

Sorry for this inconvenience, but this is necessary to get a distribution independent package.

System Start and Stop

The file(s) you need for simpleinit or for sysvinit you can load down as usual in this tutorial. Because the script is awfully big I only descripe here how the ISDN subsystem is booted within this script (modems don't need startup sections). Just load and install this script as described above.
/sbin/init.d/rc.connect (cutting)
  /sbin/isdnctrl verbose 0  # For debugging set to 2 (max. 4)
  # ISDN device drivers     ippp0 (PPP)
  /sbin/isdnctrl addif      ippp0
  /sbin/isdnctrl pppbind    ippp0 0
  /sbin/isdnctrl addphone   ippp0 out $PHONE      # dial-out number
  /sbin/isdnctrl addphone   ippp0 in $MY_PHONE    # my telephone no
  /sbin/isdnctrl eaz        ippp0 $MY_EAZ         # my MSN / EAZ
  /sbin/isdnctrl huptimeout ippp0 $HUPTIMEOUT     # defined in $BASE
  /sbin/isdnctrl secure     ippp0 on              # nobody may enter
  /sbin/isdnctrl l2_prot    ippp0 hdlc
  /sbin/isdnctrl l3_prot    ippp0 trans
  /sbin/isdnctrl encap      ippp0 syncppp
  /sbin/ifconfig ippp0 $MY_HOSTNAME pointopoint $IP_ADDRESS metric 1
  /sbin/route add default ippp0                   # interface definitions 
  /sbin/ipppd /dev/ippp0 file $OPTIONS_FILE &
  /sbin/route del default
  ifconfig ippp0 down
Some people must edit the PATH in this script!

You must make this file executable by typing in chmod 744 now.

You see: some of the environment variables defined above are used here! Some commands are remarkable: the "pppbind" command is against side effects, if more than one ipppd is started. If you don't call this command, all ipppd's use the passwords defined for the first one! The last two commands are also essential: only if no ipppd is up you can start a regular pppd for modems without problems!

By the way: We don't call the standard PPP daemon pppd 2.2.0[ef] here, but an especially patched version named "ipppd". This pppd is part of the ISDN4Linux package and is set while installation to /sbin. Anyway the PPP HOWTO and the pppd manpage is valid.

More Files

To get this stuff working you must edit some more files as root: Either pppd or ipppd use the file /etc/ppp/options to load central configuration parameters. You can tell the (i)pppd with the command line argument file to load more files - we already have defined these files while building our remote files (OPTIONS_FILE). Here now /etc/ppp/options, which always is loaded:
/etc/ppp/options
# comment out the following three lines if you don't need 
# dynamic IP negotiation.
ipcp-accept-local
ipcp-accept-remote
noipdefault
# more pppd/ipppd options
lock
mru 1500
mtu 1500
debug
-detach
If you don't dynamically receive your IP from your provider you must comment out the first three options. The rest is needed always. Now let's have a look at the extra option files. They are necessary, because
sample file for the pppd
   pppd
# /etc/ppp/options
crtscts
user hailer
sample file for the ipppd
# /etc/ppp/options for ipppd
useifip
-vjccomp
-ac
-pc
-detach
-bsdcomp
-vj
user hailer
Remark to option "-vj": If you don't define this option the system may get very angry. X Window sessions simply may hang, while common vt100 sessions may show some "kernel oopses". You may especially see the line "Aiee, killing interrupt handler". The option useifip is against side effects, if more than one ipppd is running.
/etc/resolv.conf: (see provider database)
search <what_you_need>
nameserver <IP 1st nameserver> 
nameserver <IP 2nd nameserver> 
nameserver <IP 3rd nameserver>
You may enter here max. three nameservers. At "search" you can enter where short hostnames shall be searched. Example: If you have a "search" entry like this: search lrz-muenchen.de the command ping sun3 will find sun3.lrz-muenchen.de.
/etc/host.conf:
  order hosts bind
  multi on

/etc/hosts:
  # For loopbacking.
  127.0.0.1       localhost
  # My own IP address
  192.168.1.1     machine.name                alias    # or your own IP address
  # (192.168.x.x is free, you always may use it!)
  # example entries
  129.187.10.22   sun3.lrz-muenchen.de        sun3     # (example remote)
  129.187.13.48   sunmailhost.lrz-muenchen.de getmail  # (example, for email)
  129.187.13.48   news.lrz-muenchen.de        getnews  # (example, for news)

Authentification

You must authentificate yourself at the provider if you use PPP. Therefore two methods exist: PAP (Password Authentification Protocol) and CHAP (Challenge Authentification Protocol). PAP is widely used, but CHAP offers the provider more security. The secrets are in the file /etc/ppp/pap-secrets or /etc/ppp/chap-secrets. Attention! The/etc/ppp/pap-secrets file contains passwords and must be secured in any cases against unauthorized access!
  root:# chmod 600 /etc/ppp/pap-secrets (or /etc/ppp/chap-secrets)
  root:# _

PAP

/etc/ppp/pap-secrets
  # Secrets for authentification using PAP
  # client          server           secret          IP addresses
  <provider_login>  <1st provider>   '<password>'    -
  <provider_login>  <2nd provider>   '<password>'    -
Remarks:

Don't forget to secure it with chmod 600 /etc/ppp/pap-secrets!

CHAP

Providers don't know your fully qualified hostname in most cases. So you have to rename your machine to the same name as your login at your provider - don't use a domain. But you can do it a more elegant way: give "name <provider_login>" as option while calling the ipppd (or make an entry in /etc/ppp/options). Instead of /etc/ppp/pap-secrets you must create a file /etc/ppp/chap-secrets like this (please note: there are two lines required per provider entry!):
/etc/ppp/chap-secrets
  # Secrets for authentification using CHAP
  # client          server             secret       IP addresses
  <provider_login>  <1st provider>      <password>
  <1st provider>     <provider_login>   ""
  <provider_login>  <2nd provider>      <password>
  <2nd provider>     <provider_login>   ""
Don't forget to secure it with chmod 600 /etc/ppp/chap-secrets!

Some Polish

Now you should bend the PPP log to an extra file for debugging. Therefore you should edit /etc/syslog.conf and add the following line (remark: use only tabulator characters, no spaces!):
  daemon.*                      /var/log/ppp-log
With this all the stuff the PPP daemon tells is saved to /var/log/ppp-log.

Running

The system sometimes likes to connect more or less without any motivation to the provider. This is because of the nature of the system: If there is any IP packet (e.g. a name server request) Linux wants to get rid of it. Because this costs money we must switch it off. You could do it by deleting the default route, so that Linux now doesn't know any longer the way out.

The newer kernels since 1.3.100 have a something painful behavior: they set the default route automatically when a interface is defined. To prevent collisions you need to wait until a connect is completely built up (dialing, PPP handshake) before setting the default route. The following script does this. It is written so that you may call it more than once, so the first application (e.g. exchanging email) makes the connect, and the next applications don't need to open more lines. The last application cleans up: it hangs up and deletes the default route. Call this script as /sbin/connect on und /sbin/connect off. Here's only a very short example; you can load down a very sophisticated script by clicking onto the headline.

Put the script to /sbin and make it executable (route may be called only by "root"!):

  root:# chmod 744 /sbin/connect
  root:# _
/sbin/connect
  #! /bin/bash

  PATH=/sbin:/usr/sbin:/bin:/usr/bin

  #  ISDN4Linux:

  case $1 in
    on)
      isdnctrl dial ippp0       #  connect
      sleep 5                   #  wait until open
      route add default ippp0   #  set route
      ;;
    off)
      isdnctrl hangup ippp0     #  disconnect
      route del default         #  and delete route
      ;;
    *)
      echo -e "\a Usage: 'isdn on' or 'isdn off'"
      ;;
  esac

  # Modem:

  IF_FILE=/var/lib/connect/interface
  case $1 in
    on)
      pppd connect "chat $CHAT_SCRIPT" file $OPTIONS_FILE /dev/$DEVICE &
      # the interface name was saved now by /etc/ppp/ip-up in IF_FILE.
      sleep 1
      echo "Sleeping 40 seconds for establishing connection..."
      sleep 40
      read INTERFACE <$IF_FILE
      route add default $INTERFACE
      ;;
    off)
      kill -HUP `cat /var/lock/LCK..$DEVICE`
      route del default
      ;;
  esac
Some people must edit the PATH in this script!

For modem usage INTERFACE must be retrieved with a trick: while startup of pppd the script /etc/ppp/ip-up is called with these arguments:

  ip-up interface device speed local_address remote_address
And we use that. We create a file ip-up:
/etc/ppp/ip-up
#!/bin/bash
# This script is called by (i)pppd while starting up.
# It is called this way:
#   ip-up interface device speed local_address remote_address.
#   So you can get the used interface by fetching $1
echo $1 >/tmp/connect_interface.tmp
And so we have saved the interface name!

Hints for more experiments:

Test:

  root:# connect
  Calling ippp0
  Dialing of ippp0 triggered
  Sleeping 8 sec for PPP handshaking...
  Line open - checking...
  :-) Line is ok - have fun!
  root:# telnet sun3
  [...]
(now log in as usual; later type in "exit" to finish)
  root:# connect off
  Last application stopped - closing line.
  prov0 hung up
  prov1 already closed! To force closing use "connect off all"
  root:# _

What can "connect" do?

You just learned about the first two possibilities:
"connect" (or "connect on")        connect default remote
"connect off"                      disconnect
Important command:
"connect off all"                  disconnects all channels
It is easy to connect to other remotes:
"connect remote1 (on)"             connect to remote1
"connect remote1 off"              and disconnect from it
If you enter more than one remotes in the command line, one after another will be tried, until a connection establishes.
"connect remote1 remote2 remote3 ..."
You also may build more than one connection at the same time. Of course it is nonsense to set the defaultroute more than one time; you need to set special routes for each remote:
"connect remote1 route Netz-IP"    connect via route
"connect remote2 route default"    connect via defaultroute
The route must match the remote! You don't really need "route default.

If the dial-in ports of your provider are heavily loaded, you may want to have a maximum number of dial attempts:

"connect remote1 maxtries number"       
If you don't enter a "maxtries" the default value is taken from /usr/lib/connect/base.

And this is similar:

"connect remote1 device ttySn"       
So you tell "connect" where your modem is connected, if you want to use a modem. If you don't enter a "device" the default device is taken from /usr/lib/connect/base.

More Utilities

There are some more very useful tools within the ISDN4Linux package. One is the X program "isdnmon" by Andreas Kool, wich shows the actual state of the S0 bus (free or connected). Michael Knigge's "imon" does the same in terminals. Also very useful is "isdnlog" by Andreas Kool, which gives information about the S0 bus activity. With "imontty" by Volker Goetz you can get a print-out of the ISDN card activity - very useful for scripts!

Have a look at the README by Fritz Elfert.


Bernhard Hailer
Last modification: 24-Feb-97 BeH