Brother HL-L5100DN and Slackware Linux

The Generic PCL 6 driver works; printing at the command line is fun
Tagged: slackware linux howto cli

Update: I have also successfully used the PCL 6 drivers a Brother HL-3070CW printer. That makes two and I suspect that any Brother printers listed as having PCL emulation (generally, the "business"-class printers) will work.

The exciting news

I can print to my HL-L5100DN with the "Generic PCL 6 LF Printer wide margin - CUPS+Gutenprint v5.2.11" driver (found under the Make "Generic") in Slackware 14.2.

For more detail (and pictures of real print-outs!), read on…​

Time to upgrade

I eventually stopped trying to get a Brother HL-L2340DW (HLL2340DW) to work with Slackware 14.2 (my Linux desktop). It it works great with Windows. It’s small, quiet, and reliable. But being inexpensive, it’s a GDI printer. It doesn’t have the ability to do much processing on its own and so printing needs to go through a proprietary driver to rasterize everything (essentially turn documents into bitmap images) before sending them to the printer.

So after some reading, I decided to upgrade to the more capable HL-L5100DN (HLL5100DN).

side by side images of the hl-l2340dw and hl-l5100dn brother printers

The biggest differences (of interest to me) were these:

Spec HL-L2340DW HL-L5100DN

Interface

USB, Wi Fi

USB, Ethernet

Duty cycle

10k pages/mo

50k pages/mo

Memory

32 Mb

256 Mb

Print speed

27

42

CPU speed

266

800

Emulation

GDI

BR-Script3, Epson FX, IBM Proprinter, PCL 6, PDF v1.7, XPS v1.0

Resolution

600x600 DPI

1200x1200 DPI

The RAM, CPU, and emulation abilities are what set the HL-L5100DN apart from it’s little "brother" (pun intended). Interestingly, it’s also almost twice as heavy (!) and a bit taller.

So, what’s the secret sauce to getting this thing working painlessly in Slackware 14.2?

CUPS setup for the HL-L5100DN

By default Slackware doesn’t have the CUPS daemon run on startup. To enable and start it, this’ll work:

# cd /etc/rc.d
# chmod +x rc.cups
# ./rc.cups start

Now, in theory, the process of adding a printer to CUPS is pretty simple. And if you know what does and doesn’t work for your printer, it can take all of 30 seconds.

  • Open a browser

  • Go to the CUPS management interface at http://localhost:631/

  • Click on Administration

  • Click on Add Printer

  • Hopefully, your printer is already listed under Discovered Network Printers (the Brother HL-L5100DN was), select the radio button and then click Continue

  • You can change the printer description or just click Continue again

  • The final step is either easy or hard, depending on whether or not your printer is already supported. In my (our) case, it’s Make: Generic, Model: Generic PCL 6 LF Printer wide margin - CUPS+Gutenprint v5.2.11

choosing the generic pcl 6 printer driver in cups

Immediately after that, I was able to print a test page from the Maintenance pull-down. It printed out almost immediately.

I gotta say, both of these printers are impressively quiet and fast and cheap (at least compared to the hulking beasts I remember from a decade ago!)

The official drivers

Brother does officialy support Linux for both of the laser printers. They even have a neat installer script which probably does most of the work for Redhat, Suse, Debian, and whichever other mainstream distros they targeted.

But the drivers are only available as (32-bit!) binaries in .deb or .rpm packages. So getting them working in Slackware isn’t nearly as straightforward as I would have liked. I messed with them for a while (for both printers) and decided I simply didn’t have the time or inclination.

The Brother linux installer is interesting, though. It’s a 3,000 line Bash shell script full of licenses, product names, and a huge amount of logic. Reading it, I discovered that you can find all of the network printers available on your network with lpinfo -v, though there are easier ways to find that out!

CUPS at the command line

In addition to normal printing tasks from GUI programs, I was excited to finally be able to incorporate printing into my options at the terminal, where I spend most of my time.

I’d read that CUPS supports both the System V-style lp and BSD-style lpr print commands and a quick ls confirmed it:

