Next Previous Contents

2. The Most Frequently Asked Questions

In this section, the Most Frequently Asked Questions have been placed, together with their answers. You may notice that some questions have the same answer, but the symptoms appear differently.

Some of these answers will reference other material in this FAQ, or the LPRng man pages.

2.1 Why do I get malformed from address errors?

This is the number one question asked by most LPRng users who try to use LPRng with network printers or other systems supporting RFC1179 printing. For details about LPRng and RFC1179, see RFC1179 and LPRng.

The malformed from address error is usually reported when trying to send a print job from LPRng to other BSD LPR or RFC1179 LPR implementations, or with network connected printers that have a built in LPR server. This is due to the following RFC1179 rule:

Servers originate a connection from ports in the range 721-731.

WHY? These are a subset of the 'reserved' ports in UNIX, and normal users cannot open connections from them. This provides a small amount of security from UNIX users on the host 'spoofing' a server.

IMPLICATION: in order to do use a reserved port, the program must have root privileges. This means the LPR, LPD, LPQ, etc., programs must be installed SUID root. This can open up a can of worms with regard to security, but LPRng has been designed to take as much paranoid care as possible to avoid problems.

WHAT TO DO:
When installing LPRng, you will need to install the executables SUID root. In the src/Makefile, you can remove the comment from the line

PERMS=SUID_ROOT_PERMS
and then do make install. This will install the executables SUID, and owned by root.

2.2 It was working normally, then I get connection refused errors

This message usually appears when you have been sending a large number of jobs to a network printer or a remote system. The reason for this is a combination the above port 721-731 restriction and the TCP/IP timeouts. For details, see RFC1179 and LPRng, but here is a quick explanation.

A TCP/IP connection is usually specified as between srchost:srcport, desthost:destport, although in practice the order of source (src) and destination (dest) is not important.

When a connection is established, each end of the connection exchanges the necessary flow control and error control information. When a connection is terminated, each end of the connection will not accept another connection from the same host:port that was previously active for a specified timeout period, usually 10 minutes.

Some TCP/IP implementations go further: they will not allow ANY connection to be originated (via the bind() system call or API) from a port that was active, or accepted on a port that was active for this timeout period.

Now let us see what happens when we have a client program, which must originate a connection on port 721-731, connect to the server, which waits for a connection on port 515. We first try to make a connection from host:port 1.1.1.1:721 to 1.1.1.2:515. The first time that we make the connection (or the first connection) we succeed. We can transfer a file, etc., and then close the connection. When we try to reconnect from 1.1.1.1:721 to 1.1.1.2:515 we get an error such as "address already in use" or "connection refused".

Luckily, we can use port 722 to originate a connection, and we can connect from 1.1.1.1:722 to 1.1.1.2:515. We continue on, until we come to port 731, and then we need to wait for our timeouts.

SOLUTION:

It appears that most RFC1179 implementations do not check for the exact port range 721-731, but only that the connection originates from a reserved port, i.e. - in the range 1-1023. You can extend the range of ports used by LPRng by changing the

originate_port=721 731
value in the defaults (LPRng/src/common/defaults.c) file or in the lpd.conf file. I recommend the following:
originate_port=512 1022
This is, in fact, now the default in LPRng software. If you get the infamous malformed from address error message from your spooler, then you will have to set originate_port=721 731, and live with a delayed throughput.

2.3 Job is not in print queue, but it gets printed!

In the original BSD LPD implementation, the LPR program copied users files to a special spool queue directory, and then caused the LPD server to peek in the directory and print the files.

This type of operation required spool directory space, special SETUID programs, and a slew of headaches in system security and management.

The LPR, LPQ, and other user programs in the LPRng suite use TCP/IP connections and transfer jobs directly to a LPD server running on a remote host, or even the local host if appropriate. Note that this type of operation does not require a LPD server to run on each local machine. In fact, you can have a single host system performing all of your printing. This type of operation is very similar to a central mail server versus individual systems, each having their own mail server and queues.

However, some users require or want their jobs to be spooled on the local host system, and then transferred to the remote printer. This is usually the case when some type of processing (filtering) is needed in order to print the job correctly. There are several methods that can be used to force this.

Method 1: Explicit Printer Address

You can force a job to be sent directly to the pr serviced by the LPD server on host by using the form:

lpr -Ppr@host file

You can also set the PRINTER environment variable to a similar form, and get the same effect:

PRINTER=pr@host; export PRINTER;
lpr file

Method 2: User and Server Printcap Entries

If you want to have the benefits of a printcap file, i.e. - you can use aliases or abbreviations for the names of printers, then here is a couple of hints. First, the LPRng software scans the /etc/printcap file for printcap entries, combining information for the same printer into a single entry. Information found later in the printcap file will override earlier information. In addition, you can tag entries as either being used for all utilities or just for the LPD server. Here are a couple of examples:

# for all utilities
pr:lp=pr@host
# just for LPD
pr:server
  :lp=/dev/lp
# more information
pr:check_for_nonprintable@
# --- final result for LPR
pr:lp=pr@host:check_for_nonprintable@
# --- final result for LPD
pr:lp=/dev/lp:check_for_nonprintable@

