PPP Connections Made Easy
The Internet has become a major force within business today, both for communication and casual research tasks. For an individual user with a PC and a modem, various Internet Service Providers (ISPs) provide the necessary client software to establish the connection. For businesses and other multi-user environments, however, a more cost-efficient approach is preferred. Thus, system administrators are faced with the task of providing an affordable means of connecting their organization's users to the Internet through the company's multi-user UNIX systems.
In the early days of the Internet, "real" connections were provided by expensive leased telephone lines and even more expensive packet switching gear. Other alternatives exist today for such dedicated Internet connections and for intermittent connections (on-demand), as well. Many of these connectivity alternatives use relatively inexpensive modems and the Point to Point Protocol (PPP) to provide the TCP/IP facilities required by the Internet over serial connections. This article examines the setup of PPP for on-demand (non-dedicated) connectivity in a UNIX-based, multi-user environment. I'll discuss both the hardware configuration and the software side, along with a few scripts that make the system easier for system administrators and users alike.
It is not simple to connect to Internet if you want to do it right. By doing it "right," I mean conforming to the "Internet Host Requirements" as defined by RFCs 1122 and 1123. However, if you already have TCP/IP software working on your system, you can get by with less than a full understanding of the RFC requirements with a little help from PPP. Although the various protocols are complex, there are two basic things to be taken care of: the IP routing and address resolution.
The glue that binds all hosts on the Internet is the IP routing. The host (or the network device) having two or more network interfaces configured to forward IP packets is called a router. As there are many hosts and networks on the Internet, IP routing has been designed in a way that enables routers to communicate with each other with a limited knowledge of network topology. What is important for a router (or a host) is only to know the "next-hop" router for a destination. This is accomplished through use of a default route. When a packet has to be sent to a remote destination, the router checks its routing table. If none of the entries matches the remote destination, then the default route, if it exists, is used. Therefore, many hosts and routers on the Internet can survive with only a handful of routes to particular destinations and a default route to the rest of the world.
PPP will set the default route for you - just define "defaultroute" in the /etc/ppp/options file. Some Linux distributions complicate matters by defining the default route to be the Ethernet interface. That definition will cause trouble for PPP operations because the pppd will not override the existing default route. Thus, it is wise to check the startup rc files for such a definition before firing up PPP.
Configuring Domain Name Service (DNS) isn't too complicated. But, if you have better ways of spending your time, setting up the /etc/resolv.conf file will suffice. First, obtain the IP addresses of your ISP's DNS servers. Then, for each DNS server, insert a line in that /etc/resolv.conf file in the form:
In the PPP setup presented here, I have done this in a slightly different way, but this is what the contents of the file should be while the PPP link is up.
Serial IP Background
IP is independent of the underlying link layer. To transfer the IP packets over the physical medium, there has to be a way to encapsulate IP datagrams into link layer frames. A particular link layer includes a device driver with the knowledge of physical connections and hardware details.
PPP is a common way of encapsulating TCP/IP over a serial line. It consists of three components:
1. The encapsulation of IP datagrams over a serial line;
2. LCP (Link Control Protocol) for data link establishment, configuration, and testing;
3. NCP (Network Control Protocol), which is specific for different network layer protocols.
The PPP implementation used in my company is widely available as free software and the current version is 2.2. I am using it on a Linux box and DEC Alpha running Digital UNIX (formerly OSF/1). It consists of a kernel code, the chat program, and the pppd along with various scripts and options files. You can download the PPP code from your favorite archive site.
Kernel code provides the IP datagram encapsulation. The chat program is used to connect to modem, dial the phone, talk to the provider's PPP server, and give it whatever is needed to make remote peers pppd start talking to ours. After that, two ppp daemons try to get through negotiation in three distinct phases: the LCP phase, the authentication phase (optional) and the IPCP phase. If everything goes fine, you should have the pppn interface up and running (where n is a small non-negative integer).
The purpose of the ppp script (Listing 1) is to provide easy access to Internet through your account on the remote ISP's (Internet Service Provider) peer. Still, setting everything up is a little bit to complicated. Listing 3 contains all the files you will need, but before beginning, you should gather all information about local devices and IP addresses of your ISP's name servers. Listings 1-4 are available at ftp.mfi.com in /pub/sysadmin.
Local facilities are defined in the /etc/ppp/devices file. The purpose of this file is to conceal the technicalities about a particular modem. You should know what port the modem is connected to and the speed between the computer and the device. Its format resembles that of a /etc/passwd file and has six fields. For directly connected devices, fields 5 and 6 are empty and for modems on the modem server, field 2 is empty. As users generally are not very eager to know about details like /dev/ttyS1 or nb:7002, you should put a list of services that a particular device can satisfy in field 4. Once that is done, if the user wants to transfer a file from some host on the network "happynet," he or she should enter happynet ftp or happynet fast.
Options concerning PPP are stored in the /etc/ppp/options file. The example shown here is reasonable enough for most PPP servers. Put options specific to particular port (i.e., device) into /etc/ppp/options.port. Also, if different sites require different settings, create the /etc/ppp/options.site file (e.g., options.happynet).
Every site should have its own chat file and file containing phone numbers (see /etc/ppp/happynet and /etc/ppp/happynet.phn).
There are two twin scripts to make life a lot easier: /etc/ppp/ip-up and /etc/ppp/ip-down. They are automatically called from the pppd when the link is brought up and down. As they are running set-UID root, you can implement any system changes that may be necessary while the PPP link is up within those scripts.
Finally, put all executables into /usr/local/bin (you should have this directory in PATH variable) and create soft links named after each destination to ppp script. If you are going to use modems attached to a terminal server then you should get a copy of nd package (see the Hardware Configuration Alternatives section below), compile it, and put the tcpcon and the nd programs in /usr/local/bin.
Superuser privileges are not needed to install new sites. The user can create his or her own chat and phone files and then define the PPPCONFDIR environment variable to point to the directory containing them.
Typical usage would be to bring the link up manually. However, additional functionality is provided with the -c option, which enables you to specify a command to be executed when the link is established. After the command has exited, the link will be brought down. This way users can specify unattended jobs like collecting mail or downloading files through cron scheduler. Futhermore, the -r option demands that the ppp script try to keep the link up in case of trouble. This fits well with TCP protocol, which is designed to overcome temporary network outages.
There are several points and techniques worth noting in ppp (listing 1) and netmodem (listing 2) scripts. Both of them are ksh (Korn shell) scripts, but, interestingly, it looks like you can run them with bash too. It seems that these two shells are highly compatible. However, there is one important difference: bash executes every command from a pipeline in a subshell. The consequence is that environment variables can not survive pipelines. This was the only reason for creating a temporary file in the function getdevice.
The conditional execution operators && (AND) and || (OR) are heavily used in these scripts instead of if-then constructs. These operators provide a convenient means of controlling execution of commands on a logical basis. For example, in the following construct:
command1 && command2
command2 executes upon the success of command1, that is, command2 won't execute if command1 fails for any reason. Conversely, with the construct:
command1 || command2
command2 executes only if command1 fails.
The most difficult thing to do was terminate the connection (i.e., make the pppd process bring the link down). Namely, if there are several ppp daemons running, how can we know which one the user wants to terminate? I have not found an elegant solution to this problem. The technique recommended is to leave the ppp shell script in the background while the link is up and, when you want to take the link down, to send it a TERM signal. Then, the script will catch the signal and kill the appropriate pppd.
The netmodem script is used as an interface to the programs from the nd package. Using the tiny C program ckpty.c (Listing 4), it will find an available pty and then try to connect to the modem server. The chat program is used to check the connection. However, it provides a sort of one-shot use of the port, so it is called from the main loop before bringing up the PPP link.
Hardware Configuration Alternatives
The pseudoterminal is another important concept associated with TCP/IP networks. In early days, users logged in by using dumb terminals only over the serial link, either directly connected or through a modem. Network logins are quite different and a method had to be devised to retain terminal capabilities, handle signals, etc.
A pseudoterminal is in fact a pair of virtual devices - the master (/dev/ptyMN) and the slave (/dev/ttyMN). I'll discuss an implementation from the BSD (Berkeley Software Distribution) and take an example of a telnet server and a telnet client. When the user runs the telnet client asking for an interactive session with the host, a telnetd process is spawned to deal with incoming requests. The telnetd server first has to find an available pseudoterminal to service the request. Then, it opens the master device, forks, and the child process opens the corresponding slave device. After this, the child process connects standard input, output and error streams to the slave device and execs the login process. Thus, the pseudoterminal slave device becomes the controlling terminal for the user process. In the meantime, the parent process retains control of its master device, and the network connection it has opened.
Pseudoterminals are implemented in the kernel and handled in the following way: everything written to the master device appears as input to slave and vice versa (see Figure 1). Hence, telnetd process takes care of the TCP/IP connection and passes data to the master device, and then the kernel takes it to the slave device. The signals are sent in the TCP's urgent mode to get to the user process as soon as possible. The major point is that there is a terminal line discipline implemented between the slave device and the user process (usually a shell). Terminal line discipline, being in fact a terminal driver, interprets special characters and provides all the other terminal semantics.
Pseudoterminals can be used for other things such as the script program that creates the session transcript and various systems that allow use of interactive applications in a batch (the most used one is probably expect from the Tcl/Tk package). Here, I will show how pseudoterminals can make use of a terminal server.
Terminal servers are devices that have one network interface and several serial interfaces. You can connect almost any sort of a serial device to a terminal server, including modems. Most terminal servers are able to offer a raw (direct) TCP connection to any of its serial interfaces. The nd freeware package takes advantage of this fact and provides a means to communicate directly with the modem on the terminal server as if it were connected to one of computer's serial ports. The nd programs use pseudoterminals to provide connections in much the same way as telnetd does.
A single modem can be easily attached to a system's serial port, or a pool of modems can be attached to a multiport serial card. Why would anyone prefer a terminal server to directly connected modems? The most important reason is that a modem attached to a terminal server is available to everyone on the LAN, not just the users of the system to which the modem is attached. Also, modems can be very nasty creatures and terminal servers, particularly modem servers, usually cope with them better than ordinary computers do.
However, you should take special care of timing, because the TCP connection is different from the direct serial one. For example, in my company, we have installed Sam Leffler's HylaFAX package. Among other programs, this package includes an excellent shell script, called probemodem, which examines various modem capabilities and deficiencies. At first, it refused to talk to the modem. However, after I increased the delay times of the sleep commands in the script, everything went fine.
The nd package, created by Ross Rodney Cartlidge, resides on ftp.uu.net in /networking/cisco/nd.tar.Z.
This article was not intended to cover all of the details about the PPP protocol and the underlying theory. Considerable information about the protocol and its use is available from various sources. For example, you should read the chat(8) and pppd(8) man pages and download the PPP-HOWTO file (by Robert Hart) from sunsite.unc.edu:/pub/Linux/docs/HOWTO for additional information.
Although a dedicated connection to Internet may be appropriate for large organizations with ample budgets, the setup presented here is economical and convenient for many sites. There is, of course, room for improvement in the code presented here, but I have used these scripts with considerable success.
About the Author
Dejan Muhamedagic has been involved in various UNIX systems and networking equipment maintenance and configuration for the past five years. He is currently with Yunix, a consulting company based in Belgrade. He can be reached at: firstname.lastname@example.org.