$ ls -l /usr/bin/lp*
lrwxrwxrwx 1 root root     7 Mar 24  2017 /usr/bin/lp -> lp-cups
-r-xr-xr-x 1 root root 18800 Jun 14  2016 /usr/bin/lp-cups
-rwxr-xr-x 1 root root   148 Oct 23  2015 /usr/bin/lp2pap.sh
-r-xr-xr-x 1 root root 14768 Jun 14  2016 /usr/bin/lpoptions
lrwxrwxrwx 1 root root     8 Mar 24  2017 /usr/bin/lpq -> lpq-cups
-r-xr-xr-x 1 root root 14784 Jun 14  2016 /usr/bin/lpq-cups
lrwxrwxrwx 1 root root     8 Mar 24  2017 /usr/bin/lpr -> lpr-cups
-r-xr-xr-x 1 root root 14664 Jun 14  2016 /usr/bin/lpr-cups
lrwxrwxrwx 1 root root     9 Mar 24  2017 /usr/bin/lprm -> lprm-cups
-r-xr-xr-x 1 root root 10416 Jun 14  2016 /usr/bin/lprm-cups
-rwxr-xr-x 1 root root  5470 May 27  2016 /usr/bin/lprsetup.sh
lrwxrwxrwx 1 root root    11 Mar 24  2017 /usr/bin/lpstat -> lpstat-cups
-r-xr-xr-x 1 root root 27328 Jun 14  2016 /usr/bin/lpstat-cups
-rwxr-xr-x 1 root root  2619 Mar  2  2016 /usr/bin/lpunlock

Both lp and lpr are symlinks for lpr-cups.

You can see the current list of printers with lpstat:

$ lpstat -p
printer Brother_HL-L5100DN_series is idle.  enabled since Fri 01 Jun 2018 04:25:44 PM MST
	Data file sent successfully.

And the current default printer:

$ lpstat -d
no system default destination

Since I only have the one printer available to this machine, I wish to make it the default. That way, I won’t have to specify it each time when printing, etc.

$ lpoptions -d Brother_HL5100DN_series

I was surprised that I had permission to do this without superuser status, but then learned that if envoked as a regular user, lpoptions was storing the setting just for me in ~/.cups/lpoptions:

$ cat ~/.cups/lpoptions
Default Brother_HL-L5100DN_series

Listing other options specific to the printer model using lpoptions -l is also interesting.

Okay, enough messing around, let’s print a file! I know PDF is supported

$ lp grocerylist.pdf
photo of my pdf printout via cups lp

And text

$ lp sohard.txt
photo of my text printout via cups lp

But what other types of files can I print? Well, how does CUPS answer that question itself? It turns out it has a MIME database at /usr/share/cups/mime (path found in the cupsd man page).

