%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                               %
%                       Legal Notice                            %
%                                                               %
% This document is copyright (C) Olaf Kirch, okir@monad.swb.de  %
%                                                               %
% For copying conditions, please refer to the file COPYING.	%
%                                                               %
% The author is not liable for any damages, direct or indirect, %
% resulting from the use of information provided in this        %
% document.                                                     %
%                                                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% When viewing this document with vi on an 80-columns screen,   %
% do a ':se nonumber' first.                                    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                               %
%               S T A R T   O F   C H A P T E R                 %
%                                                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{The Point-to-Point Protocol}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{ppp}

\section{Untangling the P's}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{Internet!connecting to}
\index{telephone, sending data over}
\index{IP!serial line}
\index{IP!dial-up}
\index{Point-to-Point Protocol}
\index{point-to-point link}
\index{configuring!PPP|(}
\index{PPP|(}

Just like SLIP, PPP is a protocol to send datagrams across a serial
connection, but addresses a couple of deficiencies of the former.  It
lets the communicating sides negotiate options such as the IP address
and the maximum datagram size at startup time, and provides for client
authorization.  For each of these capabilities, PPP has a separate
protocol.  Below, we will briefly cover these basic building blocks of
PPP. This discussion is far from complete; if you want to know more
about PPP, you are urged to read its specification in RFC~1548, as well
as the dozen or so companion RFCs.\footnote{
  The relevant RFCs are listed in the Annoted Bibiliography at the end
  of this book.
}


\index{HDLC}
At the very bottom of PPP is the \emph{High-Level Data Link Control}
Protocol, abbreviated HDLC,\footnote{
  In fact, HDLC is a much more general protocol devised by the
  International Standards Organization (ISO).
} which defines the boundaries around the individual PPP frames, and
provides a 16~bit checksum.  As opposed to the more primitive SLIP
encapsulation, a PPP frame is capable of holding packets from other
protocols than IP, such as Novell's IPX, or Appletalk. PPP achieves
this by adding a protocol field to the basic HDLC frame that
identifies the type of packet is carried by the frame.


\index{LCP|see {Link Control Protocol (PPP)}}
\index{Link Control Protocol (PPP)}
\index{serial line!looped back}
\index{looped back serial line}
LCP, the Link Control Protocol, is used on top of HDLC to negotiate
options pertaining to the data link, such as the Maximum Receive Unit
(MRU) that states the maximum datagram size one side of the link agrees
to receive.

% LCP is also resposible for montoring the link quality, and
% the detection of looped back lines.\footnote{
%   A serial line is called looped back when you receive back whatever
%   you write to it.
% }


% LQR is described later, if at all.


\index{authorization!with PPP}
\index{PAP|see {Password Authentication Protocol}}
\index{Password Authentication Protocol}
\index{CHAP|see {Challenge Handshake Authentication Protocol}}
\index{Challenge Handshake Authentication Protocol}
An important step at the configuration stage of a PPP link is client
authorization. Although it is not mandatory, it is really a must for
dial-up lines.  Usually, the called host (the server) asks the client to
authorize itself by proving it knows some secret key.  If the caller fails
to produce the correct secret, the connection is terminated.  With PPP,
authorization works both ways; that is, the caller may also ask the server
to authenticate itself.  These authentication procedures are totally
independent of each other.  There are two protocols for different types of
authorization, which we will discuss further below.  They are named
Password Authentication Protocol, or PAP, and Challenge Handshake
Authentication Protocol, or CHAP.


\index{Network Control Protocols}
\index{NCP|see {Network Control Protocols}}
\index{IP!Network Control Protocol (PPP)}
\index{IP!Control Protocol}
\index{IPCP|see {IP, Control Protocol}}
Each network protocol that is routed across the data link, like IP,
AppleTalk, etc, is configured dynamically using a corresponding Network
Control Protocol (NCP).  For instance, to send IP datagrams across the
link, both PPPs must first negotiate which IP~address each of them uses.
The control protocol used for this is IPCP, the Internet Protocol Control
Protocol.


\index{Van Jacobson header compression}
\index{compressing TCP/IP packets}
\index{PPP!compressing data}
\index{CSLIP}
Beside sending standard IP~datagrams across the link, PPP also supports
Van~Jacobson header compression of IP~datagrams. This is a technique to
shrink the headers of TCP packets to as little as three bytes. It is
also used in CSLIP, and is more colloquially referred to as VJ~header
compression.  The use of compression may be negotiated at startup time
through IPCP as well.


%%%
% Other methods to improve thruput: protocol and addr-control
% compression.


\section{PPP on \linux}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{driver!PPP}
\index{PPP!driver}
\index{PPP!daemon}
\index{pppd@\prog{pppd}}

On \linux, PPP functionality is split up in two parts, a low-level HDLC
driver located in the kernel, and the user space \prog{pppd} daemon
that handles the various control protocols.  The current release of PPP
for \linux{} is \file{linux-ppp-1.0.0}, and contains the kernel PPP
module, \prog{pppd}, and a program named \prog{chat} used to dial up the
remote system.


The PPP kernel driver was written by Michael Callahan.  \prog{pppd} was
derived from a free PPP implementation for Sun and 386BSD machines,
which was written by Drew Perkins and others, and is maintained by Paul
Mackerras. It was ported to \linux{} by Al Longyear.\footnote{
  Both authors have said they will be very busy for some time to come.
  If you have any questions on PPP in general, you'd best ask the people
  on the NET channel of the \linux{} activists mailing list.
} \prog{chat} was written by Karl Fox.\footnote{
  \email{karl@morningstar.com}.
}


\index{tty!line discipline}
\index{line discipline}
Just like SLIP, PPP is implemented by means of a special line discipline.
To use some serial line as a PPP link, you first establish the connection
over your modem as usual, and subsequently convert the line to PPP mode.
In this mode, all incoming data is passed to the PPP driver, which checks
the incoming HDLC frames for validity (each HDLC frame carries a 16~bit
checksum), and unwraps and dispatches them.  Currently, it is able to
handle IP datagrams, optionally using Van~Jacobson header compression.
As soon as \linux{} supports IPX, the PPP driver will be extended to
handle IPX packets, too.


The kernel driver is aided by \prog{pppd}, the PPP daemon, which performs
the entire initialization and authentication phase that is necessary before
actual network traffic can be sent across the link.  \prog{pppd}'s behavior
may be fine-tuned using a number of options.  As PPP is rather complex, it
is impossible to explain all of them in a single chapter.  This book
therefore cannot cover all aspects of \prog{pppd}, but only give you an
introduction. For more information, refer to the manual pages and
\file{README}s in the \prog{pppd} source distribution, which should help
you sort out most questions this chapter fails to discuss.  If your
problems persist even after reading all documentation, you should turn to
the newsgroup \ngrp{comp.protocols.ppp} for help, which is the place where
you will reach most of the people involved in the development of
\prog{pppd}.



\section{Running \prog{pppd}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{Internet!connecting to}
\index{pppd@\prog{pppd}|(}

When you want to connect to the Internet through a PPP link, you have to
set up basic networking capabilities such as the loopback device, and
the resolver.  Both have been covered in the previous chapters.  There
are some things to be said about using DNS over a serial link; please
refer to the SLIP chapter for a discussion of this.


As an introductory example of how to establish a PPP connection with
\prog{pppd}, assume you are at \host{vlager} again. You have already
dialed up the PPP server, \host{c3po}, and logged into the \user{ppp}
account.  \host{c3po} has already fired up its PPP driver.  After
exiting the communications program you used for dialing, you execute
the following command:


\begin{tscreen}
\begin{verbatim}
# pppd /dev/cua3 38400 crtscts defaultroute
\end{verbatim}
\end{tscreen}


\index{handshake, hardware}
\index{hardware!handshake}
This will flip the serial line \file{cua3} to PPP mode and establish
an IP~link to \host{c3po}. The transfer speed used on the serial port
will be 38400bps.  The \keyword{crtscts} option turns on hardware
handshake on the port, which is an absolute must at speeds above
9600~bps.


The first thing \prog{pppd} does after starting up is to negotiate
several link characteristics with the remote end, using LCP. Usually,
the default set of options \prog{pppd} tries to negotiate will work,
so we won't go into this here.  We will return to LCP in more detail in
some later section.


For the time being, we also assume that \host{c3po} doesn't require
any authentication from us, so that the configuration phase is
completed successfully.


\index{PPP!and IP addresses}
\index{IP!address!negotiation in PPP}
\index{address!negotiation with PPP}
\prog{pppd} will then negotiate the IP parameters with its peer using
IPCP, the IP control protocol. Since we didn't specify any particular
IP~address to \prog{pppd} above, it will try to use the address obtained
by having the resolver look up the local hostname.  Both will then
announce their address to each other.


Usually, there's nothing wrong with these defaults. Even if your
machine is on an Ethernet, you can use the same IP~address for both
the Ethernet and the PPP interface.  Nevertheless, \prog{pppd} allows
you to use a different address, or even to ask your peer to use some
specific address.  These options are discussed in a later section.


\index{interface!PPP}
\index{configuring!PPP}
\index{PPP!default route}
\index{route, default}
After going through the IPCP setup phase, \prog{pppd} will prepare
your host's networking layer to use the PPP link. It first configures
the PPP network interface as a point-to-point link, using \file{ppp0}
for the first PPP link that is active, \prog{ppp1} for the second, and
so on.  Next, it will set up a routing table entry that points to the
host at the other end of the link. In the example shown above,
\prog{pppd} will make the default network route point to \host{c3po},
because we gave it the \keyword{defaultroute} option.\footnote{
  The default network route is only installed if none is present yet.
} This causes all datagrams to hosts not on your local network to be
sent to \host{c3po}. There are a number of different routing schemes
\prog{pppd} supports, which we will cover in detail later in this
chapter.


\section{Using Options Files}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\namedlabel{ppp.ppprc}{Using Options Files}
\index{PPP!option files}

Before \prog{pppd} parses its command line arguments, it scans several
files for default options.  These files may contain any valid command
line arguments, spread out across an arbitrary number of lines.
comments are introduced by has signs.


The first options file is \file{/etc/ppp/options}, which is always scanned
when \prog{pppd} starts up.  Using it to set some global defaults is a good
idea, because it allows you to keep your users from doing several things
that may compromise security.  For instance, to make \prog{pppd} require
some kind of authentication (either PAP or CHAP) from the peer, you would
add the \option{auth} option to this file.  This option cannot be
overridden by the user, so that it becomes impossible to establish a PPP
connection with any system that is not in our authentication databases.


\index{ppprc@\file{.ppprc}}
The other option file, which is read after \file{/etc/ppp/options}, is
\file{.ppprc} in the user's home directory. It allows each user to
specify her own set of default options.


A sample \file{/etc/ppp/options} file might look like this:


\begin{tscreen}
\begin{verbatim}
# Global options for pppd running on vlager.vbrew.com
auth                 # require authentication
usehostname          # use local hostname for CHAP
lock                 # use UUCP-style device locking
domain vbrew.com     # our domain name
\end{verbatim}
\end{tscreen}


\index{lock files!and PPP}
\index{PPP!lock files}
The first two of these options apply to authentication and will be
explained below.  The \option{lock} keyword makes \prog{pppd} comply
to the standard UUCP method of device locking.  With this convention,
each process that accesses a serial device, say \file{/dev/cua3},
creates a lock file named \file{LCK..cua3} in the UUCP spool directory
to signal that the device is in use. This is necessary to prevent any
other programs such as \prog{minicom} or \prog{uucico} to open the
serial device while used by PPP.



The reason to provide these options in the global configuration file
is that options such as those shown above cannot be overridden, and so
provide for a reasonable level of security. Note however, that some
options can be overridden later; one such an example is the
\keyword{connect} string.



\section{Dialing out with \prog{chat}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{establishing the connection}
\index{chat!PPP}
\index{PPP!chat script|(}

One of the things that may have struck you as inconvenient in the above
example is that you had to establish the connection manually before you
could fire up \prog{pppd}.  Unlike \prog{dip}, \prog{pppd} does not have
its own scripting language for dialing the remote system and logging in,
but rather relies on some external program or shell script to do this.
The command to be executed can be given to \prog{pppd} with the
\keyword{connect} command line option.  \prog{pppd} will redirect the
command's standard input and output to the serial line.  One useful
program for this is \prog{expect}, written by Don Libes.  It has a very
powerful language based on Tcl, and was designed exactly for this sort
of application.


\index{chat@\prog{chat}|(}
\index{chat script}
The \prog{pppd} package comes along with a similar program called
\prog{chat}, which lets you specify a UUCP-style chat script.
Basically, a chat script consists of an alternating sequence of
strings that we expect to receive from the remote system, and the
answers we are to send. We will call the expect and send strings,
respectively.  This is a typical excerpt from a chat script;


\begin{tscreen}
\begin{verbatim}
ogin: b1ff ssword: s3kr3t
\end{verbatim}
\end{tscreen}


This tells \prog{chat} to wait for the remote system to send the login
prompt, and return the login name \user{b1ff}. We only wait for
\term{ogin:} so that it doesn't matter if the login prompt starts with
an uppercase or lowercase l, or if it arrives garbled.  The following
string is an expect-string again that makes \prog{chat} wait for the
password prompt, and send our password in response.


This is basically all that chat scripts are about. A complete script to
dial up a PPP server would, of course, also have to include the appropriate
modem commands. Assume your modem understands the Hayes command set, and
the server's telephone number was 318714. The complete \prog{chat}
invocation to establish a connection with \host{c3po} would then be


\begin{tscreen}
\begin{verbatim}
$ chat -v '' ATZ OK ATDT318714 CONNECT '' ogin: ppp word: GaGariN
\end{verbatim}
\end{tscreen}


By definition, the first string must be an expect string, but as the
modem won't say anything before we have kicked it, we make \prog{chat}
skip the first expect by specifying an empty string.  We go on and send
\term{ATZ}, the reset command for Hayes-compatible modems, and wait for
its response (\term{OK}). The next string sends the dial command along
with the phone number to \prog{chat}, and expects the \term{CONNECT}
message in response.  This is followed by an empty string again, because
we don't want to send anything now, but rather wait for the login
prompt. The remainder of the chat script works exactly as described
above.


The \option{-v} option makes \prog{chat} log all activities to the
\prog{syslog} daemon's \keyword{local2} facility.\footnote{
  If you edit \file{syslog.conf} to redirect these log messages to
  a file, make sure this file isn't world readable, as \prog{chat}
  also logs the entire chat script by default~-- including passwords
  and all.
}


\index{security!PPP}
Specifying the chat script on the command line bears a certain risk,
because users can view a process' command line with the \prog{ps}
command.  You can avoid this by putting the chat script in a file, say
\file{dial-c3po}.  You make \prog{chat} read the script from the file
instead of the command line by giving it the \option{-f} option, followed
by the file name.  The complete \prog{pppd} incantation would now look like
this:


\begin{tscreen}
\begin{verbatim}
# pppd connect "chat -f dial-c3po" /dev/cua3 38400 -detach \
        crtscts modem defaultroute
\end{verbatim}
\end{tscreen}


Beside the \keyword{connect} option that specifies the dial-up script,
we have added two more options to the command line: \keyword{-detach},
which tells \prog{pppd} not to detach from the console and become a
background process. The \keyword{modem} keyword makes it perform some
modem-specific actions on the serial device, like hanging up the line
before and after the call. If you don't use this keyword, \prog{pppd}
will not monitor the port's DCD line, and will therefore not detect if
the remote end hangs up unexpectedly.



The examples shown above were rather simple; \prog{chat} allows for much
more complex chat scripts.  One very useful feature is the ability to
specify strings on which to abort the chat with an error.  Typical abort
strings are messages like \term{BUSY}, or \term{NO CARRIER}, that your
modem usually generates when the called number is busy, or doesn't pick
up the phone.  To make \prog{chat} recognize these immediately, rather
than timing out, you can specify them at the beginning of the script
using the \option{ABORT} keyword:


\begin{tscreen}
\begin{verbatim}
$ chat -v ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ...
\end{verbatim}
\end{tscreen}


In a similar fashion, you may change the timeout value for parts of the
chat scripts by inserting \option{TIMEOUT} options. For details, please
check the \file{chat(8)} manual page.


Sometimes, you'd also want to have some sort of conditional execution
of parts of the chat script. For instance, when you don't receive the
remote end's login prompt, you might want to send a BREAK, or a carriage
return. You can achieve this by appending a sub-script to an expect
string.  It consists of a sequence of send- and expect-strings, just
like the overall script itself, which are separated by hyphens. The
sub-script is executed whenever the expected string they are appended to
is not received in time.  In the example above, we would modify the chat
script as follows:


\begin{tscreen}
\begin{verbatim}
ogin:-BREAK-ogin: ppp ssword: GaGariN
\end{verbatim}
\end{tscreen}


Now, when \prog{chat} doesn't see the remote system send the login
prompt, the sub-script is executed by first sending a BREAK, and then
waiting for the login prompt again. If the prompt now appears, the
script continues as usual, otherwise it will terminate with an error.

\index{PPP!chat script|)}
\index{chat@\prog{chat}|)}


\section{Debugging Your PPP Setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{PPP!debug information}
\index{debugging!PPP setup}
\index{syslog@\prog{syslog}}
\index{checking!PPP}

By default, \prog{pppd} will log any warnings and error messages to
\prog{syslog}'s \keyword{daemon} facility.  You have to add an entry
to \file{syslog.conf} that redirects this to a file, or even the
console, otherwise \prog{syslog} simply discards these messages. The
following entry sends all messages to \file{/var/log/ppp-log}:


\begin{tscreen}
\begin{verbatim}
daemon.*                /var/log/ppp-log
\end{verbatim}
\end{tscreen}


If your PPP setup doesn't work at once, looking into this log file
should give you a first hint of what goes wrong. If this doesn't help,
you can also turn on extra debugging output using the \option{debug}
option. This makes \prog{pppd} log the contents of all control packets
sent or received to \prog{syslog}.  All messages will go to the
\keyword{daemon} facility.


Finally, the most drastic feature is to enable kernel-level debugging
by invoking \prog{pppd} with the \keyword{kdebug} option.  It is
followed by a numeric argument that is the bitwise OR of the following
values: 1 for general debug messages, 2 for printing the contents of
all incoming HDLC frames, and 4 to make the driver print all outgoing
HDLC frames. To capture kernel debugging messages, you must either run
a \prog{syslogd} daemon that reads the \file{/proc/kmsg} file, or the
\prog{klogd} daemon. Either of them directs kernel debugging to
\prog{syslog}'s \keyword{kernel} facility.



\section{IP Configuration Options}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{IP!Control Protocol}

IPCP is used to negotiate a couple of IP parameters at link
configuration time.  Usually, each peer may send an IPCP Configuration
Request packet, indicating which values it wants to change from the
defaults, and to what value. Upon receipt, the remote end inspects each
option in turn, and either acknowledges or rejects it.


\prog{pppd} gives you a lot of control about which IPCP options it will try
to negotiate.  You can tune this through various command line options we
will discuss below.


\subsection{Choosing IP Addresses}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{PPP!IP addresses|(}
\index{IP!address!negotiation in PPP}
\index{address!negotiation with PPP}

In the example above, we had \prog{pppd} dial up \host{c3po} and establish
an IP link.  No provisions were taken to choose a particular IP~address on
either end of the link.  Instead, we picked \host{vlager}'s address as the
local IP~address, and let \host{c3po} provide its own.  Sometimes, however,
it is useful to have control over what address is used on one or the other
end of the link.  \prog{pppd} supports several variations of this.


To ask for particular addresses, you generally provide \prog{pppd} with
the following option:


\begin{tscreen}
\var{local\_addr}:\var{remote\_addr}
\end{tscreen}


\noindent
where \var{local\_addr} and \var{remote\_addr} may be specified
either in dotted quad notation, or as hostnames.\footnote{
   Using hostnames in this option has consequences on CHAP
   authentication. Please refer to the section on CHAP below.
} This makes \prog{pppd} attempt to use the first address as its own
IP~address, and the second as the peer's. If the peer rejects either of
them during IPCP negotiation, no IP~link will be established.\footnote{
   You can allow the peer PPP to override your ideas of IP addresses by
   giving \prog{pppd} the \option{ipcp-accept-local} and
   \option{ipcp-accept-remote} options. Please refer to the manual page
   for details.
}


If you want to set only the local address, but accept any address the
peer uses, you simply leave out the \var{remote\_addr} part. For
instance, to make \host{vlager} use the IP~address \host{130.83.4.27}
instead of its own, you would give it \option{130.83.4.27:} on the
command line.  Similarly, to set the remote address only, you would
leave the \var{local\_addr}\/ field blank. By default, \prog{pppd}
will then use the address associated with your hostname.


\index{PPP!dynamic address assignment}
Some PPP servers that handle a lot of client sites assign addresses
dynamically: addresses are assigned to systems only when calling in, and
are claimed after they have logged off again. When dialing up such a
server, you must make sure that \prog{pppd} doesn't request any particular
IP~address from the server, but rather accept the address the server asks
you to use. This means that you mustn't specify a \var{local\_addr}
argument. In addition, you have to use the \option{noipdefault} option,
which makes \prog{pppd} wait for the peer to provide the IP~address instead
of using the local host's address.


% Under certain circumstances, it might be desirable to turn off IP
% address negotiation altogether, and solely rely on the addresses
% specified on the command line.  This can be achieved by giving
% \prog{pppd} the \option{-ip} option.

\index{PPP!IP addresses|)}

\subsection{Routing Through a PPP Link}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{routing!over PPP}
\index{PPP!routing|(}

After setting up the network interface, \prog{pppd} will usually set up
a host route to its peer only. If the remote host is on a LAN, you
certainly want to be able to connect to hosts ``behind'' your peer as
well; that is, a network route must be set up.


We have already seen above that \prog{pppd} can be asked to set the
default route using the \option{defaultroute} option.  This option is
very useful if the PPP server you dialed up will act as your Internet
gateway.


\index{ARP!proxy}
\index{proxy ARP}
\index{PPP!proxy ARP}
The reverse case, where your system acts as a gateway for a single
host, is also relatively easy to accomplish.  For example, take some
employee at the Virtual Brewery whose home machine is called
\host{loner}.  When connecting to \host{vlager} through PPP, he uses
an address on the Brewery's subnet.  At \host{vlager}, we can now give
\prog{pppd} the \option{proxyarp} option, which will install a proxy
ARP entry for \host{loner}.  This will automatically make \host{loner}
accessible from all hosts at the Brewery and the Winery.


\index{LAN!connecting}
\index{connecting LANs}
However, things aren't always as easy as that, for instance when
linking two local area networks.  This usually requires adding a
specific network route, because these networks may have their own
default routes.  Besides, having both peers use the PPP link as the
default route would generate a loop, where packets to unknown
destinations would ping-pong between the peers until their
time-to-live expired.


As an example, suppose the Virtual Brewery opens a branch in some
other city. The subsidiary runs an Ethernet of their own using the IP
network number \host{191.72.3.0}, which is subnet 3 of the Brewery's
class B network. They want to connect to the Brewery's main Ethernet
via PPP to update customer databases, etc.  Again, \host{vlager} acts
as the gateway; its peer is called \host{sub-etha} and has an
IP~address of \host{191.72.3.1.}.


When \host{sub-etha} connects to \host{vlager}, it will make the
default route point to \host{vlager} as usual. On \host{vlager},
however, we will have to install a network route for subnet~3 that
goes through \host{sub-etha}.  For this, we use a feature of
\prog{pppd} not discussed so far~-- the \prog{ip-up} command.  This is
a shell script or program located in \file{/etc/ppp} that is executed
after the PPP interface has been configured. When present, it is
invoked with the following parameters:


\begin{tscreen}
 ip-up \var{iface} \var{device} \var{speed} \var{local\_addr}
 		\var{remote\_addr}
\end{tscreen}


\noindent
where \var{iface}\/ names the network interface used, \var{device} is the
pathname of the serial device file used (\file{/dev/tty} if stdin/stdout
are used), and \var{speed} is the device's speed.  \var{local\_addr} and
\var{remote\_addr} give the IP~addresses used at both ends of the link in
dotted quad notation. In our case, the \prog{ip-up} script may contain the
following code fragment:


\begin{tscreen}
\begin{verbatim}
#!/bin/sh
case $5 in
191.72.3.1)            # this is sub-etha
        route add -net 191.72.3.0 gw 191.72.3.1;;
...
esac
exit 0
\end{verbatim}
\end{tscreen}


In a similar fashion, \prog{/etc/ppp/ip-down} is used to undo all
actions of \prog{ip-up} after the PPP link has been taken down again.


\index{routing!dynamic}
\index{gated@\prog{gated}}
However, the routing scheme is not yet complete.  We have set up routing
table entries on both PPP hosts, but so far, all other hosts on both
networks don't know anything about the PPP link.  This is not a big
problem if all hosts at the subsidiary have their default route pointing
at \host{sub-etha}, and all Brewery hosts route to \host{vlager} by
default.  If this is not the case, your only option will usually be to
use a routing daemon like \prog{gated}.  After creating the network
route on \host{vlager}, the routing daemon would broadcast the new
route to all hosts on the attached subnets.




\index{PPP!routing|)}


\section{Link Control Options}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{Link Control Protocol (PPP)|(}

Above, we already encountered LCP, the Link Control Protocol, which is
used to negotiate link characteristics, and to test the link.


The two most important options that may be negotiated by LCP are the
maximum receive unit, and the Asynchronous Control Character Map.  There
are a number of other LCP configuration options, but they are far too
specialized to discuss here. Please refer to RFC~1548 for a description
of those.


\index{serial line!protecting characters}
\index{PPP!escaping control characters}
\index{PPP!async map}
The Asynchronous Control Character Map, colloquially called the async map,
is used on asynchronous links such as telephone lines to identify control
characters that must be escaped (replaced by a specific two-character
sequence). For instance, you may want to avoid the XON and XOFF characters
used for software handshake, because some misconfigured modem might choke
upon receipt of an XOFF.  Other candidates include \term{Ctrl-]} (the
\prog{telnet} escape character).  PPP allows you to escape any of the
characters with ASCII codes 0 through 31 by specifying them in the async
map.


The async map is a bitmap 32~bits wide, with the least significant bit
corresponding to the ASCII NUL character, and the most significant bit
corrsponding to ASCII 31.  If a bit is set, it signals that the
corresponding character must be escaped before sending it across the
link.  Initially, the async map is set to \keyword{0xffffffff}, that is,
all control characters will be esaped.


To tell your peer that it doesn't have to escape all control characters
but only a few of them, you can specify a new asyncmap to \prog{pppd}
using the \option{asyncmap} option. For instance, if only \verb|^S| and
\verb|^Q| (ASCII 17 and 19, commonly used for XON and XOFF) must be
escaped, use the following option:


\begin{tscreen}
asyncmap 0x000A0000
\end{tscreen}


\index{MRU|see {PPP, Maximum Receive Unit}}
\index{PPP!Maximum Receive Unit}
\index{Maximum Receive Unit (PPP)}
\index{Maximum Transfer Unit}
The Maximum Receive Unit, or MRU, signals to the peer the maximum size
of HDLC frames we want to receive.  Although this may remind you of the
MTU value (Maximum Transfer Unit), these two have little in common. The
MTU is a parameter of the kernel networking device, and describes the
maximum frame size the interface is able to handle. The MRU is more of
an advice to the remote end not to generate any frames larger than the
MRU; the interface must nevertheless be able to receive frames of up to
1500~bytes.


\index{PPP!compressing data}
Choosing an MRU is therefore not so much a question of what the link is
capable of transferring, but of what gives you the best throughput.  If you
intend to run interactive applications over the link, setting the MRU to
values as low as 296 is a good idea, so that an occasional larger packet
(say, from an FTP session) doesn't make your cursor ``jump''.  To tell
\prog{pppd} to request an MRU of 296, you would give it the option
\option{mru 296}.  Small MRUs, however, only make sense if you don't have
VJ header compression disabled (it is enabled by default).


\prog{pppd} understands also a couple of LCP options that configure
the overall behavior of the negotiation process, such as the maximum
number of configuration requests that may be exchanged before the
link is terminated.  Unless you kow exactly what you are doing, you
should leave these alone.


Finally, there are two options that apply to LCP echo messages. PPP
defines two messages, Echo Request and Echo Response. \prog{pppd} uses
this feature to check if a link is still operating.  You can enable this
by using the \option{lcp-echo-interval} option together with a time in
seconds.  If no frames are received from the remote host within this
interval, \prog{pppd} generates an Echo Request, and expects the peer to
return an Echo Response.  If the peer does not produce a response, the
link is terminated after a certain number of requests sent.  This number
can be set using the \option{lcp-echo-failure} option.  By default, this
feature is disabled altogether.

\index{Link Control Protocol (PPP)|)}

\section{General Security Considerations}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{access!PPP}
\index{pppd@\prog{pppd}}
\index{PPP!security}
\index{security!PPP|(}

A misconfigured PPP daemon can be a devastating security breach.  It can
be as bad as letting anyone plug in their machine into your Ethernet
(and that is very bad). In this section, we will discuss a few measures
that should make your PPP configuration safe.


One problem with \prog{pppd} is that to configure the network device
and the routing table, it requires \user{root} privilege.  You will
usually solve this by running it setuid \user{root}. However,
\prog{pppd} allows users to set various security-relevant options.  To
protect against any attacks a user may launch by manipulating these
options, it is suggested you set a couple of default values in the
global \file{/etc/ppp/options} file, like those shown in the sample
file in section~\ref{ppp.ppprc}.  Some of them, such as the
authentication options, cannot be overridden by the user, and so
provide a reasonable protection against manipulations.


Of course, you have to protect yourself from the systems you speak PPP
with, too.  To fend off hosts posing as someone else, you should
always some sort of authentication from your peer.  Additionally, you
should not allow foreign hosts to use any IP~address they choose, but
restrict them to at least a few.  The following section will deal with
these topics.



\section{Authentication with PPP}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{PPP!authentication|(}

\subsection{CHAP versus PAP}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{authorization!with PPP|(}
\index{Challenge Handshake Authentication Protocol}
\index{Password Authentication Protocol}
\index{PPP!using PAP}
\index{PPP!using CHAP}

With PPP, each system may require its peer to authenticate itself
using one of two authentication protocols.  These are the Password
Authentication Protocol (PAP), and the Challenge Handshake
Authentication Protocol (CHAP).  When a connection is established,
each end can request the other to authenticate itself, regardless of
whether it is the caller or the callee.  Below I will loosely talk of
`client' and `server' when I want to distinguish between the
authenticating system and the authenticator.  A PPP daemon can ask its
peer for authentication by sending yet another LCP configuration
request identifying the desired authentication protocol.


PAP works basically the same way as the normal login procedure. The
client authenticates itself by sending a user name and an (optionally
encrypted) password to the server, which the server compares to its
secrets database.  This technique is vulnerable to eavesdroppers who may
try to obtain the password by listening in on the serial line, and to
repeated trial and error attacks.


CHAP does not have these deficiencies. With CHAP, the authenticator
(i.e. the server) sends a randomly generated ``challenge'' string to
the client, along with its hostname. The client uses the hostname to
look up the appropriate secret, combines it with the challenge, and
encrypts the string using a one-way hashing function.  The result is
returned to the server along with the client's hostname. The server
now performs the same computation, and acknowledges the client if it
arrives at the same result.


Another feature of CHAP is that it doesn't only require the client to
authenticate itself at startup time, but sends challenges at regular
intervals to make sure the client hasn't been replaced by an intruder,
for instance by just switching phone lines.


\prog{pppd} keeps the secret keys for CHAP and PAP in two separate
files, called \file{/etc/ppp/chap-secrets} and \file{pap-secrets},
respectively.  By entering a remote host in one or the other file, you
have a fine control over whether CHAP or PAP is used to authenticate
ourselves with our peer, and vice versa.


By default, \prog{pppd} doesn't require authentication from the
remote, but will agree to authenticate itself when requested by the
remote.  As CHAP is so much stronger than PAP, \prog{pppd} tries to
use the former whenever possible.  If the peer does not support it, or
if \prog{pppd} can't find a CHAP secret for the remote system in its
\file{chap-secrets} file, it reverts to PAP. If it doesn't have a PAP
secret for its peer either, it will refuse to authenticate altogether.
As a consequence, the connection is closed down.


This behavior can be modified in several ways. For instance, when
given the \option{auth} keyword, \prog{pppd} will require the peer to
authenticate itself. \prog{pppd} will agree to use either CHAP or PAP
for this, as long as it has a secret for the peer in its CHAP or PAP
database, respectively. There are other options to turn a particular
authentication protocol on or off, but I won't describe them here.
Please refer to the \file{pppd(8)} manual page for details.


If all systems you talk PPP with agree to authenticate themselves with
you, you should put the \option{auth} option in the global
\file{/etc/ppp/options} file and define passwords for each system in the
\file{chap-secrets} file. If a system doesn't support CHAP, add an entry
for it to the \file{pap-secrets} file. In this way, you can make sure no
unauthenticated system connects to your host.


The next two sections discuss the two PPP secrets files, \file{pap-secrets}
and \file{chap-secrets}. They are located in \file{/etc/ppp} and contain
triples of clients, servers and passwords, optionally followed by a list of
IP~addresses.  The interpretation of the client and server fields is
different for CHAP and PAP, and also depends on whether we authenticate
ourselves with the peer, or whether we require the server to authenticate
itself with us.



\subsection{The CHAP Secrets File}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{Challenge Handshake Authentication Protocol|(}
\index{PPP!using CHAP|(}

When it has to authenticate itself with some server using CHAP, \prog{pppd}
searches the \file{pap-secrets} file for an entry with the client field
equal to the local hostname, and the server field equal to the remote
hostname sent in the CHAP Challenge.  When requiring the peer to
authenticate itself, the roles are simply reversed: \prog{pppd} will then
look for an entry with the client field equal to the remote hostname (sent
in the client's CHAP Response), and the server field equal to the local
hostname.


The following is a sample \file{chap-secrets} file for
\host{vlager}:\footnote{
  The double quotes are not part of the password, they merely serve to
  protect the white space within the password.
}


\begin{tscreen}
\begin{verbatim}
# CHAP secrets for vlager.vbrew.com
#
# client          server            secret                addrs
#----------------------------------------------------------------------
vlager.vbrew.com  c3po.lucas.com    "Use The Source Luke" vlager.vbrew.com
c3po.lucas.com    vlager.vbrew.com  "riverrun, pasteve"   c3po.lucas.com
*                 vlager.vbrew.com  "VeryStupidPassword"  pub.vbrew.com
\end{verbatim}
\end{tscreen}


When establishing a PPP connection with \host{c3po}, \host{c3po} asks
\host{vlager} to authenticate itself using CHAP by sending a CHAP
challenge. \prog{pppd} then scans \file{chap-secrets} for an entry
with the client field equal to \host{vlager.vbrew.com} and the server
field equal to \host{c3po.lucas.com},\footnote{
  This hostname is taken from the CHAP challenge.
} and finds the first line shown above. It then produces the CHAP Response
from the challenge string and the secret (\term{Use The Source Luke}),
and sends it off to \host{c3po}.


At the same time, \prog{pppd} composes a CHAP challenge for \host{c3po},
containing a unique challenge string, and its fully qualified hostname
\host{vlager.vbrew.com}. \host{c3po} constructs a CHAP Response in the
manner we just discussed, and returns it to \host{vlager}. \prog{pppd} now
extracts the client hostname (\host{c3po.vbrew.com}) from the Response, and
searches the \file{chap-secrets} file for a line matching \host{c3po} as a
client, and \host{vlager} as the server. The second line does this, so
\prog{pppd} combines the CHAP challenge and the secret \term{riverrun,
pasteve}, encrypts them, and compares the result to \host{c3po}'s CHAP
respnose.


\index{address!negotiation with PPP}
\index{IP!address!negotiation in PPP}
\index{access!restricting}
The optional fourth field lists the IP~addresses that are acceptable
for the clients named in the first field. The addresses may be given
in dotted quad notation or as hostnames that are looked up with the
resolver.  For instance, if \host{c3po} requests to use an IP address
during IPCP negotiation that is not in this list, the request will be
rejected, and IPCP will be shut down.  In the sample file shown above,
\host{c3po} is therefore limited to using its own IP~address.  If the
address field is empty, any addresses will be allowed; a value of
\keyword{-} prevents the use of IP with that client altogether.


The third line of the sample \file{chap-secrets} file allows any host to
establish a PPP link with \host{vlager} because a client or server field of
\keyword{*} matches any hostname.  The only requirement is that it knows
the secret, and uses the address of \host{pub.vbrew.com}.  Entries with
wildcard hostnames may appear anywhere in the secrets file, since
\prog{pppd} will always use the most specific entry that applies to a
server/client pair.


% secrets ought ot be 16 chars long


There are some words to be said about the way \prog{pppd} arrives at the
hostnames it looks up in the secrets file. As explained before, the remote
hostname is always provided by the peer in the CHAP Challenge or Response
packet.  The local hostname will be derived by calling the
\func{gethostname(2)} function by default. If you have set the system
name to your unqualified hostname, such you have to provide \prog{pppd}
with the domain name in addition using the \option{domain} option:


\begin{tscreen}
\#{} pppd \ldots domain vbrew.com
\end{tscreen}


This will append the Brewery's domain name to \host{vlager} for all
authentication-related activities.  Other options that modify
prog{pppd}'s idea of the local hostname are \option{usehostname} and
\option{name}.  When you give the local IP address on the command line
using ``\var{local}\option{:}var{remote}'', and \var{local} is a name
instead of a dotted quad, \prog{pppd} will use this as the local
hostname. For details, please refer to the \file{pppd(8)} manual page.


\index{PPP!using CHAP|)}
\index{Challenge Handshake Authentication Protocol|)}

\subsection{The PAP Secrets File}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{PPP!using PAP|(}

The PAP secrets file is very similar to that used by CHAP. The first two
fields always contain a user name and a server name; the third holds the
PAP secret.  When the remote sends an authenticate request, \prog{pppd}
uses the entry that has a server field equal to the local hostname, and
a user field equal to the user name sent in the request.  When
authenticating itself with the peer, \prog{pppd} picks the secret to be
sent from the line with the user field equal to the local user name, and
the server field equal to the remote hostname.


A sample PAP secrets file might look like this:

\begin{tscreen}
\begin{verbatim}
# /etc/ppp/pap-secrets
#
# user          server          secret          addrs
vlager-pap      c3po            cresspahl       vlager.vbrew.com
c3po            vlager          DonaldGNUth     c3po.lucas.com
\end{verbatim}
\end{tscreen}


The first line is used to authenticate ourselves when talking to
\host{c3po}.  The second line describes how a user named \host{c3po} has
to authenticate itself with us.


The name \host{vlager-pap} in column one is the user name we
send to \host{c3po}.  By default, \prog{pppd} will pick the local
hostname as the user name, but you can also specify a different name by
giving the \option{user} option, followed by that name.


When picking an entry from the \file{pap-secrets} file for
authentication with the peer, \prog{pppd} has to know the remote host's
name.  As it has no way of finding that out, you have to specify it on
the command line using the \option{remotename} keyword, followed by the
peer's hostname. For instance, to use the above entry for authentication with 
\host{c3po}, we have to add the following option to \prog{pppd}'s command
line:


\begin{tscreen}
\begin{verbatim}
 \#{} pppd ... remotename c3po user vlager-pap
\end{verbatim}
\end{tscreen}


In the fourth field (and all fields following), you may specify what
IP~addresses are allowed for that particular host, just as in the CHAP
secrets file.  The peer may then only request addresses from that list.
In the sample file, we require \host{c3po} to use its real IP~address.


Note that PAP is a rather weak authentication method, and it is
suggested you use CHAP instead whenever possible. We will therefore
not cover PAP in greater detail here;  if you are interested in using
PAP, you will find some more PAP features in the \file{pppd(8)} manual
page.

\index{PPP!using PAP|)}

\index{authorization!with PPP|)}
\index{PPP!authentication|)}
\index{security!PPP|)}


\section{Configuring a PPP Server}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\index{PPP!server}

Running \prog{pppd} as a server is just a matter of adding the appropriate
options to the command line.  Ideally, you would create a special account,
say \user{ppp}, and give it a script or program as login shell that invokes
\prog{pppd} with these options. For instance, you would add the following
line to \file{/etc/passwd}:


\begin{tscreen}
\begin{verbatim}
ppp:*:500:200:Public PPP Account:/tmp:/etc/ppp/ppplogin
\end{verbatim}
\end{tscreen}


Of course, you may want to use different uids and gids than those shown
above. You would also have to set the password for the above account
using the \prog{passwd} command.


The \prog{ppplogin} script might then look like this:


\begin{tscreen}
\begin{verbatim}
#!/bin/sh
# ppplogin - script to fire up pppd on login
mesg n
stty -echo
exec pppd -detach silent modem crtscts
\end{verbatim}
\end{tscreen}


The \prog{mesg} command disables other users to write to the tty
using, for instance, the \prog{write} command. The \prog{stty} command
turns off character echoing. The is necessary, because otherwise
everything the peer sends would be echoed back to it.  The most
important \prog{pppd} option given above is \option{-detach}, because
it prevents \prog{pppd} drom detaching from the controlling tty.  If
we didn't specify this option, it would go to the background, making
the shell script exit. This would in turn would cause the serial line
to be hung up and the connection to be dropped.  The \prog{silent}
option causes \prog{pppd} to wait until it receives a packet from the
calling system before it starts sending. This prevents transmit
timeouts to occur when the calling system is slow in firing up its PPP
client.  The \option{modem} makes \prog{pppd} watch the DTR line to
see if the peer has dropped the connection, and \option{crtscts} turns
on hardware handshake.


Beside these options, you might want to force some sort of authentication,
for example by specifying \option{auth} on \prog{pppd}'s command line, or
in the global options file.  The manual page also discusses more specific
options for turning individual authentication protocols on and off.


\index{pppd@\prog{pppd}|)}

\index{PPP|)}
\index{configuring!PPP|)}

