In order to communicate over TCP/IP using a modem (such as through a dial-up account to an Internet service provider) or through some other serial device (such as a “null modem” serial cable between two machines), Linux provides the Point-to-Point Protocol software suite, commonly known as PPP. PPP is a protocol that takes packets sent over a network (such as TCP/IP) and converts them to a format that can be easily sent over a modem or serial wire. Chances are, if you have an Internet account with an ISP, the ISP’s server uses PPP to communicate with dial-up accounts. By configuring PPP under Linux, you can directly connect to your ISP account in this way.
SLIP is an earlier protocol that has the same basic features as PPP. However, it lacks certain important qualities, such as the ability to negotiate IP addresses and packet sizes. These days SLIP has more or less been supplanted entirely by PPP; however, some older ISPs may still use SLIP rather than PPP. If this is the case for you, we refer you to other sources of information, such as the Linux Network Administrator’s Guide (O’Reilly).
In this section, we will cover configuration of a PPP client — that is, a system that will connect to an ISP (or other PPP server) in order to communicate with the Internet. Setting up a Linux machine as a PPP server is also possible but is somewhat more involved; this is covered in the Linux Network Administrator’s Guide (O’Reilly).
In the U.S. and many parts of the world, people use traditional dial-up modems to send digital data over telephone lines. So we’ll cover configuration for modems first. Then we’ll show how to configure PPP for the faster and more convenient type of line called Integrated Services Digital Network (ISDN), which is especially popular in Europe and is available but not very well marketed in most of the U.S.
Most Linux systems come preinstalled with all the software needed to run PPP. Essentially, you need a kernel compiled with PPP support and the pppd daemon and related tools, including the chat program.
Most Linux distributions include PPP support in the preconfigured kernel or as a kernel module that is loaded on demand. However, it may be necessary to compile kernel PPP support yourself; this is a simple matter of enabling the PPP options during the kernel configuration process and rebuilding the kernel. PPP is usually compiled as a separate module, so it is sufficient to recompile only the kernel modules if this is the case. See Section 7.4.2 for information on compiling the kernel and modules.
The pppd and chat utilities are
user-level applications that control the use of PPP on your system;
they are included with nearly every Linux distribution. On Red Hat
systems, these utilities are installed in
/usr/sbin
and are found in the
ppp RPM package.
Also required for PPP usage is a modem that is compatible with both Linux and the type of modems used by your ISP’s server. Most 14.4, 28.8, 56K, and other standard modem types fit into this category; very few modem types are not supported by Linux, and it would be unusual for an ISP to use anything so esoteric as to require you to buy something else.
One type of modem to watch out for is the so-called “Winmodem.” This was originally a product sold by US Robotics but has now been produced in several varieties by other vendors. Winmodems use the host CPU to convert digital signals into analog signals so that they can be sent over the phone line, unlike regular modems which have a special chip to perform this function. The problem with Winmodems is that, as of this writing, the programming details for these devices are proprietary, meaning that it is very difficult to write Linux drivers for this class of devices. Some work has been done on Winmodem drivers, but your mileage using them may vary a lot. Unless you are ready to do some serious tinkering and maybe even driver hacking, Winmodems are best avoided on Linux. (Besides, some people scoff at the idea of wasting precious CPU cycles to generate modem signals, a job best left to specialized hardware. One perceived advantage of these so-called “software modems,” on the other hand, is that upgrading their functionality is simply a matter of upgrading the operating system driver that controls them, rather than buying new hardware.)
Under
Windows 95/98/ME and MS-DOS, modems and
other serial devices are named COM1 (for the first serial device),
COM2 (for the second), and so forth, up to COM4. (Most systems
support up to four serial devices, although multiport cards are
available that can increase this number.) Under Linux, these same
devices are referred to as /dev/ttyS0
,
/dev/ttyS1
, on up to
/dev/ttyS3
.[60] On most systems, at installation time
a symbolic link called /dev/modem
will be
created. This link points to the serial device on which the modem can
be found, as shown in the following listing:
% ls -l /dev/modem
lrwxrwxrwx 1 root root 10 May 4 12:41 /dev/modem -> /dev/ttyS0
If this link is incorrect for your system (say, because you know that
your modem is not on /dev/ttyS0
but on
/dev/ttyS2
), you can easily fix it as
root by entering:
# ln -sf /dev/ttyS2 /dev/modem
Several
steps are involved in PPP configuration. The first is to write a
so-called “chat script,” which
performs the “handshaking”
necessary to set up a PPP connection between your machine and the
ISP. During this handshaking phase, various pieces of information
might be exchanged, such as your ISP username and password. The
second step is to write a script that fires up the
pppd daemon; running this script causes the modem
to dial the ISP and start up PPP. The final step is to configure your
system’s /etc/resolv.conf
file
so that it knows where to find a domain name server.
We’ll go through each step in turn.
Before you start, you need to know the following pieces of information:
The ISP dial-in account phone number
Your ISP username and password
The IP address of the ISP’s domain name server
Your ISP should have told you this information when you established the account.
In addition, you might need to know the following:
The IP address of the ISP’s server
The IP address of your system (if not dynamically assigned by the ISP)
The subnet mask you should use
These last three items can usually be determined automatically during the PPP connection setup; however, occasionally this negotiation does not work properly. It can’t hurt to have this information in case you need it.
chat is a program that can perform simple handshaking between a PPP client and server during connection setup, such as exchange usernames and passwords. chat is also responsible for causing your modem to dial the ISP’s phone number and other simple tasks.
chat is automatically invoked by
pppd when started (this is discussed later). All
you need to do is write a simple shell script that invokes
chat to handle the negotiation. A simple chat
script is shown in the following example. Edit the file
/etc/ppp/my-chat-script
(as
root) and place in it the following lines:
#!/bin/sh # my-chat-script: a program for dialing up your ISP exec chat -v '' ATZ OK ATDT555-1212 CONNECT '' ogin: mdw assword: my-password
Specifying ogin
and assword
without the initial letters allows the prompts to be either
Login
or login
, and
Password
or password
.
Be sure that the file my-chat-script
is
executable; the command chmod 755 /etc/ppp/my-chat-script
will accomplish this.
Note that each line ending in a backslash should not have any characters after the backslash; the backslash forces line-wrapping in the shell script.
The third line of this script runs chat with the
options on the following lines. Each line contains two
whitespace-delimited fields: an
“expect” string and a
“send” string. The idea is that the
chat script will respond with the send string when it receives the
expect string from the modem connection. For example, the last line
of the script informs chat to respond with
my-password
when the prompt
assword
is given by the ISP’s
server.
The first line of
the handshaking script instructs chat to send
ATZ
to the modem, which should cause the modem to
reset itself. (Specifying an expect string as '' means that nothing
is expected before ATZ
is sent.) The second line
waits for the modem to respond with OK
, after
which the number is dialed using the string
ATDT555-1212
. (If you use pulse dialing rather
than tone dialing change this to ATDP555-1212
. The
phone number, of course, should be that of the remote
system’s modem line.)
When the
modem responds with CONNECT
, a newline is sent
(indicated by '' as the send string). After this,
chat waits for the prompt ogin
:
before sending the username and assword
: before
sending the password.
The various send strings starting with AT
in the
previous example are simply Hayes-modem-standard modem control
strings. The manual that came with your modem should explain their
usage; this is not specific to Linux or any other operating system.
As one example, using a comma in a phone number indicates that the
modem should pause before sending the following digits; one might use
ATDT9,,,555-1212
if a special digit (9 in this
case) must be dialed to reach an outside line.
Note that this is a very simple chat script that
doesn’t deal with timeouts, errors, or any other
extraordinary cases that might arise while you’re
attempting to dial into the ISP. See the chat
manual pages for information on how to spruce up your script to deal
with these cases. Also, note that you need to know in advance what
prompts the ISP’s server will use (we assumed
login
and password
). There are
several ways of finding out this information; possibly, the ISP has
told you this information in advance, or supplied a handshaking
script for another system such as Windows 95 (which uses a mechanism
very similar to chat). Otherwise, you can dial
into the ISP server “by hand,”
using a simple terminal emulator, such as
minicom or
seyon. The manpages for those commands can help
you do this.
Now, we’re ready to configure the pppd daemon to initiate the PPP connection using the chat script we just wrote. Generally, you do this by writing another shell script that invokes pppd with a set of options.
The format of the pppd command is:
pppddevice-name
baudrate
options
Table 15-1 shows the options supported by pppd. You almost certainly won’t need all of them.
Table 15-1. Common pppd options
Option |
Effect |
---|---|
|
Locks the serial device to restrict access to pppd. |
|
Uses hardware flow control. |
|
Doesn’t try to determine the local IP address from the hostname. The IP is assigned by the remote system. |
|
Specifies the hostname or username for PAP or CHAP identification. |
|
Specifies the netmask for the connection. |
|
Adds a default route to the local system’s routing table, using the remote IP address as the gateway. |
|
Uses the given |
|
Specifies the local and/or remote IP addresses. Either or both of these could be 0.0.0.0 to indicate that the address should be assigned by the remote system. |
|
Logs connection information through the syslog daemon. |
It is common to invoke the pppd command from a
shell script. Edit the file /etc/ppp/ppp-on
and
add the following lines:
#!/bin/sh # the ppp-on script exec /usr/sbin/pppd /dev/modem 38400 lock crtscts noipdefault defaultroute 0.0.0.0:0.0.0.0 connect my-chat-script
As with the my-chat-script
file in the earlier
example, be sure this is executable and watch out for extra
characters after a backslash at the end of a line.
With this script in place, it should be possible to connect to the ISP using the command:
% /etc/ppp/ppp-on
You need not be root to execute this command.
Upon running this script, you should hear your modem dialing, and if
all goes well, after a minute PPP should be happily connected. The
ifconfig command should report an entry for
ppp0
if PPP is up and running:
# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Bcast:127.255.255.255 Mask:255.0.0.0
UP BROADCAST LOOPBACK RUNNING MTU:3584 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0
ppp0 Link encap:Point-to-Point Protocol
inet addr:207.25.97.248 P-t-P:207.25.97.154 Mask:255.255.255.0
UP POINTOPOINT RUNNING MTU:1500 Metric:1
RX packets:1862 errors:0 dropped:0 overruns:0 frame:0
TX packets:1288 errors:0 dropped:0 overruns:0 carrier:0
collisions:0
Memory:73038-73c04
Here, we can see that PPP is up, the local IP address is 207.25.97.248, and the remote server IP address is 207.25.97.154.
If you wish to be notified when the PPP connection is established
(the ppp-on
script returns immediately), add the
following line to /etc/ppp/ip-up
:
/usr/bin/wall "PPP is up!"
/etc/ppp/ip-up
is executed when PPP establishes
an IP connection, so you can use this script to trigger the
wall command when the connection is complete.
Another simple shell script can be used to kill the PPP session. Edit
the file /etc/ppp/ppp-off
as follows:
#!/bin/sh # A simple ppp-off script kill `cat /var/run/ppp0.pid`
Running /etc/ppp/ppp-off
now kills the PPP
daemon and shuts down the modem connection.
By
itself, use of pppd along with
chat only establishes a PPP connection and assigns
you an IP address; in order to use domain names, you need to
configure the system to be aware of the domain name server provided
by your ISP. You do this by editing
/etc/resolv.conf
. The manpage for
resolver
describes this file in detail. However,
for most purposes it suffices to simply include lines of two forms:
one that specifies the list of domains to search whenever a domain
name is used, and another that specifies the address of a DNS server.
A sample /etc/resolv.conf
file might look like
this:
# Sample /etc/resolv.conf search cs.nowhere.edu nowhere.edu nameserver 207.25.97.8 nameserver 204.148.41.1
The first line indicates that every time a domain name is used (such as orange or papaya), it should be searched for in the list of specified domains. In this case, resolver software would first expand a name like papaya to papaya.cs.nowhere.edu and try to find a system by that name, then expand it to papaya.nowhere.edu if necessary and try again.
The lines beginning with nameserver
specify the IP
address of domain name servers (which should be provided by your ISP)
that your system contacts to resolve domain names. If you specify
more than one nameserver
line, the given DNS
servers will be contacted in order, until one returns a match; in
this way, one DNS server is treated as a primary and the others as
backups.
The PPP configuration described here is meant to be very simple and will certainly not cover all cases; the best sources for additional information are the manpages for pppd and chat as well as the Linux PPP HOWTO and related documents.
Happily, both chat and pppd log
messages on their progress, as well as any errors, using the standard
syslog daemon facility. By editing
/etc/syslog.conf
, you can cause these messages
to be captured to a file. To do this, add the following lines:
# Save messages from chat local2.* /var/log/chat-log # Save messages from pppd daemon.* /var/log/pppd-log
This will cause messages from chat to be logged to
/var/log/chat-log
and messages from
pppd to be logged to
/var/log/pppd-log
.
Note that these log messages will contain private information, such
as ISP usernames and passwords! It is important that you leave this
logging enabled only while you are debugging your PPP configuration;
after things are working, remove these two log files and remove the
lines from /etc/syslog.conf
.
chat will also log certain errors to
/etc/ppp/connect-errors
, which is not controlled
through the syslog daemon. (It should be safe to
leave this log in place, however.)
Some ISPs may require you to use a special authentication protocol, such as PAP (Password Authentication Protocol) or CHAP (Challenge Handshake Authentication Protocol). These protocols rely on some form of “shared secret” known to both the client and the server; in most cases, this is just your ISP account password.
If PAP or CHAP are required by your ISP, they are configured by
adding information to the files
/etc/ppp/pap-secrets
and
/etc/ppp/chap-secrets
, respectively. Each file
has four fields separated by spaces or tabs. Here is an example of a
pap-secrets
file:
# Secrets for authentication using PAP # client server secret IP or Domain mdw * my-password
The first field is your system’s name as expected by the remote system, usually your ISP username. The second field specifies the ISP’s server name; an asterisk allows this entry to match all ISP servers to which you might connect. The third field specifies the shared secret provided by your ISP; as stated earlier, this is usually your ISP password. The fourth field is primarily used by PPP servers to limit the IP addresses to which users dialing in have access. These addresses can be specified as either IP addresses or domain names. For most PPP client configurations, however, this field is not required.
The chap-secrets
file has the same four fields,
but you need to include an entry other than *
for
the service provider’s system; this is a secret the
ISP shares with you when you establish the account.
If PAP or CHAP is being used, it’s not necessary for
the chat script to include handshaking information
after CONNECT
is received; pppd
will take care of the rest. Therefore, you can edit
/etc/ppp/my-chat-script
to contain only the
lines:
#!/bin/sh # my-chat-script: a program for dialing up your ISP exec chat -v '' ATZ OK ATDT555-1212 CONNECT ''
You will also need to add the user
option to the
pppd command line in
/etc/ppp/ppp-on
, as so:
#!/bin/sh # the ppp-on script exec /usr/sbin/pppd /dev/modem 38400 lock crtscts noipdefault user mdw defaultroute 0.0.0.0:0.0.0.0 connect my-chat-script
[60] Older versions of
Linux also used special “callout”
devices, called /dev/cua0
through
/dev/cua3
. These are obsolete as of Linux kernel
Version 2.2.