return to first page linux journal archive
keywordscontents

Almost Internet with SLiRP and PPP

by Jim Knoble

It's the '90s. More and more people around the world have heard of ``getting connected to the Internet.'' Some of those have actually made the technological, intellectual, and cultural leap into ``Cyberspace''. And some of those are using Linux to get connected. I'm part of all three groups. In fact, I've become rather dependent on my Internet connection--it's like having a telephone, only more expensive.

To be connected to the Internet, you used to have only two choices: either a direct (and expensive) Internet connection, like those used by corporations and institutions, or a modem connection into somebody else's machine which had a direct Internet connection, using your computer as if it were a ``dumb terminal''. You can still do that today, if you feel like it, but with the increasingly common availability of ``real'' net connections like SLIP (Serial Line Internet Protocol) and PPP (Point-to-Point Protocol), fewer Internet users really want to feel as if all they have on their desk is a dumb terminal. Yet, for a number of reasons, the only Internet access available to some of us is a dial-up dumb-terminal-ish Internet account, or ``shell'' account.

Enter SLiRP. SLiRP is a freely available software package, written by Danny Gasparovski ( danjo@blitzen.canberra.edu.au), which makes an ordinary shell account act like a SLIP or PPP account. There are other so-called ``SLIP emulators'' available (one of the more notable of which is The Internet Adaptor--see References sidebar, as well as ``terminal multiplexers'' such as term, which uses a non-standard protocol between the shell account and the local computer. SLiRP has advantages over both groups, many of which, along with some disadvantages, the author details in the README file accompanying the SLiRP package.

The Remote Half: Installing SLiRP

SLiRP does not run on your ``local'' computer (the one that would otherwise be a dumb terminal), but rather on the ``remote'' computer (the one that's actually connected to the Internet). In order to install SLiRP properly, you need the following:

If you're not sure whether you have a compiler or editor available, please contact your system administrator, or someone else who is familiar with your remote site.

The steps involved in installing SLiRP are as follows:

Getting SLiRP

The most recent version of SLiRP available at the time of this writing is slirp-0.95h.tar.gz. See References sidebar to find SLiRP. Once you have the package, ``untar'' it somewhere useful (such as /usr/local/src)--perhaps with the command tar zxvf slirp-0.95h.tar.gz.

Compiling the source code

Documentation of many sorts is included in the SLiRP package in slirp-0.95h/docs. Instructions for compiling SLiRP are in slirp-0.95h/docs/README.compiling, the gist of which is: change to the slirp-0.95h/src directory and run the configure program located there (usually by typing ./configure); then build the program by typing make. If you have problems, consult the file slirp-0.95h/docs/README.getting-help.

Installing the program

When you have successfully compiled SLiRP, you will need to put the SLiRP binary somewhere where you can run it. If you don't already have a directory for your own programs, I suggest creating a directory called ~/bin, and then adding it to your PATH in your login scripts. If you're not sure how to do this on your system, check with your system administrator. Then, from the slirp-0.95h/src directory, perform the following commands:

strip slirp
cp slirp ~/bin
chmod 0700 ~/bin/slirp
(Alternatively, if your site has GNU `install' available, you may perform the above actions in one step with install -s -m 0700 slirp ~/bin.)

Configuring SLiRP

This is the tricky bit, partly because SLiRP is an evolving product, and its documentation is not necessarily entirely complete and up-to-date; however, I suggest reading slirp-0.95h/docs/CONFIG and slirp-0.95h/docs/README.ppp before doing anything else. Next, using your favorite text editor, create SLiRP's configuration file, called ~/.slirprc. At the very minimum, you will want to include a baudrate setting. If you're planning on using SLiRP to emulate PPP, you should also include a ppp flag, an asyncmap setting and mtu and mru values. Your .slirprc file might look something like mine:

baudrate 115200
ppp
asyncmap 0
mtu 552
mru 552
log start
You will most likely want to adjust the ``baudrate'' to suit your modem--some experimentation may be necessary. [``baudrate'' should really be bits per second, or bpsrate. Even geeks who happen to know that their 14400 bps modems run at 2400 baud shouldn't set the baudrate parameter to 2400...--ED]

Once you have SLiRP installed and configured, you can start it by simply typing slirp; SLiRP will then attempt to initiate a connection.

The Local Half: Installing PPP Under Linux

SLiRP is only half of your net connection; you also need to activate the other half of the connection on your local Linux machine. Linux, like SLiRP, ``speaks'' both SLIP and PPP--that is, support for TCP/IP networking over both SLIP connections and PPP connections is built into the Linux kernel. However, although both are available under Linux, I highly recommend using PPP instead of SLIP, for the following reasons:

In short, it is my opinion that PPP is capable of providing a more robust and reliable connection than SLIP without significantly reducing the apparent speed of the connection.

PPP support under Linux comes in two halves. One half is part of the network system drivers, and comes built into the Linux kernel. The other half is a daemon process called pppd, which comes as a separate package.

Most distributions today come with PPP support built in, but if your Linux system is built from an older distribution, you may need to install PPP support. In order to properly install PPP networking under Linux, you need gcc installed, and either:

If you don't know whether your kernel has PPP support compiled in, look for a message similar to the following when you boot up your machine:

PPP: version 0.2.7 (4 channels) [...]

You can also use the command dmesg | grep PPP to search the kernel boot messages for the above line. If no PPP messages exist, you will need to recompile your kernel to add PPP support (unless you are using the PPP kernel module; some distributions come with a PPP module ready to use). If you don't know what version your kernel is, use the uname -a command to display information about your system. If your kernel version is less than 1.1.13, you may need to recompile your kernel with a new PPP driver in order to use PPP. If you need to recompile your kernel, and especially if you need to install a newer PPP driver, see the documentation accompanying the pppd package and the Linux Documentation Project's PPP-HOWTO and Kernel-HOWTO for more information.

The steps involved in setting up PPP are as follows:

Getting pppd

The latest version of pppd at the writing of this article is ppp-2.1.2d.tar.gz. You may already have pppd; many Linux distributions include it. You can check for it with the following command: find / -name "pppd*" -print. If your distribution already has pppd installed, you can proceed to the configuration step. If you're going to be compiling pppd, untar the source package somewhere useful (such as the place you untarred SLiRP).

Compiling and installing pppd

The pppd package comes with thorough instructions, including some specifically for Linux users, located in pppd-2.1.2d/README and pppd-2.1.2d/README.linux. I recommend you read both those documents and any documentation located in pppd-2.1.2d/linux before compiling and installing pppd. Then, change to the pppd-2.1.2d/pppd directory and create a Makefile using cp Makefile.linux Makefile (I recommend copying instead of linking so that you can make changes to the makefile if necessary without affecting the original). Inspect the makefile to make sure BINDIR and MANDIR are set to the correct location to install the pppd binary and manual page respectively (to comply with the Linux Filesystem Standard, they should probably be set to /usr/sbin and /usr/man). Make any required changes to the makefile using your favorite text editor. Build pppd by running make. To install pppd, first become the superuser (either by logging in as root or using the su command) and type make install; this installs both the pppd binary and the manual page. If you are replacing an older version of pppd, you may wish to make a backup copy of the older pppd until you are sure the new one works correctly. [If you are using the latest development kernel, you will need the latest version of pppd as well; it will be the latest in the 2.2.0 series, kept in the same places as the older 2.1.2 series pppd sources.--ED]

Compiling and installing chat

The pppd package comes with a utility program called chat which performs ``expect-send'' scripts for dialing modems, performing automated logins, etc. chat is located in pppd-2.1.2d/chat/. The steps for compiling and installing chat are essentially the same as for pppd: copy the makefile, edit to suit your system, make, and then make install as the superuser. The chat manual page, however, needs to be installed by hand; use

install -m 0444 -o root -g man chat.8 /usr/man/man8/
to do this.

Configuring pppd

Now is a good time to read the manual page for pppd. While it is rather long, the manual page contains some information critical to understanding how to set up pppd, including explanations of several scripts called by pppd. There are several steps involved in properly configuring pppd, and a few more in making it convenient to use:

The system-wide configuration file, /etc/ppp/options, is the most important thing to get right for pppd to work. The file must exist and be readable by the root user, even if you don't plan to store configuration information in it--otherwise, pppd won't start. Unfortunately, there are so many possible options to configure for pppd that it's difficult to build a configuration file from scratch. I have put together an options file template for pppd, which includes each configurable option and explanatory text taken directly from the pppd manual page, and made it freely available for anonymous FTP (see References for locations). I recommend fetching the pppopt.tgz package to use as a starting point for configuration.

A configuration file for pppd looks like this:

## /etc/ppp/options -- config file for pppd
# async character map -- 32-bit hex; each bit
# is a character that needs to be escaped for
# pppd to receive it.  0x00000001 represents
# "<\>x00", and 0x80000000 represents "<\>x1f".
asyncmap 0
# Use hardware flow control (i.e. RTS/CTS) to
# control the flow of data on the serial port.
crtscts
# Add a default route to the system routing
# tables, using the peer as the gateway, when
# IPCP negotiation is successfully completed.
# This entry is removed when the PPP connection
# is broken.
defaultroute
# Set the MRU [Maximum Receive Unit] value to <n>
# for negotiation.  pppd will ask the peer to send
# packets of no more than <n> bytes. The minimum
# MRU value is 128. The default MRU value is 1500.
# A value of 296 is recommended for slow links
# (40 bytes for TCP/IP header + 256 bytes of data)
mru 552
# Disables the default behaviour when no local IP
# address is specified, which is to determine (if
# possible) the local IP address from the
# hostname. With this option, the peer will have
# to supply the local IP address during IPCP
# negotiation (unless it is specified explicitly on
# the command line or in an options file).
noipdefault

This file assumes that the modem is set to use hardware flow control (crtscts), that the link between the local machine and the remote one is 8-bit-clean (asyncmap 0), and that the remote machine will tell pppd what the local machine's IP address is (noipdefault). It also tells pppd to add a ``default route'' to the system routing tables (defaultroute), which is generally what we want for a dial-up Internet connection, and sets the ``maximum receive unit'', the largest PPP packet that pppd will accept, to 552 (mru 552).

If you want to use software flow control instead of hardware flow control for your modem, you can use xonxoff instead of crtscts. You also need to add the XON and XOFF characters to the asyncmap option, as follows: the number following asyncmap is a 32-bit hexadecimal number, where each bit represents a character between 0x00 (^@) and 0x1f (^_) which must be ``escaped'', or sent as a two-byte sequence to avoid getting swallowed or munged in transmission; asyncmap 000a0000 escapes characters 0x13 (^S) and 0x11 (^Q), the XON/XOFF characters. You will also need to add this asyncmap setting to your SLiRP configuration file on the remote host.

The network configuration files on your Linux system which you need to modify or check are:

Configuration of these files is discussed in detail in the README.linux file that comes with pppd under the heading ``General Network Configuration''; however, a few items are important for using pppd with SLiRP:

10.0.2.15 zephyr.earth zephyr

You may wish to perform certain actions when the PPP link opens and to perform others when the PPP link closes down; you can put such actions in scripts called /etc/ppp/ip-up and /etc/ppp/ip-down. For instance, I have configured smail (my mail delivery agent) to send outgoing mail to my Internet account provider, which is only available when my PPP link is up. In my ip-up script, I have a command to send any queued outgoing mail along to the smart-host for delivery.

#!/bin/sh
#
# /etc/ppp/ip-up -- do net-stuff when ppp is up
# send queued outgoing mail over new net connection
/usr/sbin/runq

The ip-up and ip-down programs do not have to be shell scripts--they could just as easily be written in Perl, Tcl, or any other scripting language. However, the scripts should be executable, i.e. they should have execute permission set (using

Do not break up the following line:

chmod 0755 /etc/ppp/ip-up /etc/ppp/ip-down

and the first line of the script should be of the format #!path-to-program, containing the complete path to the program that should run the script (e.g., #!/bin/sh for a Bourne shell script, or #!/usr/local/bin/perl for Perl).

pppd sends messages and some debugging information to the system logging facility syslogd. You may wish to configure syslogd so that those messages get logged to a separate log file; to do this you need to become the superuser and modify the syslogd configuration file /etc/syslog.conf. pppd logs to the ``daemon'' facility, so we add the following line to syslog.conf:

# Log daemon-related messages in a special place
daemon.*        /var/log/daemon.log

You should put the daemon log in the same place as your other system logs; the Linux Filesystem Standard recommends /var/log. In order to get syslogd to re-read its configuration file, send it a hangup signal using the command kill -HUP pid, where pid is the numeric process id for syslogd as shown in a listing made by a ps ax command. Alternately, use killall -HUP syslogd.

Since it can be a bit tedious trying to start and stop pppd from the command line, I recommend creating two executable scripts called ppp-on and ppp-off. The pppd package comes with sample scripts in pppd-2.1.2d/chat, which you may wish to use as a guide. Simple versions of each are shown in Figure 1 and Figure 2. You should probably install the scripts in the same place as you install pppd (for my system, /usr/local/ppp/bin).

Figure 1. Example ppp-on Script

Figure 2. Example ppp-off Script

Making the Relationship Work

With SLiRP installed on your remote host and pppd installed on your Linux machine, it's time to try to get them to work together. It's a good idea to dial into your Internet service provider (the remote machine) using your favorite communications package (such as kermit, minicom, or Seyon) for the first few times in order to test the login and connection process. There are several steps to take:

Figure 3. Initial Routing Table

Figure 4. Final Routing Table

Gluing the Pieces Together

Once you have pppd and SLiRP talking to each other, you can create a more sophisticated ppp-on script to automatically dial the remote host, log you in, start slirp, and then start pppd on your Linux machine. I have created such a script which uses the ``chat'' utility that came with the pppd package; it is shown in Figure 5.

Figure 5. Sophisticated ppp-on Script With chat Options

This shell script is designed to look in a certain directory (such as ~/.ppp or /usr/local/ppp/script) for ``chat scripts'' to use in dialing and logging in. When started with an argument, e.g., ppp-on my-isp-name, this version of ppp-on will use a chat script called ~/.ppp/my-isp-name.chat for dialing and logging in. Such a feature allows a single user to have multiple dialing scripts for multiple Internet Service Providers, and allows multiple users to keep their passwords private.

When started with the -c option, this ppp-on script can also execute a custom script after starting the PPP connection. For example, ppp-on -c would perform a script called ~/.ppp/default.ppp after starting pppd, and ppp-on -c my-isp-name would dial and automatically log me in using the chat script as described above, then perform ~/.ppp/my-isp-name.ppp after starting pppd. This can be a useful substitute for the /etc/ppp/ip-up script in a multi-user environment. Additionally, this ppp-on script allows a verbose option -v to log the execution of the chat script to the system logs for debugging.

A chat script consists of a sequence of ``expect-send'' strings separated by whitespace. chat expects to receive on its standard input the first non-keyword string in the script; when it does, it sends the next non-keyword string followed by a carriage return to the standard output, and so on. To make a customized chat script, you can use the session log you made above while logging into your remote host. A sample session log and the resulting chat script are shown here; you may wish to consult chat's manual page as well.

First, the sample session log:

at
OK
atz
OK
at&b0s0=0
OK
atdtMY-PHONE-NUMBER
CARRIER 28800
PROTOCOL: LAP-M
CONNECT 115200
Welcome to My Internet Service Provider
suchandsuch login: MY-LOGIN-ID
Password:
--SYSTEM NEWS--
        blah blah blah blah
        blah blah blah blah blah blah.
TERM = unknown
TERM = (vt100) vt102
MY-SHELL-PROMPT% slirp

And this is the chat script that matches the session log:

ABORT BUSY
ABORT "NO CARRIER"
ABORT "NO DIALTONE"
TIMEOUT 2   OK-at-OK atz
TIMEOUT 5   OK at&b0s0=0
            OK atdtMY-PHONE-NUMBER
TIMEOUT 60  CONNECT ""
TIMEOUT 10  ogin:--ogin: MY-LOGIN-ID
            ssword: \qMY-PASSWORD
            (vt100) vt102
            MY-SHELL-PROMPT% slirp

The script uses several features of chat which make it easier to perform automated logins:

If we can make it easier to log into a remote host using SLiRP, pppd, and chat, we ought to be able to make it easier to log out as well. The ppp-off script (see Figure 2) does some of this, but not quite enough. pppd does have a disconnect option, but since you may wish to use pppd to connect to multiple Internet service providers, one or more of which may not use SLiRP, there's a more flexible solution: instead of trying to use pppd to hang up the phone (which is not its job), we'll use chat to exit SLiRP and hang up the phone after pppd has disconnected the PPP link.

Figure 6. The remote-slirp-off script

Figure 6 contains a shell script called remote-slirp-off, which does just that. This shell script shows chat scripts included as arguments to chat instead of read from a script file. Note the use of double-backslashes for chat escape sequences--if they weren't doubled, the shell would remove them, and the characters which follow would simply appear to be part of the send string. The \d escape delays for one second, while the \p escape delays for a tenth of a second. \c indicates not to send a carriage return after the send string in which it appears. The script also provides a verbose option -v to log the chats to the system logs for debugging. Like chat, remote-slirp-off expects the modem to be on both standard input and standard output.

Armed with the ``glue'' of the foregoing scripts, including your custom-made chat script for dialing into your Internet account, you can start a PPP connection between pppd and SLiRP using the simple command:

ppp-on name-of-chat-script

and you can stop the connection using the simple command sequence:

ppp-off
remote-slirp-ff </dev/modem >/dev/modem

If you simply must have simple, one-word commands to perform these actions, you can easily put them into an alias, shell function, or yet another shell script.

Epilogue

In addition to the features and capabilities I have discussed here, SLiRP has more sophisticated facilities for load-balancing and restarting interrupted connections, as well as utility programs for starting a remote shell without having to log in via telnet or for sending a file over a SLiRP connection without having to use FTP; however, none of these are necessary for a working Internet connection. Check out the documentation accompanying SLiRP and the SLiRP WWW pages for more information about those extras.

Be careful not to get too addicted to a SLiRP connection. Remember: it's like having a telephone, only more expensive.

Jim Knoble ( jmknoble@mercury.interpath.com) has been friends with computers since the days of homebuilt Heathkit Z80 machines running CP/M and has been learning about Linux since late 1992. When Jim's not at work, he enjoys international folk dancing, singing in his church choir, brushing up on his German, cycling, baking bread, hiking, and writing poetry. He lives in Chapel Hill, North Carolina, home to many fine Linux products and personalities. Jim hopes that one day the world will experience lasting peace.