Almost Internet with SLiRP and PPP

Connecting to the Internet with Linux.
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:

  • Display the system routing table using the command netstat -rn on your local machine. If netstat is not available, try using the command /sbin/route. If neither of those commands is available, you may need to install a networking package from your Linux distribution—stop here and check your distribution documentation or consult your local Linux guru. Your routing table should look similar to Figure 3.

Figure 3. Initial Routing Table

  • Start your favorite communications package.

  • Set your modem not to hang up when DTR is dropped (consult your modem documentation for how to do this—for Hayes-compatible modems, the command is usually at&d0).

  • If your communications package has a session logging feature (e.g., kermit's log session command), turn on session logging.

  • Dial the remote machine and log in as you normally do. If your communications package doesn't have a session logging feature, you should record the login procedure by hand, writing down both what prompts appear and what you type in response.

  • Start SLiRP from your shell prompt, using the command slirp.

  • Stop session logging if you started it above, and either suspend your communications program or disconnect it from the modem (I recommend the second; in kermit you can say set line at the command prompt to disconnect without hanging up or exiting kermit).

  • Start pppd using the command ppp-on.

  • Wait a few seconds for the connection to come up, and then display the network routing table again. Your routing table should now have entries for the remote host similar to Figure 4, where is the IP address of the remote host.

Figure 4. Final Routing Table

  • If your routing table appears to be correct, try connecting to the remote machine with the command telnet, using the IP address shown in the routing table, and log in as you normally would. If that works, try [telnet hostname of the remote machine or telnet to another host that you know of. You're connected! When you're done, use ppp-off to stop pppd, and resume your communications program. To stop SLiRP, wait a moment and type 0 (zero) five times. SLiRP actually requires a short pause in between each 0 to recognize it as a shutdown string, but normal typing speed works fine. Log out, and hang up your modem.

  • If those routing table entries do not appear, first check that your pppd configuration file /etc/ppp/options contains a defaultroute entry. Next, check that there is no entry for passive or silent in your pppd configuration file—by default, SLiRP silently waits for the other end of the PPP connection (in this case, pppd) to send configuration packets. If the entries are not there, check that pppd is still active, using the command ps ax | grep pppd--if it's not in passive or silent mode, pppd will time out if it receives no answer after sending a certain number (10 by default) of configuration requests.

  • If pppd times out, check the system logs for entries from pppd. If you didn't configure syslogd to catch messages from pppd as described above, now would be a good time to do that. Note that you can increase the level of system log messages from pppd by putting a debug entry in pppd's configuration file. SLiRP will also perform several levels of logging: slirp -d ~/slirp.log will log debugging output to the file ~/slirp.log on the remote host; adding the entry log start to the SLiRP configuration file ~/.slirprc will log startup information to ~/.slirp_start; and adding the entry debug to the PPP section of the SLiRP configuration file will log PPP debugging output to the file ~/ppplog.

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/ 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:

CONNECT 115200
Welcome to My Internet Service Provider
suchandsuch login: MY-LOGIN-ID
        blah blah blah blah
        blah blah blah blah blah blah.
TERM = unknown
TERM = (vt100) vt102

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

TIMEOUT 2   OK-at-OK atz
TIMEOUT 5   OK at&b0s0=0
            OK atdtMY-PHONE-NUMBER
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:

  • The ABORT keyword, which aborts the script at any time if any of the strings listed is received.

  • The TIMEOUT keyword, which adjusts the chat timeout in seconds, so you don't have to wait for 45 seconds to find out that your modem is not responding.

  • The “empty” send string surrounded by quotes, "", (chat accepts single or double quotes), which simply sends a carriage return.

  • The “sub-expect” sequences using hyphens (if the first string is not received, chat sends the string following the first hyphen, followed by a carriage return, and then expects the string following the second hyphen; if the first string is received, the rest of the hyphenated sequence is skipped)

  • The \q (“quiet”) escape sequence, which keeps the string from being logged, making sure that your remote password does not appear in the system logs.

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:

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.