$ file /usr/share/cups/mime/*
/usr/share/cups/mime/braille.convs:                 ASCII text
/usr/share/cups/mime/braille.types:                 ASCII text
/usr/share/cups/mime/cupsfilters-ghostscript.convs: ASCII text
/usr/share/cups/mime/cupsfilters.convs:             ASCII text
/usr/share/cups/mime/cupsfilters.types:             ASCII text
/usr/share/cups/mime/mime.convs:                    ASCII text
/usr/share/cups/mime/mime.types:                    ASCII text
/usr/share/cups/mime/pstotiff.convs:                ASCII text
/usr/share/cups/mime/pstotiff.types:                ASCII text

What’s all this? Lo and behold, there is a manpage for these, so we can read about them with man mime.convs and man mime.types.

In essense, all of the *.types files contain mime-type and rule pairs. The rules are either filename extensions or functions to test the content of a file (such as matching file contents (string or binary) at certain offsets).

The *.convs files contain the lists of conversions (via "filters") available in CUPS.

How to find/list the available file conversion filters in CUPS
grep "^[^#]" /usr/share/cups/mime/*.convs

I wanted a more succinct list, so I filtered out duplicates, etc:

$ cd /usr/share/cups/mime
$ grep -h "^[^#]" *.convs | awk '{print $1}' | sort | uniq
application/msword
application/octet-stream
application/pdf
application/postscript
application/rtf
application/vnd.adobe-reader-postscript
application/vnd.cups-pdf
application/vnd.cups-pdf-banner
application/vnd.cups-postscript
application/vnd.cups-raster
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/x-cshell
application/x-csource
application/x-perl
application/x-shell
application/xhtml
application/xml
image/gif
image/jpeg
image/pcx
image/png
image/pwg-raster
image/svg
image/tiff
image/urf
image/vnd.microsoft.icon
image/x-bitmap
image/x-ms-bmp
image/x-photocd
image/x-portable-anymap
image/x-portable-bitmap
image/x-portable-graymap
image/x-portable-pixmap
image/x-sgi-rgb
image/x-sun-raster
image/x-xbitmap
image/x-xpixmap
image/x-xwindowdump
text/css
text/html
text/plain
text/rtf

This appears to be an exciting list. But the truth is, anything which is essentially text, such as CSS, HTML, and even the image format SVG (which I use a lot - and I guess increasingly everybody is now that browsers support it) will all print out as line-wrapped text. So don’t expect any rendering or other special handling (such as syntax highlighting) of these formats.

$ lp rat-logo.svg
photo of my svg printout via cups lp

The real standouts are PDF, PostScript, * GIF, JPEG, PNG, and TIFF.

Let’s try a PNG:

$ lp rat-logo.png
photo of my png image printout via cups lp

(And now we’re all out of white printer paper in the house. Where did it go!?)

I was impressed that CUPS scaled the image and even printed it in landscape format to fit the page!

File-less printing

Of course, the really cool thing about lp/lpr is the ability to send data directly to the printer without having to create a file first.

Let’s pipe the listing of the root directory / to lp:

$ ls -al | lp
photo of my piped ls command printout via cups lp

And generate a graph with GraphViz (available for Slackware on Slackbuilds.org):

$ echo "digraph { a -> b; b -> c; c -> a; }" | dot -Tps | lp

The dot command is for printing directed graphs and -Tps tells it to produce an output type of PostScript.

photo of my piped dot graph postscript printout via cups lp

I don’t know about you, but I think this is really cool!

I have now achieved the printing capabilities of the 1970s and it’s a huge step…​forward?

Windows

By the way, I just witnessed the most painless printing setup I’ve ever seen between the HL-L5100DN and my wife’s Windows 10 laptop. She didn’t have to install anything. At. All. It was just there, ready to print. Sigh. That’s the way it should be for all OSs.

At home, CUPS was able to find and install the printer with only the above noted hassles.

I can ping my printer by name directly:

$ ping BRN3C2AF43DXXXX
PING BRN3C2AF43DXXXX (192.168.1.170) 56(84) bytes of data.
64 bytes from BRN3C2AF43DXXXX (192.168.1.170): icmp_seq=1 ttl=255 time=3.37 ms
64 bytes from BRN3C2AF43DXXXX (192.168.1.170): icmp_seq=2 ttl=255 time=6.49 ms
^C

But at work, I needed to enter an IP address manually for the office HL-3070CW. (I think the reason has more to do with the office network than the printer itself.)

So, CUPS could see the printer in the Add Printer interface, but I couldn’t ping the printer by name, "BRNXXXXXX" (I’m not redacting the name, I just don’t have it written down.) I couldn’t ping the printer by name and it goes without saying that I also couldn’t print to it.

I figured the IP address would do the trick…​but how to find it?

So after CUPS scans the network for printers, any located devices will end up in the ARP (Address Resolution Protocol) table.

arp and arp -n

We can query the ARP table with a command called arp.

$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
BRN3C2AF43DXXXX          ether   3c:2a:f4:3d:xx:xx   C                     wlan0
192.168.1.1              ether   7c:2e:bd:99:xx:xx   C                     wlan0

Okay, so we see the printer name, but how does this help us? Ah, well, arp has the -n option to make it display "numeric" addresses:

$ arp -n BRN3C2AF43DXXXX
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.1.170            ether   3c:2a:f4:3d:xx:xx   C                     wlan0

There we go! (Note: the ARP table is stored in memory - it likely will NOT have your printer’s entry until you have CUPS do a scan to find the printer.)

nmap with snmp-brute

As an aside, it was also bothering me that I had no idea how to manually search for such devices from the command line, so after a little searching, I found this great serverfault answer:

# nmap -sU -p161 --script snmp-brute --script-args snmplist=community.lst 192.168.1.0/24

It worked great for me, finding my Brother printer and a couple Amazon devices. :-)