As you can see, the server keyword indicates that the printcap entry is only for the printer. The LPR utility will send the job to the host, while the LPD server will print it on /dev/lp.

Note that the lp=... information overrides the :rp: (remote printer) and :rm: (remote machine) fields if they are present.

Method 3: Force sending to server on localhost

The force_localhost printcap or configuration flag forces non-LPD applications to send all requests and print jobs to the server running on the local host.

This method is similar to the previous one, but has the benefit that it can be configured as a global (i.e. - applies to all printers) rather than printer specific. You can put this in the /etc/lpd.conf file for general application, or have a printcap entry of the following form:

# for all utilities
pr:lp=pr@host:force_localhost

The LPD server will ignore the force_localhost flag, and send jobs to the pr queue on the host machine. However, the LPR, LPQ, etc., utilities will send their requests to the server running on the local host.

2.4 Job disappears and is never printed, but lpr works

This is a rather disconcerting problem, and usually occurs when sending jobs to either a network printer or a nonconforming RFC1179 print spooler. For details about LPRng and RFC1179, see RFC1179 and LPRng, but here is a quick explanation.

An LPD job consists of a control file, which contains information about the job, and one or more data files. RFC1179 is silent on the order that jobs are sent; however some implementations REQUIRE that the data files be sent first, followed by the control file.

SOLUTION:

Set the send_data_first flag in the printcap for the particular printer, or in the lpd.conf configuration file. This is:

:send_data_first:  (printcap)
send_data_first    (lpd.conf)

Note that some printers/servers INSIST on the control file first; You can clear the flag using send_job_first@ if you need to.

2.5 I get messages about bad control file format

RFC1179 describes a set of fields that MAY appear in the control file. It is silent if other ones can appear as well. Unfortunately, some implementations will reject jobs unless they contain ONLY fields from a very small set. In addition, RFC1179 is silent about the ORDER the fields can appear.

LPRng quite happily will accept jobs from poor or nonconforming RFC1179 spooler programs, but may chatter about bad formats. You can ignore these errors, or even turn them off by modifying the appropriate lines of code and recompiling.

If you are sending jobs to one of these spoolers, you can force LPRng to send jobs with only the fields described in RFC1179 and in the BSD LPD implementation by setting the the :bk: (BacKwards compatible) flag in the printcap for your printer.

2.6 What is RFC 1179, the Line Printer Daemon Protocol?

RFC1179 defines a standard method by which print jobs can be transferred using the TCP/IP protocol between hosts. The standard was developed by simply detailing the way that a version of the BSD LPD software did its job.

From the RFC Introduction:

RFC 1179 describes a print server protocol widely used on the Internet for communicating between line printer daemons (both clients and servers). RFC1179 is for informational purposes only, and does not specify an Internet standard.

Having said this, the RFC then goes on to describe the protocol used by a particular implementation of LPD. The problem was that the RFC did not provide any way to put extensions to the operations into the system, and failed to specify such interesting details as the order in which print jobs and their components could be transferred.

Comment by Patrick Powell <papowell@astart.com> :

Since 1988, there have been a large number of print spooling systems developed which claim RFC1179 conformance, but which are mutually incompatible.

Rather than live with the limited capabilities of the RFC1179 standard, LPRng has extended them by adding capabilities to perform remote control of print spoolers, encrypted and authenticated data transfers, and other operations missing from the RFC1179 specification. However, great effort was made to be backwards compatible with older and other LPD based systems.

LPRng was developed in order to be able to both accept and provide interactions with these systems. It does so by allowing various options to be used to tune how print jobs would be exchanged. Currently, LPRng can be configured to send and receive print jobs between a vast number of the existing spooling systems. It is flexible enough to act as a gateway between non-compatible systems, and has provisions to transform jobs from one format to another in a dynamic manner.

For a detailed explanation about LPRng and RFC1179, see RFC1179 and LPRng.

2.7 I want to replace lp, lpstat, etc, but my programs need them

LPRng was designed as a replacement the BSD printing system. As such, it inherited its command names and options from the latter. As you might know, System V uses a totally different set of commands, incompatible with the BSD ones.

The good news is that the LPRng binaries include an emulation for the System V commands. (See lp Simulation for details. Briefly, you create links to the appropriate programs, and invoke them by the link names. Actually, these links are installed by default in recent versions.

ln -s lpr lp
ln -s lpq lpstat
ln -s lprm cancel

If you make these links, calling lp, lpstat and cancel will give you a (partial) SVR4 emulation. They have their own man pages, which you should read if you need the emulation.

Since it is a partial emulation, you shouldn't expect everything to work. In particular, I would guess that any script which relies on the output format of one of your system binaries will break. Again, see lp Simulation for more details or additional suggestions.

2.8 What are the drawbacks to LPRng?

There are many reasons to run LPRng, and most of them are related to the extra features it has, compared to vanilla BSD LPR. A short list is given in section What is LPRng?. (A more elaborate description can be found in the LPRng package itself.)

On the other hand, there are also reasons not to switch to LPRng:

You should take these elements into account while deciding whether to stick with your old software or not. If you do not decide in favor of LPRng, you can stop reading here.


Next Previous Contents